|
|
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) 1999 Apple Computer, Inc. All rights reserved.
24: *
25: * HISTORY
26: * 16 Mar 1999 wgulland created.
27: *
28: */
29: #include <libkern/OSByteOrder.h>
30:
31: #include <IOKit/assert.h>
32: #include <IOKit/IOLib.h>
33: #include <IOKit/IOBufferMemoryDescriptor.h>
34: #include <IOKit/usb/IOUSBDevice.h>
35: #include <IOKit/usb/IOUSBInterface.h>
36: #include <IOKit/usb/IOUSBPipe.h>
37:
38: #include "IOUSBUserClient.h"
39:
40: #define super IOUserClient
41: #define DEBUGGING_LEVEL 0
42:
43: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
44:
45: OSDefineMetaClass( IOUSBUserClient, IOUserClient )
46: OSDefineAbstractStructors(IOUSBUserClient, IOUserClient)
47:
48: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
49:
50: bool IOUSBUserClient::start( IOService * provider )
51: {
52: IOUSBNub *owner = OSDynamicCast(IOUSBNub, provider);
53:
54: assert(owner);
55: if(!super::start(provider))
56: return false;
57:
58: fPipes[0] = owner->pipeZero();
59: if(!fPipes[0])
60: return false;
61:
62: // Initialize the call structures valid for IOUSBNub
63: fMethods[kUSBSetConfig].object = NULL;
64: fMethods[kUSBSetConfig].func = NULL;
65: fMethods[kUSBSetConfig].count0 = 1;
66: fMethods[kUSBSetConfig].count1 = 0;
67: fMethods[kUSBSetConfig].flags = kIOUCScalarIScalarO;
68:
69: fMethods[kUSBGetConfig].object = provider;
70: fMethods[kUSBGetConfig].func = (IOMethod)&IOUSBNub::GetConfiguration;
71: fMethods[kUSBGetConfig].count0 = 0;
72: fMethods[kUSBGetConfig].count1 = 1;
73: fMethods[kUSBGetConfig].flags = kIOUCScalarIScalarO;
74:
75: fMethods[kUSBGetConfigDescriptor].object = NULL;
76: fMethods[kUSBGetConfigDescriptor].func = NULL;
77: fMethods[kUSBGetConfigDescriptor].count0 = 1;
78: fMethods[kUSBGetConfigDescriptor].count1 = 0xffffffff; // variable
79: fMethods[kUSBGetConfigDescriptor].flags = kIOUCScalarIStructO;
80:
81: fMethods[kUSBControlReqOut].object = this;
82: fMethods[kUSBControlReqOut].func =
83: (IOMethod)&IOUSBUserClient::ControlReqOut;
84: fMethods[kUSBControlReqOut].count0 = 4;
85: fMethods[kUSBControlReqOut].count1 = 0xffffffff; // variable
86: fMethods[kUSBControlReqOut].flags = kIOUCScalarIStructI;
87:
88: fMethods[kUSBControlReqIn].object = this;
89: fMethods[kUSBControlReqIn].func =
90: (IOMethod)&IOUSBUserClient::ControlReqIn;
91: fMethods[kUSBControlReqIn].count0 = 4;
92: fMethods[kUSBControlReqIn].count1 = 0xffffffff; // variable
93: fMethods[kUSBControlReqIn].flags = kIOUCScalarIStructO;
94:
95: fMethods[kUSBOpenPipe].object = NULL;
96: fMethods[kUSBOpenPipe].func = NULL;
97: fMethods[kUSBOpenPipe].count0 = 4;
98: fMethods[kUSBOpenPipe].count1 = 1;
99: fMethods[kUSBOpenPipe].flags = kIOUCScalarIScalarO;
100:
101: fMethods[kUSBClosePipe].object = this;
102: fMethods[kUSBClosePipe].func =
103: (IOMethod)&IOUSBUserClient::ClosePipe;
104: fMethods[kUSBClosePipe].count0 = 1;
105: fMethods[kUSBClosePipe].count1 = 0;
106: fMethods[kUSBClosePipe].flags = kIOUCScalarIScalarO;
107:
108: fMethods[kUSBReadPipe].object = this;
109: fMethods[kUSBReadPipe].func =
110: (IOMethod)&IOUSBUserClient::ReadPipe;
111: fMethods[kUSBReadPipe].count0 = 1;
112: fMethods[kUSBReadPipe].count1 = 0xffffffff; // variable
113: fMethods[kUSBReadPipe].flags = kIOUCScalarIStructO;
114:
115: fMethods[kUSBWritePipe].object = this;
116: fMethods[kUSBWritePipe].func =
117: (IOMethod)&IOUSBUserClient::WritePipe;
118: fMethods[kUSBWritePipe].count0 = 1;
119: fMethods[kUSBWritePipe].count1 = 0xffffffff; // variable
120: fMethods[kUSBWritePipe].flags = kIOUCScalarIStructI;
121:
122: fMethods[kUSBGetPipeStatus].object = this;
123: fMethods[kUSBGetPipeStatus].func =
124: (IOMethod)&IOUSBUserClient::getPipeStatus;
125: fMethods[kUSBGetPipeStatus].count0 = 1;
126: fMethods[kUSBGetPipeStatus].count1 = 0;
127: fMethods[kUSBGetPipeStatus].flags = kIOUCScalarIScalarO;
128:
129: fMethods[kUSBAbortPipe].object = this;
130: fMethods[kUSBAbortPipe].func =
131: (IOMethod)&IOUSBUserClient::abortPipe;
132: fMethods[kUSBAbortPipe].count0 = 1;
133: fMethods[kUSBAbortPipe].count1 = 0;
134: fMethods[kUSBAbortPipe].flags = kIOUCScalarIScalarO;
135:
136: fMethods[kUSBResetPipe].object = this;
137: fMethods[kUSBResetPipe].func =
138: (IOMethod)&IOUSBUserClient::resetPipe;
139: fMethods[kUSBResetPipe].count0 = 1;
140: fMethods[kUSBResetPipe].count1 = 0;
141: fMethods[kUSBResetPipe].flags = kIOUCScalarIScalarO;
142:
143: fMethods[kUSBSetPipeIdle].object = this;
144: fMethods[kUSBSetPipeIdle].func =
145: (IOMethod)&IOUSBUserClient::setPipeIdle;
146: fMethods[kUSBSetPipeIdle].count0 = 1;
147: fMethods[kUSBSetPipeIdle].count1 = 0;
148: fMethods[kUSBSetPipeIdle].flags = kIOUCScalarIScalarO;
149:
150: fMethods[kUSBSetPipeActive].object = this;
151: fMethods[kUSBSetPipeActive].func =
152: (IOMethod)&IOUSBUserClient::setPipeActive;
153: fMethods[kUSBSetPipeActive].count0 = 1;
154: fMethods[kUSBSetPipeActive].count1 = 0;
155: fMethods[kUSBSetPipeActive].flags = kIOUCScalarIScalarO;
156:
157: fMethods[kUSBClearPipeStall].object = this;
158: fMethods[kUSBClearPipeStall].func =
159: (IOMethod)&IOUSBUserClient::clearPipeStall;
160: fMethods[kUSBClearPipeStall].count0 = 1;
161: fMethods[kUSBClearPipeStall].count1 = 0;
162: fMethods[kUSBClearPipeStall].flags = kIOUCScalarIScalarO;
163:
164: fMethods[kUSBReadPipeOOL].object = this;
165: fMethods[kUSBReadPipeOOL].func =
166: (IOMethod)&IOUSBUserClient::ReadPipeOOL;
167: fMethods[kUSBReadPipeOOL].count0 = 3;
168: fMethods[kUSBReadPipeOOL].count1 = 1;
169: fMethods[kUSBReadPipeOOL].flags = kIOUCScalarIScalarO;
170:
171: fAsyncMethods[kUSBReadPipeOOL].object = this;
172: fAsyncMethods[kUSBReadPipeOOL].func =
173: (IOAsyncMethod)&IOUSBUserClient::ReadPipeAsync;
174: fAsyncMethods[kUSBReadPipeOOL].count0 = 3;
175: fAsyncMethods[kUSBReadPipeOOL].count1 = 0;
176: fAsyncMethods[kUSBReadPipeOOL].flags = kIOUCScalarIScalarO;
177:
178: fMethods[kUSBWritePipeOOL].object = this;
179: fMethods[kUSBWritePipeOOL].func =
180: (IOMethod)&IOUSBUserClient::WritePipeOOL;
181: fMethods[kUSBWritePipeOOL].count0 = 3;
182: fMethods[kUSBWritePipeOOL].count1 = 0;
183: fMethods[kUSBWritePipeOOL].flags = kIOUCScalarIScalarO;
184:
185: fAsyncMethods[kUSBWritePipeOOL].object = this;
186: fAsyncMethods[kUSBWritePipeOOL].func =
187: (IOAsyncMethod)&IOUSBUserClient::WritePipeAsync;
188: fAsyncMethods[kUSBWritePipeOOL].count0 = 3;
189: fAsyncMethods[kUSBWritePipeOOL].count1 = 0;
190: fAsyncMethods[kUSBWritePipeOOL].flags = kIOUCScalarIScalarO;
191:
192: fMethods[kUSBControlReqInOOL].object = this;
193: fMethods[kUSBControlReqInOOL].func =
194: (IOMethod)&IOUSBUserClient::ControlReqInOOL;
195: fMethods[kUSBControlReqInOOL].count0 = sizeof(DevReqOOL);
196: fMethods[kUSBControlReqInOOL].count1 = sizeof(UInt32);
197: fMethods[kUSBControlReqInOOL].flags = kIOUCStructIStructO;
198:
199: fAsyncMethods[kUSBControlReqInOOL].object = this;
200: fAsyncMethods[kUSBControlReqInOOL].func =
201: (IOAsyncMethod)&IOUSBUserClient::ControlReqInAsync;
202: fAsyncMethods[kUSBControlReqInOOL].count0 = sizeof(DevReqOOL);
203: fAsyncMethods[kUSBControlReqInOOL].count1 = 0;
204: fAsyncMethods[kUSBControlReqInOOL].flags = kIOUCStructIStructO;
205:
206: fMethods[kUSBControlReqOutOOL].object = this;
207: fMethods[kUSBControlReqOutOOL].func =
208: (IOMethod)&IOUSBUserClient::ControlReqOutOOL;
209: fMethods[kUSBControlReqOutOOL].count0 = sizeof(DevReqOOL);
210: fMethods[kUSBControlReqOutOOL].count1 = 0;
211: fMethods[kUSBControlReqOutOOL].flags = kIOUCStructIStructO;
212:
213: fAsyncMethods[kUSBControlReqOutOOL].object = this;
214: fAsyncMethods[kUSBControlReqOutOOL].func =
215: (IOAsyncMethod)&IOUSBUserClient::ControlReqOutAsync;
216: fAsyncMethods[kUSBControlReqOutOOL].count0 = sizeof(DevReqOOL);
217: fAsyncMethods[kUSBControlReqOutOOL].count1 = 0;
218: fAsyncMethods[kUSBControlReqOutOOL].flags = kIOUCStructIStructO;
219:
220:
221: fMethods[kUSBResetDevice].object = NULL;
222: fMethods[kUSBResetDevice].func = NULL;
223: fMethods[kUSBResetDevice].count0 = 0;
224: fMethods[kUSBResetDevice].count1 = 0;
225: fMethods[kUSBResetDevice].flags = kIOUCScalarIScalarO;
226:
227: return true;
228: }
229:
230: IOExternalMethod *
231: IOUSBUserClient::getExternalMethodForIndex( UInt32 index )
232: {
233: if(index >= kNumUSBMethods || fMethods[index].object == NULL)
234: return NULL;
235: else
236: return &fMethods[index];
237: }
238:
239: IOExternalAsyncMethod *
240: IOUSBUserClient::getExternalAsyncMethodForIndex( UInt32 index )
241: {
242: if(index >= kNumUSBMethods || fAsyncMethods[index].object == NULL)
243: return NULL;
244: else
245: return &fAsyncMethods[index];
246: }
247:
248: /*
249: * There's a limit of max 6 arguments to user client methods, so the type, recipient and request
250: * are packed into one 16 bit integer.
251: */
252: IOReturn
253: IOUSBUserClient::ControlReqIn(UInt32 pipe, UInt16 bmreqtypeRequest, UInt16 wValue,
254: UInt16 wIndex, void *buf, UInt32 *size)
255: {
256: IOReturn res;
257: IOUSBDevRequest req;
258: IOUSBPipe *pipeObj;
259:
260: pipeObj = fPipes[pipe];
261: if(!pipeObj)
262: return kIOUSBUnknownPipeErr;
263:
264: req.rqDirection = kUSBIn;
265: req.rqType = (bmreqtypeRequest >> kUSBRqTypeShift) & kUSBRqTypeMask;
266: req.rqRecipient = bmreqtypeRequest & kUSBRqRecipientMask;
267: req.bRequest = bmreqtypeRequest >> 8;
268: OSWriteLittleInt16(&req.wValue, 0, wValue);
269: OSWriteLittleInt16(&req.wIndex, 0, wIndex);
270: OSWriteLittleInt16(&req.wLength, 0, *size);
271: req.pData = buf;
272: res = pipeObj->controlRequest(&req);
273:
274: if(res == kIOReturnSuccess) {
275: *size = req.wLenDone;
276: }
277: else {
278: IOLog("IOUSBUserClient::ControlReqIn err:0x%x\n", res);
279: *size = 0;
280: }
281: return res;
282: }
283:
284: /*
285: * There's a limit of max 6 arguments to user client methods, so the type, recipient and request
286: * are packed into one 16 bit integer.
287: */
288: IOReturn
289: IOUSBUserClient::ControlReqOut(UInt32 pipe, UInt16 bmreqtypeRequest, UInt16 wValue,
290: UInt16 wIndex, void *buf, UInt32 size)
291: {
292: IOReturn res;
293: IOUSBDevRequest req;
294: IOUSBPipe *pipeObj;
295:
296: pipeObj = fPipes[pipe];
297: if(!pipeObj)
298: return kIOUSBUnknownPipeErr;
299:
300: req.rqDirection = kUSBOut;
301: req.rqType = (bmreqtypeRequest >> kUSBRqTypeShift) & kUSBRqTypeMask;
302: req.rqRecipient = bmreqtypeRequest & kUSBRqRecipientMask;
303: req.bRequest = bmreqtypeRequest >> 8;
304: OSWriteLittleInt16(&req.wValue, 0, wValue);
305: OSWriteLittleInt16(&req.wIndex, 0, wIndex);
306: OSWriteLittleInt16(&req.wLength, 0, size);
307: req.pData = buf;
308: res = pipeObj->controlRequest(&req);
309:
310: if(kIOReturnSuccess != res) {
311: IOLog("IOUSBUserClient::ControlReqOut err:0x%x\n", res);
312: }
313: return res;
314: }
315:
316: IOReturn
317: IOUSBUserClient::ControlReqInOOL(DevReqOOL *reqIn, UInt32 *sizeOut, IOByteCount inCount,
318: IOByteCount *outCount)
319: {
320: IOReturn res;
321: IOUSBDevRequestDesc req;
322: IOMemoryDescriptor * mem;
323: IOUSBPipe * pipeObj;
324:
325: if(inCount != sizeof(DevReqOOL) ||
326: *outCount != sizeof(UInt32))
327: return kIOReturnBadArgument;
328:
329: pipeObj = fPipes[reqIn->pipe];
330: if(!pipeObj)
331: return kIOUSBUnknownPipeErr;
332:
333: mem = IOMemoryDescriptor::withAddress((vm_address_t)reqIn->buf, reqIn->sizeIn,
334: kIODirectionIn,
335: fTask);
336: if(!mem) {
337: return kIOReturnNoMemory;
338: }
339: req.rqDirection = kUSBIn;
340: req.rqType = (reqIn->bmreqtype >> kUSBRqTypeShift) & kUSBRqTypeMask;
341: req.rqRecipient = reqIn->bmreqtype & kUSBRqRecipientMask;
342: req.bRequest = reqIn->request;
343: OSWriteLittleInt16(&req.wValue, 0, reqIn->wValue);
344: OSWriteLittleInt16(&req.wIndex, 0, reqIn->wIndex);
345: OSWriteLittleInt16(&req.wLength, 0, reqIn->sizeIn);
346: req.pData = mem;
347:
348: res = mem->prepare();
349: if(res == kIOReturnSuccess)
350: res = pipeObj->controlRequest(&req);
351: mem->complete();
352: mem->release();
353: if(res == kIOReturnSuccess) {
354: *sizeOut = req.wLenDone;
355: }
356: else {
357: IOLog("IOUSBUserClient::ControlReqInOOL err:0x%x\n", res);
358: *sizeOut = 0;
359: }
360: *outCount = sizeof(UInt32);
361:
362: return res;
363: }
364:
365: typedef struct AsyncPB {
366: OSAsyncReference fAsyncRef;
367: UInt32 fMax;
368: IOMemoryDescriptor *fMem;
369: };
370:
371: IOReturn
372: IOUSBUserClient::ControlReqInAsync(OSAsyncReference asyncRef,
373: DevReqOOL *reqIn, IOByteCount inCount)
374: {
375: IOReturn res;
376: IOUSBDevRequestDesc req;
377: IOUSBPipe * pipeObj;
378:
379: IOUSBCompletion tap;
380: AsyncPB * pb = NULL;
381: IOMemoryDescriptor * mem = NULL;
382:
383: if(inCount != sizeof(DevReqOOL))
384: return kIOReturnBadArgument;
385:
386: pipeObj = fPipes[reqIn->pipe];
387: if(!pipeObj)
388: return kIOUSBUnknownPipeErr;
389:
390: do {
391: mem = IOMemoryDescriptor::withAddress((vm_address_t)reqIn->buf,
392: reqIn->sizeIn,
393: kIODirectionIn,
394: fTask);
395: if(!mem) {
396: res = kIOReturnNoMemory;
397: break;
398: }
399: res = mem->prepare();
400: if(res != kIOReturnSuccess)
401: break;
402: pb = (AsyncPB *)IOMalloc(sizeof(AsyncPB));
403: if(!pb) {
404: res = kIOReturnNoMemory;
405: break;
406: }
407:
408: req.rqDirection = kUSBIn;
409: req.rqType = (reqIn->bmreqtype >> kUSBRqTypeShift) & kUSBRqTypeMask;
410: req.rqRecipient = reqIn->bmreqtype & kUSBRqRecipientMask;
411: req.bRequest = reqIn->request;
412: OSWriteLittleInt16(&req.wValue, 0, reqIn->wValue);
413: OSWriteLittleInt16(&req.wIndex, 0, reqIn->wIndex);
414: OSWriteLittleInt16(&req.wLength, 0, reqIn->sizeIn);
415: req.pData = mem;
416:
417: bcopy(asyncRef, pb->fAsyncRef, sizeof(OSAsyncReference));
418: pb->fMax = reqIn->sizeIn;
419: pb->fMem = mem;
420: tap.target = this;
421: tap.action = &ReqComplete;
422: tap.parameter = pb;
423: res = pipeObj->controlRequest(&req, &tap);
424:
425: } while (false);
426:
427: if(res != kIOReturnSuccess) {
428: IOLog("ControlReqInAsync err 0x%x\n", res);
429: if(mem) {
430: mem->complete();
431: mem->release();
432: }
433: if(pb)
434: IOFree(pb, sizeof(*pb));
435: }
436:
437: return res;
438: }
439:
440: void
441: IOUSBUserClient::ReqComplete(void *obj, void *param, IOReturn res, UInt32 remaining)
442: {
443: void * args[1];
444: AsyncPB * pb = (AsyncPB *)param;
445:
446: if(res == kIOReturnSuccess) {
447: args[0] = (void *)(pb->fMax - remaining);
448: }
449: else {
450: IOLog("IOUSBUserClient::ReqComplete err:0x%x\n", res);
451: args[0] = 0;
452: }
453: pb->fMem->complete();
454: pb->fMem->release();
455: sendAsyncResult(pb->fAsyncRef, res, args, 1);
456:
457: IOFree(pb, sizeof(*pb));
458: }
459:
460: IOReturn
461: IOUSBUserClient::ControlReqOutOOL(DevReqOOL *reqIn, IOByteCount inCount)
462: {
463: IOReturn res;
464: IOUSBDevRequestDesc req;
465: IOMemoryDescriptor * mem;
466: IOUSBPipe * pipeObj;
467:
468: if(inCount != sizeof(DevReqOOL))
469: return kIOReturnBadArgument;
470:
471: pipeObj = fPipes[reqIn->pipe];
472: if(!pipeObj)
473: return kIOUSBUnknownPipeErr;
474:
475:
476: mem = IOMemoryDescriptor::withAddress((vm_address_t)reqIn->buf,
477: reqIn->sizeIn, kIODirectionOut, fTask);
478: if(!mem) {
479: return kIOReturnNoMemory;
480: }
481: req.rqDirection = kUSBOut;
482: req.rqType = (reqIn->bmreqtype >> kUSBRqTypeShift) & kUSBRqTypeMask;
483: req.rqRecipient = reqIn->bmreqtype & kUSBRqRecipientMask;
484: req.bRequest = reqIn->request;
485: OSWriteLittleInt16(&req.wValue, 0, reqIn->wValue);
486: OSWriteLittleInt16(&req.wIndex, 0, reqIn->wIndex);
487: OSWriteLittleInt16(&req.wLength, 0, reqIn->sizeIn);
488: req.pData = mem;
489:
490: res = mem->prepare();
491: if(res == kIOReturnSuccess)
492: res = pipeObj->controlRequest(&req);
493: mem->complete();
494: mem->release();
495: return res;
496: }
497:
498: IOReturn
499: IOUSBUserClient::ControlReqOutAsync(OSAsyncReference asyncRef,
500: DevReqOOL *reqIn, IOByteCount inCount)
501: {
502: IOReturn res;
503: IOUSBDevRequestDesc req;
504: IOUSBPipe * pipeObj;
505:
506: IOUSBCompletion tap;
507: AsyncPB * pb = NULL;
508: IOMemoryDescriptor * mem = NULL;
509:
510: if(inCount != sizeof(DevReqOOL))
511: return kIOReturnBadArgument;
512:
513: pipeObj = fPipes[reqIn->pipe];
514: if(!pipeObj)
515: return kIOUSBUnknownPipeErr;
516:
517: do {
518: mem = IOMemoryDescriptor::withAddress((vm_address_t)reqIn->buf,
519: reqIn->sizeIn,
520: kIODirectionOut,
521: fTask);
522: if(!mem) {
523: res = kIOReturnNoMemory;
524: break;
525: }
526: res = mem->prepare();
527: if(res != kIOReturnSuccess)
528: break;
529: pb = (AsyncPB *)IOMalloc(sizeof(AsyncPB));
530: if(!pb) {
531: res = kIOReturnNoMemory;
532: break;
533: }
534:
535: req.rqDirection = kUSBOut;
536: req.rqType = (reqIn->bmreqtype >> kUSBRqTypeShift) & kUSBRqTypeMask;
537: req.rqRecipient = reqIn->bmreqtype & kUSBRqRecipientMask;
538: req.bRequest = reqIn->request;
539: OSWriteLittleInt16(&req.wValue, 0, reqIn->wValue);
540: OSWriteLittleInt16(&req.wIndex, 0, reqIn->wIndex);
541: OSWriteLittleInt16(&req.wLength, 0, reqIn->sizeIn);
542: req.pData = mem;
543:
544: bcopy(asyncRef, pb->fAsyncRef, sizeof(OSAsyncReference));
545: pb->fMax = reqIn->sizeIn;
546: pb->fMem = mem;
547: tap.target = this;
548: tap.action = &ReqComplete; // Want same number of reply args as for ControlReqIn
549: tap.parameter = pb;
550: res = pipeObj->controlRequest(&req, &tap);
551:
552: } while (false);
553:
554: if(res != kIOReturnSuccess) {
555: IOLog("controlRequest err 0x%x\n", res);
556: if(mem) {
557: mem->complete();
558: mem->release();
559: }
560: if(pb)
561: IOFree(pb, sizeof(*pb));
562: }
563:
564: return res;
565: }
566:
567:
568: // Controlling pipe state
569:
570: IOReturn IOUSBUserClient::getPipeStatus(UInt32 pipe)
571: {
572: IOUSBPipe *pipeObj;
573: pipeObj = fPipes[pipe];
574: if(!pipeObj)
575: return kIOUSBUnknownPipeErr;
576: return pipeObj->status();
577: }
578:
579: IOReturn IOUSBUserClient::abortPipe(UInt32 pipe)
580: {
581: IOUSBPipe *pipeObj;
582: pipeObj = fPipes[pipe];
583: if(!pipeObj)
584: return kIOUSBUnknownPipeErr;
585: return pipeObj->abort();
586: }
587:
588: IOReturn IOUSBUserClient::resetPipe(UInt32 pipe)
589: {
590: IOUSBPipe *pipeObj;
591: pipeObj = fPipes[pipe];
592: if(!pipeObj)
593: return kIOUSBUnknownPipeErr;
594: return pipeObj->reset();
595: }
596:
597: IOReturn IOUSBUserClient::setPipeIdle(UInt32 pipe)
598: {
599: return(0);
600: }
601:
602: IOReturn IOUSBUserClient::setPipeActive(UInt32 pipe)
603: {
604: return(0);
605: }
606:
607: IOReturn IOUSBUserClient::clearPipeStall(UInt32 pipe)
608: {
609: IOUSBPipe *pipeObj;
610: pipeObj = fPipes[pipe];
611: if(!pipeObj)
612: return kIOUSBUnknownPipeErr;
613: return pipeObj->clearStall();
614: }
615:
616: IOReturn
617: IOUSBUserClient::ReadPipe(UInt32 pipe, void *buf, UInt32 *size)
618: {
619: IOReturn res;
620: IOMemoryDescriptor * mem;
621: IOUSBPipe * pipeObj;
622:
623: pipeObj = fPipes[pipe];
624: if(!pipeObj)
625: return kIOUSBUnknownPipeErr;
626:
627: mem = IOMemoryDescriptor::withAddress(buf, *size, kIODirectionIn);
628: if(!mem) {
629: *size = 0;
630: return kIOReturnNoMemory;
631: }
632: res = pipeObj->read(mem, 0, size);
633: if(kIOReturnSuccess != res)
634: *size = 0;
635: mem->release();
636:
637: return res;
638: }
639:
640: IOReturn
641: IOUSBUserClient::WritePipe(UInt32 pipe, void *buf, UInt32 size)
642: {
643: IOReturn res;
644: IOMemoryDescriptor * mem;
645: IOUSBPipe * pipeObj;
646:
647: pipeObj = fPipes[pipe];
648: if(!pipeObj)
649: return kIOUSBUnknownPipeErr;
650:
651: mem = IOMemoryDescriptor::withAddress(buf, size, kIODirectionOut);
652: if(!mem) {
653: res = kIOReturnNoMemory;
654: }
655: else {
656: res = pipeObj->write(mem);
657: mem->release();
658: }
659: return res;
660: }
661:
662: /*
663: * Out of line version of read pipe - the buffer isn't mapped (yet) into the kernel task
664: */
665: IOReturn
666: IOUSBUserClient::ReadPipeOOL(UInt32 pipe, void *buf, UInt32 sizeIn, UInt32 *sizeOut)
667: {
668: IOReturn res;
669: IOMemoryDescriptor * mem;
670: IOUSBPipe * pipeObj;
671:
672: pipeObj = fPipes[pipe];
673: if(!pipeObj)
674: return kIOUSBUnknownPipeErr;
675:
676: mem = IOMemoryDescriptor::withAddress((vm_address_t)buf, sizeIn,
677: kIODirectionIn,
678: fTask);
679: if(!mem) {
680: *sizeOut = 0;
681: return kIOReturnNoMemory;
682: }
683: res = mem->prepare();
684: if(res == kIOReturnSuccess)
685: res = pipeObj->read(mem, 0, sizeOut);
686: mem->complete();
687: if(kIOReturnSuccess != res)
688: *sizeOut = 0;
689: mem->release();
690:
691: return res;
692: }
693:
694: /*
695: * Out of line version of write pipe - the buffer isn't mapped (yet) into the kernel task
696: */
697: IOReturn
698: IOUSBUserClient::WritePipeOOL(UInt32 pipe, void *buf, UInt32 size)
699: {
700: IOReturn res;
701: IOMemoryDescriptor * mem;
702: IOUSBPipe * pipeObj;
703:
704: pipeObj = fPipes[pipe];
705: if(!pipeObj)
706: return kIOUSBUnknownPipeErr;
707:
708: mem = IOMemoryDescriptor::withAddress((vm_address_t)buf, size,
709: kIODirectionOut,
710: fTask);
711: if(!mem) {
712: res = kIOReturnNoMemory;
713: }
714: else {
715: res = mem->prepare();
716: if(res == kIOReturnSuccess)
717: res = pipeObj->write(mem);
718: mem->complete();
719: mem->release();
720: }
721: return res;
722: }
723:
724: /*
725: * Async version of read pipe - the buffer isn't mapped (yet) into the kernel task
726: */
727: IOReturn
728: IOUSBUserClient::ReadPipeAsync(OSAsyncReference asyncRef,
729: UInt32 pipe, void *buf, UInt32 size)
730: {
731: IOReturn res;
732: IOUSBPipe * pipeObj;
733: IOUSBCompletion tap;
734: IOMemoryDescriptor * mem = NULL;
735: AsyncPB * pb = NULL;
736:
737: pipeObj = fPipes[pipe];
738: if(!pipeObj)
739: return kIOUSBUnknownPipeErr;
740:
741: do {
742: mem = IOMemoryDescriptor::withAddress((vm_address_t)buf, size,
743: kIODirectionIn,
744: fTask);
745: if(!mem) {
746: res = kIOReturnNoMemory;
747: break;
748: }
749: res = mem->prepare();
750: if(res != kIOReturnSuccess)
751: break;
752:
753: pb = (AsyncPB *)IOMalloc(sizeof(AsyncPB));
754: if(!pb) {
755: res = kIOReturnNoMemory;
756: break;
757: }
758:
759: bcopy(asyncRef, pb->fAsyncRef, sizeof(OSAsyncReference));
760: pb->fMax = size;
761: pb->fMem = mem;
762: tap.target = this;
763: tap.action = &ReqComplete;
764: tap.parameter = pb;
765: res = pipeObj->read(mem, &tap, NULL);
766: } while (false);
767: if(res != kIOReturnSuccess) {
768: if(mem) {
769: mem->complete();
770: mem->release();
771: }
772: if(pb)
773: IOFree(pb, sizeof(*pb));
774: }
775:
776: return res;
777: }
778:
779: /*
780: * Async version of write pipe - the buffer isn't mapped (yet) into the kernel task
781: */
782: IOReturn
783: IOUSBUserClient::WritePipeAsync(OSAsyncReference asyncRef,
784: UInt32 pipe, void *buf, UInt32 size)
785: {
786: IOReturn res;
787: IOUSBPipe * pipeObj;
788: IOUSBCompletion tap;
789: IOMemoryDescriptor * mem = NULL;
790: AsyncPB * pb = NULL;
791:
792: pipeObj = fPipes[pipe];
793: if(!pipeObj)
794: return kIOUSBUnknownPipeErr;
795:
796: do {
797: mem = IOMemoryDescriptor::withAddress((vm_address_t)buf, size,
798: kIODirectionOut,
799: fTask);
800: if(!mem) {
801: res = kIOReturnNoMemory;
802: break;
803: }
804: res = mem->prepare();
805: if(res != kIOReturnSuccess)
806: break;
807:
808: pb = (AsyncPB *)IOMalloc(sizeof(AsyncPB));
809: if(!pb) {
810: res = kIOReturnNoMemory;
811: break;
812: }
813:
814: bcopy(asyncRef, pb->fAsyncRef, sizeof(OSAsyncReference));
815: pb->fMax = size;
816: pb->fMem = mem;
817: tap.target = this;
818: tap.action = &ReqComplete;
819: tap.parameter = pb;
820: res = pipeObj->write(mem, &tap);
821: } while (false);
822: if(res != kIOReturnSuccess) {
823: if(mem) {
824: mem->complete();
825: mem->release();
826: }
827: if(pb)
828: IOFree(pb, sizeof(*pb));
829: }
830: return res;
831: }
832:
833: IOReturn IOUSBUserClient::ClosePipe(UInt32 pipe)
834: {
835: fPipes[pipe] = 0;
836: return kIOReturnSuccess;
837: }
838:
839: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
840:
841: OSDefineMetaClassAndStructors(IOUSBDeviceUserClient, IOUSBUserClient)
842:
843: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
844:
845: IOUSBDeviceUserClient *IOUSBDeviceUserClient::withTask(task_t owningTask)
846: {
847: IOUSBDeviceUserClient *me;
848:
849: me = new IOUSBDeviceUserClient;
850: if(me) {
851: if(!me->init()) {
852: me->release();
853: return NULL;
854: }
855: me->fTask = owningTask;
856: }
857: return me;
858: }
859:
860: bool IOUSBDeviceUserClient::start( IOService * provider )
861: {
862: assert(OSDynamicCast(IOUSBDevice, provider));
863: if(!IOUSBUserClient::start(provider))
864: return false;
865: fOwner = (IOUSBDevice *)provider;
866: fOwner->retain();
867: fInterfaces = OSSet::withCapacity(1);
868: if(!fInterfaces)
869: return false;
870:
871: // initialize the call structures valid for IOUSBDevice
872: fMethods[kUSBSetConfig].object = provider;
873: fMethods[kUSBSetConfig].func = (IOMethod)&IOUSBDevice::SetConfiguration;
874: fMethods[kUSBSetConfig].count0 = 1;
875: fMethods[kUSBSetConfig].count1 = 0;
876: fMethods[kUSBSetConfig].flags = kIOUCScalarIScalarO;
877:
878: fMethods[kUSBGetConfigDescriptor].object = this;
879: fMethods[kUSBGetConfigDescriptor].func =
880: (IOMethod)&IOUSBDeviceUserClient::GetConfigDescriptor;
881: fMethods[kUSBGetConfigDescriptor].count0 = 1;
882: fMethods[kUSBGetConfigDescriptor].count1 = 0xffffffff; // variable
883: fMethods[kUSBGetConfigDescriptor].flags = kIOUCScalarIStructO;
884:
885: fMethods[kUSBOpenPipe].object = this;
886: fMethods[kUSBOpenPipe].func =
887: (IOMethod)&IOUSBDeviceUserClient::OpenPipe;
888: fMethods[kUSBOpenPipe].count0 = 4;
889: fMethods[kUSBOpenPipe].count1 = 1;
890: fMethods[kUSBOpenPipe].flags = kIOUCScalarIScalarO;
891:
892: fMethods[kUSBResetDevice].object = provider;
893: fMethods[kUSBResetDevice].func =
894: (IOMethod)&IOUSBDevice::resetDevice;
895: fMethods[kUSBResetDevice].count0 = 0;
896: fMethods[kUSBResetDevice].count1 = 0;
897: fMethods[kUSBResetDevice].flags = kIOUCScalarIScalarO;
898:
899: return true;
900: }
901:
902: IOReturn IOUSBDeviceUserClient::clientClose( void )
903: {
904: if(fInterfaces) {
905: OSCollectionIterator *iter;
906:
907: iter = OSCollectionIterator::withCollection(fInterfaces);
908: if(iter) {
909: OSObject *obj;
910: while( (obj=iter->getNextObject()) ) {
911: ((IOService *)obj)->close(this);
912: }
913: iter->release();
914: }
915: fInterfaces->release();
916: fInterfaces = NULL;
917: }
918: if(fOwner) {
919: detach( fOwner);
920: fOwner->release();
921: fOwner = NULL;
922: }
923: return IOUSBUserClient::clientClose();
924: }
925:
926: IOReturn
927: IOUSBDeviceUserClient::OpenPipe(UInt32 configIndex,
928: UInt32 intfNo, UInt32 altSet, UInt32 endPtOff, UInt32 *pipe)
929: {
930: IOReturn res;
931: IOUSBInterface *intf;
932: const IOUSBInterfaceDescriptor *id = NULL;
933: UInt8 configVal;
934: IOUSBDevice::FindInterfaceRequest request;
935: UInt32 i;
936: const IOUSBConfigurationDescriptor *config;
937:
938: config = fOwner->getFullConfigurationDescriptor(configIndex);
939: configVal = config->configValue;
940:
941: intf = NULL;
942: request.theClass = 0;
943: request.subClass = 0;
944: request.protocol = 0;
945: request.maxPower = 0;
946:
947: while( (intf = fOwner->findNextInterface(intf, &request))) {
948: if(intf->getConfigValue() == configVal) {
949: id = intf->interfaceDescriptor();
950: if(id->interfaceNumber == intfNo &&
951: id->alternateSetting == altSet)
952: break;
953: }
954: intf->release();
955: // Reset request fields to wildcard values.
956: request.theClass = 0;
957: request.subClass = 0;
958: request.protocol = 0;
959: request.maxPower = 0;
960: }
961:
962: if(!intf)
963: return kIOUSBInterfaceNotFound;
964:
965: if(id->numEndpoints <= endPtOff)
966: return kIOUSBUnknownPipeErr;
967:
968: do {
969: IOUSBFindEndpointRequest findPipe;
970: IOUSBPipe *pipeObj;
971: if(!fInterfaces->member(intf)) {
972: if(!intf->open(this)) {
973: res = kIOReturnExclusiveAccess;
974: break;
975: }
976: fInterfaces->setObject(intf);
977: }
978:
979: // Loop through pipes the requested number of times
980: pipeObj = NULL;
981: endPtOff++; // Easier to be 1-based.
982: for(i=0; i<endPtOff; i++) {
983: findPipe.type = kUSBAnyType;
984: findPipe.direction = kUSBAnyDirn;
985: pipeObj = intf->findNextPipe(pipeObj, &findPipe);
986: if(pipeObj == NULL) {
987: res = kIOUSBEndpointNotFound;
988: break;
989: }
990: }
991: if(i != endPtOff) {
992: res = kIOUSBEndpointNotFound;
993: break;
994: }
995: for(i=1; i<kUSBMaxPipes; i++) {
996: if(!fPipes[i]) {
997: fPipes[i] = pipeObj;
998: break;
999: }
1000: }
1001: if(i >= kUSBMaxPipes) {
1002: res = kIOUSBTooManyPipesErr;
1003: break;
1004: }
1005: *pipe = i;
1006: res = kIOReturnSuccess;
1007: } while(false);
1008: if(intf)
1009: intf->release();
1010: return res;
1011: }
1012:
1013: IOReturn
1014: IOUSBDeviceUserClient::GetConfigDescriptor(UInt8 configIndex,
1015: IOUSBConfigurationDescriptorPtr desc, UInt32 *size)
1016: {
1017: UInt16 length;
1018: const IOUSBConfigurationDescriptor *cached;
1019:
1020: cached = fOwner->getFullConfigurationDescriptor(configIndex);
1021: length = OSReadLittleInt16(&cached->totalLength, 0);
1022: if(length < *size)
1023: *size = length;
1024: bcopy(cached, desc, *size);
1025: return kIOReturnSuccess;
1026: }
1027:
1028: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1029:
1030: OSDefineMetaClassAndStructors(IOUSBInterfaceUserClient, IOUSBUserClient)
1031:
1032: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1033:
1034: IOUSBInterfaceUserClient *IOUSBInterfaceUserClient::withTask(task_t owningTask)
1035: {
1036: IOUSBInterfaceUserClient *me;
1037:
1038: me = new IOUSBInterfaceUserClient;
1039: if(me) {
1040: if(!me->init()) {
1041: me->release();
1042: return NULL;
1043: }
1044: me->fTask = owningTask;
1045: }
1046: return me;
1047: }
1048:
1049: bool IOUSBInterfaceUserClient::start( IOService * provider )
1050: {
1051: assert(OSDynamicCast(IOUSBInterface, provider));
1052: if(!IOUSBUserClient::start(provider))
1053: return false;
1054: fOwner = (IOUSBInterface *)provider;
1055: fOwner->retain();
1056:
1057: // initialize the call structures valid for IOUSBInterface
1058: fMethods[kUSBGetConfigDescriptor].object = this;
1059: fMethods[kUSBGetConfigDescriptor].func =
1060: (IOMethod)&IOUSBInterfaceUserClient::GetConfigDescriptor;
1061: fMethods[kUSBGetConfigDescriptor].count0 = 1;
1062: fMethods[kUSBGetConfigDescriptor].count1 = 0xffffffff; // variable
1063: fMethods[kUSBGetConfigDescriptor].flags = kIOUCScalarIStructO;
1064:
1065: fMethods[kUSBOpenPipe].object = this;
1066: fMethods[kUSBOpenPipe].func =
1067: (IOMethod)&IOUSBInterfaceUserClient::OpenPipe;
1068: fMethods[kUSBOpenPipe].count0 = 4;
1069: fMethods[kUSBOpenPipe].count1 = 1;
1070: fMethods[kUSBOpenPipe].flags = kIOUCScalarIScalarO;
1071:
1072: return true;
1073: }
1074:
1075: IOReturn IOUSBInterfaceUserClient::clientClose( void )
1076: {
1077: if(fOwner) {
1078: if(fOpen) {
1079: fOwner->close(this);
1080: fOpen = false;
1081: }
1082: detach( fOwner);
1083: fOwner->release();
1084: fOwner = NULL;
1085: }
1086: return IOUSBUserClient::clientClose();
1087: }
1088:
1089: IOReturn
1090: IOUSBInterfaceUserClient::OpenPipe(UInt32 configIndex,
1091: UInt32 intfNo, UInt32 altSet, UInt32 endPtOff, UInt32 *pipe)
1092: {
1093: IOReturn res;
1094: const IOUSBInterfaceDescriptor *id = fOwner->interfaceDescriptor();
1095: UInt32 i;
1096: const IOUSBConfigurationDescriptor *config;
1097:
1098: config = fOwner->device()->getFullConfigurationDescriptor(configIndex);
1099:
1100: if(config->configValue != fOwner->getConfigValue())
1101: return kIOUSBConfigNotFound;
1102:
1103: if(intfNo != id->interfaceNumber ||
1104: altSet != id->alternateSetting)
1105: return kIOUSBInterfaceNotFound;
1106:
1107: if(id->numEndpoints <= endPtOff)
1108: return kIOUSBUnknownPipeErr;
1109:
1110: do {
1111: IOUSBFindEndpointRequest findPipe;
1112: IOUSBPipe *pipeObj;
1113: if(!fOpen) {
1114: if(!fOwner->open(this)) {
1115: res = kIOReturnExclusiveAccess;
1116: break;
1117: }
1118: fOpen = true;
1119: }
1120:
1121: // Loop through pipes the requested number of times
1122: pipeObj = NULL;
1123: endPtOff++; // Easier to be 1-based.
1124: for(i=0; i<endPtOff; i++) {
1125: findPipe.type = kUSBAnyType;
1126: findPipe.direction = kUSBAnyDirn;
1127: pipeObj = fOwner->findNextPipe(pipeObj, &findPipe);
1128: if(pipeObj == NULL) {
1129: res = kIOUSBEndpointNotFound;
1130: break;
1131: }
1132: }
1133: if(i != endPtOff) {
1134: res = kIOUSBEndpointNotFound;
1135: break;
1136: }
1137: for(i=1; i<kUSBMaxPipes; i++) {
1138: if(!fPipes[i]) {
1139: fPipes[i] = pipeObj;
1140: break;
1141: }
1142: }
1143: if(i >= kUSBMaxPipes) {
1144: res = kIOUSBTooManyPipesErr;
1145: break;
1146: }
1147: *pipe = i;
1148: res = kIOReturnSuccess;
1149: } while(false);
1150: return res;
1151: }
1152:
1153: IOReturn
1154: IOUSBInterfaceUserClient::GetConfigDescriptor(UInt8 configIndex,
1155: IOUSBConfigurationDescriptorPtr desc, UInt32 *size)
1156: {
1157: UInt16 length;
1158: const IOUSBConfigurationDescriptor *cached;
1159:
1160: cached = fOwner->device()->getFullConfigurationDescriptor(configIndex);
1161: length = OSReadLittleInt16(&cached->totalLength, 0);
1162: if(length < *size)
1163: *size = length;
1164: bcopy(cached, desc, *size);
1165: return kIOReturnSuccess;
1166: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.