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