Annotation of kernel/bsd/dev/ppc/drvUSBCMD/CompositeClassDriver/CompositeClassDriver.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:           CompositeClassDriver.c
                     27: 
                     28:        Contains:       Core functionality to Composite Class Driver
                     29: 
                     30:        Version:        xxx put version here xxx
                     31: 
                     32:        Copyright:      � 1997-1998 by Apple Computer, Inc., all rights reserved.
                     33: 
                     34:        File Ownership:
                     35: 
                     36:                DRI:                            Craig Keithley
                     37: 
                     38:                Other Contact:          xxx put other contact here xxx
                     39: 
                     40:                Technology:                     xxx put technology here xxx
                     41: 
                     42:        Writers:
                     43: 
                     44:                (DF)    David Ferguson
                     45:                (BT)    Barry Twycross
                     46:                (CJK)   Craig Keithley
                     47: 
                     48:        Change History (most recent first):
                     49: 
                     50:         <USB12>         8/25/98        BT              Isoc name changes
                     51:         <USB11>         8/11/98        CJK             add error checking to GetInterfaceDescriptor.  If
                     52:                                                                        GetInterfaceDescriptor has a problem then the Composite class
                     53:                                                                        driver won't try to load an interface driver for the device.
                     54:         <USB10>         6/11/98        CJK             add reserved params to USBExpertSetDevicePowerStatus. Wanted to
                     55:                                                                        get it into the USB.i before freezing C1. pass 0 for right now.
                     56:          <USB9>          6/8/98        CJK             add check of power required against power available
                     57:          <USB8>          6/6/98        DF              Increment the InterfaceIndex before checking to see if it's
                     58:                                                                        valid, pass the deviceRef to InstallInterfaceDriver
                     59:          <USB7>          6/5/98        CJK             implement finalize routine (which disposes of the interface refs
                     60:                                                                        and removes the interface drivers)
                     61:          <USB6>         5/20/98        BT              Set pbVersion correctly
                     62:          <USB5>         5/12/98        BT              New name for add interface
                     63:          <USB4>          5/2/98        DF              use pascal strings for errors
                     64:          <USB3>          4/9/98        CJK             change to use USB.h
                     65:          <USB2>          4/9/98        DF              Massaged to work with MasterInterfaces
                     66:                 <1>      4/7/98        CJK             first checked in
                     67:                <36>     3/31/98        CJK             start out at config 0
                     68:                <35>     3/27/98        CJK             set default config to be 1, then step back to 0, if that doesn't
                     69:                                                                        work.
                     70:                <34>     3/26/98        CJK             check for config #0 & config #1 when setting up the Composite
                     71:                                                                        device.  Some devices respond to 1, others to 0.
                     72:                <33>     3/17/98        CJK             Replace "};" with just "}". Used ExtractPrototypes to create
                     73:                                                                        function prototypes for this file (placed the in the header
                     74:                                                                        files).
                     75:                <32>     2/26/98        CJK             change to use USL's GetFullConfiguration function.
                     76:                <31>     2/17/98        CJK             replace debugstrs with notify expert calls.
                     77:                <30>     2/17/98        CJK             Change get configuration to byte swap the length
                     78:                <29>     2/10/98        CJK             Change call to USBExpertNewDevice to use the USL's add interface
                     79:                                                                        call.
                     80:                <28>      2/9/98        CJK             add back in set configuration
                     81:                <27>      2/9/98        CJK             remove HID Emulation related items (no more include of
                     82:                                                                        HIDEmulation.h, etc.)
                     83:                <26>      2/9/98        CJK             remove unneeded HID support. Now in mouse & keyboard modules.
                     84:                                                                        The add new interface call now properly loads the HID Modules
                     85:                                                                        for mouse & keyboard.
                     86:                <25>      2/8/98        BT              Power allocation stuff
                     87:                <24>      2/6/98        CJK             add call to InitUSBKeyboard.  (Disabled for now)
                     88:                <23>      2/6/98        CJK             Crank delay back down to 10ms.
                     89:                <22>      2/4/98        BT              Add ref/port info to expert notify]
                     90:                <21>      2/3/98        CJK             Change set configuration USB Direction to "USBOut". Changed
                     91:                                                                        sequence of states to be "get configuration, set configuration,
                     92:                                                                        set protocol, get HID descriptor"
                     93:                <20>      2/2/98        CJK             change retry to simply abort if limit is reached.  Also changed
                     94:                                                                        sequence of getting the configuration data & then setting the
                     95:                                                                        selected configuration.  Used to do a set configuration before
                     96:                                                                        reading the first one.
                     97:                <19>      2/2/98        CJK             change readhidreport state to only copy the new hid data to the
                     98:                                                                        old hid data *after* doing a hid notification.
                     99:                <18>     1/30/98        CJK             rework test for mouse/keyboard device types
                    100:                <17>     1/27/98        CJK             Fixed change history... Previously said something about
                    101:                                                                        commenting out code
                    102:                <16>     1/27/98        CJK             Work on interface set protocol & get report handling.  Wasn't
                    103:                                                                        setting the direction or target properly.
                    104:                <15>     1/26/98        CJK             Add call to USBExpertNewDevice routine
                    105:                <14>     1/26/98        BT              Mangle names after design review
                    106:                <13>     1/23/98        CJK             Change to use USBServicesLib USBDelay function.
                    107:                <12>     1/23/98        CJK             Implement HID data change detection
                    108:                <11>     1/23/98        CJK             Add call to configuration parser.
                    109:                <10>     1/22/98        CJK             Work on get configuration code.
                    110:                 <9>     1/22/98        CJK             Change state tag to async operation
                    111:                 <8>     1/20/98        CJK             Add states to handle reading the configuration (both the base
                    112:                                                                        size and full size).
                    113:                 <7>     1/15/98        CJK             Change ClassDrivers.h to USBClassDrivers.h
                    114:                 <6>     1/14/98        BT              Remove superceded expert stuff
                    115:                 <5>     1/14/98        CJK             Add setup of version field
                    116:                 <4>      1/8/98        CJK             Moved initialize & finalize routines over to
                    117:                                                                        CompositeClassDescription.c
                    118:                 <3>      1/6/98        CJK             Add tasktime and expert entry procs
                    119:                 <2>    12/17/97        CJK             Add basic functionality for mouse and keyboard.
                    120:                 <1>    12/17/97        CJK             First time checkin
                    121: */
                    122: 
                    123: //naga#include "../types.h"
                    124: //naga#include "../devices.h"
                    125: //naga#include "../processes.h"
                    126: #include "../driverservices.h"
                    127: #include "../USB.h"
                    128: 
                    129: #include "CompositeClassDriver.h"
                    130: extern usbCompositePBStruct myCompositePBRecord;
                    131: 
                    132: 
                    133: void InitParamBlock(USBDeviceRef theDeviceRef, USBPB * paramblock)
                    134: {
                    135:        paramblock->usbReference = theDeviceRef;
                    136:        paramblock->usbCompletion = (USBCompletion)CompositeDeviceCompletionProc;
                    137:        paramblock->pbLength = sizeof(usbCompositePBStruct);
                    138:        paramblock->pbVersion = kUSBCurrentPBVersion;
                    139:        paramblock->usb.cntl.WIndex = 0;                        
                    140:        paramblock->usbBuffer = nil;            
                    141:        paramblock->usbStatus = kUSBNoErr;
                    142:        paramblock->usbReqCount = 0;
                    143:        paramblock->usbActCount = 0;
                    144:        paramblock->usb.cntl.WValue = 0;
                    145:        paramblock->usbFlags = 0;
                    146: }
                    147: 
                    148: 
                    149: static Boolean immediateError(OSStatus err)
                    150: {
                    151:        return((err != kUSBPending) && (err != kUSBNoErr) );
                    152: }
                    153: 
                    154: void CompositeDeviceInitiateTransaction(USBPB *pb)
                    155: {
                    156: register usbCompositePBStruct *pCompositePB;
                    157: OSStatus myErr;
                    158: 
                    159:        pCompositePB = (usbCompositePBStruct *)(pb);
                    160:        pCompositePB->transDepth++;
                    161:        if ((pCompositePB->transDepth < 0) || (pCompositePB->transDepth > 1))
                    162:        {
                    163:        
                    164:                USBExpertFatalError(pCompositePB->pb.usbReference, kUSBInternalErr, "Composite Driver: Illegal Transaction Depth", pCompositePB->pb.usbRefcon);
                    165:        }
                    166:        do 
                    167:        {
                    168:                switch(pCompositePB->pb.usbRefcon & ~kRetryTransaction)
                    169:                {
                    170:                        case kGetFullConfiguration0:
                    171:                                InitParamBlock(pCompositePB->deviceRef, &pCompositePB->pb);
                    172:                                pCompositePB->pb.usb.cntl.WIndex = 0;                   /* First try configuration 0, if it doesn't succeed, then try config 1*/
                    173:                                
                    174:                                pCompositePB->pb.usbRefcon |= kCompletionPending;
                    175:                                pCompositePB->pb.usbCompletion = (USBCompletion)CompositeDeviceCompletionProc;
                    176:                                myErr = USBGetFullConfigurationDescriptor(pb);
                    177:                                if(immediateError(myErr))
                    178:                                {
                    179:                                        USBExpertFatalError(pCompositePB->pb.usbReference, kUSBInternalErr, "Composite Driver: USBGetFullConfiguration (#0) - immediate error", myErr);
                    180:                                }
                    181:                                break;
                    182:                        
                    183:                        case kGetFullConfiguration1:
                    184:                                InitParamBlock(pCompositePB->deviceRef, &pCompositePB->pb);
                    185:                                pCompositePB->pb.usb.cntl.WIndex = 1;                   /* Try configuration 1 (some devices seem to expect config 0, others config 1 */
                    186:                                pCompositePB->pb.usbRefcon |= kCompletionPending;
                    187:                                
                    188:                                pCompositePB->pb.usbCompletion = (USBCompletion)CompositeDeviceCompletionProc;
                    189:                                myErr = USBGetFullConfigurationDescriptor(pb);
                    190:                                if(immediateError(myErr))
                    191:                                {
                    192:                                        USBExpertFatalError(pCompositePB->pb.usbReference, kUSBInternalErr, "Composite Driver: USBGetFullConfiguration (#1) - immediate error", myErr);
                    193:                                }
                    194:                                break;
                    195:                        
                    196:                        case kSetConfig:
                    197:                                InitParamBlock(pCompositePB->deviceRef, &pCompositePB->pb);
                    198:                                pCompositePB->pb.usb.cntl.BMRequestType = USBMakeBMRequestType(kUSBOut, kUSBStandard, kUSBDevice);
                    199:                                
                    200:                                pCompositePB->pb.usb.cntl.BRequest = kUSBRqSetConfig;
                    201:                                pCompositePB->pb.usb.cntl.WValue = pCompositePB->pFullConfigDescriptor->configValue;            /* Use configuration ID value from descriptor */
                    202:                                
                    203:                                pCompositePB->pb.usbRefcon |= kCompletionPending;
                    204:                                
                    205:                                pCompositePB->pb.usbCompletion = (USBCompletion)CompositeDeviceCompletionProc;
                    206:                                myErr = USBDeviceRequest(pb);
                    207:                                if(immediateError(myErr))
                    208:                                {
                    209:                                        USBExpertFatalError(pCompositePB->pb.usbReference, kUSBInternalErr, "Composite Driver: kSetConfig - immediate error", myErr);
                    210:                                }
                    211:                                break;
                    212:                                
                    213:                        case kNewInterfaceRef:
                    214:                                InitParamBlock(pCompositePB->deviceRef, &pCompositePB->pb);
                    215:                                // Note: pCompositePB->usb.cntl.WIndex will be set to zero by InitParamBlock
                    216:                                // so set it again to pCompositePB->interfaceIndex before calling USBNewInterfaceRef
                    217:                                pCompositePB->pb.usb.cntl.WIndex = pCompositePB->interfaceIndex;
                    218:                                pCompositePB->pb.usbRefcon |= kCompletionPending;
                    219:                                pCompositePB->pb.usbCompletion = (USBCompletion)CompositeDeviceCompletionProc;
                    220: 
                    221:                                myErr = USBNewInterfaceRef(pb);
                    222:                                if(immediateError(myErr))
                    223:                                {
                    224:                                        USBExpertFatalError(pCompositePB->pb.usbReference, kUSBInternalErr, "Composite Driver: kNewInterfaceRef - immediate error", myErr);
                    225:                                }
                    226:                                break;
                    227:                                
                    228:                        default:
                    229:                                USBExpertFatalError(pCompositePB->pb.usbReference, kUSBInternalErr, "Composite Driver - Transaction initiated with bad refcon value", pCompositePB->pb.usbRefcon);
                    230:                                pCompositePB->pb.usbRefcon = kUndefined + kExitDriver;
                    231:                                break;
                    232:                }
                    233:        } while (false);
                    234:        
                    235: // At this point the control is returned to the system.  If a USB transaction
                    236: // has been initiated, then it will call the Complete procs
                    237: // (below) to handle the results of the transaction.
                    238: }
                    239: 
                    240: void CompositeDeviceCompletionProc(USBPB *pb)
                    241: {
                    242: OSStatus myErr;
                    243: register usbCompositePBStruct *pCompositePB;
                    244: USBInterfaceDescriptorPtr pInterfaceDescriptor;
                    245: UInt32 i;
                    246: 
                    247:        pCompositePB = (usbCompositePBStruct *)(pb);
                    248:        pCompositePB->transDepth--;
                    249:        if ((pCompositePB->transDepth < 0) || (pCompositePB->transDepth > 1))
                    250:        {
                    251:                USBExpertFatalError(pCompositePB->pb.usbReference, kUSBInternalErr, "Composite Driver - Illegal Transaction Depth", pCompositePB->transDepth);
                    252:        }
                    253:        
                    254:        if((pCompositePB->pb.usbStatus != kUSBNoErr) && (pCompositePB->pb.usbStatus != kUSBPending))
                    255:        {
                    256:                USBExpertStatus(pCompositePB->pb.usbReference, "Composite Driver: Completion Error", pCompositePB->pb.usbStatus);
                    257:                pCompositePB->pb.usbRefcon &= ~(kCompletionPending + kExitDriver);
                    258:                pCompositePB->pb.usbRefcon |= kRetryTransaction;
                    259:                pCompositePB->retryCount--;
                    260:                if (!pCompositePB->retryCount)
                    261:                {
                    262:                        if (pCompositePB->pb.usbRefcon == kGetFullConfiguration1)
                    263:                        {
                    264:                                pCompositePB->pb.usbRefcon = kGetFullConfiguration0;
                    265:                        }
                    266:                        else
                    267:                        {
                    268:                                USBExpertFatalError(pCompositePB->pb.usbReference, kUSBInternalErr, "Composite Driver: Too many retries", pCompositePB->pb.usbRefcon);
                    269:                                pCompositePB->pb.usbRefcon = kExitDriver;
                    270:                                return;
                    271:                        }
                    272:                }
                    273:        }
                    274:        else
                    275:        {
                    276:                pCompositePB->pb.usbRefcon &= ~kRetryTransaction;
                    277:                pCompositePB->retryCount = kCompositeRetryCount;
                    278:        }
                    279: 
                    280:        if (pCompositePB->pb.usbRefcon & kCompletionPending)                     
                    281:        {                                                                                               
                    282:                pCompositePB->pb.usbRefcon &= ~(kCompletionPending + kExitDriver);
                    283:                switch(pCompositePB->pb.usbRefcon)
                    284:                {
                    285:                        case kGetFullConfiguration0:
                    286:                        case kGetFullConfiguration1:
                    287: //                             DebugStr("Check power");
                    288:                                pCompositePB->pFullConfigDescriptor = pCompositePB->pb.usbBuffer;
                    289:                                if (pCompositePB->pFullConfigDescriptor == nil)
                    290:                                {
                    291:                                        USBExpertFatalError(pCompositePB->pb.usbReference, kUSBInternalErr, "Composite Driver: USBGetFullConfiguration - pointer is nil", pCompositePB->pb.usbRefcon);
                    292:                                        pCompositePB->pb.usbRefcon = kExitDriver;
                    293:                                        break;
                    294:                                }
                    295:                                
                    296:                                BlockCopy(   (void *)pCompositePB->pFullConfigDescriptor, (void *)(&(pCompositePB->partialConfigDescriptor)), (Size)(sizeof(USBConfigurationDescriptor) )  );
                    297:                                if (pCompositePB->pFullConfigDescriptor->maxPower <= pCompositePB->busPowerAvailable)
                    298:                                {
                    299:                                        pCompositePB->pb.usbRefcon = kSetConfig;
                    300:                                }
                    301:                                else
                    302:                                {
                    303:                                        USBExpertSetDevicePowerStatus(pCompositePB->pb.usbReference, 0, 0, kUSBDevicePower_BusPowerInsufficient, pCompositePB->busPowerAvailable, pCompositePB->pFullConfigDescriptor->maxPower);
                    304:                                        USBExpertFatalError(pCompositePB->pb.usbReference, kUSBDevicePowerProblem, "Composite Driver - Insufficient power for device", pCompositePB->pb.usbRefcon);
                    305:                                        pCompositePB->pb.usbRefcon = kExitDriver;
                    306:                                }
                    307:                                break;
                    308:                                
                    309:                        case kSetConfig:                        /* get all the interface descriptors and save them */
                    310:                                for (i=0; i < pCompositePB->partialConfigDescriptor.numInterfaces; i++)
                    311:                                {
                    312:                                        pCompositePB->interfaceRefArray[i] = 0;
                    313:                                        myErr = GetInterfaceDescriptor(pCompositePB->pFullConfigDescriptor, (UInt32)i, &pInterfaceDescriptor);
                    314:                                        if (kUSBNoErr == myErr)
                    315:                                        {
                    316:                                                BlockCopy((void *)pInterfaceDescriptor, (void *)(&(pCompositePB->interfaceDescriptors[i])), (Size)(pInterfaceDescriptor->length));
                    317:                                        }
                    318:                                        else                            /* if GetInterfaceDescriptor returned an error, then set the length to zero (so we know later) */
                    319:                                        {
                    320:                                                pCompositePB->interfaceDescriptors[i].length = 0;
                    321:                                        }
                    322:                                }
                    323:                                pCompositePB->interfaceIndex = 0;
                    324:                                pCompositePB->interfaceCount = pCompositePB->partialConfigDescriptor.numInterfaces;
                    325:                                pCompositePB->pb.usbRefcon = kNewInterfaceRef;
                    326:                                break;
                    327:                                
                    328:                        case kNewInterfaceRef:
                    329:                                /* save the new interface ref for this interface */
                    330:                                pCompositePB->interfaceRefArray[pCompositePB->interfaceIndex] = pCompositePB->pb.usbReference;
                    331:                                
                    332:                                /* only install the interface driver if we had a valid interface descriptor */
                    333:                                if (pCompositePB->interfaceDescriptors[pCompositePB->interfaceIndex].length != 0)
                    334:                                {
                    335:                                        USBExpertInstallInterfaceDriver(pCompositePB->interfaceRefArray[pCompositePB->interfaceIndex], &pCompositePB->deviceDescriptor, &pCompositePB->interfaceDescriptors[pCompositePB->interfaceIndex], pCompositePB->deviceRef, 0);
                    336:                                }
                    337:                                
                    338:                                /* advance to the next interface */
                    339:                                pCompositePB->interfaceIndex++;
                    340:                                
                    341:                                /* if there's more interfaces, then just keep cycling through kNewInterfaceRef */
                    342:                                if (pCompositePB->interfaceIndex < pCompositePB->interfaceCount)
                    343:                                {
                    344:                                        pCompositePB->pb.usbRefcon = kNewInterfaceRef;
                    345:                                }
                    346:                                else
                    347:                                {
                    348:                                        pCompositePB->pb.usbRefcon = kExitDriver;
                    349:                                }
                    350:                                break;
                    351:                        
                    352:                        default:
                    353:                                USBExpertFatalError(pCompositePB->pb.usbReference, kUSBInternalErr, "Composite Driver - Transaction completed with a bad refcon value", pCompositePB->pb.usbRefcon);
                    354:                                pCompositePB->pb.usbRefcon = kExitDriver;
                    355:                                break;
                    356:                }
                    357:        }
                    358:        if (!(pCompositePB->pb.usbRefcon & kExitDriver))
                    359:                CompositeDeviceInitiateTransaction(pb);
                    360: 
                    361:        pCompositePB->okayToFinalizeFlag = true;
                    362:        pCompositePB->disposeCompletedFlag = true;
                    363: }
                    364: 
                    365: 

unix.superglobalmegacorp.com

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