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