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