|
|
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.