Annotation of kernel/bsd/dev/ppc/drvUSBCMD/CompositeClassDriver/CompositeClassDriver.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:           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.