1 /* 2 * Copyright 2003-2006, Haiku Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Michael Lotz <mmlr@mlotz.ch> 7 * Niels S. Reedijk 8 */ 9 #ifndef _USB_PRIVATE_H 10 #define _USB_PRIVATE_H 11 12 #include "usbspec_private.h" 13 #include <lock.h> 14 #include <util/Vector.h> 15 16 17 #define TRACE_OUTPUT(x, y, z...) \ 18 { \ 19 dprintf("usb %s%s %" B_PRId32 ": ", y, (x)->TypeName(), (x)->USBID()); \ 20 dprintf(z); \ 21 } 22 23 //#define TRACE_USB 24 #ifdef TRACE_USB 25 #define TRACE(x...) TRACE_OUTPUT(this, "", x) 26 #define TRACE_STATIC(x, y...) TRACE_OUTPUT(x, "", y) 27 #define TRACE_MODULE(x...) dprintf("usb " USB_MODULE_NAME ": " x) 28 #else 29 #define TRACE(x...) /* nothing */ 30 #define TRACE_STATIC(x, y...) /* nothing */ 31 #define TRACE_MODULE(x...) /* nothing */ 32 #endif 33 34 #define TRACE_ALWAYS(x...) TRACE_OUTPUT(this, "", x) 35 #define TRACE_ERROR(x...) TRACE_OUTPUT(this, "error ", x) 36 #define TRACE_MODULE_ALWAYS(x...) dprintf("usb " USB_MODULE_NAME ": " x) 37 #define TRACE_MODULE_ERROR(x...) dprintf("usb " USB_MODULE_NAME ": " x) 38 39 class Hub; 40 class Stack; 41 class Device; 42 class Transfer; 43 class BusManager; 44 class Pipe; 45 class ControlPipe; 46 class Object; 47 class PhysicalMemoryAllocator; 48 49 50 struct usb_host_controller_info { 51 module_info info; 52 status_t (*control)(uint32 op, void *data, size_t length); 53 status_t (*add_to)(Stack *stack); 54 }; 55 56 57 struct usb_driver_cookie { 58 usb_id device; 59 void *cookie; 60 usb_driver_cookie *link; 61 }; 62 63 64 struct usb_driver_info { 65 const char *driver_name; 66 usb_support_descriptor *support_descriptors; 67 uint32 support_descriptor_count; 68 const char *republish_driver_name; 69 usb_notify_hooks notify_hooks; 70 usb_driver_cookie *cookies; 71 usb_driver_info *link; 72 }; 73 74 75 struct change_item { 76 bool added; 77 Device *device; 78 change_item *link; 79 }; 80 81 82 struct rescan_item { 83 const char *name; 84 rescan_item *link; 85 }; 86 87 88 typedef enum { 89 USB_SPEED_LOWSPEED = 0, 90 USB_SPEED_FULLSPEED, 91 USB_SPEED_HIGHSPEED, 92 USB_SPEED_SUPER, 93 USB_SPEED_WIRELESS, 94 USB_SPEED_MAX = USB_SPEED_WIRELESS 95 } usb_speed; 96 97 98 typedef enum { 99 USB_CHANGE_CREATED = 0, 100 USB_CHANGE_DESTROYED, 101 USB_CHANGE_PIPE_POLICY_CHANGED 102 } usb_change; 103 104 105 #define USB_OBJECT_NONE 0x00000000 106 #define USB_OBJECT_PIPE 0x00000001 107 #define USB_OBJECT_CONTROL_PIPE 0x00000002 108 #define USB_OBJECT_INTERRUPT_PIPE 0x00000004 109 #define USB_OBJECT_BULK_PIPE 0x00000008 110 #define USB_OBJECT_ISO_PIPE 0x00000010 111 #define USB_OBJECT_INTERFACE 0x00000020 112 #define USB_OBJECT_DEVICE 0x00000040 113 #define USB_OBJECT_HUB 0x00000080 114 115 116 class Stack { 117 public: 118 Stack(); 119 ~Stack(); 120 121 status_t InitCheck(); 122 123 bool Lock(); 124 void Unlock(); 125 126 usb_id GetUSBID(Object *object); 127 void PutUSBID(usb_id id); 128 Object * GetObject(usb_id id); 129 130 // only for the kernel debugger 131 Object * GetObjectNoLock(usb_id id) const; 132 133 void AddBusManager(BusManager *bus); 134 int32 IndexOfBusManager(BusManager *bus); 135 BusManager * BusManagerAt(int32 index) const; 136 137 status_t AllocateChunk(void **logicalAddress, 138 phys_addr_t *physicalAddress, 139 size_t size); 140 status_t FreeChunk(void *logicalAddress, 141 phys_addr_t physicalAddress, 142 size_t size); 143 144 area_id AllocateArea(void **logicalAddress, 145 phys_addr_t *physicalAddress, 146 size_t size, const char *name); 147 148 void NotifyDeviceChange(Device *device, 149 rescan_item **rescanList, 150 bool added); 151 void RescanDrivers(rescan_item *rescanItem); 152 153 // USB API 154 status_t RegisterDriver(const char *driverName, 155 const usb_support_descriptor * 156 descriptors, 157 size_t descriptorCount, 158 const char *republishDriverName); 159 160 status_t InstallNotify(const char *driverName, 161 const usb_notify_hooks *hooks); 162 status_t UninstallNotify(const char *driverName); 163 164 usb_id USBID() const { return 0; } 165 const char * TypeName() const { return "stack"; } 166 167 private: 168 static int32 ExploreThread(void *data); 169 170 Vector<BusManager *> fBusManagers; 171 thread_id fExploreThread; 172 bool fFirstExploreDone; 173 bool fStopThreads; 174 175 mutex fStackLock; 176 mutex fExploreLock; 177 PhysicalMemoryAllocator * fAllocator; 178 179 uint32 fObjectIndex; 180 uint32 fObjectMaxCount; 181 Object ** fObjectArray; 182 183 usb_driver_info * fDriverList; 184 }; 185 186 187 /* 188 * This class manages a bus. It is created by the Stack object 189 * after a host controller gives positive feedback on whether the hardware 190 * is found. 191 */ 192 class BusManager { 193 public: 194 BusManager(Stack *stack); 195 virtual ~BusManager(); 196 197 virtual status_t InitCheck(); 198 199 bool Lock(); 200 void Unlock(); 201 202 int8 AllocateAddress(); 203 void FreeAddress(int8 address); 204 205 virtual Device * AllocateDevice(Hub *parent, 206 int8 hubAddress, uint8 hubPort, 207 usb_speed speed); 208 virtual void FreeDevice(Device *device); 209 210 virtual status_t Start(); 211 virtual status_t Stop(); 212 213 virtual status_t StartDebugTransfer(Transfer *transfer); 214 virtual status_t CheckDebugTransfer(Transfer *transfer); 215 virtual void CancelDebugTransfer(Transfer *transfer); 216 217 virtual status_t SubmitTransfer(Transfer *transfer); 218 virtual status_t CancelQueuedTransfers(Pipe *pipe, 219 bool force); 220 221 virtual status_t NotifyPipeChange(Pipe *pipe, 222 usb_change change); 223 224 Object * RootObject() const 225 { return fRootObject; } 226 227 Hub * GetRootHub() const { return fRootHub; } 228 void SetRootHub(Hub *hub) { fRootHub = hub; } 229 230 usb_id USBID() const { return fUSBID; } 231 virtual const char * TypeName() const = 0; 232 233 protected: 234 bool fInitOK; 235 236 private: 237 ControlPipe * _GetDefaultPipe(usb_speed); 238 239 mutex fLock; 240 241 bool fDeviceMap[128]; 242 int8 fDeviceIndex; 243 244 Stack * fStack; 245 ControlPipe * fDefaultPipes[USB_SPEED_MAX + 1]; 246 Hub * fRootHub; 247 Object * fRootObject; 248 249 usb_id fUSBID; 250 }; 251 252 253 class Object { 254 public: 255 Object(Stack *stack, BusManager *bus); 256 Object(Object *parent); 257 virtual ~Object(); 258 259 Object * Parent() const { return fParent; } 260 261 BusManager * GetBusManager() const 262 { return fBusManager; } 263 Stack * GetStack() const { return fStack; } 264 265 usb_id USBID() const { return fUSBID; } 266 virtual uint32 Type() const { return USB_OBJECT_NONE; } 267 virtual const char * TypeName() const { return "object"; } 268 269 // Convenience functions for standard requests 270 virtual status_t SetFeature(uint16 selector); 271 virtual status_t ClearFeature(uint16 selector); 272 virtual status_t GetStatus(uint16 *status); 273 274 private: 275 Object * fParent; 276 BusManager * fBusManager; 277 Stack * fStack; 278 usb_id fUSBID; 279 }; 280 281 282 /* 283 * The Pipe class is the communication management between the hardware and 284 * the stack. It creates packets, manages these and performs callbacks. 285 */ 286 class Pipe : public Object { 287 public: 288 enum pipeDirection { In, Out, Default }; 289 290 Pipe(Object *parent); 291 virtual ~Pipe(); 292 293 virtual void InitCommon(int8 deviceAddress, 294 uint8 endpointAddress, 295 usb_speed speed, 296 pipeDirection direction, 297 size_t maxPacketSize, 298 uint8 interval, 299 int8 hubAddress, uint8 hubPort); 300 301 virtual uint32 Type() const { return USB_OBJECT_PIPE; } 302 virtual const char * TypeName() const { return "pipe"; } 303 304 int8 DeviceAddress() const 305 { return fDeviceAddress; } 306 usb_speed Speed() const { return fSpeed; } 307 pipeDirection Direction() const { return fDirection; } 308 uint8 EndpointAddress() const 309 { return fEndpointAddress; } 310 size_t MaxPacketSize() const 311 { return fMaxPacketSize; } 312 uint8 Interval() const { return fInterval; } 313 314 // Hub port being the one-based logical port number on the hub 315 void SetHubInfo(int8 address, uint8 port); 316 int8 HubAddress() const 317 { return fHubAddress; } 318 uint8 HubPort() const { return fHubPort; } 319 320 virtual bool DataToggle() const 321 { return fDataToggle; } 322 virtual void SetDataToggle(bool toggle) 323 { fDataToggle = toggle; } 324 325 status_t SubmitTransfer(Transfer *transfer); 326 status_t CancelQueuedTransfers(bool force); 327 328 void SetControllerCookie(void *cookie) 329 { fControllerCookie = cookie; } 330 void * ControllerCookie() const 331 { return fControllerCookie; } 332 333 // Convenience functions for standard requests 334 virtual status_t SetFeature(uint16 selector); 335 virtual status_t ClearFeature(uint16 selector); 336 virtual status_t GetStatus(uint16 *status); 337 338 private: 339 int8 fDeviceAddress; 340 uint8 fEndpointAddress; 341 pipeDirection fDirection; 342 usb_speed fSpeed; 343 size_t fMaxPacketSize; 344 uint8 fInterval; 345 int8 fHubAddress; 346 uint8 fHubPort; 347 bool fDataToggle; 348 void * fControllerCookie; 349 }; 350 351 352 class ControlPipe : public Pipe { 353 public: 354 ControlPipe(Object *parent); 355 virtual ~ControlPipe(); 356 357 virtual void InitCommon(int8 deviceAddress, 358 uint8 endpointAddress, 359 usb_speed speed, 360 pipeDirection direction, 361 size_t maxPacketSize, 362 uint8 interval, 363 int8 hubAddress, uint8 hubPort); 364 365 virtual uint32 Type() const { return USB_OBJECT_PIPE 366 | USB_OBJECT_CONTROL_PIPE; } 367 virtual const char * TypeName() const 368 { return "control pipe"; } 369 370 // The data toggle is not relevant 371 // for control transfers, as they are 372 // always enclosed by a setup and 373 // status packet. The toggle always 374 // starts at 1. 375 virtual bool DataToggle() const { return true; } 376 virtual void SetDataToggle(bool toggle) {} 377 378 status_t SendRequest(uint8 requestType, 379 uint8 request, uint16 value, 380 uint16 index, uint16 length, 381 void *data, size_t dataLength, 382 size_t *actualLength); 383 static void SendRequestCallback(void *cookie, 384 status_t status, void *data, 385 size_t actualLength); 386 387 status_t QueueRequest(uint8 requestType, 388 uint8 request, uint16 value, 389 uint16 index, uint16 length, 390 void *data, size_t dataLength, 391 usb_callback_func callback, 392 void *callbackCookie); 393 394 private: 395 mutex fSendRequestLock; 396 sem_id fNotifySem; 397 status_t fTransferStatus; 398 size_t fActualLength; 399 }; 400 401 402 class InterruptPipe : public Pipe { 403 public: 404 InterruptPipe(Object *parent); 405 406 virtual uint32 Type() const { return USB_OBJECT_PIPE 407 | USB_OBJECT_INTERRUPT_PIPE; } 408 virtual const char * TypeName() const 409 { return "interrupt pipe"; } 410 411 status_t QueueInterrupt(void *data, 412 size_t dataLength, 413 usb_callback_func callback, 414 void *callbackCookie); 415 }; 416 417 418 class BulkPipe : public Pipe { 419 public: 420 BulkPipe(Object *parent); 421 422 virtual void InitCommon(int8 deviceAddress, 423 uint8 endpointAddress, 424 usb_speed speed, 425 pipeDirection direction, 426 size_t maxPacketSize, 427 uint8 interval, 428 int8 hubAddress, uint8 hubPort); 429 430 virtual uint32 Type() const { return USB_OBJECT_PIPE 431 | USB_OBJECT_BULK_PIPE; } 432 virtual const char * TypeName() const { return "bulk pipe"; } 433 434 status_t QueueBulk(void *data, 435 size_t dataLength, 436 usb_callback_func callback, 437 void *callbackCookie); 438 status_t QueueBulkV(iovec *vector, 439 size_t vectorCount, 440 usb_callback_func callback, 441 void *callbackCookie, 442 bool physical); 443 }; 444 445 446 class IsochronousPipe : public Pipe { 447 public: 448 IsochronousPipe(Object *parent); 449 450 virtual uint32 Type() const { return USB_OBJECT_PIPE 451 | USB_OBJECT_ISO_PIPE; } 452 virtual const char * TypeName() const { return "iso pipe"; } 453 454 status_t QueueIsochronous(void *data, 455 size_t dataLength, 456 usb_iso_packet_descriptor * 457 packetDescriptor, 458 uint32 packetCount, 459 uint32 *startingFrameNumber, 460 uint32 flags, 461 usb_callback_func callback, 462 void *callbackCookie); 463 464 status_t SetPipePolicy(uint8 maxQueuedPackets, 465 uint16 maxBufferDurationMS, 466 uint16 sampleSize); 467 status_t GetPipePolicy(uint8 *maxQueuedPackets, 468 uint16 *maxBufferDurationMS, 469 uint16 *sampleSize); 470 471 private: 472 uint8 fMaxQueuedPackets; 473 uint16 fMaxBufferDuration; 474 uint16 fSampleSize; 475 }; 476 477 478 class Interface : public Object { 479 public: 480 Interface(Object *parent, 481 uint8 interfaceIndex); 482 483 virtual uint32 Type() const 484 { return USB_OBJECT_INTERFACE; } 485 virtual const char * TypeName() const { return "interface"; } 486 487 // Convenience functions for standard requests 488 virtual status_t SetFeature(uint16 selector); 489 virtual status_t ClearFeature(uint16 selector); 490 virtual status_t GetStatus(uint16 *status); 491 492 private: 493 uint8 fInterfaceIndex; 494 }; 495 496 497 class Device : public Object { 498 public: 499 Device(Object *parent, int8 hubAddress, 500 uint8 hubPort, 501 usb_device_descriptor &desc, 502 int8 deviceAddress, 503 usb_speed speed, bool isRootHub, 504 void *controllerCookie = NULL); 505 virtual ~Device(); 506 507 status_t InitCheck(); 508 509 virtual status_t Changed(change_item **changeList, 510 bool added); 511 512 virtual uint32 Type() const 513 { return USB_OBJECT_DEVICE; } 514 virtual const char * TypeName() const { return "device"; } 515 516 ControlPipe * DefaultPipe() const 517 { return fDefaultPipe; } 518 519 virtual status_t GetDescriptor(uint8 descriptorType, 520 uint8 index, uint16 languageID, 521 void *data, size_t dataLength, 522 size_t *actualLength); 523 524 int8 DeviceAddress() const 525 { return fDeviceAddress; } 526 const usb_device_descriptor * DeviceDescriptor() const; 527 usb_speed Speed() const { return fSpeed; } 528 529 const usb_configuration_info * Configuration() const; 530 const usb_configuration_info * ConfigurationAt(uint8 index) const; 531 status_t SetConfiguration( 532 const usb_configuration_info * 533 configuration); 534 status_t SetConfigurationAt(uint8 index); 535 status_t Unconfigure(bool atDeviceLevel); 536 537 status_t SetAltInterface( 538 const usb_interface_info * 539 interface); 540 541 void InitEndpoints(int32 interfaceIndex); 542 void ClearEndpoints(int32 interfaceIndex); 543 544 virtual status_t ReportDevice( 545 usb_support_descriptor * 546 supportDescriptors, 547 uint32 supportDescriptorCount, 548 const usb_notify_hooks *hooks, 549 usb_driver_cookie **cookies, 550 bool added, bool recursive); 551 virtual status_t BuildDeviceName(char *string, 552 uint32 *index, size_t bufferSize, 553 Device *device); 554 555 int8 HubAddress() const 556 { return fHubAddress; } 557 uint8 HubPort() const { return fHubPort; } 558 559 void SetControllerCookie(void *cookie) 560 { fControllerCookie = cookie; } 561 void * ControllerCookie() const 562 { return fControllerCookie; } 563 564 // Convenience functions for standard requests 565 virtual status_t SetFeature(uint16 selector); 566 virtual status_t ClearFeature(uint16 selector); 567 virtual status_t GetStatus(uint16 *status); 568 569 protected: 570 usb_device_descriptor fDeviceDescriptor; 571 bool fInitOK; 572 573 private: 574 bool fAvailable; 575 bool fIsRootHub; 576 usb_configuration_info * fConfigurations; 577 usb_configuration_info * fCurrentConfiguration; 578 usb_speed fSpeed; 579 int8 fDeviceAddress; 580 int8 fHubAddress; 581 uint8 fHubPort; 582 ControlPipe * fDefaultPipe; 583 void * fControllerCookie; 584 }; 585 586 587 class Hub : public Device { 588 public: 589 Hub(Object *parent, int8 hubAddress, 590 uint8 hubPort, 591 usb_device_descriptor &desc, 592 int8 deviceAddress, 593 usb_speed speed, bool isRootHub, 594 void *controllerCookie = NULL); 595 virtual ~Hub(); 596 597 virtual status_t Changed(change_item **changeList, 598 bool added); 599 600 virtual uint32 Type() const { return USB_OBJECT_DEVICE 601 | USB_OBJECT_HUB; } 602 virtual const char * TypeName() const { return "hub"; } 603 604 virtual status_t GetDescriptor(uint8 descriptorType, 605 uint8 index, uint16 languageID, 606 void *data, size_t dataLength, 607 size_t *actualLength); 608 609 Device * ChildAt(uint8 index) const 610 { return fChildren[index]; } 611 612 status_t UpdatePortStatus(uint8 index); 613 status_t ResetPort(uint8 index); 614 status_t DisablePort(uint8 index); 615 616 void Explore(change_item **changeList); 617 static void InterruptCallback(void *cookie, 618 status_t status, void *data, 619 size_t actualLength); 620 621 virtual status_t ReportDevice( 622 usb_support_descriptor * 623 supportDescriptors, 624 uint32 supportDescriptorCount, 625 const usb_notify_hooks *hooks, 626 usb_driver_cookie **cookies, 627 bool added, bool recursive); 628 virtual status_t BuildDeviceName(char *string, 629 uint32 *index, size_t bufferSize, 630 Device *device); 631 632 private: 633 status_t _DebouncePort(uint8 index); 634 635 InterruptPipe * fInterruptPipe; 636 usb_hub_descriptor fHubDescriptor; 637 638 usb_port_status fInterruptStatus[USB_MAX_PORT_COUNT]; 639 usb_port_status fPortStatus[USB_MAX_PORT_COUNT]; 640 Device * fChildren[USB_MAX_PORT_COUNT]; 641 }; 642 643 644 /* 645 * A Transfer is allocated on the heap and passed to the Host Controller in 646 * SubmitTransfer(). It is generated for all queued transfers. If queuing 647 * succeds (SubmitTransfer() returns with >= B_OK) the Host Controller takes 648 * ownership of the Transfer and will delete it as soon as it has called the 649 * set callback function. If SubmitTransfer() failes, the calling function is 650 * responsible for deleting the Transfer. 651 * Also, the transfer takes ownership of the usb_request_data passed to it in 652 * SetRequestData(), but does not take ownership of the data buffer set by 653 * SetData(). 654 */ 655 class Transfer { 656 public: 657 Transfer(Pipe *pipe); 658 ~Transfer(); 659 660 Pipe * TransferPipe() const { return fPipe; } 661 662 void SetRequestData(usb_request_data *data); 663 usb_request_data * RequestData() const { return fRequestData; } 664 665 void SetIsochronousData( 666 usb_isochronous_data *data); 667 usb_isochronous_data * IsochronousData() const 668 { return fIsochronousData; } 669 670 void SetData(uint8 *buffer, size_t length); 671 uint8 * Data() const 672 { return (uint8 *)fData.iov_base; } 673 size_t DataLength() const { return fData.iov_len; } 674 675 void SetPhysical(bool physical); 676 bool IsPhysical() const { return fPhysical; } 677 678 void SetVector(iovec *vector, 679 size_t vectorCount); 680 iovec * Vector() { return fVector; } 681 size_t VectorCount() const { return fVectorCount; } 682 size_t VectorLength(); 683 684 uint16 Bandwidth() const { return fBandwidth; } 685 686 bool IsFragmented() const { return fFragmented; } 687 void AdvanceByFragment(size_t actualLength); 688 689 status_t InitKernelAccess(); 690 status_t PrepareKernelAccess(); 691 692 void SetCallback(usb_callback_func callback, 693 void *cookie); 694 usb_callback_func Callback() const 695 { return fCallback; } 696 void * CallbackCookie() const 697 { return fCallbackCookie; } 698 699 void Finished(uint32 status, 700 size_t actualLength); 701 702 usb_id USBID() const { return 0; } 703 const char * TypeName() const { return "transfer"; } 704 705 private: 706 status_t _CalculateBandwidth(); 707 708 // Data that is related to the transfer 709 Pipe * fPipe; 710 iovec fData; 711 iovec * fVector; 712 size_t fVectorCount; 713 void * fBaseAddress; 714 bool fPhysical; 715 bool fFragmented; 716 size_t fActualLength; 717 area_id fUserArea; 718 area_id fClonedArea; 719 720 usb_callback_func fCallback; 721 void * fCallbackCookie; 722 723 // For control transfers 724 usb_request_data * fRequestData; 725 726 // For isochronous transfers 727 usb_isochronous_data * fIsochronousData; 728 729 // For bandwidth management. 730 // It contains the bandwidth necessary in microseconds 731 // for either isochronous, interrupt or control transfers. 732 // Not used for bulk transactions. 733 uint16 fBandwidth; 734 }; 735 736 #endif // _USB_PRIVATE_H 737