|
|
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: * 08 Dec 98 ehewitt created.
27: *
28: */
29: #include <libkern/OSByteOrder.h>
30:
31: #include <IOKit/IOSyncer.h>
32: #include <IOKit/usb/IOUSBController.h>
33:
34: #include <IOKit/usb/IOUSBPipe.h>
35: #include <IOKit/usb/IOUSBNub.h>
36:
37: #define super OSObject
38: #define self this
39: #define DEBUGGING_LEVEL 0
40: #define DEBUGLOG kprintf
41:
42: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
43:
44: OSDefineMetaClassAndStructors(IOUSBPipe, OSObject)
45:
46: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
47:
48: bool IOUSBPipe::initToEndpoint(const IOUSBEndpointDescriptor *ed, UInt8 speed,
49: USBDeviceAddress address, IOUSBController * controller)
50: {
51: if( !super::init() || ed == 0)
52: return (false);
53:
54: _controller = controller;
55: _descriptor = ed;
56: _endpoint.number = ed->endpointAddress & kUSBPipeIDMask;
57: _endpoint.transferType = ed->attributes & 0x03;
58: if(_endpoint.transferType == kUSBControl)
59: _endpoint.direction = kUSBAnyDirn;
60: else
61: _endpoint.direction = ed->endpointAddress & 0x80 ? kUSBIn : kUSBOut;
62: _endpoint.maxPacketSize = OSReadLittleInt16(&ed->maxPacketSizeLo, 0);
63: _endpoint.interval = ed->interval;
64: _status = 0;
65: _address = address;
66: if(_controller->openPipe(_address, speed, &_endpoint) != kIOReturnSuccess)
67: return false;
68:
69: return (true);
70: }
71:
72: IOUSBPipe *IOUSBPipe::toEndpoint(const IOUSBEndpointDescriptor *ed, UInt8 speed,
73: USBDeviceAddress address, IOUSBController * controller)
74: {
75: IOUSBPipe *me = new IOUSBPipe;
76:
77: if (me && !me->initToEndpoint(ed, speed, address, controller)) {
78: me->free();
79: return 0;
80: }
81:
82: return me;
83: }
84:
85: void IOUSBPipe::free()
86: {
87: _controller->closePipe(_address, &_endpoint);
88: super::free();
89: }
90:
91: // Controlling pipe state
92:
93: UInt8 IOUSBPipe::status(void)
94: {
95: return(_status);
96: }
97:
98: IOReturn IOUSBPipe::abort(void)
99: {
100: return _controller->abortPipe(_address, &_endpoint);
101: }
102:
103: IOReturn IOUSBPipe::reset(void)
104: {
105: return _controller->resetPipe(_address, &_endpoint);
106: }
107:
108: IOReturn IOUSBPipe::clearStall(void)
109: {
110: return _controller->clearPipeStall(_address, &_endpoint);
111: }
112:
113: // Transferring Data
114: IOReturn IOUSBPipe::read(IOMemoryDescriptor * buffer,
115: IOUSBCompletion * completion = 0,
116: IOByteCount * bytesRead = 0)
117: {
118: IOReturn err = kIOReturnSuccess;
119:
120:
121: if (completion == 0)
122: {
123: // put in our own completion routine if none was specified to
124: // fake synchronous operation
125: IOUSBCompletion tap;
126: IOSyncer * syncer;
127:
128: syncer = IOSyncer::create();
129: if (bytesRead)
130: *bytesRead = buffer->getLength();
131:
132: tap.target = syncer;
133: tap.action = &IOUSBSyncCompletion;
134: tap.parameter = bytesRead;
135:
136: err = _controller->read(buffer, _address, &_endpoint, &tap);
137: if (err == kIOReturnSuccess){
138: err = syncer->wait();
139: }
140: else {
141: syncer->release(); syncer->release();
142: }
143: }
144: else
145: {
146: err = _controller->read(buffer, _address, &_endpoint, completion);
147: }
148:
149: return(err);
150: }
151:
152: IOReturn IOUSBPipe::write(IOMemoryDescriptor * buffer,
153: IOUSBCompletion * completion = 0)
154: {
155: IOReturn err = kIOReturnSuccess;
156:
157: if (completion == 0)
158: {
159: // put in our own completion routine if none was specified to
160: // fake synchronous operation
161: IOUSBCompletion tap;
162: IOSyncer * syncer;
163:
164: syncer = IOSyncer::create();
165:
166: tap.target = syncer;
167: tap.action = &IOUSBSyncCompletion;
168: tap.parameter = NULL;
169:
170: err = _controller->write(buffer, _address, &_endpoint, &tap);
171: if (err == kIOReturnSuccess) {
172: err = syncer->wait();
173: }
174: else {
175: syncer->release(); syncer->release();
176: }
177: }
178: else
179: {
180: err = _controller->write(buffer, _address, &_endpoint, completion);
181: }
182:
183: return(err);
184: }
185:
186: // Isochronous read and write
187: IOReturn IOUSBPipe::read(IOMemoryDescriptor * buffer,
188: UInt64 frameStart, UInt32 numFrames, IOUSBIsocFrame *pFrames,
189: IOUSBIsocCompletion * completion)
190: {
191: IOReturn err = kIOReturnSuccess;
192:
193: if (completion == 0)
194: {
195: // put in our own completion routine if none was specified to
196: // fake synchronous operation
197: IOUSBIsocCompletion tap;
198: IOSyncer * syncer;
199:
200: syncer = IOSyncer::create();
201:
202: tap.target = (void *)syncer;
203: tap.action = IOUSBSyncIsoCompletion;
204: tap.parameter = NULL;
205:
206: err = _controller->isocIO(buffer, frameStart, numFrames, pFrames,
207: _address, &_endpoint, &tap);
208:
209: if (err == kIOReturnSuccess) {
210: err = syncer->wait();
211: }
212: else {
213: syncer->release(); syncer->release();
214: }
215: }
216: else {
217: err = _controller->isocIO(buffer, frameStart, numFrames, pFrames,
218: _address, &_endpoint, completion);
219: }
220:
221: return(err);
222: }
223:
224: IOReturn IOUSBPipe::write(IOMemoryDescriptor * buffer,
225: UInt64 frameStart, UInt32 numFrames, IOUSBIsocFrame *pFrames,
226: IOUSBIsocCompletion * completion)
227: {
228: IOReturn err = kIOReturnSuccess;
229:
230: if (completion == 0)
231: {
232: // put in our own completion routine if none was specified to
233: // fake synchronous operation
234: IOUSBIsocCompletion tap;
235: IOSyncer * syncer;
236:
237: syncer = IOSyncer::create();
238:
239: tap.target = syncer;
240: tap.action = &IOUSBSyncIsoCompletion;
241: tap.parameter = NULL;
242:
243: err = _controller->isocIO(buffer, frameStart, numFrames, pFrames,
244: _address, &_endpoint, &tap);
245:
246: if (err == kIOReturnSuccess)
247: {
248: err = syncer->wait();
249: }
250: else {
251: syncer->release(); syncer->release();
252: }
253: }
254: else
255: {
256: err = _controller->isocIO(buffer, frameStart, numFrames, pFrames,
257: _address, &_endpoint, completion);
258:
259: }
260:
261: return(err);
262: }
263:
264: IOReturn IOUSBPipe::controlRequest(IOUSBDevRequest *request,
265: IOUSBCompletion *completion = 0)
266: {
267: IOReturn err = kIOReturnSuccess;
268:
269:
270: #if (DEBUGGING_LEVEL > 0)
271: DEBUGLOG("%s: deviceRequest([%x,%s,%x,%x],[%x,%x],[%x,%lx])\n", "IOUSBPipe",
272: request->bRequest,
273: request->rqDirection?"in":"out",
274: request->rqType, request->rqRecipient,
275: OSReadLittleInt16(&request->wValue, 0),
276: OSReadLittleInt16(&request->wIndex, 0),
277: OSReadLittleInt16(&request->wLength, 0),
278: (UInt32)request->pData);
279: #endif
280:
281: if (completion == 0)
282: {
283: // put in our own completion routine if none was specified to
284: // fake synchronous operation
285: IOUSBCompletion tap;
286: IOSyncer * syncer;
287:
288: syncer = IOSyncer::create();
289: request->wLenDone = OSReadLittleInt16(&request->wLength, 0);
290:
291: tap.target = syncer;
292: tap.action = &IOUSBSyncCompletion;
293: tap.parameter = &request->wLenDone;
294:
295: err = _controller->deviceRequest(request, &tap, _address, _endpoint.number);
296: if (err == kIOReturnSuccess) {
297: err = syncer->wait();
298: }
299: else {
300: syncer->release(); syncer->release();
301: }
302: }
303: else
304: {
305: err = _controller->deviceRequest(request, completion, _address, _endpoint.number);
306: }
307:
308: return(err);
309: }
310:
311: IOReturn IOUSBPipe::controlRequest(IOUSBDevRequestDesc *request,
312: IOUSBCompletion *completion = 0)
313: {
314: IOReturn err = kIOReturnSuccess;
315:
316:
317: #if (DEBUGGING_LEVEL > 0)
318: DEBUGLOG("%s: deviceRequest([%x,%s,%x,%x],[%x,%x],[%x,%lx])\n", "IOUSBPipe",
319: request->bRequest,
320: request->rqDirection?"in":"out",
321: request->rqType, request->rqRecipient,
322: OSReadLittleInt16(&request->wValue, 0),
323: OSReadLittleInt16(&request->wIndex, 0),
324: OSReadLittleInt16(&request->wLength, 0),
325: (UInt32)request->pData);
326: #endif
327:
328: if (completion == 0)
329: {
330: // put in our own completion routine if none was specified to
331: // fake synchronous operation
332: IOUSBCompletion tap;
333: IOSyncer * syncer;
334:
335: syncer = IOSyncer::create();
336: request->wLenDone = OSReadLittleInt16(&request->wLength, 0);
337:
338: tap.target = syncer;
339: tap.action = &IOUSBSyncCompletion;
340: tap.parameter = &request->wLenDone;
341:
342: err = _controller->deviceRequest(request, &tap, _address, _endpoint.number);
343: if (err == kIOReturnSuccess) {
344: err = syncer->wait();
345: }
346: else {
347: syncer->release(); syncer->release();
348: }
349: }
350: else
351: {
352: err = _controller->deviceRequest(request, completion, _address, _endpoint.number);
353: }
354:
355: return(err);
356: }
357:
358: const IOUSBDescriptorHeader *
359: IOUSBPipe::findNextAssociatedDescriptor(const void *current, UInt8 type)
360: {
361: const IOUSBDescriptorHeader *next;
362: if(current == NULL)
363: current = _descriptor;
364: next = (const IOUSBDescriptorHeader *)current;
365:
366: while (true) {
367: next = IOUSBNub::findNextDescriptor(next, kUSBAnyDesc);
368:
369: if(!next || next->descriptorType == kUSBEndpointDesc)
370: return NULL; // Reached end of our list.
371: if(next->descriptorType == type || type == kUSBAnyDesc)
372: break;
373: }
374: return next;
375: }
376:
377: UInt32 IOUSBPipe::GetBandwidthAvailable()
378: {
379: return _controller->GetBandwidthAvailable();
380: }
381:
382: UInt64 IOUSBPipe::GetFrameNumber()
383: {
384: return _controller->GetFrameNumber();
385: }
386:
387:
388: /*
389: * Accessors
390: */
391: const IOUSBController::Endpoint *IOUSBPipe::endpoint(void)
392: { return(&_endpoint); }
393:
394: const IOUSBEndpointDescriptor *IOUSBPipe::endpointDescriptor(void)
395: { return(_descriptor); }
396:
397: UInt8 IOUSBPipe::direction(void)
398: { return(_endpoint.direction); }
399:
400: UInt8 IOUSBPipe::type(void)
401: { return(_endpoint.transferType); }
402:
403: UInt8 IOUSBPipe::endpointNumber(void)
404: { return(_endpoint.number); }
405:
406: USBDeviceAddress IOUSBPipe::address(void)
407: { return(_address); }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.