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

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
        !             3:  *
        !             4:  * @APPLE_LICENSE_HEADER_START@
        !             5:  * 
        !             6:  * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
        !             7:  * Reserved.  This file contains Original Code and/or Modifications of
        !             8:  * Original Code as defined in and that are subject to the Apple Public
        !             9:  * Source License Version 1.1 (the "License").  You may not use this file
        !            10:  * except in compliance with the License.  Please obtain a copy of the
        !            11:  * License at http://www.apple.com/publicsource and read it before using
        !            12:  * this file.
        !            13:  * 
        !            14:  * The Original Code and all software distributed under the License are
        !            15:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
        !            16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
        !            17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
        !            18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
        !            19:  * License for the specific language governing rights and limitations
        !            20:  * under the License.
        !            21:  * 
        !            22:  * @APPLE_LICENSE_HEADER_END@
        !            23:  */
        !            24: 
        !            25: /*
        !            26:        File:           usl.c
        !            27: 
        !            28:        Contains:       USB Services Library source code.
        !            29:  
        !            30:        Version:        Neptune 1.0
        !            31:  
        !            32:        Copyright:      � 1997-1998 by Apple Computer, Inc., all rights reserved.
        !            33: 
        !            34:        File Ownership:
        !            35: 
        !            36:                DRI:                            Barry Twycross
        !            37: 
        !            38:                Other Contact:          xxx put other contact here xxx
        !            39: 
        !            40:                Technology:                     USB
        !            41: 
        !            42:        Writers:
        !            43: 
        !            44:                (DF)    David Ferguson
        !            45:                (TC)    Tom Clark
        !            46:                (BG)    Bill Galcher
        !            47:                (DKF)   David Ferguson
        !            48:                (CJK)   Craig Keithley
        !            49:                (BT)    Barry Twycross
        !            50: 
        !            51:        Change History (most recent first):
        !            52: 
        !            53:         <USB76>        11/25/98        TC              Add calls to USBExpertStatusLevel.
        !            54:         <USB75>        11/16/98        BT              Mark pipe stalled on allocate to check open pipe is clearing it
        !            55:                                                                        properly.
        !            56:         <USB74>         11/8/98        TC              We need to assign a unique DeviceRef for UIM's. So when creating
        !            57:                                                                        DeviceRefs, don't return one that matches kUIMRefID.
        !            58:         <USB73>         11/6/98        TC              Formalize parameter names for uslRefToBus.
        !            59:         <USB72>         11/6/98        BT              ref to bus function
        !            60:         <USB71>        10/29/98        BT              Close old configurations on reset or reconfiguration.
        !            61:         <USB70>        10/21/98        DF              Add uslDeviceAddrToBus function
        !            62:         <USB69>         10/7/98        BT              Fix hub not killing children
        !            63:         <USB68>         9/17/98        BT              1.1 rules for captive devices.
        !            64:         <USB67>         8/24/98        BT              Eliminate old checkPB version, add new one for Isoc
        !            65:         <USB66>         8/13/98        BT              Add multibus support
        !            66:         <USB65>         7/10/98        BT              Device zero has a valid ref, delete device deletes mem even
        !            67:                                                                        after trashing device and ref.
        !            68:         <USB64>          7/9/98        BT              Fix previous fixes. Device refs can also be validated
        !            69:         <USB63>          7/9/98        BT              Clean up after delete device and config clash.
        !            70:         <USB62>         6/13/98        BT              Eliminate V1 param blocks
        !            71:         <USB61>         6/10/98        CJK             add uslGetDeviceRefByID function (thanks Barry!)
        !            72:         <USB60>          6/5/98        BT              Delete mem properly in delete device
        !            73:         <USB59>          6/5/98        TC              Change uxBusRef to USBBusRef.
        !            74:         <USB58>          6/3/98        BT              Make dispose interface ref able to ignore call back
        !            75:         <USB57>         5/21/98        BT              Don't initialise redundant firstConf field in dev structure
        !            76:         <USB56>         5/20/98        BT              Add check for V2 param block function
        !            77:         <USB55>         5/19/98        BG              Fixed ZeroMem() be a little easier for MrC to swallow.
        !            78:         <USB54>         5/17/98        BT              Impliment new interface ref correctly, add some functions to
        !            79:                                                                        support config stuff
        !            80:         <USB53>         5/12/98        BT              New interface handling
        !            81:         <USB52>          5/8/98        BT              Add open interface for Tom
        !            82:         <USB51>         4/26/98        BT              Add pipe state control
        !            83:         <USB50>         4/24/98        BT              Add clear endpoint stall
        !            84:         <USB49>         4/24/98        CJK             change string for status message
        !            85:         <USB48>         4/21/98        BT              Allow requests to device zero, pipe zero.
        !            86:         <USB47>         4/20/98        BT              Add abort pipe
        !            87:         <USB46>         4/16/98        BT              Add back UIMpriv prototypes
        !            88:         <USB45>         4/15/98        BT              Remove redundant diagnostic
        !            89:         <USB44>         4/15/98        BT              Fix wrong flags check.
        !            90:         <USB43>         4/14/98        BT              Impliment device remove
        !            91:         <USB42>          4/9/98        CJK             remove uimpriv.h
        !            92:         <USB41>          4/9/98        BT              Use USB.h
        !            93:                <40>      4/8/98        BT              More error checking
        !            94:                <39>      4/6/98        BT              Change w names
        !            95:                <38>      4/6/98        BT              New param block names
        !            96:                <37>      4/2/98        BT              Start on config/interface/endpoint stuff. First caching config
        !            97:                                                                        descriptors.
        !            98:                <36>     3/24/98        BT              Record device speed in device structure. (Fixes low speed int
        !            99:                                                                        pipe problems.)
        !           100:                <35>     3/24/98        BT              Fix recording of Maxpacketsize
        !           101:                <34>     3/19/98        BT              Stop double inititialisation
        !           102:                <33>     3/19/98        BT              Open bulk takes max poacket size in usbValue.
        !           103:                <32>     3/18/98        BT              Add remove device.
        !           104:                <31>      3/5/98        BT              Add interrupt pipe
        !           105:         <USB30>         2/17/98        DKF             Fix a typo in the error codes
        !           106:                <29>     2/16/98        BT              Direct notifications to expert
        !           107:                <28>      2/9/98        BT              Add add interface stuff
        !           108:                <27>      2/8/98        BT              Power Allocation stuff
        !           109:                <26>      2/5/98        BT              Add status notification stuff
        !           110:                <25>      2/4/98        BT              Add ref/port info to expert notify]
        !           111:                <24>      2/4/98        BT              More USBprobe support
        !           112:                <23>      2/3/98        BT              Fix uslControlPacket to have errors. Add mnore support for
        !           113:                                                                        usbProbe. Also add USBExpertNotify
        !           114:                <22>      2/2/98        BT              Add bulk stuff
        !           115:                <21>     1/29/98        BT              Utility stuff split off
        !           116:                <20>     1/26/98        CJK             Change to use USBDeviceDescriptor (instead of just
        !           117:                                                                        deviceDescriptor)
        !           118:                <19>     1/26/98        BT              Mangle names after design review, finish up
        !           119:                <18>     1/26/98        BT              Mangle names after design review
        !           120:                <17>     1/26/98        BT              Make expert notify public
        !           121:                <16>     1/26/98        BT              Fix status in USB delay function
        !           122:                <15>     1/23/98        BT              Add USB delay function
        !           123:                <14>     1/20/98        BT              Increase number of timers
        !           124:                <13>     1/19/98        BT              Fix race condition
        !           125:                <12>     1/15/98        BT              Use new USBClassDrivers.h
        !           126:                <11>     1/14/98        BT              Remove outdated expert stuff
        !           127:                <10>     1/13/98        BT              User timer services for task time, starting implimenting Int
        !           128:                                                                        transactions (not finished)
        !           129:                 <9>    12/23/97        BT              Remove obsolete include
        !           130:                 <8>    12/19/97        BT              Add add and remove bus.
        !           131:                 <7>    12/19/97        BT              UIM now a Shared lib
        !           132:                 <6>    12/18/97        BT              Changed expert proc declaratiopn in USLInitialise
        !           133:                 <5>    12/18/97        BT              Fix header dependancies, add expert call back
        !           134:                 <4>    12/17/97        BT              Fix header
        !           135:                 <3>    12/17/97        BT              First checking to BBS
        !           136: */
        !           137: 
        !           138: 
        !           139: 
        !           140: /* ************* Includes ************* */
        !           141: #include "../USB.h"
        !           142: #include "../USBpriv.h"
        !           143: #include "../driverservices.h"
        !           144: 
        !           145: #include "uslpriv.h"
        !           146: #include "../uimpriv.h" // This does need to be included. It contains prototypes
        !           147:                                            // Stupid MPW just doesn't tell
        !           148: /*****************************************************************************
        !           149: 
        !           150:        Data Structures
        !           151:        
        !           152: There is an array of devices. 
        !           153: 
        !           154: Each device entry has information specific to it. It also holds and array of
        !           155: indexes of pipes (open endpoints) for the device.
        !           156: 
        !           157: Each open pipe holds information specific to it.
        !           158: 
        !           159: Devices are refrenced by device IDs, which are currently an index in tot the
        !           160: devices table in the lower bits and random number in the high bits. This 
        !           161: knowledge is kept to a few functions and could be changed.
        !           162: 
        !           163: The pipe refs are similarly indexes in to the pipes array.
        !           164: 
        !           165: ******************************************************************************/
        !           166: 
        !           167: static pipe AllPipes[kUSBMaxPipes];
        !           168: static usbDevice devices[kUSBMaxDevices];
        !           169: 
        !           170: enum{
        !           171:        kUSBInterfaceShift = 8,
        !           172:        kUSBMaxInterface = 1 << kUSBInterfaceShift,
        !           173:        kUSBIntefaceMask = kUSBMaxInterface-1
        !           174:        };
        !           175: static uslInterface interfaces[kUSBMaxInterface];
        !           176: 
        !           177: //static usbDevice *devices;
        !           178: 
        !           179: static Boolean initialised;
        !           180: 
        !           181: 
        !           182: /* ************* CallBack prototyopes. ************* */
        !           183: /* These need to be referenced before the properplace for their definition */
        !           184: static void controlCallBack(
        !           185:                UInt32  refcon,                         /* General Purpose reference supplied by call */
        !           186:                OSStatus status,                        /* normal or error condition */
        !           187:                short shortFall);                       /* how much less than requested transferred */
        !           188: 
        !           189: 
        !           190: 
        !           191: 
        !           192: /* ************* Actual Code *************** */
        !           193: 
        !           194: /* This doesn't work without length bytes in the strings */
        !           195: 
        !           196: OSStatus USBServicesGetVersion(UInt32 ID, VersRec *vers, UInt32 versSize)
        !           197: {
        !           198: #if 0
        !           199: static VersRec ID1=
        !           200: #if kOverrideIndividualVersions
        !           201:        {
        !           202:        {kPKGHexMajorVers, kPKGHexMinorVers, kPKGCurrentRelease, kPKGReleaseStage},
        !           203:        0,                                      /* Country code */
        !           204:        "\p"kPKGStringVersShort, "\p"kPKGStringVers1Long
        !           205:        
        !           206:        },
        !           207: #else
        !           208:        {
        !           209:        {kSRVHexMajorVers, kSRVHexMinorVers, kSRVCurrentRelease, kSRVReleaseStage},
        !           210:        0,                                      /* Country code */
        !           211:        kMNGRStringVersShort kMNGRStringVers1Long
        !           212:        
        !           213:        },
        !           214: #endif
        !           215:        ID2 = {
        !           216:        {kPKGHexMajorVers, kPKGHexMinorVers, kPKGCurrentRelease, kPKGReleaseStage},
        !           217:        0,                                      /* Country code */
        !           218:        kPKGStringVersShort kPKGStringVers1Long
        !           219:        
        !           220:        },
        !           221:        *theVers;
        !           222: 
        !           223:        if( (ID == 0) || (ID > 2) )
        !           224:        {
        !           225:                return(paramErr);
        !           226:        }
        !           227:        if(ID == 1)
        !           228:        {
        !           229:                theVers = &ID1;
        !           230:        }
        !           231:        else
        !           232:        {
        !           233:                theVers = &ID2;
        !           234:        }
        !           235:        if(versSize > sizeof(VersRec) )
        !           236:        {
        !           237:                versSize = sizeof(VersRec);
        !           238:        }
        !           239:        usb_BlockMoveData(theVers, vers, versSize);
        !           240: #endif
        !           241:        ID = 0;
        !           242:        vers = 0;
        !           243:        versSize = 0;
        !           244:        return(noErr);
        !           245: }
        !           246: /* ******** Interfaces ********** */
        !           247: 
        !           248: /* This impliments the arbitrary high bits as a counter. */
        !           249: static USBInterfaceRef MakeInterfaceRef(UInt16 addr)
        !           250: {
        !           251: static long strangeCounter = 0x980508;
        !           252: long shiftedCounter;
        !           253: 
        !           254:        strangeCounter++;
        !           255:        shiftedCounter = strangeCounter << kUSBInterfaceShift;
        !           256:        if(shiftedCounter == 0)
        !           257:        {
        !           258:                shiftedCounter = ++strangeCounter << kUSBInterfaceShift;
        !           259:        }
        !           260:        return(addr | shiftedCounter | 0x80000000);     // high bit is one
        !           261: }
        !           262: 
        !           263: /* Given a interfaceRef find the pointer to its structure */
        !           264:        
        !           265: OSStatus findInterface(USBInterfaceRef InterfaceRef, uslInterface **p)
        !           266: {
        !           267: InterfacesIdx idx;
        !           268: uslInterface *theInterface;
        !           269: 
        !           270:        idx = InterfaceRef & kUSBIntefaceMask;
        !           271:        theInterface = & interfaces[idx];
        !           272:        *p = theInterface;
        !           273:        if(theInterface->ref == InterfaceRef)
        !           274:        {
        !           275: #if 0
        !           276:                if(theInterface->state != kUSBActive)
        !           277:                {
        !           278:                        if(theInterface->state == kUSBIdle)
        !           279:                        {
        !           280:                                return(kUSBInterfaceIdleError);
        !           281:                        }
        !           282:                        else
        !           283:                        {
        !           284:                                return(kUSBInterfaceStalledError);
        !           285:                        }                       
        !           286:                }
        !           287: #endif
        !           288:                return(noErr);
        !           289:        }
        !           290:        *p = nil;
        !           291:        return(kUSBUnknownInterfaceErr);
        !           292: }
        !           293: 
        !           294: 
        !           295: /* This probably is not the best method for Interfaces */
        !           296: static InterfacesIdx AllocInterfaceIdx(void)
        !           297: {
        !           298: static InterfacesIdx current;
        !           299: InterfacesIdx new;
        !           300: unsigned counted;
        !           301: 
        !           302: /* Allocates a Interface. This implimentation has a pointer to */
        !           303: /* the next Interface to be allocated, which is incrimented each */
        !           304: /* time. If that Interface is in use, the list is search linearly */
        !           305: /* from that point for the next free Interface */
        !           306: /* Same as packet allocator */
        !           307: 
        !           308: /* Do we need to use atomicTestAndSet for this? */
        !           309: /* Not if transactions are queued */
        !           310: 
        !           311:        new = current;
        !           312:        counted = 0;
        !           313: 
        !           314:        while(counted < kUSBMaxInterface)
        !           315:        {
        !           316:                if(interfaces[new].ref == 0)    /* Zero not a valid Interface ref */
        !           317:                {
        !           318:                        break;
        !           319:                }
        !           320:                counted++;
        !           321:                new++;
        !           322:                if(new > kUSBMaxInterface)
        !           323:                {
        !           324:                        new = 0;
        !           325:                }
        !           326:                
        !           327:        }
        !           328:        if(counted < kUSBMaxInterface)
        !           329:        {
        !           330:                if(counted > 0)
        !           331:                {
        !           332:                        /* maybe keep track of these at some time */
        !           333:                }
        !           334:                interfaces[new].ref = 0;
        !           335:        }
        !           336:        else
        !           337:        {
        !           338:                /* maybe keep track of these at some time */
        !           339:                new = -1;
        !           340:        }
        !           341: 
        !           342:        current++;
        !           343:        if(current > kUSBMaxInterface)
        !           344:        {
        !           345:                current = 0;
        !           346:        }
        !           347:        return(new);
        !           348: }
        !           349: 
        !           350: /* Allocate a new Interface structure for the given device and endpoint */
        !           351: uslInterface *AllocInterface(USBDeviceRef device)
        !           352: {
        !           353: long newIdx;
        !           354: 
        !           355:        newIdx = AllocInterfaceIdx();
        !           356:        if(newIdx == -1)
        !           357:        {
        !           358:                return(nil);
        !           359:        }
        !           360:        interfaces[newIdx].ref = MakeInterfaceRef(newIdx);
        !           361:        interfaces[newIdx].device = device;
        !           362:        return(&interfaces[newIdx]);
        !           363: }
        !           364: 
        !           365: 
        !           366: static void deallocAllDeviceInterfaces(USBDeviceRef ID)
        !           367: {
        !           368: int i;
        !           369:        for(i = 0; i<kUSBMaxInterface ; i++)
        !           370:        {
        !           371:                if(interfaces[i].device == ID)
        !           372:                {
        !           373:                        USBExpertStatusLevel(4, interfaces[i].ref, "USL - Delete undeleted interface", 0);
        !           374:                        
        !           375:                        interfaces[i].device = 0;
        !           376:                        interfaces[i].interfaceNum = 0;
        !           377:                        interfaces[i].alt = 0;
        !           378:                        interfaces[i].ref = 0;
        !           379:                }
        !           380:        }
        !           381: 
        !           382: 
        !           383: }
        !           384: 
        !           385: /* ************* Device Table maintainance internal functions *************/
        !           386: unsigned makeDeviceIdx(USBDeviceRef device)
        !           387: {
        !           388:        return(device & kUSBDeviceIDMask);
        !           389: }
        !           390: 
        !           391: Boolean uslIsInterfaceRef(USBInterfaceRef interf)
        !           392: {
        !           393:        return((interf & 0x80000000) != 0);
        !           394: }
        !           395: 
        !           396: usbDevice *getDevicePtrFromIdx(unsigned deviceIndex)
        !           397: {
        !           398:        if(deviceIndex > kUSBMaxDevices)
        !           399:        {
        !           400:                return(nil);
        !           401:        }
        !           402:        return(&devices[deviceIndex]);
        !           403: }
        !           404: 
        !           405: USBDeviceRef uslGetDeviceRefByID(unsigned short deviceID, USBBusRef bus);
        !           406: 
        !           407: USBDeviceRef uslGetDeviceRefByID(unsigned short deviceID, USBBusRef bus)
        !           408: {
        !           409: usbDevice *device;
        !           410:        if(bus != 1)
        !           411:        {
        !           412:                return(kUSBUnknownDeviceErr);
        !           413:        }
        !           414:        device = getDevicePtrFromIdx(deviceID);
        !           415:        if(device == nil)
        !           416:        {
        !           417:                return(kUSBUnknownDeviceErr);
        !           418:        }
        !           419:        return(device->ID);
        !           420: 
        !           421: }
        !           422: 
        !           423: usbDevice *getDevicePtr(USBDeviceRef device)
        !           424: {
        !           425: unsigned deviceIndex;
        !           426: 
        !           427:        if( (device & 0x80000000) != 0)
        !           428:        {
        !           429:        OSStatus err;
        !           430:        uslInterface *intrfc;
        !           431:        
        !           432:                err = findInterface(device, &intrfc);
        !           433:                if(intrfc == nil)
        !           434:                {
        !           435:                        return(nil);
        !           436:                }
        !           437:                device = intrfc->device;
        !           438:        }
        !           439: 
        !           440:        deviceIndex = makeDeviceIdx(device);
        !           441:        if(devices[deviceIndex].ID == device)
        !           442:        {
        !           443:                return(&devices[deviceIndex]);
        !           444:        }
        !           445:        return(nil);
        !           446: }
        !           447: 
        !           448: OSStatus uslRefToBus(USBReference ref, USBBusRef *bus)
        !           449: {
        !           450: usbDevice *dev;
        !           451:        dev = getDevicePtr(ref);
        !           452:        if(dev != nil)
        !           453:        {
        !           454:                if(bus != nil)
        !           455:                {
        !           456:                        *bus = dev->bus;
        !           457:                }
        !           458:                return(noErr);
        !           459:        }
        !           460:        else
        !           461:        {
        !           462:                return(kUSBUnknownDeviceErr);
        !           463:        }
        !           464: 
        !           465: }
        !           466: 
        !           467: 
        !           468: /* This one is a prober only hack function */
        !           469: UInt32 uslDeviceAddrToBus(UInt16 addr)
        !           470: {
        !           471: unsigned deviceIndex;
        !           472: 
        !           473:        for(deviceIndex = 0; deviceIndex < kUSBMaxDevices; deviceIndex++)
        !           474:        {
        !           475:                if ((devices[deviceIndex].ID != 0) && (devices[deviceIndex].usbAddress == addr))
        !           476:                {
        !           477:                        return(devices[deviceIndex].bus);
        !           478:                }
        !           479:        }
        !           480:        return (0xffff);  // indicate that we couldn't find a bus
        !           481: }
        !           482: 
        !           483: 
        !           484: 
        !           485: static void initialiseOneDevice(usbDevice *device)
        !           486: {      /* Shared by delete device */
        !           487:        device->ID = 0; 
        !           488: }
        !           489: 
        !           490: static void initialiseDevices(void)
        !           491: {
        !           492: unsigned deviceIndex;
        !           493: 
        !           494:        for(deviceIndex = 0; deviceIndex < kUSBMaxDevices; deviceIndex++)
        !           495:        {
        !           496:                initialiseOneDevice(&devices[deviceIndex]);
        !           497:        }
        !           498: 
        !           499: }
        !           500: 
        !           501: UInt8 getNewAddress(void)
        !           502: {
        !           503: static int addr = -1;
        !           504: int counted = 1;
        !           505:        if(addr == -1)
        !           506:        {
        !           507:        AbsoluteTime t;
        !           508:                t = UpTime();
        !           509:                //naga addr = t.lo & 0x7f;
        !           510:                addr = t & 0x7f;
        !           511:        }
        !           512:        do{
        !           513:                addr++;
        !           514:                if(addr > 127)
        !           515:                {
        !           516:                        addr = 1;
        !           517:                }
        !           518:                if(devices[addr].ID == 0)
        !           519:                {
        !           520:                        break;
        !           521:                }
        !           522:        }while(counted++ <= 127);
        !           523:        
        !           524:        if(counted > 127)
        !           525:        {
        !           526:                addr = 0;
        !           527:        }
        !           528:        
        !           529:        USBExpertStatusLevel(4, 0, "USL - New device:", addr); // Paging Mr. Twycross
        !           530: kprintf("****getNewAddress returning addr=%d***\n",addr);
        !           531:        return(addr);
        !           532: }
        !           533: 
        !           534: 
        !           535: /* This impliments the arbitrary high bits as a counter. */
        !           536: USBDeviceRef MakeDevRef(UInt32 bus, UInt16 addr)
        !           537: {
        !           538: static long strangeCounter = 0x090263;
        !           539: long shiftedCounter;
        !           540: 
        !           541:        strangeCounter++;
        !           542:        shiftedCounter = strangeCounter << kUSBDeviceIDShift;
        !           543:        if(shiftedCounter == 0)
        !           544:        {
        !           545:                shiftedCounter = ++strangeCounter << kUSBDeviceIDShift;
        !           546:        }
        !           547: 
        !           548:        bus = 0; // currenty not used.
        !           549:        return( (addr + shiftedCounter) & 0x7fffffff);  // High bit is zero
        !           550: }
        !           551: 
        !           552: /* ************* Pipe Table Maintainance internal functions ************* */
        !           553: 
        !           554: /* So that stale pipeRefs can not be reused, the pipe ref is */
        !           555: /* the index into the pipe table (the interesting part) */
        !           556: /* and an arbitrary value stuffing the high bits. */
        !           557: /* A pipe ref is only accepted if it matches the pipeRef */
        !           558: /* stored in the pipe structure. */
        !           559: 
        !           560: /* This impliments the arbitrary high bits as a counter. */
        !           561: static USBPipeRef MakePipeRef(long pipeIdx)
        !           562: {
        !           563: static long strangeCounter = 0x230259;
        !           564: long shiftedCounter;
        !           565: 
        !           566:        strangeCounter++;
        !           567:        shiftedCounter = strangeCounter << kUSBMaxPipeIDShift;
        !           568:        if(shiftedCounter == 0)
        !           569:        {
        !           570:                shiftedCounter = ++strangeCounter << kUSBMaxPipeIDShift;
        !           571:        }
        !           572:        return(pipeIdx + shiftedCounter);
        !           573: }
        !           574: 
        !           575: /* Given a pipeRef find the pointer to its structure */
        !           576:        
        !           577: OSStatus findPipe(USBPipeRef pipeRef, pipe **p)
        !           578: {
        !           579: pipesIdx idx;
        !           580: pipe *thePipe;
        !           581: 
        !           582:        idx = pipeRef & kUSBPipeIDMask;
        !           583:        thePipe = & AllPipes[idx];
        !           584:        *p = thePipe;
        !           585:        if(thePipe->ref == pipeRef)
        !           586:        {
        !           587:                if(thePipe->state != kUSBActive)
        !           588:                {
        !           589:                        if(thePipe->state == kUSBIdle)
        !           590:                        {
        !           591:                                return(kUSBPipeIdleError);
        !           592:                        }
        !           593:                        else
        !           594:                        {
        !           595:                                return(kUSBPipeStalledError);
        !           596:                        }                       
        !           597:                }
        !           598:                return(noErr);
        !           599:        }
        !           600:        *p = nil;       // BT some things rely on this being nil if no pipe, oops.
        !           601:        return(kUSBUnknownPipeErr);
        !           602: }
        !           603: 
        !           604: 
        !           605: /* This probably is not the best method for pipes */
        !           606: static pipesIdx AllocPipeIdx(void)
        !           607: {
        !           608: static pipesIdx current;
        !           609: pipesIdx new;
        !           610: unsigned counted;
        !           611: 
        !           612: /* Allocates a pipe. This implimentation has a pointer to */
        !           613: /* the next pipe to be allocated, which is incrimented each */
        !           614: /* time. If that pipe is in use, the list is search linearly */
        !           615: /* from that point for the next free pipe */
        !           616: /* Same as packet allocator */
        !           617: 
        !           618: /* Do we need to use atomicTestAndSet for this? */
        !           619: /* Not if transactions are queued */
        !           620: 
        !           621:        new = current;
        !           622:        counted = 0;
        !           623: 
        !           624:        while(counted < kUSBMaxPipes)
        !           625:        {
        !           626:                if(AllPipes[new].ref == 0)      /* Zero not a valid pipe ref */
        !           627:                {
        !           628:                        break;
        !           629:                }
        !           630:                counted++;
        !           631:                new++;
        !           632:                if(new > kUSBMaxPipes)
        !           633:                {
        !           634:                        new = 0;
        !           635:                }
        !           636:                
        !           637:        }
        !           638:        if(counted < kUSBMaxPipes)
        !           639:        {
        !           640:                if(counted > 0)
        !           641:                {
        !           642:                        /* maybe keep track of these at some time */
        !           643:                }
        !           644:                AllPipes[new].ref = 0;
        !           645:                AllPipes[new].state = kUSBStalled;      // This is just here to tell me an open pipe forgot to set state
        !           646:        }
        !           647:        else
        !           648:        {
        !           649:                /* maybe keep track of these at some time */
        !           650:                new = -1;
        !           651:        }
        !           652: 
        !           653:        current++;
        !           654:        if(current > kUSBMaxPipes)
        !           655:        {
        !           656:                current = 0;
        !           657:        }
        !           658:        return(new);
        !           659: }
        !           660: 
        !           661: int makeDevPipeIdx( UInt8 endpoint, UInt8 direction)
        !           662: {
        !           663: int devPipeIdx;
        !           664:        devPipeIdx = endpoint-1;
        !           665:        if(direction != kUSBOut)
        !           666:        {
        !           667:                devPipeIdx += kUSBMaxEndptPerDevice/2;
        !           668:        }
        !           669:        return(devPipeIdx);
        !           670: }
        !           671: 
        !           672: /* Given a device and an endpoint, wheres the pipe? */
        !           673: pipe *getPipe(usbDevice *device, UInt8 endpoint, UInt8 direction)
        !           674: {
        !           675: pipesIdx index;
        !           676:        index = device->pipes[makeDevPipeIdx(endpoint, direction)];
        !           677:        if(index == -1)
        !           678:        {
        !           679:                return(nil);
        !           680:        }
        !           681:        else
        !           682:        {
        !           683:                return(&AllPipes[index]);
        !           684:        }
        !           685: }
        !           686: 
        !           687: pipe *getPipeByIdx(pipesIdx idx)
        !           688: {
        !           689:        if(idx > kUSBMaxPipes)
        !           690:        {
        !           691:                return(nil);
        !           692:        }
        !           693:        
        !           694:        return(&AllPipes[idx]);
        !           695: 
        !           696: }
        !           697: 
        !           698: /* Allocate a new pipe structure for the given device and endpoint */
        !           699: pipe *AllocPipe(usbDevice *device, UInt8 endpoint, UInt8 direction)
        !           700: {
        !           701: long newIdx;
        !           702: 
        !           703:        newIdx = AllocPipeIdx();
        !           704:        if(newIdx == -1)
        !           705:        {
        !           706:                return(nil);
        !           707:        }
        !           708:        device->pipes[makeDevPipeIdx(endpoint, direction)] = newIdx;
        !           709:        AllPipes[newIdx].ref = MakePipeRef(newIdx);
        !           710:        return(&AllPipes[newIdx]);
        !           711: }
        !           712: 
        !           713: 
        !           714: /* XXXXXXXX More to be done */
        !           715: void deallocPipe(usbDevice *device, UInt8 endpoint, UInt8 direction)
        !           716: {
        !           717: pipesIdx index;
        !           718: int devPipeIdx;
        !           719: 
        !           720:        devPipeIdx = makeDevPipeIdx(endpoint, direction);
        !           721:        index = device->pipes[devPipeIdx];
        !           722:        AllPipes[index].ref = 0;
        !           723:        AllPipes[index].state = kUSBStalled;    // This is just here to tell me an open pipe forgot to set state
        !           724:        device->pipes[devPipeIdx] = -1;
        !           725: }
        !           726: 
        !           727: 
        !           728: OSStatus uslClosePipe(pipesIdx pipe)
        !           729: {
        !           730: OSStatus err;
        !           731:        if(pipe == -1)
        !           732:        {
        !           733:                return(noErr);
        !           734:        }
        !           735:        if(AllPipes[pipe].type == kUSBControl)
        !           736:        {
        !           737: kprintf("uslClosePipe:calling UIMControlEDDelete\n");
        !           738:                err = UIMControlEDDelete(AllPipes[pipe].bus, AllPipes[pipe].devAddress, AllPipes[pipe].endPt);
        !           739:        }
        !           740:        else
        !           741:        {
        !           742:                err = UIMEDDelete(AllPipes[pipe].bus, AllPipes[pipe].devAddress, AllPipes[pipe].endPt, AllPipes[pipe].direction);
        !           743:        }
        !           744: 
        !           745:        AllPipes[pipe].ref = 0;
        !           746:        AllPipes[pipe].state = kUSBStalled;     // This is just here to tell me an open pipe forgot to set state
        !           747:        return(noErr);
        !           748: }
        !           749: 
        !           750: void uslCloseNonDefaultPipes(usbDevice *deviceP)
        !           751: {
        !           752: int i;
        !           753:        for(i = 0; i< kUSBMaxEndptPerDevice; i++)
        !           754:        {
        !           755:                uslClosePipe(deviceP->pipes[i]);
        !           756:                deviceP->pipes[i] = -1;
        !           757:        }
        !           758: }
        !           759: 
        !           760: void uslCloseInterfacePipes(USBInterfaceRef iRef, usbDevice *deviceP)
        !           761: {
        !           762: int i;
        !           763:        for(i = 0; i< kUSBMaxEndptPerDevice; i++)
        !           764:        {
        !           765:                if(AllPipes[deviceP->pipes[i]].devIntfRef == iRef)
        !           766:                {
        !           767:                        uslClosePipe(deviceP->pipes[i]);
        !           768:                        deviceP->pipes[i] = -1;
        !           769:                }
        !           770:        }
        !           771: }
        !           772: 
        !           773: 
        !           774: OSStatus validateRef(USBReference ref, UInt32 *bus)
        !           775: {
        !           776: OSStatus err;
        !           777: usbDevice *dev;
        !           778: pipe *p;
        !           779: 
        !           780:        dev = getDevicePtr(ref);
        !           781:        if(dev != nil)
        !           782:        {
        !           783:                if(bus != nil)
        !           784:                {
        !           785:                        *bus = dev->bus;
        !           786:                }
        !           787:                return(noErr);
        !           788:        }
        !           789:        err = findPipe(ref, &p);
        !           790:        if(p != nil)
        !           791:        {
        !           792:                if(bus != nil)
        !           793:                {
        !           794:                        *bus = p->bus;
        !           795:                }
        !           796:                return(noErr);
        !           797:        }
        !           798:        if(uslHubValidateDevZero(ref, bus))
        !           799:        {
        !           800:                return(noErr);
        !           801:        }
        !           802:        USBExpertStatusLevel(2, ref, "USL - Invalid ref passed to USL", 0);
        !           803: 
        !           804:        return(kUSBUnknownDeviceErr);
        !           805: }
        !           806: 
        !           807: Boolean isSameDevice(USBReference ref, USBDeviceRef devRef)
        !           808: {      // true if the ref refers to the device
        !           809: usbDevice *dev;
        !           810: OSStatus err;
        !           811: pipe *p;
        !           812: 
        !           813:        dev = getDevicePtr(ref);
        !           814:        if(dev == nil)
        !           815:        {
        !           816:                err = findPipe(ref, &p);
        !           817:                if(p == nil)
        !           818:                {
        !           819:                        return(false);
        !           820:                }
        !           821:                
        !           822:                dev = getDevicePtr(p->devIntfRef);
        !           823:        }
        !           824:        if(dev != nil)
        !           825:        {
        !           826:                if(dev->ID == devRef)
        !           827:                {
        !           828:                        return(true);
        !           829:                }
        !           830:        }
        !           831:        return(false);
        !           832: }
        !           833: 
        !           834: static void ZeroMem(void *addr, UInt32 len)
        !           835: {
        !           836: UInt8  *byteAddr;
        !           837: 
        !           838:        if(len == 0)
        !           839:                return;
        !           840: 
        !           841:        byteAddr = (UInt8 *) addr;
        !           842:        while(len--)
        !           843:        {
        !           844:                *byteAddr++ = 0;
        !           845:        }
        !           846: }
        !           847: 
        !           848: 
        !           849: void uslUnconfigureDevice(usbDevice *device)
        !           850: {
        !           851:        uslCloseNonDefaultPipes(device);
        !           852:        deallocAllDeviceInterfaces(device->ID);
        !           853:        device->currentConfiguration = 0;
        !           854: }
        !           855: 
        !           856: OSStatus uslDeleteDevice(USBPB *pb, usbDevice *device)
        !           857: {      /* All pipes are closed, kill off the device */
        !           858: OSStatus retVal = noErr;
        !           859: void *allConfDesc;
        !           860: 
        !           861:        if(device->configLock != 0)
        !           862:        {
        !           863:                USBExpertStatusLevel(2, device->ID, "USL - Device busy when deleting: Address ==", device->usbAddress);
        !           864:                device->killMe = true;
        !           865:                if(device->configLock != 0)
        !           866:                {       // Make sure it hasn't been asynchronously unlocked                     
        !           867:                        return(noErr);
        !           868:                }
        !           869:                USBExpertStatusLevel(2, device->ID, "USL - Device no longer busy: Address ==", device->usbAddress);
        !           870:        }
        !           871: 
        !           872:        USBExpertStatusLevel(4, 0, "USL - Deleting device: Address ==", device->usbAddress);
        !           873: 
        !           874:        allConfDesc = device->allConfigDescriptors;
        !           875:        
        !           876:        deallocAllDeviceInterfaces(device->ID);
        !           877:        
        !           878:        /* Zero out the structure, not strictly necessary, but prudent */
        !           879:        /* This bit relies on allConfigDescriptors being the second field after ID */
        !           880:        ZeroMem(&device->allConfigDescriptors, sizeof(usbDevice)-OFFSET(usbDevice, allConfigDescriptors));
        !           881:        
        !           882:        initialiseOneDevice(device);
        !           883: 
        !           884:        if(allConfDesc != nil)
        !           885:        {
        !           886:                if(CurrentExecutionLevel() != kTaskLevel)
        !           887:                {
        !           888:                        if(pb->usbCompletion == kUSBNoCallBack)
        !           889:                        {
        !           890:                                retVal = kUSBCompletionError;
        !           891:                        }
        !           892:                        else
        !           893:                        {
        !           894:                                pb->usbBuffer = allConfDesc;
        !           895:                                retVal = kUSBPending;
        !           896:                                uslDeallocMem(pb);
        !           897:                        }
        !           898:                }
        !           899:                else
        !           900:                {
        !           901:                        PoolDeallocate(device->allConfigDescriptors);
        !           902:                }
        !           903:        }
        !           904: 
        !           905:        return(retVal);
        !           906: }
        !           907: 
        !           908: 
        !           909: /* Given a pipeRef, whats the pipe index? */
        !           910: long recoverPipeIdx(USBPipeRef pipeRef)
        !           911: {
        !           912:        if(pipeRef == 0)
        !           913:        {
        !           914:                return(-1);
        !           915:        }
        !           916:        
        !           917:        return(pipeRef & kUSBPipeIDMask);
        !           918: }
        !           919: 
        !           920: 
        !           921: /* GIven a pipeRef, find the pipe structure */
        !           922: pipe *GetPipePtr(USBPipeRef pipeRef)
        !           923: {
        !           924: pipe *retPipe = nil;
        !           925: long pipeIdx;
        !           926:        do{
        !           927:                pipeIdx = recoverPipeIdx(pipeRef);
        !           928:                if(pipeIdx == -1)
        !           929:                {
        !           930:                        break;
        !           931:                }
        !           932:                
        !           933:                retPipe = &AllPipes[pipeIdx];
        !           934:                
        !           935:                if(pipeRef != retPipe->ref)
        !           936:                {
        !           937:                        retPipe = nil;
        !           938:                        break;
        !           939:                }
        !           940:                
        !           941:        }while(0);
        !           942: 
        !           943:        return(retPipe);
        !           944: }
        !           945: 
        !           946: /* Mark all pipes unused */
        !           947: static void initialisePipes(void)
        !           948: {
        !           949: long index, index2;
        !           950: 
        !           951:        /* Mark all pipes close */
        !           952:        for(index = 0; index < kUSBMaxDevices; index++)
        !           953:        {
        !           954:                for(index2 = 0; index2 < kUSBMaxEndptPerDevice; index2++)
        !           955:                {
        !           956:                        devices[index].pipes[index2] = -1;
        !           957:                }
        !           958:        }
        !           959:        
        !           960:        
        !           961: }
        !           962: #define  kUIMRefID 0x061563
        !           963: /* This needs to take account of bus in some manner */
        !           964: USBDeviceRef addNewDevice(UInt32 bus, UInt16 addr, UInt8 speed, UInt8 maxPacket, UInt32 power)
        !           965: {
        !           966: USBDeviceRef new;
        !           967: usbDevice *dev;
        !           968: long pipeIdx;
        !           969: pipe *pipe0;
        !           970: 
        !           971:        new = 0;
        !           972:        
        !           973:        do{     /* for error checking */
        !           974: 
        !           975:        if( (addr == 0) || (addr > kUSBMaxDevice) )
        !           976:        {
        !           977:                break;
        !           978:        }
        !           979: 
        !           980:        if(UIMControlEDCreate(bus, addr, 0, maxPacket, speed) != noErr)
        !           981:        {
        !           982:                break;
        !           983:        }
        !           984: 
        !           985: 
        !           986:        dev = &devices[addr];
        !           987:        if(dev->ID != 0)
        !           988:        {
        !           989:                break;
        !           990:        }
        !           991:        
        !           992:        do
        !           993:        {
        !           994:                new = MakeDevRef(bus, addr);
        !           995:        }while (new == kUIMRefID);
        !           996:        
        !           997:        dev->bus = bus;
        !           998:        dev->ID = new;
        !           999:        dev->usbAddress = addr;
        !          1000:        dev->speed = speed;
        !          1001:        dev->powerAvailable = power;    
        !          1002:        USBExpertStatusLevel(4, dev->ID, "USL - New device power:", power);
        !          1003: 
        !          1004:        pipeIdx = AllocPipeIdx();
        !          1005:        if(pipeIdx == -1)
        !          1006:        {
        !          1007:                break;
        !          1008:        }       
        !          1009:        dev->pipe0 = pipeIdx;
        !          1010:        pipe0 = &AllPipes[pipeIdx];
        !          1011:        
        !          1012: /* this is repeated with open control endpoint. Should be consolodated */
        !          1013:        pipe0->bus = bus;
        !          1014:        pipe0->devIntfRef = new;
        !          1015:        pipe0->endPt = 0;
        !          1016:        pipe0->ref = MakePipeRef(pipeIdx);
        !          1017:        pipe0->devAddress = addr;
        !          1018:        pipe0->type = kUSBControl;
        !          1019:        pipe0->state = kUSBActive;
        !          1020:        for(pipeIdx = 0; pipeIdx < kUSBMaxEndptPerDevice; pipeIdx++)
        !          1021:        {
        !          1022:                dev->pipes[pipeIdx] = -1;
        !          1023:        }
        !          1024:        
        !          1025:        }while(0);
        !          1026:        
        !          1027:        return(new);
        !          1028: }
        !          1029: 
        !          1030: 
        !          1031: 
        !          1032: /* ************* Functions dealing with transactions ************* */
        !          1033: 
        !          1034: /* Each pipe has a number of possible transactions outstanding */
        !          1035: /* on it at one time. The pipe structure has 2 tables one of the */
        !          1036: /* UIM transaction ref for these and another parallel one which */
        !          1037: /* has the index of the packet its using */
        !          1038: 
        !          1039: 
        !          1040: 
        !          1041: /* ************* Actual Functions ************* */
        !          1042: 
        !          1043: 
        !          1044: 
        !          1045: 
        !          1046: 
        !          1047: USBPipeRef getPipeZero(USBDeviceRef device)
        !          1048: {
        !          1049: usbDevice *deviceP;
        !          1050: pipesIdx pipe0Idx;
        !          1051: USBPipeRef retVal = 0;
        !          1052:        
        !          1053:        /* Validate device */
        !          1054:        deviceP = getDevicePtr(device);
        !          1055:        
        !          1056:        if(deviceP == nil)
        !          1057:        {
        !          1058:                return(0);
        !          1059:        }
        !          1060:        pipe0Idx = deviceP->pipe0;
        !          1061:        if( (pipe0Idx < 0) || (pipe0Idx > kUSBMaxPipes) )
        !          1062:        {
        !          1063:                return(0);
        !          1064:        }
        !          1065:        return(AllPipes[pipe0Idx].ref);         
        !          1066: }
        !          1067: 
        !          1068: 
        !          1069: OSStatus USBServicesInitialise(void *exProc)
        !          1070: {      
        !          1071: kprintf("***USBServicesInitialize:calling severel inits***\n");
        !          1072:        if(initialised)
        !          1073:        {
        !          1074:                return(kUSBAlreadyOpenErr);
        !          1075:        }
        !          1076:        SetExpertFunction(exProc);
        !          1077:        
        !          1078:        initialiseDevices();
        !          1079:        initialisePipes();
        !          1080:        initialiseHubs();
        !          1081:        initialiseDelays();
        !          1082:        initialiseNotifications();
        !          1083: 
        !          1084:        initialised = true;
        !          1085:        
        !          1086:        return(noErr);
        !          1087: }
        !          1088: 
        !          1089: void USBServicesFinalise(void)
        !          1090: {
        !          1091:        if(!initialised)
        !          1092:        {
        !          1093:                return;//(paramErr);
        !          1094:        }
        !          1095:        finaliseHubs();
        !          1096:        finaliseDelays();
        !          1097:        finaliseNotifications();
        !          1098:        
        !          1099:        initialised = false;
        !          1100: }
        !          1101: 
        !          1102: 
        !          1103: Boolean checkPBVersionIsoc(USBPB *pb, UInt32 flags)
        !          1104: {
        !          1105:        if(     ( (pb->pbVersion == 0x109) || (pb->pbVersion == 0x109) )&& 
        !          1106:                (pb->pbLength >= sizeof(USBPB)) &&
        !          1107:                ( (pb->usbCompletion != nil) && (pb->usbCompletion != (void *)-1) ) &&
        !          1108:                ((pb->usbFlags & ~flags) == 0) )
        !          1109:        {
        !          1110:                pb->usbStatus = noErr;
        !          1111:                return(true);
        !          1112:        }
        !          1113:        else
        !          1114:        {
        !          1115:                if((pb->pbVersion != 0x109) && (pb->pbVersion != 0x109) )
        !          1116:                {
        !          1117:                        USBExpertStatusLevel(2, pb->usbReference, "USL error - Bad param block version", pb->pbVersion);
        !          1118:                        pb->usbStatus = kUSBPBVersionError;
        !          1119:                }
        !          1120:                else if(pb->pbLength < sizeof(USBPB)) 
        !          1121:                {
        !          1122:                        USBExpertStatusLevel(2, pb->usbReference, "USL error - small param block version", pb->pbLength);
        !          1123:                        pb->usbStatus = kUSBPBLengthError;
        !          1124:                }
        !          1125:                else if( (pb->usbCompletion == nil) || (pb->usbCompletion == (void *)-1) )
        !          1126:                {
        !          1127:                        USBExpertStatusLevel(2, pb->usbReference, "USL error - bad completion function", (UInt32)pb->usbCompletion);
        !          1128:                        pb->usbStatus = kUSBCompletionError;
        !          1129:                }
        !          1130:                else if((pb->usbFlags & ~flags) != 0)
        !          1131:                {
        !          1132:                        USBExpertStatusLevel(2, pb->usbReference, "USL error - bad flags", pb->usbFlags & ~flags);
        !          1133:                        pb->usbStatus = kUSBFlagsError;
        !          1134:                }
        !          1135:                else
        !          1136:                {
        !          1137:                        USBExpertStatusLevel(2, pb->usbReference, "USL error - What??", 0);
        !          1138:                        pb->usbStatus = paramErr;
        !          1139:                }
        !          1140:                return(false);
        !          1141:        }
        !          1142: }
        !          1143: 
        !          1144: Boolean checkPBVersion(USBPB *pb, UInt32 flags)
        !          1145: {
        !          1146:        if(     ( (pb->pbVersion == 2) || (pb->pbVersion == 0x100) || (pb->pbVersion == 0x109))&& 
        !          1147:                (pb->pbLength >= sizeof(USBPB)) &&
        !          1148:                ( (pb->usbCompletion != nil) && (pb->usbCompletion != (void *)-1) ) &&
        !          1149:                ((pb->usbFlags & ~flags) == 0) )
        !          1150:        {
        !          1151:                pb->usbStatus = noErr;
        !          1152:                return(true);
        !          1153:        }
        !          1154:        else
        !          1155:        {
        !          1156:                if((pb->pbVersion != 2) && (pb->pbVersion != 0x100)  && (pb->pbVersion != 0x109) )
        !          1157:                {
        !          1158:                        USBExpertStatusLevel(2, pb->usbReference, "USL error - Bad param block version", pb->pbVersion);
        !          1159:                        pb->usbStatus = kUSBPBVersionError;
        !          1160:                }
        !          1161:                else if(pb->pbLength < sizeof(USBPB)) 
        !          1162:                {
        !          1163:                        USBExpertStatusLevel(2, pb->usbReference, "USL error - small param block version", pb->pbLength);
        !          1164:                        pb->usbStatus = kUSBPBLengthError;
        !          1165:                }
        !          1166:                else if( (pb->usbCompletion == nil) || (pb->usbCompletion == (void *)-1) )
        !          1167:                {
        !          1168:                        USBExpertStatusLevel(2, pb->usbReference, "USL error - bad completion function", (UInt32)pb->usbCompletion);
        !          1169:                        pb->usbStatus = kUSBCompletionError;
        !          1170:                }
        !          1171:                else if((pb->usbFlags & ~flags) != 0)
        !          1172:                {
        !          1173:                        USBExpertStatusLevel(2, pb->usbReference, "USL error - bad flags", pb->usbFlags & ~flags);
        !          1174:                        pb->usbStatus = kUSBFlagsError;
        !          1175:                }
        !          1176:                else
        !          1177:                {
        !          1178:                        USBExpertStatusLevel(2, pb->usbReference, "USL error - What??", 0);
        !          1179:                        pb->usbStatus = paramErr;
        !          1180:                }
        !          1181:                return(false);
        !          1182:        }
        !          1183: }
        !          1184: 
        !          1185: 
        !          1186: 
        !          1187: UInt8 USBMakeBMRequestType(USBDirection direction, USBRqType type, USBRqRecipient recipient)
        !          1188: {
        !          1189: UInt8 rq = 0xff;
        !          1190:        do{
        !          1191:                if(direction == kUSBNone)
        !          1192:                {
        !          1193:                        direction = kUSBOut;
        !          1194:                }
        !          1195:                if(direction != kUSBOut && direction != kUSBIn)
        !          1196:                {
        !          1197:                        break;
        !          1198:                }
        !          1199:                if(type < kUSBStandard || type > kUSBVendor)
        !          1200:                {
        !          1201:                        break;
        !          1202:                }
        !          1203:                if(recipient < kUSBDevice || recipient > kUSBOther)
        !          1204:                {
        !          1205:                        break;
        !          1206:                }
        !          1207:        
        !          1208:                rq = recipient + (type << kUSBRqTypeShift) + (direction << kUSBRqDirnShift);
        !          1209:        
        !          1210:        }while(0);
        !          1211:        return(rq);
        !          1212: }
        !          1213: 
        !          1214: 
        !          1215: 
        !          1216: OSStatus USBDisposeInterfaceRef(USBPB *pb)
        !          1217: {
        !          1218: //      --> usbReference        --> interface
        !          1219: OSStatus err;
        !          1220: uslInterface *intfrc;
        !          1221: Boolean nocallBack = false;
        !          1222:        
        !          1223:        if(pb->usbCompletion == kUSBNoCallBack)
        !          1224:        {
        !          1225:                nocallBack = true;
        !          1226:                pb->usbCompletion = (void *)-2;
        !          1227:        }
        !          1228:        
        !          1229:        if(!checkPBVersion(pb, 0))
        !          1230:        {
        !          1231:                return(pb->usbStatus);
        !          1232:        }
        !          1233:        err = findInterface(pb->usbReference, &intfrc);
        !          1234:        if(intfrc == nil)
        !          1235:        {
        !          1236:                USBExpertStatusLevel(4, pb->usbReference, "USL - Interface to dispose not found", 0);
        !          1237:                return(kUSBUnknownInterfaceErr);
        !          1238:        }
        !          1239:        intfrc->device = 0;
        !          1240:        intfrc->interfaceNum = 0;
        !          1241:        intfrc->alt = 0;
        !          1242:        intfrc->ref = 0;
        !          1243:        
        !          1244:        if(nocallBack)
        !          1245:        {
        !          1246:                pb->usbCompletion = kUSBNoCallBack;
        !          1247:        }
        !          1248:        else
        !          1249:        {
        !          1250:                (*pb->usbCompletion)(pb);
        !          1251:        }
        !          1252:        return(kUSBPending);
        !          1253: }
        !          1254: 

unix.superglobalmegacorp.com

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