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