1853e6be8SMichael Lotz /* 2853e6be8SMichael Lotz * Copyright 2003-2006, Haiku Inc. All rights reserved. 3853e6be8SMichael Lotz * Distributed under the terms of the MIT License. 4853e6be8SMichael Lotz * 5853e6be8SMichael Lotz * Authors: 6853e6be8SMichael Lotz * Michael Lotz <mmlr@mlotz.ch> 7853e6be8SMichael Lotz * Niels S. Reedijk 8853e6be8SMichael Lotz */ 9cc9f959dSMichael Lotz #ifndef _USB_PRIVATE_H 10cc9f959dSMichael Lotz #define _USB_PRIVATE_H 11853e6be8SMichael Lotz 12853e6be8SMichael Lotz #include "BeOSCompatibility.h" 13cc9f959dSMichael Lotz #include "usbspec_private.h" 14853e6be8SMichael Lotz #include <lock.h> 150e76cf0bSJérôme Duval #include <util/Vector.h> 16853e6be8SMichael Lotz 17853e6be8SMichael Lotz 18853e6be8SMichael Lotz #define TRACE_OUTPUT(x, y, z...) \ 19853e6be8SMichael Lotz { \ 20853e6be8SMichael Lotz dprintf("usb %s%s %ld: ", y, (x)->TypeName(), (x)->USBID()); \ 21853e6be8SMichael Lotz dprintf(z); \ 22853e6be8SMichael Lotz } 23853e6be8SMichael Lotz 24853e6be8SMichael Lotz //#define TRACE_USB 25853e6be8SMichael Lotz #ifdef TRACE_USB 26853e6be8SMichael Lotz #define TRACE(x...) TRACE_OUTPUT(this, "", x) 27853e6be8SMichael Lotz #define TRACE_STATIC(x, y...) TRACE_OUTPUT(x, "", y) 28853e6be8SMichael Lotz #define TRACE_MODULE(x...) dprintf("usb "USB_MODULE_NAME": "x) 29853e6be8SMichael Lotz #else 30853e6be8SMichael Lotz #define TRACE(x...) /* nothing */ 31853e6be8SMichael Lotz #define TRACE_STATIC(x, y...) /* nothing */ 32853e6be8SMichael Lotz #define TRACE_MODULE(x...) /* nothing */ 33853e6be8SMichael Lotz #endif 34853e6be8SMichael Lotz 35853e6be8SMichael Lotz #define TRACE_ALWAYS(x...) TRACE_OUTPUT(this, "", x) 36853e6be8SMichael Lotz #define TRACE_ERROR(x...) TRACE_OUTPUT(this, "error ", x) 37853e6be8SMichael Lotz #define TRACE_MODULE_ALWAYS(x...) dprintf("usb "USB_MODULE_NAME": "x) 38853e6be8SMichael Lotz #define TRACE_MODULE_ERROR(x...) dprintf("usb "USB_MODULE_NAME": "x) 39853e6be8SMichael Lotz 40853e6be8SMichael Lotz class Hub; 41853e6be8SMichael Lotz class Stack; 42853e6be8SMichael Lotz class Device; 43853e6be8SMichael Lotz class Transfer; 44853e6be8SMichael Lotz class BusManager; 45853e6be8SMichael Lotz class Pipe; 46853e6be8SMichael Lotz class ControlPipe; 47853e6be8SMichael Lotz class Object; 48853e6be8SMichael Lotz class PhysicalMemoryAllocator; 49853e6be8SMichael Lotz 50853e6be8SMichael Lotz 51853e6be8SMichael Lotz struct usb_host_controller_info { 52853e6be8SMichael Lotz module_info info; 53853e6be8SMichael Lotz status_t (*control)(uint32 op, void *data, size_t length); 54853e6be8SMichael Lotz status_t (*add_to)(Stack *stack); 55853e6be8SMichael Lotz }; 56853e6be8SMichael Lotz 57853e6be8SMichael Lotz 58853e6be8SMichael Lotz struct usb_driver_cookie { 59853e6be8SMichael Lotz usb_id device; 60853e6be8SMichael Lotz void *cookie; 61853e6be8SMichael Lotz usb_driver_cookie *link; 62853e6be8SMichael Lotz }; 63853e6be8SMichael Lotz 64853e6be8SMichael Lotz 65853e6be8SMichael Lotz struct usb_driver_info { 66853e6be8SMichael Lotz const char *driver_name; 67853e6be8SMichael Lotz usb_support_descriptor *support_descriptors; 68853e6be8SMichael Lotz uint32 support_descriptor_count; 69853e6be8SMichael Lotz const char *republish_driver_name; 70853e6be8SMichael Lotz usb_notify_hooks notify_hooks; 71853e6be8SMichael Lotz usb_driver_cookie *cookies; 72853e6be8SMichael Lotz usb_driver_info *link; 73853e6be8SMichael Lotz }; 74853e6be8SMichael Lotz 75853e6be8SMichael Lotz 76853e6be8SMichael Lotz struct change_item { 77853e6be8SMichael Lotz bool added; 78853e6be8SMichael Lotz Device *device; 79853e6be8SMichael Lotz change_item *link; 80853e6be8SMichael Lotz }; 81853e6be8SMichael Lotz 82853e6be8SMichael Lotz 83853e6be8SMichael Lotz struct rescan_item { 84853e6be8SMichael Lotz const char *name; 85853e6be8SMichael Lotz rescan_item *link; 86853e6be8SMichael Lotz }; 87853e6be8SMichael Lotz 88853e6be8SMichael Lotz 89853e6be8SMichael Lotz typedef enum { 90853e6be8SMichael Lotz USB_SPEED_LOWSPEED = 0, 91853e6be8SMichael Lotz USB_SPEED_FULLSPEED, 92853e6be8SMichael Lotz USB_SPEED_HIGHSPEED, 93d6e4f54fSJérôme Duval USB_SPEED_SUPER, 94*319a3798SJérôme Duval USB_SPEED_WIRELESS, 95*319a3798SJérôme Duval USB_SPEED_MAX = USB_SPEED_WIRELESS 96853e6be8SMichael Lotz } usb_speed; 97853e6be8SMichael Lotz 98853e6be8SMichael Lotz 99853e6be8SMichael Lotz typedef enum { 100853e6be8SMichael Lotz USB_CHANGE_CREATED = 0, 101853e6be8SMichael Lotz USB_CHANGE_DESTROYED, 102853e6be8SMichael Lotz USB_CHANGE_PIPE_POLICY_CHANGED 103853e6be8SMichael Lotz } usb_change; 104853e6be8SMichael Lotz 105853e6be8SMichael Lotz 106853e6be8SMichael Lotz #define USB_OBJECT_NONE 0x00000000 107853e6be8SMichael Lotz #define USB_OBJECT_PIPE 0x00000001 108853e6be8SMichael Lotz #define USB_OBJECT_CONTROL_PIPE 0x00000002 109853e6be8SMichael Lotz #define USB_OBJECT_INTERRUPT_PIPE 0x00000004 110853e6be8SMichael Lotz #define USB_OBJECT_BULK_PIPE 0x00000008 111853e6be8SMichael Lotz #define USB_OBJECT_ISO_PIPE 0x00000010 112853e6be8SMichael Lotz #define USB_OBJECT_INTERFACE 0x00000020 113853e6be8SMichael Lotz #define USB_OBJECT_DEVICE 0x00000040 114853e6be8SMichael Lotz #define USB_OBJECT_HUB 0x00000080 115853e6be8SMichael Lotz 116853e6be8SMichael Lotz 117853e6be8SMichael Lotz class Stack { 118853e6be8SMichael Lotz public: 119853e6be8SMichael Lotz Stack(); 120853e6be8SMichael Lotz ~Stack(); 121853e6be8SMichael Lotz 122853e6be8SMichael Lotz status_t InitCheck(); 123853e6be8SMichael Lotz 124853e6be8SMichael Lotz bool Lock(); 125853e6be8SMichael Lotz void Unlock(); 126853e6be8SMichael Lotz 127853e6be8SMichael Lotz usb_id GetUSBID(Object *object); 128853e6be8SMichael Lotz void PutUSBID(usb_id id); 129853e6be8SMichael Lotz Object * GetObject(usb_id id); 130853e6be8SMichael Lotz 131853e6be8SMichael Lotz // only for the kernel debugger 13238fc536eSMichael Lotz Object * GetObjectNoLock(usb_id id) const; 133853e6be8SMichael Lotz 134853e6be8SMichael Lotz void AddBusManager(BusManager *bus); 135853e6be8SMichael Lotz int32 IndexOfBusManager(BusManager *bus); 13638fc536eSMichael Lotz BusManager * BusManagerAt(int32 index) const; 137853e6be8SMichael Lotz 138853e6be8SMichael Lotz status_t AllocateChunk(void **logicalAddress, 13919b8f8a0SMichael Lotz void **physicalAddress, 14019b8f8a0SMichael Lotz size_t size); 141853e6be8SMichael Lotz status_t FreeChunk(void *logicalAddress, 142853e6be8SMichael Lotz void *physicalAddress, size_t size); 143853e6be8SMichael Lotz 144853e6be8SMichael Lotz area_id AllocateArea(void **logicalAddress, 145853e6be8SMichael Lotz void **physicalAddress, 146853e6be8SMichael Lotz size_t size, const char *name); 147853e6be8SMichael Lotz 148853e6be8SMichael Lotz void NotifyDeviceChange(Device *device, 149853e6be8SMichael Lotz rescan_item **rescanList, 150853e6be8SMichael Lotz bool added); 151853e6be8SMichael Lotz void RescanDrivers(rescan_item *rescanItem); 152853e6be8SMichael Lotz 153853e6be8SMichael Lotz // USB API 154853e6be8SMichael Lotz status_t RegisterDriver(const char *driverName, 15519b8f8a0SMichael Lotz const usb_support_descriptor * 15619b8f8a0SMichael Lotz descriptors, 157853e6be8SMichael Lotz size_t descriptorCount, 158853e6be8SMichael Lotz const char *republishDriverName); 159853e6be8SMichael Lotz 160853e6be8SMichael Lotz status_t InstallNotify(const char *driverName, 161853e6be8SMichael Lotz const usb_notify_hooks *hooks); 162853e6be8SMichael Lotz status_t UninstallNotify(const char *driverName); 163853e6be8SMichael Lotz 16419b8f8a0SMichael Lotz usb_id USBID() const { return 0; } 16519b8f8a0SMichael Lotz const char * TypeName() const { return "stack"; } 166853e6be8SMichael Lotz 167853e6be8SMichael Lotz private: 168853e6be8SMichael Lotz static int32 ExploreThread(void *data); 169853e6be8SMichael Lotz 170853e6be8SMichael Lotz Vector<BusManager *> fBusManagers; 171853e6be8SMichael Lotz thread_id fExploreThread; 172853e6be8SMichael Lotz bool fFirstExploreDone; 173853e6be8SMichael Lotz bool fStopThreads; 174853e6be8SMichael Lotz 175853e6be8SMichael Lotz mutex fStackLock; 176853e6be8SMichael Lotz mutex fExploreLock; 177853e6be8SMichael Lotz PhysicalMemoryAllocator * fAllocator; 178853e6be8SMichael Lotz 179853e6be8SMichael Lotz uint32 fObjectIndex; 180853e6be8SMichael Lotz uint32 fObjectMaxCount; 181853e6be8SMichael Lotz Object ** fObjectArray; 182853e6be8SMichael Lotz 183853e6be8SMichael Lotz usb_driver_info * fDriverList; 184853e6be8SMichael Lotz }; 185853e6be8SMichael Lotz 186853e6be8SMichael Lotz 187853e6be8SMichael Lotz /* 188853e6be8SMichael Lotz * This class manages a bus. It is created by the Stack object 189853e6be8SMichael Lotz * after a host controller gives positive feedback on whether the hardware 190853e6be8SMichael Lotz * is found. 191853e6be8SMichael Lotz */ 192853e6be8SMichael Lotz class BusManager { 193853e6be8SMichael Lotz public: 194853e6be8SMichael Lotz BusManager(Stack *stack); 195853e6be8SMichael Lotz virtual ~BusManager(); 196853e6be8SMichael Lotz 197853e6be8SMichael Lotz virtual status_t InitCheck(); 198853e6be8SMichael Lotz 199853e6be8SMichael Lotz bool Lock(); 200853e6be8SMichael Lotz void Unlock(); 201853e6be8SMichael Lotz 202853e6be8SMichael Lotz int8 AllocateAddress(); 203853e6be8SMichael Lotz void FreeAddress(int8 address); 204853e6be8SMichael Lotz 205*319a3798SJérôme Duval virtual Device * AllocateDevice(Hub *parent, 206853e6be8SMichael Lotz int8 hubAddress, uint8 hubPort, 207853e6be8SMichael Lotz usb_speed speed); 208*319a3798SJérôme Duval virtual void FreeDevice(Device *device); 209853e6be8SMichael Lotz 210853e6be8SMichael Lotz virtual status_t Start(); 211853e6be8SMichael Lotz virtual status_t Stop(); 212853e6be8SMichael Lotz 213853e6be8SMichael Lotz virtual status_t SubmitTransfer(Transfer *transfer); 214853e6be8SMichael Lotz virtual status_t CancelQueuedTransfers(Pipe *pipe, 215853e6be8SMichael Lotz bool force); 216853e6be8SMichael Lotz 217853e6be8SMichael Lotz virtual status_t NotifyPipeChange(Pipe *pipe, 218853e6be8SMichael Lotz usb_change change); 219853e6be8SMichael Lotz 22019b8f8a0SMichael Lotz Object * RootObject() const 22119b8f8a0SMichael Lotz { return fRootObject; } 222853e6be8SMichael Lotz 22319b8f8a0SMichael Lotz Hub * GetRootHub() const { return fRootHub; } 22419b8f8a0SMichael Lotz void SetRootHub(Hub *hub) { fRootHub = hub; } 225853e6be8SMichael Lotz 22619b8f8a0SMichael Lotz usb_id USBID() const { return fUSBID; } 22738fc536eSMichael Lotz virtual const char * TypeName() const = 0; 228853e6be8SMichael Lotz 229853e6be8SMichael Lotz protected: 230853e6be8SMichael Lotz bool fInitOK; 231853e6be8SMichael Lotz 232853e6be8SMichael Lotz private: 233853e6be8SMichael Lotz ControlPipe * _GetDefaultPipe(usb_speed); 234853e6be8SMichael Lotz 235853e6be8SMichael Lotz mutex fLock; 236853e6be8SMichael Lotz 237853e6be8SMichael Lotz bool fDeviceMap[128]; 238853e6be8SMichael Lotz int8 fDeviceIndex; 239853e6be8SMichael Lotz 240853e6be8SMichael Lotz Stack * fStack; 241853e6be8SMichael Lotz ControlPipe * fDefaultPipes[USB_SPEED_MAX + 1]; 242853e6be8SMichael Lotz Hub * fRootHub; 243853e6be8SMichael Lotz Object * fRootObject; 24419b8f8a0SMichael Lotz 24519b8f8a0SMichael Lotz usb_id fUSBID; 246853e6be8SMichael Lotz }; 247853e6be8SMichael Lotz 248853e6be8SMichael Lotz 249853e6be8SMichael Lotz class Object { 250853e6be8SMichael Lotz public: 251853e6be8SMichael Lotz Object(Stack *stack, BusManager *bus); 252853e6be8SMichael Lotz Object(Object *parent); 253853e6be8SMichael Lotz virtual ~Object(); 254853e6be8SMichael Lotz 25519b8f8a0SMichael Lotz Object * Parent() const { return fParent; } 256853e6be8SMichael Lotz 25719b8f8a0SMichael Lotz BusManager * GetBusManager() const 25819b8f8a0SMichael Lotz { return fBusManager; } 25919b8f8a0SMichael Lotz Stack * GetStack() const { return fStack; } 260853e6be8SMichael Lotz 26119b8f8a0SMichael Lotz usb_id USBID() const { return fUSBID; } 26219b8f8a0SMichael Lotz virtual uint32 Type() const { return USB_OBJECT_NONE; } 26319b8f8a0SMichael Lotz virtual const char * TypeName() const { return "object"; } 264853e6be8SMichael Lotz 265853e6be8SMichael Lotz // Convenience functions for standard requests 266853e6be8SMichael Lotz virtual status_t SetFeature(uint16 selector); 267853e6be8SMichael Lotz virtual status_t ClearFeature(uint16 selector); 268853e6be8SMichael Lotz virtual status_t GetStatus(uint16 *status); 269853e6be8SMichael Lotz 270853e6be8SMichael Lotz private: 271853e6be8SMichael Lotz Object * fParent; 272853e6be8SMichael Lotz BusManager * fBusManager; 273853e6be8SMichael Lotz Stack * fStack; 274853e6be8SMichael Lotz usb_id fUSBID; 275853e6be8SMichael Lotz }; 276853e6be8SMichael Lotz 277853e6be8SMichael Lotz 278853e6be8SMichael Lotz /* 279853e6be8SMichael Lotz * The Pipe class is the communication management between the hardware and 280853e6be8SMichael Lotz * the stack. It creates packets, manages these and performs callbacks. 281853e6be8SMichael Lotz */ 282853e6be8SMichael Lotz class Pipe : public Object { 283853e6be8SMichael Lotz public: 284853e6be8SMichael Lotz enum pipeDirection { In, Out, Default }; 285853e6be8SMichael Lotz 286853e6be8SMichael Lotz Pipe(Object *parent); 287853e6be8SMichael Lotz virtual ~Pipe(); 288853e6be8SMichael Lotz 289853e6be8SMichael Lotz void InitCommon(int8 deviceAddress, 290853e6be8SMichael Lotz uint8 endpointAddress, 291853e6be8SMichael Lotz usb_speed speed, 292853e6be8SMichael Lotz pipeDirection direction, 293853e6be8SMichael Lotz size_t maxPacketSize, 294853e6be8SMichael Lotz uint8 interval, 295853e6be8SMichael Lotz int8 hubAddress, uint8 hubPort); 296853e6be8SMichael Lotz 29719b8f8a0SMichael Lotz virtual uint32 Type() const { return USB_OBJECT_PIPE; } 29819b8f8a0SMichael Lotz virtual const char * TypeName() const { return "pipe"; } 299853e6be8SMichael Lotz 30019b8f8a0SMichael Lotz int8 DeviceAddress() const 30119b8f8a0SMichael Lotz { return fDeviceAddress; } 30219b8f8a0SMichael Lotz usb_speed Speed() const { return fSpeed; } 30319b8f8a0SMichael Lotz pipeDirection Direction() const { return fDirection; } 30419b8f8a0SMichael Lotz uint8 EndpointAddress() const 30519b8f8a0SMichael Lotz { return fEndpointAddress; } 30619b8f8a0SMichael Lotz size_t MaxPacketSize() const 30719b8f8a0SMichael Lotz { return fMaxPacketSize; } 30819b8f8a0SMichael Lotz uint8 Interval() const { return fInterval; } 309853e6be8SMichael Lotz 310853e6be8SMichael Lotz // Hub port being the one-based logical port number on the hub 311853e6be8SMichael Lotz void SetHubInfo(int8 address, uint8 port); 31219b8f8a0SMichael Lotz int8 HubAddress() const 31319b8f8a0SMichael Lotz { return fHubAddress; } 31419b8f8a0SMichael Lotz uint8 HubPort() const { return fHubPort; } 315853e6be8SMichael Lotz 31619b8f8a0SMichael Lotz virtual bool DataToggle() const 31719b8f8a0SMichael Lotz { return fDataToggle; } 31819b8f8a0SMichael Lotz virtual void SetDataToggle(bool toggle) 31919b8f8a0SMichael Lotz { fDataToggle = toggle; } 320853e6be8SMichael Lotz 321853e6be8SMichael Lotz status_t SubmitTransfer(Transfer *transfer); 322853e6be8SMichael Lotz status_t CancelQueuedTransfers(bool force); 323853e6be8SMichael Lotz 32419b8f8a0SMichael Lotz void SetControllerCookie(void *cookie) 32519b8f8a0SMichael Lotz { fControllerCookie = cookie; } 32619b8f8a0SMichael Lotz void * ControllerCookie() const 32719b8f8a0SMichael Lotz { return fControllerCookie; } 328853e6be8SMichael Lotz 329853e6be8SMichael Lotz // Convenience functions for standard requests 330853e6be8SMichael Lotz virtual status_t SetFeature(uint16 selector); 331853e6be8SMichael Lotz virtual status_t ClearFeature(uint16 selector); 332853e6be8SMichael Lotz virtual status_t GetStatus(uint16 *status); 333853e6be8SMichael Lotz 334853e6be8SMichael Lotz private: 335853e6be8SMichael Lotz int8 fDeviceAddress; 336853e6be8SMichael Lotz uint8 fEndpointAddress; 337853e6be8SMichael Lotz pipeDirection fDirection; 338853e6be8SMichael Lotz usb_speed fSpeed; 339853e6be8SMichael Lotz size_t fMaxPacketSize; 340853e6be8SMichael Lotz uint8 fInterval; 341853e6be8SMichael Lotz int8 fHubAddress; 342853e6be8SMichael Lotz uint8 fHubPort; 343853e6be8SMichael Lotz bool fDataToggle; 344853e6be8SMichael Lotz void * fControllerCookie; 345853e6be8SMichael Lotz }; 346853e6be8SMichael Lotz 347853e6be8SMichael Lotz 348853e6be8SMichael Lotz class ControlPipe : public Pipe { 349853e6be8SMichael Lotz public: 350853e6be8SMichael Lotz ControlPipe(Object *parent); 351853e6be8SMichael Lotz virtual ~ControlPipe(); 352853e6be8SMichael Lotz 35319b8f8a0SMichael Lotz virtual uint32 Type() const { return USB_OBJECT_PIPE 35419b8f8a0SMichael Lotz | USB_OBJECT_CONTROL_PIPE; } 35519b8f8a0SMichael Lotz virtual const char * TypeName() const 35619b8f8a0SMichael Lotz { return "control pipe"; } 357853e6be8SMichael Lotz 358853e6be8SMichael Lotz // The data toggle is not relevant 359853e6be8SMichael Lotz // for control transfers, as they are 360853e6be8SMichael Lotz // always enclosed by a setup and 361853e6be8SMichael Lotz // status packet. The toggle always 362853e6be8SMichael Lotz // starts at 1. 36319b8f8a0SMichael Lotz virtual bool DataToggle() const { return true; } 36438fc536eSMichael Lotz virtual void SetDataToggle(bool toggle) {} 365853e6be8SMichael Lotz 366853e6be8SMichael Lotz status_t SendRequest(uint8 requestType, 367853e6be8SMichael Lotz uint8 request, uint16 value, 368853e6be8SMichael Lotz uint16 index, uint16 length, 369853e6be8SMichael Lotz void *data, size_t dataLength, 370853e6be8SMichael Lotz size_t *actualLength); 371853e6be8SMichael Lotz static void SendRequestCallback(void *cookie, 372853e6be8SMichael Lotz status_t status, void *data, 373853e6be8SMichael Lotz size_t actualLength); 374853e6be8SMichael Lotz 375853e6be8SMichael Lotz status_t QueueRequest(uint8 requestType, 376853e6be8SMichael Lotz uint8 request, uint16 value, 377853e6be8SMichael Lotz uint16 index, uint16 length, 378853e6be8SMichael Lotz void *data, size_t dataLength, 379853e6be8SMichael Lotz usb_callback_func callback, 380853e6be8SMichael Lotz void *callbackCookie); 381853e6be8SMichael Lotz 382853e6be8SMichael Lotz private: 383853e6be8SMichael Lotz mutex fSendRequestLock; 384853e6be8SMichael Lotz sem_id fNotifySem; 385853e6be8SMichael Lotz status_t fTransferStatus; 386853e6be8SMichael Lotz size_t fActualLength; 387853e6be8SMichael Lotz }; 388853e6be8SMichael Lotz 389853e6be8SMichael Lotz 390853e6be8SMichael Lotz class InterruptPipe : public Pipe { 391853e6be8SMichael Lotz public: 392853e6be8SMichael Lotz InterruptPipe(Object *parent); 393853e6be8SMichael Lotz 39419b8f8a0SMichael Lotz virtual uint32 Type() const { return USB_OBJECT_PIPE 39519b8f8a0SMichael Lotz | USB_OBJECT_INTERRUPT_PIPE; } 39619b8f8a0SMichael Lotz virtual const char * TypeName() const 39719b8f8a0SMichael Lotz { return "interrupt pipe"; } 398853e6be8SMichael Lotz 399853e6be8SMichael Lotz status_t QueueInterrupt(void *data, 400853e6be8SMichael Lotz size_t dataLength, 401853e6be8SMichael Lotz usb_callback_func callback, 402853e6be8SMichael Lotz void *callbackCookie); 403853e6be8SMichael Lotz }; 404853e6be8SMichael Lotz 405853e6be8SMichael Lotz 406853e6be8SMichael Lotz class BulkPipe : public Pipe { 407853e6be8SMichael Lotz public: 408853e6be8SMichael Lotz BulkPipe(Object *parent); 409853e6be8SMichael Lotz 41019b8f8a0SMichael Lotz virtual uint32 Type() const { return USB_OBJECT_PIPE 41119b8f8a0SMichael Lotz | USB_OBJECT_BULK_PIPE; } 41219b8f8a0SMichael Lotz virtual const char * TypeName() const { return "bulk pipe"; } 413853e6be8SMichael Lotz 414853e6be8SMichael Lotz status_t QueueBulk(void *data, 415853e6be8SMichael Lotz size_t dataLength, 416853e6be8SMichael Lotz usb_callback_func callback, 417853e6be8SMichael Lotz void *callbackCookie); 418853e6be8SMichael Lotz status_t QueueBulkV(iovec *vector, 419853e6be8SMichael Lotz size_t vectorCount, 420853e6be8SMichael Lotz usb_callback_func callback, 421853e6be8SMichael Lotz void *callbackCookie, 422853e6be8SMichael Lotz bool physical); 423853e6be8SMichael Lotz }; 424853e6be8SMichael Lotz 425853e6be8SMichael Lotz 426853e6be8SMichael Lotz class IsochronousPipe : public Pipe { 427853e6be8SMichael Lotz public: 428853e6be8SMichael Lotz IsochronousPipe(Object *parent); 429853e6be8SMichael Lotz 43019b8f8a0SMichael Lotz virtual uint32 Type() const { return USB_OBJECT_PIPE 43119b8f8a0SMichael Lotz | USB_OBJECT_ISO_PIPE; } 43219b8f8a0SMichael Lotz virtual const char * TypeName() const { return "iso pipe"; } 433853e6be8SMichael Lotz 434853e6be8SMichael Lotz status_t QueueIsochronous(void *data, 435853e6be8SMichael Lotz size_t dataLength, 43619b8f8a0SMichael Lotz usb_iso_packet_descriptor * 43719b8f8a0SMichael Lotz packetDescriptor, 438853e6be8SMichael Lotz uint32 packetCount, 439853e6be8SMichael Lotz uint32 *startingFrameNumber, 440853e6be8SMichael Lotz uint32 flags, 441853e6be8SMichael Lotz usb_callback_func callback, 442853e6be8SMichael Lotz void *callbackCookie); 443853e6be8SMichael Lotz 444853e6be8SMichael Lotz status_t SetPipePolicy(uint8 maxQueuedPackets, 445853e6be8SMichael Lotz uint16 maxBufferDurationMS, 446853e6be8SMichael Lotz uint16 sampleSize); 447853e6be8SMichael Lotz status_t GetPipePolicy(uint8 *maxQueuedPackets, 448853e6be8SMichael Lotz uint16 *maxBufferDurationMS, 449853e6be8SMichael Lotz uint16 *sampleSize); 450853e6be8SMichael Lotz 451853e6be8SMichael Lotz private: 452853e6be8SMichael Lotz uint8 fMaxQueuedPackets; 453853e6be8SMichael Lotz uint16 fMaxBufferDuration; 454853e6be8SMichael Lotz uint16 fSampleSize; 455853e6be8SMichael Lotz }; 456853e6be8SMichael Lotz 457853e6be8SMichael Lotz 458853e6be8SMichael Lotz class Interface : public Object { 459853e6be8SMichael Lotz public: 460853e6be8SMichael Lotz Interface(Object *parent, 461853e6be8SMichael Lotz uint8 interfaceIndex); 462853e6be8SMichael Lotz 46319b8f8a0SMichael Lotz virtual uint32 Type() const 46419b8f8a0SMichael Lotz { return USB_OBJECT_INTERFACE; } 46519b8f8a0SMichael Lotz virtual const char * TypeName() const { return "interface"; } 466853e6be8SMichael Lotz 467853e6be8SMichael Lotz // Convenience functions for standard requests 468853e6be8SMichael Lotz virtual status_t SetFeature(uint16 selector); 469853e6be8SMichael Lotz virtual status_t ClearFeature(uint16 selector); 470853e6be8SMichael Lotz virtual status_t GetStatus(uint16 *status); 471853e6be8SMichael Lotz 472853e6be8SMichael Lotz private: 473853e6be8SMichael Lotz uint8 fInterfaceIndex; 474853e6be8SMichael Lotz }; 475853e6be8SMichael Lotz 476853e6be8SMichael Lotz 477853e6be8SMichael Lotz class Device : public Object { 478853e6be8SMichael Lotz public: 479853e6be8SMichael Lotz Device(Object *parent, int8 hubAddress, 480853e6be8SMichael Lotz uint8 hubPort, 481853e6be8SMichael Lotz usb_device_descriptor &desc, 482853e6be8SMichael Lotz int8 deviceAddress, 483853e6be8SMichael Lotz usb_speed speed, bool isRootHub); 484853e6be8SMichael Lotz virtual ~Device(); 485853e6be8SMichael Lotz 486853e6be8SMichael Lotz status_t InitCheck(); 487853e6be8SMichael Lotz 488853e6be8SMichael Lotz virtual status_t Changed(change_item **changeList, 489853e6be8SMichael Lotz bool added); 490853e6be8SMichael Lotz 49119b8f8a0SMichael Lotz virtual uint32 Type() const 49219b8f8a0SMichael Lotz { return USB_OBJECT_DEVICE; } 49319b8f8a0SMichael Lotz virtual const char * TypeName() const { return "device"; } 494853e6be8SMichael Lotz 49519b8f8a0SMichael Lotz ControlPipe * DefaultPipe() const 49619b8f8a0SMichael Lotz { return fDefaultPipe; } 497853e6be8SMichael Lotz 498853e6be8SMichael Lotz virtual status_t GetDescriptor(uint8 descriptorType, 499853e6be8SMichael Lotz uint8 index, uint16 languageID, 500853e6be8SMichael Lotz void *data, size_t dataLength, 501853e6be8SMichael Lotz size_t *actualLength); 502853e6be8SMichael Lotz 50319b8f8a0SMichael Lotz int8 DeviceAddress() const 50419b8f8a0SMichael Lotz { return fDeviceAddress; } 505853e6be8SMichael Lotz const usb_device_descriptor * DeviceDescriptor() const; 50619b8f8a0SMichael Lotz usb_speed Speed() const { return fSpeed; } 507853e6be8SMichael Lotz 508853e6be8SMichael Lotz const usb_configuration_info * Configuration() const; 509853e6be8SMichael Lotz const usb_configuration_info * ConfigurationAt(uint8 index) const; 51019b8f8a0SMichael Lotz status_t SetConfiguration( 51119b8f8a0SMichael Lotz const usb_configuration_info * 51219b8f8a0SMichael Lotz configuration); 513853e6be8SMichael Lotz status_t SetConfigurationAt(uint8 index); 514853e6be8SMichael Lotz status_t Unconfigure(bool atDeviceLevel); 515853e6be8SMichael Lotz 51619b8f8a0SMichael Lotz status_t SetAltInterface( 51719b8f8a0SMichael Lotz const usb_interface_info * 51819b8f8a0SMichael Lotz interface); 519853e6be8SMichael Lotz 520853e6be8SMichael Lotz void InitEndpoints(int32 interfaceIndex); 521853e6be8SMichael Lotz void ClearEndpoints(int32 interfaceIndex); 522853e6be8SMichael Lotz 523853e6be8SMichael Lotz virtual status_t ReportDevice( 52419b8f8a0SMichael Lotz usb_support_descriptor * 52519b8f8a0SMichael Lotz supportDescriptors, 526853e6be8SMichael Lotz uint32 supportDescriptorCount, 527853e6be8SMichael Lotz const usb_notify_hooks *hooks, 528853e6be8SMichael Lotz usb_driver_cookie **cookies, 529853e6be8SMichael Lotz bool added, bool recursive); 530853e6be8SMichael Lotz virtual status_t BuildDeviceName(char *string, 531853e6be8SMichael Lotz uint32 *index, size_t bufferSize, 532853e6be8SMichael Lotz Device *device); 533853e6be8SMichael Lotz 53419b8f8a0SMichael Lotz int8 HubAddress() const 53519b8f8a0SMichael Lotz { return fHubAddress; } 53619b8f8a0SMichael Lotz uint8 HubPort() const { return fHubPort; } 537853e6be8SMichael Lotz 538853e6be8SMichael Lotz // Convenience functions for standard requests 539853e6be8SMichael Lotz virtual status_t SetFeature(uint16 selector); 540853e6be8SMichael Lotz virtual status_t ClearFeature(uint16 selector); 541853e6be8SMichael Lotz virtual status_t GetStatus(uint16 *status); 542853e6be8SMichael Lotz 543853e6be8SMichael Lotz protected: 544853e6be8SMichael Lotz usb_device_descriptor fDeviceDescriptor; 545853e6be8SMichael Lotz bool fInitOK; 546853e6be8SMichael Lotz 547853e6be8SMichael Lotz private: 548853e6be8SMichael Lotz bool fAvailable; 549853e6be8SMichael Lotz bool fIsRootHub; 550853e6be8SMichael Lotz usb_configuration_info * fConfigurations; 551853e6be8SMichael Lotz usb_configuration_info * fCurrentConfiguration; 552853e6be8SMichael Lotz usb_speed fSpeed; 553853e6be8SMichael Lotz int8 fDeviceAddress; 554853e6be8SMichael Lotz int8 fHubAddress; 555853e6be8SMichael Lotz uint8 fHubPort; 556853e6be8SMichael Lotz ControlPipe * fDefaultPipe; 557853e6be8SMichael Lotz }; 558853e6be8SMichael Lotz 559853e6be8SMichael Lotz 560853e6be8SMichael Lotz class Hub : public Device { 561853e6be8SMichael Lotz public: 562853e6be8SMichael Lotz Hub(Object *parent, int8 hubAddress, 563853e6be8SMichael Lotz uint8 hubPort, 564853e6be8SMichael Lotz usb_device_descriptor &desc, 565853e6be8SMichael Lotz int8 deviceAddress, 566853e6be8SMichael Lotz usb_speed speed, bool isRootHub); 567853e6be8SMichael Lotz virtual ~Hub(); 568853e6be8SMichael Lotz 569853e6be8SMichael Lotz virtual status_t Changed(change_item **changeList, 570853e6be8SMichael Lotz bool added); 571853e6be8SMichael Lotz 57219b8f8a0SMichael Lotz virtual uint32 Type() const { return USB_OBJECT_DEVICE 57319b8f8a0SMichael Lotz | USB_OBJECT_HUB; } 57419b8f8a0SMichael Lotz virtual const char * TypeName() const { return "hub"; } 575853e6be8SMichael Lotz 576853e6be8SMichael Lotz virtual status_t GetDescriptor(uint8 descriptorType, 577853e6be8SMichael Lotz uint8 index, uint16 languageID, 578853e6be8SMichael Lotz void *data, size_t dataLength, 579853e6be8SMichael Lotz size_t *actualLength); 580853e6be8SMichael Lotz 58119b8f8a0SMichael Lotz Device * ChildAt(uint8 index) const 58219b8f8a0SMichael Lotz { return fChildren[index]; } 583853e6be8SMichael Lotz 584853e6be8SMichael Lotz status_t UpdatePortStatus(uint8 index); 585853e6be8SMichael Lotz status_t ResetPort(uint8 index); 586853e6be8SMichael Lotz status_t DisablePort(uint8 index); 587853e6be8SMichael Lotz 588853e6be8SMichael Lotz void Explore(change_item **changeList); 589853e6be8SMichael Lotz static void InterruptCallback(void *cookie, 590853e6be8SMichael Lotz status_t status, void *data, 591853e6be8SMichael Lotz size_t actualLength); 592853e6be8SMichael Lotz 593853e6be8SMichael Lotz virtual status_t ReportDevice( 59419b8f8a0SMichael Lotz usb_support_descriptor * 59519b8f8a0SMichael Lotz supportDescriptors, 596853e6be8SMichael Lotz uint32 supportDescriptorCount, 597853e6be8SMichael Lotz const usb_notify_hooks *hooks, 598853e6be8SMichael Lotz usb_driver_cookie **cookies, 599853e6be8SMichael Lotz bool added, bool recursive); 600853e6be8SMichael Lotz virtual status_t BuildDeviceName(char *string, 601853e6be8SMichael Lotz uint32 *index, size_t bufferSize, 602853e6be8SMichael Lotz Device *device); 603853e6be8SMichael Lotz 604853e6be8SMichael Lotz private: 605853e6be8SMichael Lotz InterruptPipe * fInterruptPipe; 606853e6be8SMichael Lotz usb_hub_descriptor fHubDescriptor; 607853e6be8SMichael Lotz 608853e6be8SMichael Lotz usb_port_status fInterruptStatus[USB_MAX_PORT_COUNT]; 609853e6be8SMichael Lotz usb_port_status fPortStatus[USB_MAX_PORT_COUNT]; 610853e6be8SMichael Lotz Device * fChildren[USB_MAX_PORT_COUNT]; 611853e6be8SMichael Lotz }; 612853e6be8SMichael Lotz 613853e6be8SMichael Lotz 614853e6be8SMichael Lotz /* 615853e6be8SMichael Lotz * A Transfer is allocated on the heap and passed to the Host Controller in 616853e6be8SMichael Lotz * SubmitTransfer(). It is generated for all queued transfers. If queuing 617853e6be8SMichael Lotz * succeds (SubmitTransfer() returns with >= B_OK) the Host Controller takes 618853e6be8SMichael Lotz * ownership of the Transfer and will delete it as soon as it has called the 619853e6be8SMichael Lotz * set callback function. If SubmitTransfer() failes, the calling function is 620853e6be8SMichael Lotz * responsible for deleting the Transfer. 621853e6be8SMichael Lotz * Also, the transfer takes ownership of the usb_request_data passed to it in 622853e6be8SMichael Lotz * SetRequestData(), but does not take ownership of the data buffer set by 623853e6be8SMichael Lotz * SetData(). 624853e6be8SMichael Lotz */ 625853e6be8SMichael Lotz class Transfer { 626853e6be8SMichael Lotz public: 627853e6be8SMichael Lotz Transfer(Pipe *pipe); 628853e6be8SMichael Lotz ~Transfer(); 629853e6be8SMichael Lotz 63019b8f8a0SMichael Lotz Pipe * TransferPipe() const { return fPipe; } 631853e6be8SMichael Lotz 632853e6be8SMichael Lotz void SetRequestData(usb_request_data *data); 63319b8f8a0SMichael Lotz usb_request_data * RequestData() const { return fRequestData; } 634853e6be8SMichael Lotz 63519b8f8a0SMichael Lotz void SetIsochronousData( 63619b8f8a0SMichael Lotz usb_isochronous_data *data); 63719b8f8a0SMichael Lotz usb_isochronous_data * IsochronousData() const 63819b8f8a0SMichael Lotz { return fIsochronousData; } 639853e6be8SMichael Lotz 640853e6be8SMichael Lotz void SetData(uint8 *buffer, size_t length); 64119b8f8a0SMichael Lotz uint8 * Data() const 64219b8f8a0SMichael Lotz { return (uint8 *)fData.iov_base; } 64319b8f8a0SMichael Lotz size_t DataLength() const { return fData.iov_len; } 644853e6be8SMichael Lotz 645853e6be8SMichael Lotz void SetPhysical(bool physical); 64619b8f8a0SMichael Lotz bool IsPhysical() const { return fPhysical; } 647853e6be8SMichael Lotz 64819b8f8a0SMichael Lotz void SetVector(iovec *vector, 64919b8f8a0SMichael Lotz size_t vectorCount); 65019b8f8a0SMichael Lotz iovec * Vector() { return fVector; } 65119b8f8a0SMichael Lotz size_t VectorCount() const { return fVectorCount; } 652853e6be8SMichael Lotz size_t VectorLength(); 653853e6be8SMichael Lotz 65419b8f8a0SMichael Lotz uint16 Bandwidth() const { return fBandwidth; } 655853e6be8SMichael Lotz 65619b8f8a0SMichael Lotz bool IsFragmented() const { return fFragmented; } 657853e6be8SMichael Lotz void AdvanceByFragment(size_t actualLength); 658853e6be8SMichael Lotz 659853e6be8SMichael Lotz status_t InitKernelAccess(); 660853e6be8SMichael Lotz status_t PrepareKernelAccess(); 661853e6be8SMichael Lotz 662853e6be8SMichael Lotz void SetCallback(usb_callback_func callback, 663853e6be8SMichael Lotz void *cookie); 664853e6be8SMichael Lotz 66519b8f8a0SMichael Lotz void Finished(uint32 status, 66619b8f8a0SMichael Lotz size_t actualLength); 667853e6be8SMichael Lotz 66819b8f8a0SMichael Lotz usb_id USBID() const { return 0; } 66919b8f8a0SMichael Lotz const char * TypeName() const { return "transfer"; } 670853e6be8SMichael Lotz 671853e6be8SMichael Lotz private: 672853e6be8SMichael Lotz status_t _CalculateBandwidth(); 673853e6be8SMichael Lotz 674853e6be8SMichael Lotz // Data that is related to the transfer 675853e6be8SMichael Lotz Pipe * fPipe; 676853e6be8SMichael Lotz iovec fData; 677853e6be8SMichael Lotz iovec * fVector; 678853e6be8SMichael Lotz size_t fVectorCount; 679853e6be8SMichael Lotz void * fBaseAddress; 680853e6be8SMichael Lotz bool fPhysical; 681853e6be8SMichael Lotz bool fFragmented; 682853e6be8SMichael Lotz size_t fActualLength; 683853e6be8SMichael Lotz area_id fUserArea; 684853e6be8SMichael Lotz area_id fClonedArea; 685853e6be8SMichael Lotz 686853e6be8SMichael Lotz usb_callback_func fCallback; 687853e6be8SMichael Lotz void * fCallbackCookie; 688853e6be8SMichael Lotz 689853e6be8SMichael Lotz // For control transfers 690853e6be8SMichael Lotz usb_request_data * fRequestData; 691853e6be8SMichael Lotz 692853e6be8SMichael Lotz // For isochronous transfers 693853e6be8SMichael Lotz usb_isochronous_data * fIsochronousData; 694853e6be8SMichael Lotz 695853e6be8SMichael Lotz // For bandwidth management. 696853e6be8SMichael Lotz // It contains the bandwidth necessary in microseconds 697853e6be8SMichael Lotz // for either isochronous, interrupt or control transfers. 698853e6be8SMichael Lotz // Not used for bulk transactions. 699853e6be8SMichael Lotz uint16 fBandwidth; 700853e6be8SMichael Lotz }; 701853e6be8SMichael Lotz 702cc9f959dSMichael Lotz #endif // _USB_PRIVATE_H 703