|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * The contents of this file constitute Original Code as defined in and ! 7: * are subject to the Apple Public Source License Version 1.1 (the ! 8: * "License"). You may not use this file except in compliance with the ! 9: * License. Please obtain a copy of the License at ! 10: * http://www.apple.com/publicsource and read it before using this file. ! 11: * ! 12: * This Original Code and all software distributed under the License are ! 13: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 16: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 17: * License for the specific language governing rights and limitations ! 18: * under the License. ! 19: * ! 20: * @APPLE_LICENSE_HEADER_END@ ! 21: */ ! 22: /* ! 23: * Copyright (c) 1998 Apple Computer, Inc. All rights reserved. ! 24: * ! 25: * HISTORY ! 26: * ! 27: */ ! 28: ! 29: ! 30: #ifndef _IOKIT_IOUSBCONTROLLER_H ! 31: #define _IOKIT_IOUSBCONTROLLER_H ! 32: ! 33: #include <IOKit/IOService.h> ! 34: #include <IOKit/IOMemoryDescriptor.h> ! 35: #include <libkern/c++/OSArray.h> ! 36: #include <IOKit/IODeviceMemory.h> ! 37: #include <IOKit/IOWorkLoop.h> ! 38: #include <IOKit/IOCommandGate.h> ! 39: ! 40: #include <IOKit/usb/USB.h> ! 41: #include <IOKit/usb/IOUSBBus.h> ! 42: #include <IOKit/usb/IOUSBDevice.h> ! 43: #include <IOKit/usb/USBHub.h> ! 44: ! 45: /* ! 46: * USB Command ! 47: * This is the command block for a USB command to be queued on the ! 48: * Command Gate of the WorkLoop. Although the actual work of creating ! 49: * the command and enqueueing it is done for them via the deviceRequest, ! 50: * read, and write methods, this is the primary way that devices will get ! 51: * work done. ! 52: * Note: This is private to IOUSBController and should be moved to a ! 53: * private header. ! 54: */ ! 55: ! 56: typedef enum { ! 57: DEVICE_REQUEST, // Device request using pointer ! 58: READ, ! 59: WRITE, ! 60: CREATE_EP, ! 61: DELETE_EP, ! 62: DEVICE_REQUEST_DESC // Device request using descriptor ! 63: } usbCommand; ! 64: ! 65: typedef struct { ! 66: usbCommand selector; ! 67: IOUSBDevRequest *request; ! 68: USBDeviceAddress address; ! 69: UInt8 endpoint; ! 70: UInt8 direction; ! 71: UInt8 type; ! 72: IOMemoryDescriptor *buffer; ! 73: IOUSBCompletion completion; ! 74: UInt32 dataRemaining; // For Control transfers ! 75: UInt8 stage; // For Control transfers ! 76: IOReturn status; ! 77: } IOUSBCommand; ! 78: ! 79: typedef struct { ! 80: usbCommand selector; ! 81: USBDeviceAddress address; ! 82: UInt8 endpoint; ! 83: UInt8 direction; ! 84: IOMemoryDescriptor *buffer; ! 85: IOUSBIsocCompletion completion; ! 86: UInt64 startFrame; ! 87: UInt32 numFrames; ! 88: IOUSBIsocFrame * frameList; ! 89: IOReturn status; ! 90: } IOUSBIsocCommand; ! 91: ! 92: /* ! 93: * Errata ! 94: * These indicate the anomolies of the various chips sets. Test ! 95: * for these in errataBits. ! 96: */ ! 97: enum { ! 98: // turn off UHCI test mode ! 99: kErrataCMDDisableTestMode = (1 << 0), ! 100: // Don't cross page boundaries in a single transfer ! 101: kErrataOnlySinglePageTransfers = (1 << 1), ! 102: // UIM will retry out transfers with buffer underrun errors ! 103: kErrataRetryBufferUnderruns = (1 << 2), ! 104: // UIM will insert delay buffer between HS and LS transfers ! 105: kErrataLSHSOpti = (1 << 3), ! 106: // Always set the NOCP bit in rhDescriptorA register ! 107: kErrataDisableOvercurrent = (1 << 4), ! 108: // Don't allow port suspend at the root hub ! 109: kErrataLucentSuspendResume = (1 << 5) ! 110: }; ! 111: /* errataBits */ ! 112: ! 113: /* ! 114: This table contains the list of errata that are necessary for known problems with particular devices. ! 115: The format is vendorID, product ID, lowest revisionID needing errata, highest rev needing errata, errataBits. ! 116: The result of all matches is ORed together, so more than one entry may match. ! 117: Typically for a given errata a list of revisions that this applies to is supplied. ! 118: */ ! 119: ! 120: struct ErrataListEntryStruct { ! 121: UInt16 vendID; ! 122: UInt16 deviceID; ! 123: UInt16 revisionLo; ! 124: UInt16 revisionHi; ! 125: UInt32 errata; ! 126: }; ! 127: ! 128: typedef struct ErrataListEntryStruct ! 129: ErrataListEntry, ! 130: *ErrataListEntryPtr; ! 131: ! 132: class IOUSBController; ! 133: class IOUSBDeviceZero; ! 134: class IOUSBRootHubDevice; ! 135: class IOMemoryDescriptor; ! 136: ! 137: void IOUSBSyncCompletion(void *target, void * parameter, ! 138: IOReturn status, ! 139: UInt32 bufferSizeRemaining); ! 140: ! 141: void IOUSBSyncIsoCompletion(void *target, void * parameter, ! 142: IOReturn status, ! 143: IOUSBIsocFrame *pFrames); ! 144: ! 145: ! 146: ! 147: /*! ! 148: @class IOUSBController ! 149: @abstract Base class for USB hardware driver ! 150: @discussion Not many directly useful methods for USB device driver writers, ! 151: IOUSBDevice, IOUSBInterface and IOUSBPipe provide more useful abstractions. ! 152: The bulk of this class interfaces between IOKit and the low-level UIM, which is ! 153: based on the MacOS9 UIM. ! 154: */ ! 155: class IOUSBController : public IOUSBBus ! 156: { ! 157: OSDeclareAbstractStructors(IOUSBController) ! 158: ! 159: protected: ! 160: ! 161: IOWorkLoop *_workLoop; ! 162: IOCommandGate *_commandGate; ! 163: ! 164: IOUSBRootHubDevice *_rootHubDevice; ! 165: ! 166: IOLock * _devZeroLock; ! 167: ! 168: static IOReturn doDeleteEP(OSObject *owner, ! 169: void *arg0, void *arg1, ! 170: void *arg2, void *arg3); ! 171: static IOReturn doCreateEP(OSObject *owner, ! 172: void *arg0, void *arg1, ! 173: void *arg2, void *arg3); ! 174: ! 175: static IOReturn doControlTransfer(OSObject *owner, ! 176: void *arg0, void *arg1, ! 177: void *arg2, void *arg3); ! 178: static IOReturn doIOTransfer(OSObject *owner, ! 179: void *arg0, void *arg1, ! 180: void *arg2, void *arg3); ! 181: static IOReturn doIsocTransfer(OSObject *owner, ! 182: void *arg0, void *arg1, ! 183: void *arg2, void *arg3); ! 184: virtual bool init(OSDictionary * propTable); ! 185: virtual bool start( IOService * provider ); ! 186: ! 187: virtual IOUSBDevice *newDevice(); ! 188: IOReturn CreateDevice(IOUSBDevice *device, ! 189: USBDeviceAddress deviceAddress, ! 190: IOUSBDeviceDescriptor *desc, ! 191: UInt8 speed, ! 192: UInt32 powerAvailable); ! 193: IOReturn getNubResources( IOService * regEntry ); ! 194: USBDeviceAddress getNewAddress(void); ! 195: IOReturn ControlTransaction(IOUSBCommand *command); ! 196: IOReturn InterruptTransaction(IOUSBCommand *command); ! 197: IOReturn BulkTransaction(IOUSBCommand *command); ! 198: IOReturn IsocTransaction(IOUSBIsocCommand *command); ! 199: void ControlPacketHandler( ! 200: void * parameter, ! 201: IOReturn status, ! 202: UInt32 bufferSizeRemaining); ! 203: void InterruptPacketHandler( ! 204: void * parameter, ! 205: IOReturn status, ! 206: UInt32 bufferSizeRemaining); ! 207: void BulkPacketHandler( ! 208: void * parameter, ! 209: IOReturn status, ! 210: UInt32 bufferSizeRemaining); ! 211: ! 212: void IsocCompletionHandler( ! 213: void * parameter, ! 214: IOReturn status, ! 215: IOUSBIsocFrame *pFrames); ! 216: ! 217: // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! 218: // Invokes the specified completion action of the request. If ! 219: // the completion action is unspecified, no action is taken. ! 220: inline void complete(IOUSBCompletion completion, ! 221: IOReturn status, ! 222: UInt32 actualByteCount = 0); ! 223: ! 224: void freeCommand(IOUSBCommand * command); ! 225: ! 226: virtual UInt32 GetErrataBits(UInt16 vendorID, UInt16 deviceID, UInt16 revisionID); ! 227: ! 228: /* ! 229: * UIM methods ! 230: */ ! 231: virtual IOReturn UIMInitialize(IOService * provider) = 0; ! 232: virtual IOReturn UIMFinalize() = 0; ! 233: // Control ! 234: virtual IOReturn UIMCreateControlEndpoint( ! 235: UInt8 functionNumber, ! 236: UInt8 endpointNumber, ! 237: UInt16 maxPacketSize, ! 238: UInt8 speed) = 0; ! 239: ! 240: virtual IOReturn UIMCreateControlTransfer( ! 241: short functionNumber, ! 242: short endpointNumber, ! 243: IOUSBCompletion completion, ! 244: void * CBP, ! 245: bool bufferRounding, ! 246: UInt32 bufferSize, ! 247: short direction) = 0; ! 248: ! 249: virtual IOReturn UIMCreateControlTransfer( ! 250: short functionNumber, ! 251: short endpointNumber, ! 252: IOUSBCompletion completion, ! 253: IOMemoryDescriptor * CBP, ! 254: bool bufferRounding, ! 255: UInt32 bufferSize, ! 256: short direction) = 0; ! 257: ! 258: // Bulk ! 259: virtual IOReturn UIMCreateBulkEndpoint( ! 260: UInt8 functionNumber, ! 261: UInt8 endpointNumber, ! 262: UInt8 direction, ! 263: UInt8 speed, ! 264: UInt8 maxPacketSize) = 0; ! 265: ! 266: virtual IOReturn UIMCreateBulkTransfer( ! 267: short functionNumber, ! 268: short endpointNumber, ! 269: IOUSBCompletion completion, ! 270: IOMemoryDescriptor * CBP, ! 271: bool bufferRounding, ! 272: UInt32 bufferSize, ! 273: short direction) = 0; ! 274: ! 275: // Interrupt ! 276: virtual IOReturn UIMCreateInterruptEndpoint( ! 277: short functionAddress, ! 278: short endpointNumber, ! 279: UInt8 direction, ! 280: short speed, ! 281: UInt16 maxPacketSize, ! 282: short pollingRate) = 0; ! 283: ! 284: virtual IOReturn UIMCreateInterruptTransfer( ! 285: short functionNumber, ! 286: short endpointNumber, ! 287: IOUSBCompletion completion, ! 288: IOMemoryDescriptor * CBP, ! 289: bool bufferRounding, ! 290: UInt32 bufferSize, ! 291: short direction) = 0; ! 292: ! 293: // Isoch ! 294: virtual IOReturn UIMCreateIsochEndpoint( ! 295: short functionAddress, ! 296: short endpointNumber, ! 297: UInt32 maxPacketSize, ! 298: UInt8 direction) = 0; ! 299: ! 300: virtual IOReturn UIMCreateIsochTransfer( ! 301: short functionAddress, ! 302: short endpointNumber, ! 303: IOUSBIsocCompletion completion, ! 304: UInt8 direction, ! 305: UInt64 frameStart, ! 306: IOMemoryDescriptor * pBuffer, ! 307: UInt32 frameCount, ! 308: IOUSBIsocFrame *pFrames) = 0; ! 309: ! 310: virtual IOReturn UIMAbortEndpoint( ! 311: short functionNumber, ! 312: short endpointNumber, ! 313: short direction) = 0; ! 314: ! 315: virtual IOReturn UIMDeleteEndpoint( ! 316: short functionNumber, ! 317: short endpointNumber, ! 318: short direction) = 0; ! 319: ! 320: virtual IOReturn UIMClearEndpointStall( ! 321: short functionNumber, ! 322: short endpointNumber, ! 323: short direction) = 0; ! 324: ! 325: virtual void UIMRootHubStatusChange(void) = 0; ! 326: ! 327: public: ! 328: ! 329: /*! ! 330: @struct Endpoint ! 331: Describes an endpoint of a device. ! 332: Simply an easier to use version of the endpoint descriptor. ! 333: @field descriptor The raw endpoint descriptor. ! 334: @field number Endpoint number ! 335: @field direction Endpoint direction: kUSBOut, kUSBIn, kUSBAnyDirn ! 336: @field transferType Type of endpoint: kUSBControl, kUSBIsoc, kUSBBulk, kUSBInterrupt ! 337: @field maxPacketSize Maximum packet size for endpoint ! 338: @field interval Polling interval in milliseconds (only relevent for Interrupt endpoints) ! 339: */ ! 340: struct Endpoint { ! 341: IOUSBEndpointDescriptor *descriptor; ! 342: UInt8 number; ! 343: UInt8 direction; // in, out ! 344: UInt8 transferType; // cntrl, bulk, isoc, int ! 345: UInt16 maxPacketSize; ! 346: UInt8 interval; ! 347: }; ! 348: ! 349: // Implements IOService::getWorkLoop const member function ! 350: virtual IOWorkLoop *getWorkLoop() const; ! 351: ! 352: /* ! 353: * Root hub methods ! 354: * Only of interest to the IOUSBRootHubDevice object ! 355: */ ! 356: virtual IOReturn getRootHubDeviceDescriptor(IOUSBDeviceDescriptor *desc) = 0; ! 357: virtual IOReturn getRootHubDescriptor(IOUSBHubDescriptor *desc) = 0; ! 358: virtual IOReturn setRootHubDescriptor(OSData *buffer) = 0; ! 359: virtual IOReturn getRootHubConfDescriptor(OSData *desc) = 0; ! 360: virtual IOReturn getRootHubStatus(IOUSBHubStatus *status) = 0; ! 361: virtual IOReturn setRootHubFeature(UInt16 wValue) = 0; ! 362: virtual IOReturn clearRootHubFeature(UInt16 wValue) = 0; ! 363: virtual IOReturn getRootHubPortStatus(IOUSBHubPortStatus *status, ! 364: UInt16 port) = 0; ! 365: virtual IOReturn setRootHubPortFeature(UInt16 wValue, UInt16 port) = 0; ! 366: virtual IOReturn clearRootHubPortFeature(UInt16 wValue, UInt16 port) = 0; ! 367: virtual IOReturn getRootHubPortState(UInt8 *state, UInt16 port) = 0; ! 368: virtual IOReturn setHubAddress(UInt16 wValue) = 0; ! 369: ! 370: /*! ! 371: @function openPipe ! 372: Open a pipe to the specified device endpoint ! 373: @param address Address of the device on the USB bus ! 374: @param speed of the device: kUSBHighSpeed or kUSBLowSpeed ! 375: @param endpoint description of endpoint to connect to ! 376: */ ! 377: virtual IOReturn openPipe(USBDeviceAddress address, UInt8 speed, ! 378: Endpoint *endpoint); ! 379: /*! ! 380: @function closePipe ! 381: Close a pipe to the specified device endpoint ! 382: @param address Address of the device on the USB bus ! 383: @param endpoint description of endpoint ! 384: */ ! 385: virtual IOReturn closePipe(USBDeviceAddress address, ! 386: Endpoint * endpoint); ! 387: ! 388: // Controlling pipe state ! 389: /*! ! 390: @function abortPipe ! 391: Abort pending I/O to/from the specified endpoint, causing them to complete ! 392: with return code kIOReturnAborted ! 393: @param address Address of the device on the USB bus ! 394: @param endpoint description of endpoint ! 395: */ ! 396: virtual IOReturn abortPipe(USBDeviceAddress address, ! 397: Endpoint * endpoint); ! 398: /*! ! 399: @function resetPipe ! 400: Abort pending I/O and clear stalled state - this method is a combination of ! 401: abortPipe and clearPipeStall ! 402: @param address Address of the device on the USB bus ! 403: @param endpoint description of endpoint ! 404: */ ! 405: virtual IOReturn resetPipe(USBDeviceAddress address, ! 406: Endpoint * endpoint); ! 407: /*! ! 408: @function clearPipeStall ! 409: Clear a pipe stall. ! 410: @param address Address of the device on the USB bus ! 411: @param endpoint description of endpoint ! 412: */ ! 413: virtual IOReturn clearPipeStall(USBDeviceAddress address, ! 414: Endpoint * endpoint); ! 415: ! 416: // Transferring Data ! 417: /*! ! 418: @function read ! 419: Read from an interrupt or bulk endpoint ! 420: @param buffer place to put the transferred data ! 421: @param address Address of the device on the USB bus ! 422: @param endpoint description of endpoint ! 423: @param completion describes action to take when buffer has been filled ! 424: */ ! 425: virtual IOReturn read(IOMemoryDescriptor * buffer, ! 426: USBDeviceAddress address, ! 427: Endpoint * endpoint, ! 428: IOUSBCompletion * completion); ! 429: /*! ! 430: @function write ! 431: Write to an interrupt or bulk endpoint ! 432: @param buffer place to get the transferred data ! 433: @param address Address of the device on the USB bus ! 434: @param endpoint description of endpoint ! 435: @param completion describes action to take when buffer has been emptied ! 436: */ ! 437: virtual IOReturn write(IOMemoryDescriptor * buffer, ! 438: USBDeviceAddress address, ! 439: Endpoint * endpoint, ! 440: IOUSBCompletion * completion); ! 441: ! 442: /*! ! 443: @function isocIO ! 444: Read from or write to an isochronous endpoint ! 445: @param buffer place to put the transferred data ! 446: @param frameStart USB frame number of the frame to start transfer ! 447: @param numFrames Number of frames to transfer ! 448: @param frameList Bytes to transfer and result for each frame ! 449: @param address Address of the device on the USB bus ! 450: @param endpoint description of endpoint ! 451: @param completion describes action to take when buffer has been filled ! 452: */ ! 453: virtual IOReturn isocIO(IOMemoryDescriptor * buffer, ! 454: UInt64 frameStart, ! 455: UInt32 numFrames, ! 456: IOUSBIsocFrame *frameList, ! 457: USBDeviceAddress address, ! 458: Endpoint * endpoint, ! 459: IOUSBIsocCompletion * completion); ! 460: /*! ! 461: @function deviceRequest ! 462: Make a control request to the specified endpoint ! 463: There are two versions of this method, one uses a simple void * ! 464: to point to the data portion of the transfer, the other uses an ! 465: IOMemoryDescriptor to point to the data. ! 466: @param request parameter block for the control request ! 467: @param completion describes action to take when the request has been executed ! 468: @param address Address of the device on the USB bus ! 469: @param epNum endpoint number ! 470: */ ! 471: virtual IOReturn deviceRequest(IOUSBDevRequest * request, ! 472: IOUSBCompletion * completion, ! 473: USBDeviceAddress address, UInt8 epNum); ! 474: virtual IOReturn deviceRequest(IOUSBDevRequestDesc *request, ! 475: IOUSBCompletion * completion, ! 476: USBDeviceAddress address, UInt8 epNum); ! 477: ! 478: /* ! 479: * Methods used by the hub driver to initialize a device ! 480: */ ! 481: /*! ! 482: @function AcquireDeviceZero ! 483: Get the device zero lock - call this before resetting a device, to ensure there's ! 484: only one device with address 0 ! 485: */ ! 486: virtual IOReturn AcquireDeviceZero(); ! 487: /*! ! 488: @function ReleaseDeviceZero ! 489: Release the device zero lock - call this to release the device zero lock, ! 490: when there is no longer a device at address 0 ! 491: */ ! 492: virtual void ReleaseDeviceZero(void); ! 493: ! 494: /*! ! 495: @function WaitForReleaseDeviceZero ! 496: Block until the device zero lock is released ! 497: */ ! 498: void WaitForReleaseDeviceZero(); ! 499: ! 500: /*! ! 501: @function ConfigureDeviceZero ! 502: create a pipe to the default pipe for the device at address 0 ! 503: @param maxPacketSize max packet size for the pipe ! 504: @param speed Device speed ! 505: */ ! 506: IOReturn ConfigureDeviceZero(UInt8 maxPacketSize, UInt8 speed); ! 507: /*! ! 508: @function GetDeviceZeroDescriptor ! 509: read the device descriptor of the device at address 0 ! 510: @param desc pointer to descriptor ! 511: */ ! 512: IOReturn GetDeviceZeroDescriptor(IOUSBDeviceDescriptor *desc); ! 513: /*! ! 514: @function SetDeviceZeroAddress ! 515: Set the device address of the device currently at address 0. ! 516: When this routine returns, it's safe to release the device zero lock. ! 517: @param address New address for the device ! 518: @param maxPacketSize maximum packet size for the default pipe ! 519: @param speed speed of the device ! 520: */ ! 521: IOReturn SetDeviceZeroAddress(USBDeviceAddress address, ! 522: UInt8 maxPacketSize, UInt8 speed); ! 523: /*! ! 524: @function MakeDevice ! 525: Create a new device object for the device currently at address 0. ! 526: This routine calls SetDeviceZeroAddress() with a new, unique, address for the device ! 527: and adds the device into the registry. ! 528: @param desc Device descriptor of the device ! 529: @param speed Device speed ! 530: @param power Bus power available to the device ! 531: @result Pointer to the newly-created device, 0 if the object coudn't be created. ! 532: */ ! 533: IOUSBDevice *MakeDevice(IOUSBDeviceDescriptor *desc, ! 534: UInt8 speed, UInt32 power); ! 535: ! 536: /*! ! 537: @function GetBandwidthAvailable ! 538: Returns the available bandwidth (in bytes) per frame for ! 539: isochronous transfers. ! 540: @result maximum number of bytes that a new iso pipe could transfer ! 541: per frame given current allocations. ! 542: */ ! 543: virtual UInt32 GetBandwidthAvailable() = 0; ! 544: ! 545: /*! ! 546: @function GetFrameNumber ! 547: Returns the full current frame number. ! 548: @result The frame number. ! 549: */ ! 550: virtual UInt64 GetFrameNumber() = 0; ! 551: ! 552: /*! ! 553: @function GetFrameNumber32 ! 554: Returns the least significant 32 bits of the frame number. ! 555: @result The lsb 32 bits of the frame number. ! 556: */ ! 557: virtual UInt32 GetFrameNumber32() = 0; ! 558: ! 559: // Debugger polled mode ! 560: virtual void pollInterrupts(IOUSBCompletionAction safeAction=0) = 0; ! 561: virtual IOReturn PolledRead( ! 562: short functionNumber, ! 563: short endpointNumber, ! 564: IOUSBCompletion completion, ! 565: IOMemoryDescriptor * CBP, ! 566: bool bufferRounding, ! 567: UInt32 bufferSize); ! 568: }; ! 569: ! 570: // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! 571: // Inline Functions ! 572: ! 573: inline void IOUSBController::complete(IOUSBCompletion completion, ! 574: IOReturn status, ! 575: UInt32 actualByteCount) ! 576: { ! 577: if (completion.action) (*completion.action)(completion.target, ! 578: completion.parameter, ! 579: status, ! 580: actualByteCount); ! 581: } ! 582: ! 583: #endif /* ! _IOKIT_IOUSBCONTROLLER_H */ ! 584:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.