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

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

unix.superglobalmegacorp.com

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