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

unix.superglobalmegacorp.com

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