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