Annotation of kernel/bsd/dev/ppc/drvUSBCMD/Library/usldescriptors.c, revision 1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.