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