|
|
1.1 root 1: /*
2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7: * Reserved. This file contains Original Code and/or Modifications of
8: * Original Code as defined in and that are subject to the Apple Public
9: * Source License Version 1.1 (the "License"). You may not use this file
10: * except in compliance with the License. Please obtain a copy of the
11: * License at http://www.apple.com/publicsource and read it before using
12: * this file.
13: *
14: * The Original Code and all software distributed under the License are
15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19: * License for the specific language governing rights and limitations
20: * under the License.
21: *
22: * @APPLE_LICENSE_HEADER_END@
23: */
24:
25: /*
26: File: uslDescriptors.c
27:
28: Contains: xxx put contents here xxx
29:
30: Version: xxx put version here xxx
31:
32: Copyright: � 1998 by Apple Computer, Inc., all rights reserved.
33:
34: File Ownership:
35:
36: DRI: xxx put dri here xxx
37:
38: Other Contact: xxx put other contact here xxx
39:
40: Technology: xxx put technology here xxx
41:
42: Writers:
43:
44: (BG) Bill Galcher
45: (DF) David Ferguson
46: (BT) Barry Twycross
47:
48: Change History (most recent first):
49:
50: <USB45> 11/13/98 BT Change to unconfigure device
51: <USB44> 11/13/98 BT Add unconfigure interface
52: <USB43> 11/11/98 BT Allow set config to same value for device, add Set config entry
53: point
54: <USB42> 11/10/98 BT Fix abnormal completion when cache config descriptor can not
55: find device.
56: <USB41> 11/10/98 BT Fix early termination from set config with callback return.
57: <USB40> 11/10/98 BT Fix crash on set config with interface ref.
58: <USB39> 10/29/98 BT Close old configurations on reset or reconfiguration.
59: <USB38> 10/26/98 BT fix not finding interface
60: <USB37> 10/12/98 BT Add power qualification to find next interface
61: <USB36> 10/6/98 BT Fix Find next assoc desc with endpoint. Fix usage of getDev in
62: various places
63: <USB35> 9/17/98 BT 1.1 rules for captive devices.
64: <USB34> 8/25/98 BT Isoc name changes
65: <USB33> 8/24/98 BT Isoc param block definition
66: <USB32> 8/18/98 BT Fix small config descriptor error again
67: <USB31> 7/9/98 BT Fix previous fixes. Do not call back to dead device
68: <USB30> 7/9/98 BT Clean up after delete device and config clash.
69: <USB29> 7/8/98 BT Make findconfigdescriptor more paranoid.
70: <USB28> 7/2/98 BT Fix new interface ref to not accept interface ref
71: <USB27> 7/2/98 BT Fix hang if associated descriptor does not exist.
72: <USB26> 6/29/98 BT Fix zeroing paramblock fields after callback in FindNextPipe.
73: <USB25> 6/24/98 BT Fix config interface to open all pipes properly.
74: <USB24> 6/22/98 BT Add Alt interface to configure interface
75: <USB23> 6/18/98 BG Use the correct notation for including <Errors.h> and
76: <DriverServices.h>. I know, this is a nit.
77: <USB22> 6/9/98 BT Find next pipe returns max packert size
78: <USB21> 5/21/98 BT Note dependancy on dev req in open device. Make config work with
79: more than one descriptor
80: <USB20> 5/20/98 BT FIx find with interface alt
81: <USB19> 5/20/98 BT Fix alt usage in interface functions
82: <USB18> 5/20/98 BT Make this top of trunk, (17a2, V2 param b lock stuff)
83: <USB17> 5/18/98 DF Get config descriptor actually takes notice of index.
84: <USB16> 5/18/98 DF Remove nested comment warning
85: <USB15> 5/17/98 BT Add config stuff
86: <USB14> 5/5/98 BT Change name to ...immediate
87: <USB13> 4/16/98 BT Add include of USBpriv
88: <USB12> 4/9/98 BT Use USB.h
89: <11> 4/8/98 BT Move error codes
90: <10> 4/8/98 BT More error checking
91: <9> 4/6/98 BT Change w names
92: <8> 4/6/98 BT Change param block names.
93: <7> 4/2/98 BT Add grabbing all config descriptors
94: <6> 3/19/98 BT Get endpoint descriptor returns max packet size with right byte
95: ordering.
96: <5> 3/9/98 BT Eliminate one set of redundant enums
97: <4> 3/5/98 BT Add interrupt pipe
98: <3> 2/23/98 BT Fix swapped values
99: <2> 2/4/98 BT Cope with multiple configs
100: <1> 1/29/98 BT first checked in
101: */
102:
103:
104: #include "../USB.h"
105: #include "../USBpriv.h"
106:
107: #include "uslpriv.h"
108: //#include <Errors.h>
109: #include "../driverservices.h"
110:
111:
112:
113: //enum{
114: // kUSLClientUser = 0,
115: // kUSLClientEndPoint
116:
117: // };
118:
119: static Boolean checkZeroBuffer(USBPB *pb)
120: {
121: return( (pb->usbBuffer != 0) || (pb->usbReqCount != 0) || (pb->usbActCount != 0) );
122: }
123:
124: /* These allow USL functions to have an internal stage counter. */
125: /* This drives internal state machines. */
126:
127: /* In this incarnation some bits in the flags long word are */
128: /* hijacked for this. If you wanted to revise the PB, an */
129: /* internal field could be added to do this. See uslPriv.h */
130: /* abuse of flags */
131:
132: static void uslClearInternalStage(USBPB *pb)
133: {
134: pb->usbFlags &= ~kUSLStageMask;
135: }
136:
137: static int uslFindInternalStageAndIncriment(USBPB *pb)
138: {
139: int stage;
140: stage = (pb->usbFlags & kUSLStageMask) >>kUSLStageShift;
141: stage++;
142: pb->usbFlags = (pb->usbFlags & ~kUSLStageMask) | stage << kUSLStageShift;
143: return(stage);
144: }
145:
146: static void uslCompleteInternalStages(USBPB *pb)
147: {
148: usbDevice *dev;
149:
150: /* make sure we never hose up a device by leaving it locked */
151: dev = getDevicePtr(pb->usbReference);
152: if( (dev != nil) && (dev->configLock != 0) )
153: {
154: dev->configLock = 0;
155: }
156:
157: uslClearInternalStage(pb);
158: pb->usbCompletion = (void *)pb->reserved2;
159: (*pb->usbCompletion)(pb);
160: }
161:
162: static void uslInitialiseInternalStages(USBPB *pb, void (*fn)(USBPB *pb))
163: {
164: uslClearInternalStage(pb);
165: pb->reserved2 = (UInt32) pb->usbCompletion; /* Save users handler */
166: pb->usbCompletion = fn; /* use our handler */
167: pb->usbStatus = noErr; // so cache conf desc doesn't crapout to start.
168: (*fn)(pb);
169: }
170:
171:
172: static SInt32 subtractAddress(void *a1, void *a2)
173: {
174: /* Use this to get signed addess compares. */
175: /* you get large pos instead of neg using UInts */
176: return((SInt32)a1 - (SInt32)a2);
177:
178: }
179:
180: static void uslSetInternalStage(USBPB *pb, int stage)
181: {
182: pb->usbFlags = (pb->usbFlags & ~kUSLStageMask) | stage << kUSLStageShift;
183: }
184:
185: static void nextInternalStage(USBPB *pb)
186: {
187: int stage;
188: stage = (pb->usbFlags & kUSLStageMask) >>kUSLStageShift;
189: stage ++;
190: pb->usbFlags = (pb->usbFlags & ~kUSLStageMask) | stage << kUSLStageShift;
191: }
192: #if 0
193:
194: static void uslMoveStageAlong(USBPB *pb, int n)
195: {
196: int stage;
197: stage = (pb->usbFlags & kUSLStageMask) >>kUSLStageShift;
198: stage += n;
199: pb->usbFlags = (pb->usbFlags & ~kUSLStageMask) | stage << kUSLStageShift;
200: }
201: #endif
202:
203: static OSStatus uslReadConfigurationDescriptor(USBPB *pb)
204: {
205:
206: // --> usbReference Device
207: // --> usb.cntl.WValue Configuration value
208: // --> usbBuffer Configuration Descriptor Structure
209: // --> usbReqCount size of descriptor
210: // <-- usbActCount size of descriptor returned
211:
212: pb->usb.cntl.BMRequestType = USBMakeBMRequestType(kUSBIn, kUSBStandard, kUSBDevice);
213: pb->usb.cntl.BRequest = kUSBRqGetDescriptor;
214:
215: pb->usb.cntl.WValue = (kUSBConfDesc << 8) + (pb->usb.cntl.WValue & 0xff);
216: pb->usb.cntl.WIndex = 0;
217:
218: return(uslDeviceRequest(pb));
219: }
220:
221: static usbDevice *getDev(USBPB *pb)
222: {
223: usbDevice *dev;
224: dev = getDevicePtr(pb->usbReference);
225: if(dev == nil)
226: {
227: pb->usbStatus = kUSBUnknownDeviceErr;
228: (*pb->usbCompletion)(pb);
229: }
230: return(dev);
231: }
232:
233: /* xxxx This needs to be redone in terms or cache config descr */
234: static void getFulConfHandler(USBPB *pb)
235: {
236: int stage;
237:
238: // --> usbReference Device
239: // --> usb.cntl.WValue Configuration number
240: // <-- usbBuffer Configuration Descriptor Structure
241: // usbReqCount undefined
242: // <-- usbActCount size of descriptor returned
243:
244:
245: usbDevice *dev;
246:
247: if(pb->usbStatus != noErr)
248: {
249: uslCompleteInternalStages(pb);
250: return;
251: }
252:
253: stage = uslFindInternalStageAndIncriment(pb);
254:
255: do{switch(stage)
256: {
257: case 1:
258: dev = getDev(pb);
259: if(dev == nil) break;
260:
261: /* use dev scratch to get the root config descritor */
262: pb->usbReqCount = sizeof(configHeader);
263: pb->usbBuffer = &dev->configScratch;
264:
265: /* Get the descriptor */
266: if(immediateError(uslReadConfigurationDescriptor(pb)))
267: {
268: uslCompleteInternalStages(pb);
269: }
270: break;
271:
272: case 2:
273: /* How long is full descritptor */
274: pb->usbReqCount = USBToHostWord(((configHeader *)pb->usbBuffer)->totalLen);
275:
276: /* Allocate the full descriptor */
277: if(immediateError(uslAllocMem(pb)))
278: {
279: uslCompleteInternalStages(pb);
280: }
281: break;
282:
283: case 3:
284: /* Populate the full descriptor */
285: pb->usb.cntl.WValue = pb->usb.cntl.WValue & 0xff; // assumes what readconf does internally
286: if(immediateError(uslReadConfigurationDescriptor(pb)))
287: {
288: uslCompleteInternalStages(pb);
289: }
290: break;
291:
292: case 4:
293: uslCompleteInternalStages(pb);
294:
295: break;
296:
297: default:
298: USBExpertStatus(0,"USL - get full conf handler, unknown case", 0);
299: pb->usbStatus = kUSBInternalErr;
300: uslCompleteInternalStages(pb);
301: break;
302: }
303: break; /* only execute once, unless continue used */
304: }while(1); /* so case can be reentered with a continue */
305:
306:
307: }
308:
309: /* xxxx recast interms of cached */
310: OSStatus USBGetFullConfigurationDescriptor(USBPB *pb)
311: {
312: // --> usbReference Device
313: // --> usb.cntl.WValue Configuration
314: // <-- usbBuffer Configuration Descriptor Structure
315: // <-- usbActCount size of descriptor returned
316:
317:
318: if(!checkPBVersion(pb, 0))
319: {
320: return(pb->usbStatus);
321: }
322:
323:
324: pb->usbStatus = noErr;
325: uslInitialiseInternalStages(pb, getFulConfHandler);
326:
327: return(kUSBPending);
328: }
329:
330: static void *nextDescriptor(void *desc)
331: {
332: UInt8 *next;
333: next = desc;
334: next = &next[next[0]];
335: return(next);
336: }
337:
338: static OSStatus isConfigDescriptor(USBConfigurationDescriptor *conf)
339: {
340: if( (conf->descriptorType != kUSBConfDesc) ||
341: (conf->length < 9) ||
342: (conf->totalLength < 9) )
343: {
344: USBExpertStatus(0,"USL - Parse bad config descriptor", 0);
345: return(kUSBInternalErr);
346: }
347: return(noErr);
348: }
349:
350: /* xxxx make externally visible ? */
351: /* xxxx do some sanity checking on the dscriptor?? */
352: static OSStatus USBFindConfigDescriptorImmedite(USBPB *pb)
353: {
354: // <--> usbBuffer --> all config descriptors <-- Config desc
355: // --> usbReqCount total length of descriptors
356: // <-- usbActCount offset of this descriptor in config descriptor
357: // --> usb.cntl.WValue Config number
358: USBConfigurationDescriptor *conf;
359: void *end;
360:
361: if(!checkPBVersion(pb, 0))
362: {
363: return(pb->usbStatus);
364: }
365:
366: /* find configuration */
367: conf = pb->usbBuffer;
368: pb->usbStatus = isConfigDescriptor(conf);
369: if(pb->usbStatus != noErr)
370: {
371: return(pb->usbStatus);
372: }
373:
374: end = (void *)(((UInt32)pb->usbBuffer) + pb->usbReqCount);
375:
376: while( subtractAddress(end, conf) > 4)
377: {
378: pb->usbStatus = isConfigDescriptor(conf);
379: if(pb->usbStatus != noErr)
380: {
381: return(pb->usbStatus);
382: }
383:
384: if(subtractAddress(end, conf) < USBToHostWord(conf->totalLength) )
385: {
386: return(kUSBNotFound);
387: }
388: if(conf->configValue == pb->usb.cntl.WValue)
389: {
390: break;
391: }
392:
393: conf = (void *)(((UInt32)conf) + USBToHostWord(conf->totalLength) );
394:
395: }
396: if(subtractAddress(end, conf) < (9+9)) // smaller than 1 interface desc and 1 config desc
397: { // BT 18 Aug 98, Rainbow fix. Eliminate the =, so minimal descriptor can work
398: return(kUSBNotFound);
399: }
400:
401: // This check must be done after the one above.
402: pb->usbStatus = isConfigDescriptor(conf);
403: if(pb->usbStatus != noErr)
404: {
405: return(pb->usbStatus);
406: }
407:
408: pb->usbActCount = subtractAddress(conf, pb->usbBuffer);
409: pb->usbBuffer = conf;
410: return(noErr);
411:
412: }
413:
414: /* xxxx make externally visible ? */
415: /* xxxx do some sanity checking on the dscriptor?? */
416: static OSStatus USBFindNextConfigDescriptorImmedite(USBPB *pb)
417: {
418: // <--> usbBuffer --> all config descriptors <-- Config desc
419: // --> usbReqCount total length of descriptors
420: // <-- usbActCount offset of this descriptor in config descriptor
421: // <--> usb.cntl.WValue -->Config number <-- next config number
422: USBConfigurationDescriptor *conf;
423: void *end;
424: UInt32 remaining, confLen;
425:
426: if(!checkPBVersion(pb, 0))
427: {
428: return(pb->usbStatus);
429: }
430:
431: end = (void *)(((UInt32)pb->usbBuffer) + pb->usbReqCount);
432: /* find configuration */
433: pb->usbStatus = USBFindConfigDescriptorImmedite(pb);
434: if(pb->usbStatus != noErr)
435: {
436: return(pb->usbStatus);
437: }
438:
439: conf = pb->usbBuffer;
440: if(conf > end)
441: {
442: return(kUSBNotFound);
443: }
444: confLen = USBToHostWord(conf->totalLength);
445: remaining = subtractAddress(end, conf) - confLen;
446: if(remaining < 9+9) // a config plus an interface desc again
447: {
448: return(kUSBNotFound);
449: }
450: pb->usbBuffer = (void *)( ((UInt32)conf) + confLen );
451: pb->usbActCount += confLen;
452: conf = pb->usbBuffer;
453:
454: pb->usbStatus = isConfigDescriptor(conf);
455: if(pb->usbStatus != noErr)
456: {
457: return(pb->usbStatus);
458: }
459:
460: pb->usb.cntl.WValue = conf->configValue;
461: return(noErr);
462:
463: }
464: /* xxxx make externally visible ? */
465: /* xxxx do some sanity checking on the dscriptor?? */
466: static OSStatus USBFindInterfaceDescriptorImmedite(USBPB *pb)
467: {
468: // <--> usbBuffer --> all config descriptors <-- interface desc
469: // --> usbReqCount total length of descriptors
470: // <-- usbActCount offset of this descriptor in config descriptor
471: // --> usb.cntl.WIndex Interface number
472: // --> usb.cntl.WValue Config number
473: // --> usbOther alt. Set to 0xff to only find alt zero.
474: USBConfigurationDescriptor *conf;
475: USBInterfaceDescriptor *interface;
476: void *end;
477: UInt8 matchAlt;
478:
479: if(!checkPBVersion(pb, 0))
480: {
481: return(pb->usbStatus);
482: }
483:
484: pb->usbStatus = USBFindConfigDescriptorImmedite(pb);
485: if(pb->usbStatus != noErr)
486: {
487: return(pb->usbStatus);
488: }
489:
490: /* we found the configuration descriptor with this number */
491:
492: conf = pb->usbBuffer;
493:
494: /* now find the right interface */
495:
496: end = (void *)(((UInt32)conf) + USBToHostWord(conf->totalLength) - 9 /* interface desc length */ );
497: interface = nextDescriptor(conf);
498:
499: matchAlt = pb->usbOther;
500: if(matchAlt == 0xff)
501: {
502: matchAlt = 0;
503: }
504:
505: while(interface <= end) // BT 18Aug98, add = so minimal descriptors can work.
506: {
507: if( (interface->descriptorType == kUSBInterfaceDesc) &&
508: (interface->interfaceNumber == pb->usb.cntl.WIndex) &&
509: (interface->alternateSetting == matchAlt)
510: )
511: {
512: pb->usbActCount = subtractAddress(interface, pb->usbBuffer);
513: pb->usbBuffer = interface;
514: return(noErr);
515: }
516:
517: interface = nextDescriptor(interface);
518: }
519:
520: return(kUSBNotFound);
521: }
522:
523:
524:
525: OSStatus USBFindNextEndpointDescriptorImmediate(USBPB *pb)
526: {
527:
528: // <--> usbBuffer --> interface/endpoint descriptor <-- endpoint desc
529: // <--> usbReqCount offset of this descriptor in config descriptor
530: // <-- usbActcount length of descriptor found
531: // <--> usbDirection direction/wild card
532: // <--> usbClassType Endpoint type/wild card
533: // <--> usbOther Endpoint number, start at zero
534: // <-- usb.cntl.WValue Max packet size of endpoint
535:
536: // Note: usbReqCount is used for output here, the value needs to be fed back to the
537: // next call for this to work. In this sense, treat it like a magic cookie. It should
538: // be initialised to zero.
539:
540: USBConfigurationDescriptor *conf;
541: USBInterfaceDescriptor *interface;
542: USBEndPointDescriptor *endPt, *end;
543: UInt8 endPointNum;
544: UInt8 direction;
545: UInt8 type;
546: USBDirection usbDirection;
547:
548: if(!checkPBVersion(pb, kUSBAnyDirn))
549: {
550: return(pb->usbStatus);
551: }
552:
553: usbDirection = pb->usbFlags & kUSBAnyDirn;
554:
555: conf = (void *)((UInt8 *)pb->usbBuffer - pb->usbReqCount);
556: if( (conf->descriptorType != kUSBConfDesc)
557: || (pb->usbReqCount == 0) )
558: {
559: pb->usbStatus = paramErr;
560: return(pb->usbStatus);
561: }
562: end = (void *)(((UInt8 *)conf)+USBToHostWord(conf->totalLength));
563:
564: interface = (void *)pb->usbBuffer;
565:
566: if(interface->descriptorType == kUSBInterfaceDesc)
567: {
568: /* We have an interface descriptor */
569: endPt = nextDescriptor(interface);
570: }
571: else
572: { /* We have an endPt desccriptor */
573: endPt = pb->usbBuffer;
574: if(endPt->descriptorType != kUSBEndpointDesc)
575: {
576: pb->usbStatus = paramErr;
577: return(pb->usbStatus);
578: }
579: endPt = nextDescriptor(endPt);
580: }
581:
582: while(endPt < end)
583: {
584: if(endPt->descriptorType == kUSBInterfaceDesc)
585: {
586: break; /* not found */
587: }
588: if(endPt->descriptorType == kUSBEndpointDesc)
589: {
590: endPointNum = endPt->endpointAddress & 0xf;
591: direction = endPt->endpointAddress >> 7;
592: type = endPt->attributes & 3;
593:
594: if(
595: ( (usbDirection == kUSBAnyDirn) || (usbDirection == direction) ) &&
596: ( (pb->usbClassType == kUSBAnyType) || (pb->usbClassType == type) ) &&
597: ( (pb->usbOther == 0) || (pb->usbOther == endPointNum) )
598: )
599: {
600: /* This matches */
601: pb->usbBuffer = endPt;
602: pb->usbReqCount = subtractAddress(endPt, conf);
603: pb->usbActCount = endPt->length;
604: pb->usbFlags = direction;
605: pb->usbClassType = type; /* Fix this sometime */
606: pb->usbOther = endPointNum;
607: pb->usb.cntl.WValue = USBToHostWord(endPt->maxPacketSize);
608: return(noErr);
609: }
610: }
611:
612: endPt = nextDescriptor(endPt);
613: }
614:
615: pb->usbBuffer = conf;
616: pb->usbReqCount = 0;
617: pb->usbActCount = 0;
618: pb->usbFlags = kUSBAnyDirn;
619: pb->usbClassType = kUSBAnyType;
620: pb->usbOther = 0;
621: return(kUSBNotFound);
622:
623: }
624:
625: static OSStatus uslFindNextInterfaceDescriptorImmediate(USBPB *pb)
626: {
627:
628: // <--> usbBuffer --> config/interface descriptor <-- interface desc
629: // <-- usbActcount length of descriptor found
630: // <--> usbReqCount offset of this descriptor in config descriptor start = 0
631: // <--> usbClassType Class/wild card
632: // <--> usbSubclass subclass/wildcard
633: // <--> usbProtocol Protocol/wildcard
634: // <-- usb.cntl.WIndex InterfaceNumber
635: // <-- usb.cntl.WValue configuration value - Always return this, even on error
636: // <--> usbWOther alt. Set to Oxff to only find alt zero.
637:
638:
639: // Note: usbReqCount is used for output here, the value needs to be fed back to the
640: // next call for this to work. In this sense, treat it like a magic cookie. It should
641: // be initialised to zero.
642:
643: USBConfigurationDescriptor *conf;
644: USBInterfaceDescriptor *interface, *end;
645: UInt8 confNum;
646:
647: conf = (void *)((UInt8 *)pb->usbBuffer - pb->usbReqCount);
648: if(conf->descriptorType != kUSBConfDesc)
649: {
650: pb->usbStatus = paramErr;
651: return(pb->usbStatus);
652: }
653: confNum = conf->configValue;
654: end = (void *)(((UInt8 *)conf)+USBToHostWord(conf->totalLength));
655: pb->usb.cntl.WValue = confNum; // always return this
656:
657: if(pb->usbReqCount == 0)
658: {
659: /* We have a config descriptor */
660: interface = nextDescriptor(conf);
661: }
662: else
663: { /* We have an interface desccriptor */
664: interface = pb->usbBuffer;
665: if(interface->descriptorType != kUSBInterfaceDesc)
666: {
667: pb->usbStatus = paramErr;
668: return(pb->usbStatus);
669: }
670: interface = nextDescriptor(interface);
671: }
672:
673: while(interface < end)
674: {
675: if(interface->descriptorType == kUSBInterfaceDesc)
676: {
677: if(
678: ( (pb->usbClassType == 0) || (pb->usbClassType == interface->interfaceClass) ) &&
679: ( (pb->usbSubclass == 0) || (pb->usbSubclass == interface->interfaceSubClass) ) &&
680: ( (pb->usbProtocol == 0) || (pb->usbProtocol == interface->interfaceProtocol) ) &&
681: ( (pb->usbOther != 0xff) || (interface->alternateSetting == 0) )
682: )
683: {
684: /* This matches */
685: pb->usbBuffer = interface;
686: pb->usbReqCount = subtractAddress(interface, conf);
687: pb->usbActCount = interface->length;
688: pb->usb.cntl.WIndex = interface->interfaceNumber;
689: pb->usbClassType = interface->interfaceClass;
690: pb->usbSubclass = interface->interfaceSubClass;
691: pb->usbProtocol = interface->interfaceProtocol;
692: if(pb->usbOther != 0xff)
693: {
694: pb->usbOther = interface->alternateSetting;
695: }
696: return(noErr);
697: }
698: }
699:
700: interface = nextDescriptor(interface);
701: }
702:
703: pb->usbBuffer = conf;
704: pb->usbReqCount = 0;
705: pb->usbActCount = 0;
706:
707: return(kUSBNotFound);
708:
709: }
710:
711: OSStatus USBFindNextInterfaceDescriptorImmediate(USBPB *pb)
712: {
713:
714: // <--> usbBuffer --> config/interface descriptor <-- interface desc
715: // <-- usbActcount length of descriptor found
716: // <--> usbReqCount offset of this descriptor in config descriptor start = 0
717: // <--> usbClassType Class/wild card
718: // <--> usbSubclass subclass/wildcard
719: // <--> usbProtocol Protocol/wildcard
720: // <-- usb.cntl.WIndex InterfaceNumber
721: // <-- usb.cntl.WValue configuration value
722: // <--> usbWOther alt. Set to Oxff to only find alt zero.
723:
724: // Note: usbReqCount is used for output here, the value needs to be fed back to the
725: // next call for this to work. In this sense, treat it like a magic cookie. It should
726: // be initialised to zero.
727: OSStatus err;
728:
729: if(!checkPBVersion(pb, 0))
730: {
731: return(pb->usbStatus);
732: }
733:
734: err = uslFindNextInterfaceDescriptorImmediate(pb);
735: if(err != noErr)
736: {
737: pb->usb.cntl.WIndex = 0;
738: pb->usb.cntl.WValue = 0;
739: }
740: return(err);
741: }
742:
743: /* xxxx Need a force unit access bit, or clear cahced descriptor function */
744: /* xxxx need to read configs other than zero */
745: static void *uslCacheConfigDescriptors(USBPB *pb)
746: { /* make confid descriptors are cached. Return pointer when they are */
747: int stage;
748: usbDevice *dev;
749: static countLoop, getLoop;
750:
751: #if 0
752: if(pb->usbStatus != noErr)
753: {
754: uslCompleteInternalStages(pb);
755: return(nil);
756: }
757: #endif
758:
759: // Don't use getDev here, if it goes wrong it calls back straight to here
760: dev = getDevicePtr(pb->usbReference);
761: if(dev == nil)
762: {
763: pipe *p;
764: // Maybe its a pipe ref. This is only used find assoc desc.
765: // That should have the descriptors cached, so this is not going to be called too often
766: (void)findPipe(pb->usbReference, &p);
767: if(p != nil)
768: {
769: dev = getDevicePtr(p->devIntfRef);
770: }
771: if(dev == nil)
772: {
773: pb->usbStatus = kUSBUnknownDeviceErr;
774: uslCompleteInternalStages(pb);
775: return(nil);
776: }
777: }
778:
779: if(dev->killMe)
780: {
781: USBExpertStatus(0,"USL - Killing dead device", 0);
782: dev->killMe = 0;
783: #if 1
784: dev->configLock = 0;
785: uslClearInternalStage(pb);
786: // Don't call back this has been hosed already?
787: #else
788: dev->configLock = 0;
789: uslClearInternalStage(pb);
790: pb->usbCompletion = (void *)pb->reserved2;
791: uslDeleteDevice(pb, dev);
792: #endif
793: return(nil);
794: }
795:
796:
797: if(dev->confValid)
798: { /* We should CRC the descriptor here */
799: pb->usbActCount = dev->allConfigLen;
800: pb->usbBuffer = dev->allConfigDescriptors;
801: return(dev->allConfigDescriptors);
802: }
803:
804: /* xxx we need to lock out concurrent attempts to do this */
805:
806:
807: do{
808: stage = uslFindInternalStageAndIncriment(pb);
809: switch(stage)
810: {
811: case 1:
812: pb->usb.cntl.BMRequestType = USBMakeBMRequestType(kUSBIn, kUSBStandard, kUSBDevice);
813: pb->usb.cntl.BRequest = kUSBRqGetDescriptor;
814: pb->usb.cntl.WValue = (kUSBDeviceDesc << 8) + 0/*index*/;
815: pb->usb.cntl.WIndex = 0;
816: pb->usbReqCount = OFFSET(USBDeviceDescriptor, descEnd);
817: pb->usbBuffer = &dev->deviceDescriptor;
818:
819: if(immediateError(uslDeviceRequest(pb)))
820: {
821: uslCompleteInternalStages(pb);
822: }
823:
824: break;
825:
826: case 2:
827: /* use dev scratch to get the root config descritor */
828:
829: /* count length of all descriptors */
830: dev->allConfigLen = 0;
831:
832: pb->usbReqCount = sizeof(configHeader);
833: pb->usbBuffer = &dev->configScratch;
834: pb->usb.cntl.WValue = 0;
835: countLoop = stage;
836:
837: continue;
838: break;
839:
840: case 3:
841: /* Get the descriptor */
842: if(immediateError(uslReadConfigurationDescriptor(pb)))
843: {
844: uslCompleteInternalStages(pb);
845: }
846: break;
847:
848: case 4:
849:
850: pb->usb.cntl.WValue &= 0xff;
851: pb->usb.cntl.WValue++;
852: if(pb->usbStatus == noErr)
853: {
854: dev->allConfigLen += USBToHostWord(((configHeader *)pb->usbBuffer)->totalLen);
855: if(pb->usb.cntl.WValue < dev->deviceDescriptor.numConf)
856: {
857: stage = countLoop;
858: uslSetInternalStage(pb, stage);
859: }
860: }
861: else
862: {
863: if(dev->allConfigLen == 0)
864: {
865: uslCompleteInternalStages(pb);
866: return(nil);
867: }
868: }
869: continue;
870:
871: break;
872:
873: case 5:
874: /* How long is full descritptor */
875: pb->usbReqCount = dev->allConfigLen;
876:
877: /* Allocate the full descriptor */
878: if(immediateError(uslAllocMem(pb)))
879: {
880: uslCompleteInternalStages(pb);
881: }
882: break;
883:
884: case 6:
885: if(pb->usbStatus != noErr)
886: {
887: uslCompleteInternalStages(pb);
888: return(nil);
889: }
890: dev->allConfigDescriptors = pb->usbBuffer;
891: // note pb->usbReqCount still valid from alloc
892: /* Populate the full descriptor */
893: getLoop =stage;
894: pb->usb.cntl.WValue = 0;
895:
896: continue;
897: break;
898:
899: case 7:
900:
901: if(immediateError(uslReadConfigurationDescriptor(pb)))
902: {
903: uslCompleteInternalStages(pb);
904: }
905: break;
906:
907: case 8:
908: pb->usb.cntl.WValue &= 0xff;
909: pb->usb.cntl.WValue++;
910:
911: if(pb->usbStatus == noErr)
912: {
913: pb->usbBuffer = (void *)((UInt32)pb->usbBuffer + USBToHostWord(((configHeader *)pb->usbBuffer)->totalLen));
914: pb->usbReqCount = dev->allConfigLen - subtractAddress(pb->usbBuffer, dev->allConfigDescriptors);
915: if(pb->usbReqCount > dev->allConfigLen) // we wrapped
916: {
917: pb->usbStatus = kUSBInternalErr;
918: }
919: if( (pb->usbReqCount != 0) && (pb->usb.cntl.WValue < dev->deviceDescriptor.numConf) )
920: {
921: stage = getLoop;
922: uslSetInternalStage(pb, stage);
923: }
924: }
925: else
926: {
927: if(dev->allConfigLen == 0)
928: {
929: uslCompleteInternalStages(pb);
930: return(nil);
931: }
932: }
933: continue;
934: break;
935:
936: case 9:
937: dev->confValid = true;
938: uslClearInternalStage(pb);
939: pb->usbActCount = dev->allConfigLen;
940: pb->usbBuffer = dev->allConfigDescriptors;
941: return(dev->allConfigDescriptors);
942:
943: break;
944:
945: default:
946: USBExpertStatus(0,"USL - cache conf handler, unknown case", 0);
947: pb->usbStatus = kUSBInternalErr;
948: uslCompleteInternalStages(pb);
949: break;
950: }
951: break; /* only execute once, unless continue used */
952: }while(1); /* so case can be reentered with a continue */
953: return(nil);
954: }
955: #if 0
956: OSStatus USBFindInterface(USBPB *pb); (Not implemented yet)
957:
958: --> usbReference device /interface????
959: <-- usbBuffer interface descriptor
960: <-- usbActcount length of descriptor found
961: -- usbReqCount reserved, set to zero.
962: --> usbClassType Class
963: --> usbSubclass subclass
964: --> usbProtocol Protocol
965: <--> usb.cntl.WValue configuration number (start at zero)
966: <--> usb.cntl.WIndex InterfaceNumber (start at zero)
967: <--> usbOther alt // (set to 0xff to find first alt zero only)
968: #endif
969:
970: /* xxxx sort out usage of alt */
971: static void uslFindNextInterface(USBPB *pb)
972: {
973: OSStatus err = kUSBNotFound;
974: void *configDescriptors;
975: UInt32 totalLen;
976:
977: configDescriptors = uslCacheConfigDescriptors(pb);
978: if(configDescriptors == nil)
979: {
980: return;
981: }
982: totalLen = pb->usbActCount;
983:
984: pb->usb.cntl.WIndex = pb->wIndexStash;
985: pb->usb.cntl.WValue = pb->wValueStash;
986:
987: if( (pb->usb.cntl.WIndex == 0) && (pb->usb.cntl.WValue == 0) )
988: {
989: /* First call to this, init config descriptor */
990: pb->usbReqCount = 0;
991: pb->usbStatus = noErr;
992: }
993: else
994: {
995: pb->usbReqCount = pb->usbActCount;
996: pb->usbStatus = USBFindInterfaceDescriptorImmedite(pb);
997: pb->usbReqCount = pb->usbActCount;
998: }
999: while(pb->usbStatus == noErr)
1000: {
1001: USBConfigurationDescriptor *c;
1002: c = (void *)pb->usbBuffer;
1003: pb->usbStatus = uslFindNextInterfaceDescriptorImmediate(pb);
1004: if(pb->usbStatus == noErr)
1005: {
1006: if( (pb->addrStash == 0) ||
1007: (c->maxPower <= pb->addrStash) )
1008: {
1009: break;
1010: }
1011: err = kUSBDevicePowerProblem;
1012: }
1013:
1014: /* Not found in that config desc, try the next */
1015: pb->usbReqCount = totalLen;
1016: pb->usbBuffer = configDescriptors;
1017: pb->usbStatus = USBFindNextConfigDescriptorImmedite(pb);
1018: pb->usbReqCount = 0;
1019: }
1020:
1021: pb->usbActCount = 0;
1022: pb->usbBuffer = 0;
1023: // pb->usbReqCount = 0;
1024: pb->usbReqCount = pb->addrStash;
1025:
1026: if(pb->usbStatus != noErr)
1027: {
1028: pb->usb.cntl.WValue = 0;
1029: pb->usb.cntl.WIndex = 0;
1030: }
1031:
1032: if(pb->usbStatus == kUSBNotFound)
1033: { // If an interface found without sufficient power, say power prob
1034: pb->usbStatus = err;
1035: }
1036: uslCompleteInternalStages(pb);
1037: return;
1038:
1039: }
1040:
1041: /* xxxx sort out usage of alt */
1042: OSStatus USBFindNextInterface(USBPB *pb)
1043: {
1044: usbDevice *dev;
1045:
1046: if(!checkPBVersion(pb, 0))
1047: {
1048: return(pb->usbStatus);
1049: }
1050: pb->addrStash = pb->usbReqCount; // reqcount now has the power available
1051: pb->usbReqCount = 0;
1052: if(checkZeroBuffer(pb))
1053: {
1054: return(paramErr);
1055: }
1056: dev = getDev(pb);
1057: if(dev == nil)
1058: {
1059: return(kUSBUnknownDeviceErr);
1060: }
1061:
1062: pb->wIndexStash = pb->usb.cntl.WIndex;
1063: pb->wValueStash = pb->usb.cntl.WValue;
1064:
1065: pb->usbStatus = noErr;
1066: uslInitialiseInternalStages(pb, uslFindNextInterface);
1067: return(kUSBPending);
1068: }
1069:
1070: static void uslGetConfigurationDescriptor(USBPB *pb)
1071: {
1072: USBConfigurationDescriptor *configDescriptors;
1073: UInt32 confLen;
1074: kprintf("uslGetConf:ref=0x%x\n",pb->usbReference);
1075: configDescriptors = uslCacheConfigDescriptors(pb);
1076: if(configDescriptors == nil)
1077: {
1078: return;
1079: }
1080:
1081: /* note, we're relying on WValue being passed through here */
1082:
1083: kprintf("uslGetConf after NIL:ref=0x%x\n",pb->usbReference);
1084: pb->usbReqCount = pb->usbActCount;
1085: pb->usbStatus = USBFindConfigDescriptorImmedite(pb);
1086: configDescriptors = pb->usbBuffer;
1087: confLen = USBToHostWord(configDescriptors->totalLength);
1088: pb->usbActCount = pb->usbReqCount;
1089: if(pb->usbActCount > pb->wValueStash)
1090: {
1091: pb->usbActCount = pb->wValueStash;
1092: }
1093: if(pb->usbActCount > confLen)
1094: {
1095: pb->usbActCount = confLen;
1096: }
1097: pb->usbReqCount = pb->wValueStash;
1098: pb->wIndexStash = pb->usb.cntl.WIndex;
1099: usb_BlockMoveData(pb->usbBuffer, (void *) pb->addrStash, pb->usbActCount);
1100: pb->usbBuffer = (void *)pb->addrStash;
1101:
1102: uslCompleteInternalStages(pb);
1103: return;
1104:
1105: }
1106:
1107: OSStatus USBGetConfigurationDescriptor(USBPB *pb)
1108: {
1109:
1110: // --> usbReference Device
1111: // --> usb.cntl.WValue Configuration index
1112: // --> usbBuffer Configuration Descriptor Structure
1113: // --> usbReqCount size of edscriptor
1114: // <-- usbActCount size of descriptor returned
1115: usbDevice *dev;
1116:
1117: if(!checkPBVersion(pb, 0))
1118: {
1119: return(pb->usbStatus);
1120: }
1121: dev = getDev(pb);
1122: if(dev == nil)
1123: {
1124: return(kUSBUnknownDeviceErr);
1125: }
1126: pb->usbStatus = noErr;
1127: pb->wIndexStash = pb->usb.cntl.WIndex;
1128: pb->addrStash = (UInt32)pb->usbBuffer;
1129: pb->wValueStash = pb->usbReqCount;
1130: if(pb->usbReqCount > 0x7fff)
1131: {
1132: pb->wValueStash = 0x7fff;
1133: }
1134: uslInitialiseInternalStages(pb, uslGetConfigurationDescriptor);
1135: return(kUSBPending);
1136: }
1137:
1138: static Boolean noMoreDescriptors(USBDescriptorHeader *desc, void *end, Boolean endpoint)
1139: {
1140: return(
1141: (desc >= end) || /* run out of descriptors */
1142: /* BT 2Jul98, don't forget ==, caused hang of desc did not exist */
1143: (desc->descriptorType == kUSBConfDesc) || /* got to next conf desc */
1144: (desc->descriptorType == kUSBInterfaceDesc) || /* got to next interfc desc */
1145: ( (desc->descriptorType == kUSBEndpointDesc) && endpoint )
1146: /* got to next endpoint desc, for endpoint only*/
1147: );
1148: }
1149:
1150: static void uslFindNextAssociatedDescriptor(USBPB *pb)
1151: {
1152: USBConfigurationDescriptor *configDescriptors;
1153: uslInterface *intrfc;
1154: pipe *p;
1155: USBInterfaceRef iRef;
1156: usbDevice *dev;
1157: UInt16 count;
1158: UInt8 *end;
1159: USBDescriptorHeader *desc;
1160: UInt8 descType;
1161:
1162: configDescriptors = uslCacheConfigDescriptors(pb);
1163: if(configDescriptors == nil)
1164: {
1165: return;
1166: }
1167:
1168: pb->usbFlags = 0;
1169: end = (UInt8 *)configDescriptors + pb->usbActCount;
1170: pb->usbReqCount = pb->usbActCount;
1171:
1172: pb->usbStatus = findPipe(pb->usbReference, &p);
1173: if(pb->usbStatus == noErr)
1174: {
1175: iRef = p->devIntfRef;
1176: }
1177: else
1178: {
1179: p = nil;
1180: iRef = pb->usbReference;
1181: }
1182: pb->usbStatus = findInterface(iRef, &intrfc);
1183: if(pb->usbStatus != noErr)
1184: {
1185: uslCompleteInternalStages(pb);
1186: return;
1187: }
1188:
1189: /* ref was an interface or pipe ref (with interface container). */
1190: /* p not nil if pipe, intrfc set */
1191:
1192: dev = getDevicePtr(iRef);
1193: if(dev == nil)
1194: {
1195: pb->usbStatus = kUSBUnknownDeviceErr;
1196: uslCompleteInternalStages(pb);
1197: return;
1198: }
1199:
1200: pb->usb.cntl.WIndex = intrfc->interfaceNum;
1201: pb->usb.cntl.WValue = dev->currentConfiguration;
1202: descType = pb->usbOther;
1203: pb->usbOther = intrfc->alt;
1204: pb->usbStatus = USBFindInterfaceDescriptorImmedite(pb);
1205: if(pb->usbStatus != noErr)
1206: {
1207: uslCompleteInternalStages(pb);
1208: return;
1209: }
1210:
1211: if(p != nil)
1212: {
1213: pb->usbReqCount = pb->usbActCount;
1214: pb->usbFlags = kUSBAnyDirn;
1215: pb->usbClassType = kUSBAnyType;
1216: pb->usbOther = p->endPt;
1217: pb->usbStatus = USBFindNextEndpointDescriptorImmediate(pb);
1218: if(pb->usbStatus != noErr)
1219: {
1220: uslCompleteInternalStages(pb);
1221: return;
1222: }
1223: }
1224:
1225: /* we're now pointing to the relevant descriptor to start with */
1226: pb->usb.cntl.WIndex = pb->wIndexStash;
1227:
1228: count = 0;
1229: desc = pb->usbBuffer;
1230: while(count < pb->usb.cntl.WIndex)
1231: {
1232: desc = nextDescriptor(desc);
1233: if(noMoreDescriptors(desc, end, (p != nil)))
1234: {
1235: pb->usbStatus = kUSBNotFound;
1236: uslCompleteInternalStages(pb);
1237: return;
1238: }
1239: count++;
1240: }
1241:
1242: pb->usb.cntl.WIndex++; /* Next descriptor */
1243:
1244: if(descType != 0)
1245: {
1246: while(desc->descriptorType != descType)
1247: {
1248: desc = nextDescriptor(desc);
1249: pb->usb.cntl.WIndex++;
1250: if(noMoreDescriptors(desc, end, (p != nil)) ||
1251: (pb->usb.cntl.WIndex > 0x7ffe) ) // BT 2Jul98, if something goes wrong stop
1252: {
1253: pb->usbStatus = kUSBNotFound;
1254: uslCompleteInternalStages(pb);
1255: return;
1256: }
1257: }
1258: }
1259:
1260: /* now desc points to the descriptor to return */
1261: pb->usbOther = desc->descriptorType;
1262: pb->usbBuffer = (void *)pb->addrStash;
1263: pb->usbReqCount = pb->wValueStash;
1264: pb->usbActCount = desc->length;
1265:
1266: if(pb->usbActCount > pb->usbReqCount)
1267: {
1268: pb->usbActCount = pb->usbReqCount;
1269: }
1270:
1271: pb->wIndexStash = pb->usb.cntl.WIndex;
1272: pb->usb.cntl.WValue = 0;
1273: usb_BlockMoveData(desc, pb->usbBuffer, pb->usbActCount);
1274:
1275: uslCompleteInternalStages(pb);
1276: return;
1277:
1278: }
1279:
1280: OSStatus USBFindNextAssociatedDescriptor(USBPB *pb)
1281: {
1282: // --> usbReference Interface/Endpoint
1283: // <--> usb.cntl.WIndex Descriptor index (magic cookie) start at zero
1284: // --> usbBuffer Descriptor buffer
1285: // --> usbReqCount size of buffer
1286: // <-- usbActCount size of descriptor returned
1287: // <--> usbOther Descriptor type (zero matches any)
1288:
1289:
1290: if(!checkPBVersion(pb, 0))
1291: {
1292: return(pb->usbStatus);
1293: }
1294:
1295: /* check interface/endpoint here */
1296:
1297: pb->usbStatus = noErr;
1298: pb->wIndexStash = pb->usb.cntl.WIndex;
1299: pb->addrStash = (UInt32)pb->usbBuffer;
1300: pb->wValueStash = pb->usbReqCount;
1301: if(pb->usbReqCount > 0x7fff)
1302: {
1303: pb->wValueStash = 0x7fff;
1304: }
1305: uslInitialiseInternalStages(pb, uslFindNextAssociatedDescriptor);
1306: return(kUSBPending);
1307: }
1308:
1309: #if 0
1310: OSStatus USBOpenDevice(USBPB *pb);
1311:
1312: --> usbReference device
1313: --> usb.cntl.WValue configuration number (preserved)
1314: --> usbFlags Open interfaces immediately
1315: -- usb.cntl.WIndex is preserved (unusually)
1316: <-- usbValue4 number of interfaces in configuration
1317: #endif
1318:
1319: /* xxxx Check device power before config */
1320: static void uslSetDeviceConfig(USBPB *pb)
1321: {
1322: // <--> usbBuffer --> Config desc
1323: // --> usb.cntl.WValue Config number
1324: int stage;
1325: usbDevice *dev;
1326: USBConfigurationDescriptor *conf;
1327:
1328: if(pb->usbStatus != noErr)
1329: {
1330: uslCompleteInternalStages(pb);
1331: return;
1332: }
1333:
1334: stage = uslFindInternalStageAndIncriment(pb);
1335:
1336: do{switch(stage)
1337: {
1338: case 1:
1339: pb->usbReqCount = 0;
1340: // pb->usbBuffer = nil; // preserve config desc
1341:
1342: pb->usb.cntl.BMRequestType = USBMakeBMRequestType(kUSBNone, kUSBStandard, kUSBDevice);
1343: pb->usb.cntl.BRequest = kUSBRqSetConfig;
1344: // pb->usb.cntl.WValue = confNum; // input param
1345: pb->usb.cntl.WIndex = 0;
1346: kprintf("uslSetDeviceConfig:usbRef=0x%x\n",pb->usbReference);
1347: if(immediateError(uslDeviceRequest(pb)))
1348: {
1349: uslCompleteInternalStages(pb);
1350: }
1351: break;
1352:
1353: case 2:
1354: dev = getDev(pb);
1355: if(dev == nil)
1356: {
1357: pb->usbStatus = kUSBUnknownDeviceErr;
1358: }
1359: /* We've configured the device, so what? */
1360: else
1361: {
1362: conf = pb->usbBuffer;
1363: pb->usbActCount = USBToHostWord(conf->totalLength);
1364: dev->currentConfiguration = pb->wValueStash;
1365: /* note complete stages now implictly unlcoks device */
1366:
1367: }
1368:
1369: /* restore these values, so find interface, getinterface ref works across here */
1370: pb->usb.cntl.WValue = pb->wValueStash;
1371: pb->usb.cntl.WIndex = pb->wIndexStash;
1372:
1373: pb->usbReqCount = 0;
1374: pb->usbActCount = 0;
1375: pb->usbBuffer = 0;
1376:
1377: uslCompleteInternalStages(pb);
1378: break;
1379:
1380: default:
1381: USBExpertStatus(0,"USL - set conf handler, unknown case", 0);
1382: pb->usbStatus = kUSBInternalErr;
1383: pb->usbBuffer = (void *)pb->addrStash; // for dev reqs diverted
1384: uslCompleteInternalStages(pb);
1385: break;
1386: }
1387: break; /* only execute once, unless continue used */
1388: }while(1); /* so case can be reentered with a continue */
1389: return;
1390: }
1391:
1392: /* xxxx Check device power before config */
1393: static void uslOpenDevice2(USBPB *pb)
1394: {
1395: USBConfigurationDescriptor *conf;
1396: usbDevice *dev;
1397:
1398: conf = uslCacheConfigDescriptors(pb);
1399: if(conf == nil)
1400: {
1401: return;
1402: }
1403: dev = getDev(pb);
1404: if(dev == nil)
1405: {
1406: return;
1407: }
1408:
1409: pb->usbReqCount = pb->usbActCount;
1410:
1411: pb->usb.cntl.WValue = pb->wValueStash;
1412: pb->usbStatus = USBFindConfigDescriptorImmedite(pb);
1413:
1414: if(pb->usbStatus != noErr)
1415: {
1416: uslCompleteInternalStages(pb);
1417: return;
1418: }
1419: conf = pb->usbBuffer;
1420:
1421: if(conf->maxPower > dev->powerAvailable)
1422: {
1423: USBExpertStatus(0,"USL - Not enough power. Available:", dev->powerAvailable);
1424: USBExpertStatus(0,"USL - Not enough power. needed:", conf->maxPower);
1425:
1426: pb->usbStatus = kUSBDevicePowerProblem;
1427: USBExpertSetDevicePowerStatus(pb->usbReference, 0, 0, kUSBDevicePower_BusPowerInsufficient, dev->powerAvailable, conf->maxPower); // TC: <USB67>
1428: uslCompleteInternalStages(pb);
1429: return;
1430: }
1431: // pb->usb.cntl.WValue already set up. USBFindConfigDescriptorImmedite doesn't change it
1432:
1433: pb->usbOther = conf->numInterfaces; // eventual output
1434: pb->usbCompletion = (void *)pb->reserved2; /* restore users handler */
1435: uslInitialiseInternalStages(pb, uslSetDeviceConfig);
1436: return;
1437:
1438: }
1439:
1440: OSStatus uslOpenDevice(USBPB *pb)
1441: {
1442: usbDevice *dev;
1443:
1444: /* This is called by dev req when a set config is requested */
1445: /* thats stashed the buffer, we need to restore the buffer */
1446: /* if stashed */
1447: dev = getDev(pb);
1448: kprintf("uslOpenDevice:ref=%d,dev=0x%x\n",pb->usbReference,dev);
1449: if(dev == nil)
1450: {
1451: return(kUSBUnknownDeviceErr);
1452: }
1453:
1454: if(dev->ID != pb->usbReference)
1455: {
1456: /* Not a device ref */
1457: USBExpertStatus(0, "USL - Attempt to set config on interface", pb->usbReference);
1458:
1459: if(dev->currentConfiguration == pb->usb.cntl.WValue)
1460: {
1461: USBExpertStatus(0, "USL - setting current config", pb->usb.cntl.WValue);
1462: kprintf("uslOpenDevice:USL - setting current config\n");
1463: pb->usbStatus = noErr;
1464: (*pb->usbCompletion)(pb);
1465: return(kUSBPending);
1466: }
1467:
1468: return(kUSBUnknownDeviceErr);
1469: }
1470:
1471: if(!CompareAndSwap(0, 1, &dev->configLock)) /* complete stages now unlocks */
1472: {
1473: USBExpertStatus(0, "USL - Attempt to open busy device", dev->usbAddress);
1474: return(kUSBDeviceBusy);
1475: }
1476: kprintf("uslOpenDevice:calling uslUnConfigureDevice\n");
1477: uslUnconfigureDevice(dev);
1478:
1479: pb->usbStatus = noErr;
1480: pb->wValueStash = pb->usb.cntl.WValue;
1481: pb->wIndexStash = pb->usb.cntl.WIndex;
1482: kprintf("uslOpenDevice:calling uslInitialiseInternalStages\n");
1483: uslInitialiseInternalStages(pb, uslOpenDevice2);
1484: return(kUSBPending);
1485: }
1486:
1487: /* xxxx Check device power before config */
1488: /* xxxx sort out config value in usb.cntl.WValue or usbValue4 */
1489: OSStatus USBSetConfiguration(USBPB *pb)
1490: {
1491: if(!checkPBVersion(pb, 0))
1492: {
1493: return(pb->usbStatus);
1494: }
1495: if(checkZeroBuffer(pb))
1496: {
1497: return(paramErr);
1498: }
1499: pb->addrStash = 0; // so crap doesn't get restored
1500: return(uslOpenDevice(pb));
1501: }
1502:
1503: OSStatus USBOpenDevice(USBPB *pb)
1504: {
1505: return(USBSetConfiguration(pb));
1506: }
1507: #if 0
1508: OSStatus USBNewInterfaceRef(USBPB *pb)
1509:
1510: // <--> usbReference --> device <-- interface
1511: // --> usb.cntl.WIndex InterfaceNumber
1512: #endif
1513:
1514: /* xxxx sort out alt usage */
1515: static void uslNewInterfaceRef(USBPB *pb)
1516: {
1517: USBConfigurationDescriptor *conf;
1518: uslInterface *intrfc;
1519: usbDevice *dev;
1520: UInt8 oldOther;
1521:
1522: conf = uslCacheConfigDescriptors(pb);
1523: if(conf == nil)
1524: {
1525: return;
1526: }
1527: dev = getDev(pb);
1528: if(dev == nil)
1529: {
1530: return;
1531: }
1532:
1533: pb->usbReqCount = pb->usbActCount;
1534: pb->usb.cntl.WValue = dev->currentConfiguration;
1535: //WIndex is a param
1536: oldOther = pb->usbOther;
1537: pb->usbOther = 0xff; // Ignore alt
1538: pb->usbStatus = USBFindInterfaceDescriptorImmedite(pb);
1539: pb->usbOther = oldOther;
1540:
1541: if(pb->usbStatus != noErr)
1542: {
1543: uslCompleteInternalStages(pb);
1544: return;
1545: }
1546:
1547: /* Specified interface does exist */
1548:
1549: intrfc = AllocInterface(pb->usbReference);
1550: kprintf("uslNewInterfaceRef: intrfc=%d\n",intrfc);
1551: if(intrfc == 0)
1552: {
1553: pb->usbStatus = kUSBOutOfMemoryErr;
1554: uslCompleteInternalStages(pb);
1555: return;
1556: }
1557:
1558: pb->usbReference = intrfc->ref;
1559: intrfc->interfaceNum = pb->wIndexStash;
1560:
1561: pb->usbStatus = noErr;
1562: pb->usbReqCount = 0;
1563: pb->usbActCount = 0;
1564: pb->usbBuffer = 0;
1565:
1566: /* note complete stages now unlocks device */
1567: uslCompleteInternalStages(pb);
1568: }
1569:
1570: #if 0
1571: OSStatus USBNewInterfaceRef(USBPB *pb);
1572:
1573:
1574: <--> usbReference --> device <-- interface
1575: --> usb.cntl.WIndex InterfaceNumber
1576: --> usbFlags
1577: #endif
1578:
1579: /* xxxx sort out alt usage */
1580: OSStatus USBNewInterfaceRef(USBPB *pb)
1581: {
1582: usbDevice *dev;
1583: uslInterface *intrfc;
1584:
1585: if(!checkPBVersion(pb, 0))
1586: {
1587: return(pb->usbStatus);
1588: }
1589: if(checkZeroBuffer(pb))
1590: {
1591: return(paramErr);
1592: }
1593: pb->usbStatus = findInterface(pb->usbReference, &intrfc);
1594: if(pb->usbStatus == noErr)
1595: { // BT 2Jul98, don't allow interface ref here, device ref only.
1596: pb->usbStatus = kUSBUnknownDeviceErr;
1597: return(kUSBUnknownDeviceErr);
1598: }
1599: dev = getDev(pb);
1600: if(dev == nil)
1601: {
1602: return(kUSBUnknownDeviceErr);
1603: }
1604: if(!CompareAndSwap(0, 1, &dev->configLock))
1605: {
1606: USBExpertStatus(0, "USL - USBNewInterfaceRef, device busy", dev->usbAddress);
1607: return(kUSBDeviceBusy);
1608: }
1609:
1610: pb->usbStatus = noErr;
1611: pb->wIndexStash = pb->usb.cntl.WIndex;
1612: kprintf("*** USBNewInterfaceRef:ref=0x%x\n",pb->usbReference);
1613: uslInitialiseInternalStages(pb, uslNewInterfaceRef);
1614: return(kUSBPending);
1615: }
1616:
1617: /* xxxx sort out alt usage */
1618: static void uslConfigureInterface(USBPB *pb)
1619: {
1620: USBConfigurationDescriptor *conf;
1621: uslInterface *intrfc;
1622: usbDevice *dev;
1623: UInt16 pipeCount;
1624:
1625: conf = uslCacheConfigDescriptors(pb);
1626: if(conf == nil)
1627: {
1628: return;
1629: }
1630: pb->usbStatus = findInterface(pb->usbReference, &intrfc);
1631: if(pb->usbStatus != noErr)
1632: {
1633: uslCompleteInternalStages(pb);
1634: return;
1635: }
1636: dev = getDev(pb);
1637: if(dev == nil)
1638: {
1639: return;
1640: }
1641:
1642: uslCloseInterfacePipes(intrfc->ref, dev);
1643:
1644: pb->usb.cntl.WValue = pb->wValueStash;
1645:
1646: pb->usbReqCount = pb->usbActCount;
1647: pb->usb.cntl.WValue = dev->currentConfiguration;
1648: pb->usb.cntl.WIndex = intrfc->interfaceNum;
1649: pb->usbStatus = USBFindInterfaceDescriptorImmedite(pb);
1650:
1651: if(pb->usbStatus != noErr)
1652: {
1653: uslCompleteInternalStages(pb);
1654: return;
1655: }
1656:
1657: intrfc->alt = pb->usbOther; // remember alt
1658: pb->usbOther = 0; // count of endpoints in interface
1659: pb->usbReqCount = pb->usbActCount;
1660:
1661: pipeCount = 0;
1662: do{
1663: pb->usbFlags = kUSBAnyDirn;
1664: pb->usbClassType = kUSBAnyType;
1665: pb->usbOther = 0; // don't match against endpoint number
1666:
1667: pb->usbStatus = USBFindNextEndpointDescriptorImmediate(pb);
1668: if(pb->usbStatus == noErr)
1669: {
1670: pb->usbStatus = uslOpenPipeImmed(intrfc->ref, pb->usbBuffer);
1671: if(pb->usbStatus == noErr)
1672: {
1673: pipeCount++;
1674: }
1675: else
1676: {
1677:
1678: pb->usbReqCount = 0;
1679: pb->usbActCount = 0;
1680: pb->usbBuffer = 0;
1681:
1682: uslCompleteInternalStages(pb);
1683: return;
1684: }
1685: }
1686:
1687: }while(pb->usbStatus == noErr);
1688:
1689: pb->usbStatus = noErr;
1690:
1691: pb->usbReqCount = 0;
1692: pb->usbActCount = 0;
1693: pb->usbBuffer = 0;
1694:
1695: pb->usbOther = pipeCount;
1696:
1697: uslCompleteInternalStages(pb);
1698: }
1699:
1700: /* xxxx sort out alt usage */
1701: OSStatus USBConfigureInterface(USBPB *pb)
1702: {
1703: // <--> usbReference interface
1704: // --> usbW??? alt
1705: // --> usbFlags
1706: // <-- usbOther Number of pipes in interface
1707: uslInterface *intrfc;
1708:
1709: if(!checkPBVersion(pb, 0))
1710: {
1711: return(pb->usbStatus);
1712: }
1713: if(checkZeroBuffer(pb))
1714: {
1715: return(paramErr);
1716: }
1717:
1718: pb->usbStatus = findInterface(pb->usbReference, &intrfc);
1719: if(pb->usbStatus != noErr)
1720: {
1721: return(pb->usbStatus);
1722: }
1723: pb->usbStatus = noErr;
1724: pb->wValueStash = pb->usb.cntl.WValue;
1725: uslInitialiseInternalStages(pb, uslConfigureInterface);
1726: return(kUSBPending);
1727:
1728: }
1729:
1730: OSStatus uslUnconfigureDeviceByReference(USBDeviceRef ref)
1731: {
1732: usbDevice *dev;
1733:
1734: dev = getDevicePtr(ref);
1735: if(dev == nil)
1736: {
1737: return(kUSBUnknownDeviceErr);
1738: }
1739: uslUnconfigureDevice(dev);
1740: USBAbortPipeByReference(dev->pipe0);
1741: return(noErr);
1742:
1743: }
1744:
1745:
1746:
1747: /* xxxx test this with mor ethan one interface */
1748: OSStatus USBFindNextPipe(USBPB *pb)
1749: {
1750:
1751: // <--> usbReference --> interface/pipe <-- Pipe
1752: // <--> usbFLags direction/wild card
1753: // <--> usbValue1 Endpoint type/wild card
1754: uslInterface *intrfc;
1755: usbDevice *dev;
1756: pipe *p;
1757: USBReference container;
1758: int idx;
1759:
1760:
1761: if(!checkPBVersion(pb, kUSBAnyDirn))
1762: {
1763: return(pb->usbStatus);
1764: }
1765: if(checkZeroBuffer(pb))
1766: {
1767: return(paramErr);
1768: }
1769:
1770: pb->usbStatus = findInterface(pb->usbReference, &intrfc);
1771: if(pb->usbStatus == noErr)
1772: {
1773: idx = 0;
1774: dev = getDev(pb);
1775: if(dev == nil)
1776: {
1777: return(kUSBUnknownDeviceErr);
1778: }
1779: container = pb->usbReference;
1780: }
1781: else
1782: {
1783: pb->usbStatus = findPipe(pb->usbReference, &p);
1784: if(p == nil)
1785: {
1786: return(pb->usbStatus);
1787: }
1788: container = p->devIntfRef;
1789: dev = getDevicePtr(container);
1790: if(dev == nil)
1791: {
1792: return(kUSBUnknownPipeErr);
1793: }
1794:
1795: idx = makeDevPipeIdx(p->endPt, p->direction)+1;
1796: if(idx > kUSBMaxEndptPerDevice)
1797: {
1798: return(kUSBNotFound);
1799: }
1800: }
1801:
1802: /* Now have a starting point in devices pipe table */
1803:
1804: for(; idx < kUSBMaxEndptPerDevice; idx++)
1805: {
1806: if(dev->pipes[idx] != -1)
1807: {
1808: p = getPipeByIdx(dev->pipes[idx]);
1809: if(p == nil)
1810: {
1811: return(kUSBInternalErr);
1812: }
1813: if( (container == p->devIntfRef) &&
1814: ((pb->usbFlags == kUSBAnyDirn) || (pb->usbFlags == p->direction)) &&
1815: ((pb->usbClassType == kUSBAnyType) || (pb->usbClassType == p->type)) )
1816: {
1817: pb->usbStatus = noErr;
1818: pb->usbReference = p->ref;
1819: pb->usbFlags = p->direction;
1820: pb->usbClassType = p->type;
1821: pb->usb.cntl.WValue = p->maxPacket;
1822:
1823: pb->usbReqCount = 0;
1824: pb->usbActCount = 0;
1825: pb->usbBuffer = 0;
1826:
1827: (*pb->usbCompletion)(pb);
1828:
1829: return(kUSBPending);
1830: }
1831: }
1832: }
1833: pb->usbReqCount = 0;
1834: pb->usbActCount = 0;
1835: pb->usbBuffer = 0;
1836: pb->usb.cntl.WValue = 0;
1837: return(kUSBNotFound);
1838:
1839: }
1840:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.