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(usb_id id); 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 private: 274 Object * fParent; 275 BusManager * fBusManager; 276 Stack * fStack; 277 usb_id fUSBID; 278 }; 279 280 281 /* 282 * The Pipe class is the communication management between the hardware and 283 * the stack. It creates packets, manages these and performs callbacks. 284 */ 285 class Pipe : public Object { 286 public: 287 enum pipeDirection { In, Out, Default }; 288 289 Pipe(Object *parent); 290 virtual ~Pipe(); 291 292 virtual void InitCommon(int8 deviceAddress, 293 uint8 endpointAddress, 294 usb_speed speed, 295 pipeDirection direction, 296 size_t maxPacketSize, 297 uint8 interval, 298 int8 hubAddress, uint8 hubPort); 299 virtual void InitSuperSpeed(uint8 maxBurst, 300 uint16 bytesPerInterval); 301 302 virtual uint32 Type() const { return USB_OBJECT_PIPE; } 303 virtual const char * TypeName() const { return "pipe"; } 304 305 int8 DeviceAddress() const 306 { return fDeviceAddress; } 307 usb_speed Speed() const { return fSpeed; } 308 pipeDirection Direction() const { return fDirection; } 309 uint8 EndpointAddress() const 310 { return fEndpointAddress; } 311 size_t MaxPacketSize() const 312 { return fMaxPacketSize; } 313 uint8 Interval() const { return fInterval; } 314 315 // SuperSpeed-only parameters 316 uint8 MaxBurst() const 317 { return fMaxBurst; } 318 uint16 BytesPerInterval() const 319 { return fBytesPerInterval; } 320 321 // Hub port being the one-based logical port number on the hub 322 void SetHubInfo(int8 address, uint8 port); 323 int8 HubAddress() const 324 { return fHubAddress; } 325 uint8 HubPort() const { return fHubPort; } 326 327 virtual bool DataToggle() const 328 { return fDataToggle; } 329 virtual void SetDataToggle(bool toggle) 330 { fDataToggle = toggle; } 331 332 status_t SubmitTransfer(Transfer *transfer); 333 status_t CancelQueuedTransfers(bool force); 334 335 void SetControllerCookie(void *cookie) 336 { fControllerCookie = cookie; } 337 void * ControllerCookie() const 338 { return fControllerCookie; } 339 340 // Convenience functions for standard requests 341 virtual status_t SetFeature(uint16 selector); 342 virtual status_t ClearFeature(uint16 selector); 343 virtual status_t GetStatus(uint16 *status); 344 345 private: 346 int8 fDeviceAddress; 347 uint8 fEndpointAddress; 348 pipeDirection fDirection; 349 usb_speed fSpeed; 350 size_t fMaxPacketSize; 351 uint8 fInterval; 352 uint8 fMaxBurst; 353 uint16 fBytesPerInterval; 354 int8 fHubAddress; 355 uint8 fHubPort; 356 bool fDataToggle; 357 void * fControllerCookie; 358 }; 359 360 361 class ControlPipe : public Pipe { 362 public: 363 ControlPipe(Object *parent); 364 virtual ~ControlPipe(); 365 366 virtual void InitCommon(int8 deviceAddress, 367 uint8 endpointAddress, 368 usb_speed speed, 369 pipeDirection direction, 370 size_t maxPacketSize, 371 uint8 interval, 372 int8 hubAddress, uint8 hubPort); 373 374 virtual uint32 Type() const { return USB_OBJECT_PIPE 375 | USB_OBJECT_CONTROL_PIPE; } 376 virtual const char * TypeName() const 377 { return "control pipe"; } 378 379 // The data toggle is not relevant 380 // for control transfers, as they are 381 // always enclosed by a setup and 382 // status packet. The toggle always 383 // starts at 1. 384 virtual bool DataToggle() const { return true; } 385 virtual void SetDataToggle(bool toggle) {} 386 387 status_t SendRequest(uint8 requestType, 388 uint8 request, uint16 value, 389 uint16 index, uint16 length, 390 void *data, size_t dataLength, 391 size_t *actualLength); 392 static void SendRequestCallback(void *cookie, 393 status_t status, void *data, 394 size_t actualLength); 395 396 status_t QueueRequest(uint8 requestType, 397 uint8 request, uint16 value, 398 uint16 index, uint16 length, 399 void *data, size_t dataLength, 400 usb_callback_func callback, 401 void *callbackCookie); 402 403 private: 404 mutex fSendRequestLock; 405 sem_id fNotifySem; 406 status_t fTransferStatus; 407 size_t fActualLength; 408 }; 409 410 411 class InterruptPipe : public Pipe { 412 public: 413 InterruptPipe(Object *parent); 414 415 virtual uint32 Type() const { return USB_OBJECT_PIPE 416 | USB_OBJECT_INTERRUPT_PIPE; } 417 virtual const char * TypeName() const 418 { return "interrupt pipe"; } 419 420 status_t QueueInterrupt(void *data, 421 size_t dataLength, 422 usb_callback_func callback, 423 void *callbackCookie); 424 }; 425 426 427 class BulkPipe : public Pipe { 428 public: 429 BulkPipe(Object *parent); 430 431 virtual void InitCommon(int8 deviceAddress, 432 uint8 endpointAddress, 433 usb_speed speed, 434 pipeDirection direction, 435 size_t maxPacketSize, 436 uint8 interval, 437 int8 hubAddress, uint8 hubPort); 438 439 virtual uint32 Type() const { return USB_OBJECT_PIPE 440 | USB_OBJECT_BULK_PIPE; } 441 virtual const char * TypeName() const { return "bulk pipe"; } 442 443 status_t QueueBulk(void *data, 444 size_t dataLength, 445 usb_callback_func callback, 446 void *callbackCookie); 447 status_t QueueBulkV(iovec *vector, 448 size_t vectorCount, 449 usb_callback_func callback, 450 void *callbackCookie, 451 bool physical); 452 }; 453 454 455 class IsochronousPipe : public Pipe { 456 public: 457 IsochronousPipe(Object *parent); 458 459 virtual uint32 Type() const { return USB_OBJECT_PIPE 460 | USB_OBJECT_ISO_PIPE; } 461 virtual const char * TypeName() const { return "iso pipe"; } 462 463 status_t QueueIsochronous(void *data, 464 size_t dataLength, 465 usb_iso_packet_descriptor * 466 packetDescriptor, 467 uint32 packetCount, 468 uint32 *startingFrameNumber, 469 uint32 flags, 470 usb_callback_func callback, 471 void *callbackCookie); 472 473 status_t SetPipePolicy(uint8 maxQueuedPackets, 474 uint16 maxBufferDurationMS, 475 uint16 sampleSize); 476 status_t GetPipePolicy(uint8 *maxQueuedPackets, 477 uint16 *maxBufferDurationMS, 478 uint16 *sampleSize); 479 480 private: 481 uint8 fMaxQueuedPackets; 482 uint16 fMaxBufferDuration; 483 uint16 fSampleSize; 484 }; 485 486 487 class Interface : public Object { 488 public: 489 Interface(Object *parent, 490 uint8 interfaceIndex); 491 492 virtual uint32 Type() const 493 { return USB_OBJECT_INTERFACE; } 494 virtual const char * TypeName() const { return "interface"; } 495 496 // Convenience functions for standard requests 497 virtual status_t SetFeature(uint16 selector); 498 virtual status_t ClearFeature(uint16 selector); 499 virtual status_t GetStatus(uint16 *status); 500 501 private: 502 uint8 fInterfaceIndex; 503 }; 504 505 506 class Device : public Object { 507 public: 508 Device(Object *parent, int8 hubAddress, 509 uint8 hubPort, 510 usb_device_descriptor &desc, 511 int8 deviceAddress, 512 usb_speed speed, bool isRootHub, 513 void *controllerCookie = NULL); 514 virtual ~Device(); 515 516 status_t InitCheck(); 517 518 virtual status_t Changed(change_item **changeList, 519 bool added); 520 521 virtual uint32 Type() const 522 { return USB_OBJECT_DEVICE; } 523 virtual const char * TypeName() const { return "device"; } 524 525 ControlPipe * DefaultPipe() const 526 { return fDefaultPipe; } 527 528 virtual status_t GetDescriptor(uint8 descriptorType, 529 uint8 index, uint16 languageID, 530 void *data, size_t dataLength, 531 size_t *actualLength); 532 533 int8 DeviceAddress() const 534 { return fDeviceAddress; } 535 const usb_device_descriptor * DeviceDescriptor() const; 536 usb_speed Speed() const { return fSpeed; } 537 538 const usb_configuration_info * Configuration() const; 539 const usb_configuration_info * ConfigurationAt(uint8 index) const; 540 status_t SetConfiguration( 541 const usb_configuration_info * 542 configuration); 543 status_t SetConfigurationAt(uint8 index); 544 status_t Unconfigure(bool atDeviceLevel); 545 546 status_t SetAltInterface( 547 const usb_interface_info * 548 interface); 549 550 void InitEndpoints(int32 interfaceIndex); 551 void ClearEndpoints(int32 interfaceIndex); 552 553 virtual status_t ReportDevice( 554 usb_support_descriptor * 555 supportDescriptors, 556 uint32 supportDescriptorCount, 557 const usb_notify_hooks *hooks, 558 usb_driver_cookie **cookies, 559 bool added, bool recursive); 560 virtual status_t BuildDeviceName(char *string, 561 uint32 *index, size_t bufferSize, 562 Device *device); 563 564 int8 HubAddress() const 565 { return fHubAddress; } 566 uint8 HubPort() const { return fHubPort; } 567 568 void SetControllerCookie(void *cookie) 569 { fControllerCookie = cookie; } 570 void * ControllerCookie() const 571 { return fControllerCookie; } 572 573 // Convenience functions for standard requests 574 virtual status_t SetFeature(uint16 selector); 575 virtual status_t ClearFeature(uint16 selector); 576 virtual status_t GetStatus(uint16 *status); 577 578 protected: 579 usb_device_descriptor fDeviceDescriptor; 580 bool fInitOK; 581 582 private: 583 bool fAvailable; 584 bool fIsRootHub; 585 usb_configuration_info * fConfigurations; 586 usb_configuration_info * fCurrentConfiguration; 587 usb_speed fSpeed; 588 int8 fDeviceAddress; 589 int8 fHubAddress; 590 uint8 fHubPort; 591 ControlPipe * fDefaultPipe; 592 void * fControllerCookie; 593 }; 594 595 596 class Hub : public Device { 597 public: 598 Hub(Object *parent, int8 hubAddress, 599 uint8 hubPort, 600 usb_device_descriptor &desc, 601 int8 deviceAddress, 602 usb_speed speed, bool isRootHub, 603 void *controllerCookie = NULL); 604 virtual ~Hub(); 605 606 virtual status_t Changed(change_item **changeList, 607 bool added); 608 609 virtual uint32 Type() const { return USB_OBJECT_DEVICE 610 | USB_OBJECT_HUB; } 611 virtual const char * TypeName() const { return "hub"; } 612 613 virtual status_t GetDescriptor(uint8 descriptorType, 614 uint8 index, uint16 languageID, 615 void *data, size_t dataLength, 616 size_t *actualLength); 617 618 Device * ChildAt(uint8 index) const 619 { return fChildren[index]; } 620 621 status_t UpdatePortStatus(uint8 index); 622 status_t ResetPort(uint8 index); 623 status_t DisablePort(uint8 index); 624 625 void Explore(change_item **changeList); 626 static void InterruptCallback(void *cookie, 627 status_t status, void *data, 628 size_t actualLength); 629 630 virtual status_t ReportDevice( 631 usb_support_descriptor * 632 supportDescriptors, 633 uint32 supportDescriptorCount, 634 const usb_notify_hooks *hooks, 635 usb_driver_cookie **cookies, 636 bool added, bool recursive); 637 virtual status_t BuildDeviceName(char *string, 638 uint32 *index, size_t bufferSize, 639 Device *device); 640 641 private: 642 status_t _DebouncePort(uint8 index); 643 644 InterruptPipe * fInterruptPipe; 645 usb_hub_descriptor fHubDescriptor; 646 647 usb_port_status fInterruptStatus[USB_MAX_PORT_COUNT]; 648 usb_port_status fPortStatus[USB_MAX_PORT_COUNT]; 649 Device * fChildren[USB_MAX_PORT_COUNT]; 650 }; 651 652 653 /* 654 * A Transfer is allocated on the heap and passed to the Host Controller in 655 * SubmitTransfer(). It is generated for all queued transfers. If queuing 656 * succeds (SubmitTransfer() returns with >= B_OK) the Host Controller takes 657 * ownership of the Transfer and will delete it as soon as it has called the 658 * set callback function. If SubmitTransfer() failes, the calling function is 659 * responsible for deleting the Transfer. 660 * Also, the transfer takes ownership of the usb_request_data passed to it in 661 * SetRequestData(), but does not take ownership of the data buffer set by 662 * SetData(). 663 */ 664 class Transfer { 665 public: 666 Transfer(Pipe *pipe); 667 ~Transfer(); 668 669 Pipe * TransferPipe() const { return fPipe; } 670 671 void SetRequestData(usb_request_data *data); 672 usb_request_data * RequestData() const { return fRequestData; } 673 674 void SetIsochronousData( 675 usb_isochronous_data *data); 676 usb_isochronous_data * IsochronousData() const 677 { return fIsochronousData; } 678 679 void SetData(uint8 *buffer, size_t length); 680 uint8 * Data() const 681 { return (uint8 *)fData.iov_base; } 682 size_t DataLength() const { return fData.iov_len; } 683 684 void SetPhysical(bool physical); 685 bool IsPhysical() const { return fPhysical; } 686 687 void SetVector(iovec *vector, 688 size_t vectorCount); 689 iovec * Vector() { return fVector; } 690 size_t VectorCount() const { return fVectorCount; } 691 size_t VectorLength(); 692 693 uint16 Bandwidth() const { return fBandwidth; } 694 695 bool IsFragmented() const { return fFragmented; } 696 void AdvanceByFragment(size_t actualLength); 697 698 status_t InitKernelAccess(); 699 status_t PrepareKernelAccess(); 700 701 void SetCallback(usb_callback_func callback, 702 void *cookie); 703 usb_callback_func Callback() const 704 { return fCallback; } 705 void * CallbackCookie() const 706 { return fCallbackCookie; } 707 708 void Finished(uint32 status, 709 size_t actualLength); 710 711 usb_id USBID() const { return 0; } 712 const char * TypeName() const { return "transfer"; } 713 714 private: 715 status_t _CalculateBandwidth(); 716 717 // Data that is related to the transfer 718 Pipe * fPipe; 719 iovec fData; 720 iovec * fVector; 721 size_t fVectorCount; 722 void * fBaseAddress; 723 bool fPhysical; 724 bool fFragmented; 725 size_t fActualLength; 726 area_id fUserArea; 727 area_id fClonedArea; 728 729 usb_callback_func fCallback; 730 void * fCallbackCookie; 731 732 // For control transfers 733 usb_request_data * fRequestData; 734 735 // For isochronous transfers 736 usb_isochronous_data * fIsochronousData; 737 738 // For bandwidth management. 739 // It contains the bandwidth necessary in microseconds 740 // for either isochronous, interrupt or control transfers. 741 // Not used for bulk transactions. 742 uint16 fBandwidth; 743 }; 744 745 #endif // _USB_PRIVATE_H 746