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