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

unix.superglobalmegacorp.com

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