Annotation of kernel/bsd/dev/ppc/drvUSBCMD/Library/uslpipe.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:           uslPipe.c
        !            27: 
        !            28:        Contains:       xxx put contents here xxx
        !            29: 
        !            30:        Version:        xxx put version here xxx
        !            31: 
        !            32:        Copyright:      � 1998 by Apple Computer, Inc., all rights reserved.
        !            33: 
        !            34:        File Ownership:
        !            35: 
        !            36:                DRI:                            xxx put dri here xxx
        !            37: 
        !            38:                Other Contact:          xxx put other contact here xxx
        !            39: 
        !            40:                Technology:                     xxx put technology here xxx
        !            41: 
        !            42:        Writers:
        !            43: 
        !            44:                (BT)    Barry Twycross
        !            45: 
        !            46:        Change History (most recent first):
        !            47: 
        !            48:         <USB16>        10/22/98        BT              Fix wrong status for deleted devices.
        !            49:         <USB15>        10/12/98        BT              Add addressed device request
        !            50:         <USB14>         9/29/98        BT              Use real frame timing
        !            51:         <USB13>         8/31/98        BT              Add isoc pipes
        !            52:         <USB12>         8/25/98        BT              Isoc name changes
        !            53:         <USB11>         8/24/98        BT              Isoc param block definition
        !            54:         <USB10>         8/13/98        BT              Add multibus support
        !            55:          <USB9>         8/13/98        BT              Allow zero length transactions
        !            56:          <USB8>         7/23/98        BT              Cut annoying message
        !            57:          <USB7>          7/7/98        BT              Avoid control reentrancy problem by making sure they're done at
        !            58:                                                                        secondary interrupt time.
        !            59:          <USB6>         5/21/98        BT              Don't corrupt usbBuffer when diverting to opendevice.
        !            60:          <USB5>         5/20/98        BT              Find implicit dev config
        !            61:          <USB4>         5/20/98        BT              Fix pipe devidx field
        !            62:          <USB3>         5/17/98        BT              Device request doesn't squash reqcount, buffer. Add internal
        !            63:                                                                        open pipe for config interface
        !            64:          <USB2>         4/28/98        BT              Add bulk performance monitoring.
        !            65:          <USB1>         4/26/98        BT              first checked in
        !            66: */
        !            67: 
        !            68: #include "../USB.h"
        !            69: #include "../USBpriv.h"
        !            70: 
        !            71: #include "uslpriv.h"
        !            72: #include "../uimpriv.h"
        !            73: 
        !            74: #include "../driverservices.h"
        !            75: 
        !            76: static pipe pipeZeroZero;      // the default pipe to device zero 
        !            77: 
        !            78: #if 0
        !            79: static OSStatus uslOpenControlEndpoint(struct USBPB *pb)
        !            80: {
        !            81: usbDevice *deviceP;
        !            82: OSStatus retVal = kUSBInternalErr;
        !            83: pipe *newPipe;
        !            84: 
        !            85:        do{     /* For error recovery */
        !            86:        
        !            87:                /* Validate device */
        !            88:                deviceP = getDevicePtr(pb->usbReference);
        !            89:                
        !            90:                if(deviceP == nil)
        !            91:                {
        !            92:                        retVal = kUSBUnknownDeviceErr;
        !            93:                        break;
        !            94:                }
        !            95:        
        !            96: #if 0
        !            97:                /* Validate endpoint */
        !            98:                if(deviceP->numberOfEndpoints >= endpoint)
        !            99:                {
        !           100:                        retVal = kUSBUnknownEndpointErr;
        !           101:                        break;
        !           102:                }
        !           103: #endif
        !           104: 
        !           105:                newPipe = getPipe(deviceP, pb->usbValue2);
        !           106:                
        !           107:                if(newPipe != nil)
        !           108:                {
        !           109:                        retVal = kUSBAlreadyOpenErr;
        !           110:                        break;
        !           111:                }
        !           112: 
        !           113:                /* This endpoint has not yet been opened. */
        !           114:                if(pb->usbValue2 == 0)  /* Endpoint zero is a control endpoint */
        !           115:                {
        !           116:                        retVal = kUSBUnknownEndpointErr;
        !           117:                        break;
        !           118:                }
        !           119: 
        !           120: 
        !           121:                /* Allocate a new pipe */
        !           122:                newPipe = AllocPipe(deviceP, pb->usbValue2);
        !           123:                if(newPipe == nil)
        !           124:                {
        !           125:                        retVal = kUSBTooManyPipesErr;
        !           126:                        break;
        !           127:                }
        !           128:                /* Fill in pertinent information for this pipe instantiation */
        !           129:                newPipe->deviceIdx = makeDeviceIdx(pb->usbReference);
        !           130:                newPipe->intrfc = pb->usbReference;
        !           131:                newPipe->endPt = pb->usbValue2;
        !           132:                newPipe->devAddress = deviceP->usbAddress;
        !           133:                newPipe->flags = pb->usbFlags;
        !           134: 
        !           135: #if 0
        !           136:                retVal = UIMSetupControlEndpoint(newPipe->addEnd, &newPipe->uimRef, 
        !           137:                                        newPipe->maxPacket, controlCallBack, newPipe->iflags, newPipe->addEnd /* refCon */);
        !           138: #endif
        !           139: 
        !           140:                if(retVal != kUSBNoErr)
        !           141:                {
        !           142:                        deallocPipe(deviceP, pb->usbValue2);
        !           143:                        break;
        !           144:                }
        !           145: 
        !           146: 
        !           147:                pb->usbReference = newPipe->ref;
        !           148: 
        !           149:                /* Just assume you can have an endpoint zero for now. */
        !           150:                /* Shouldn't this be already open */
        !           151: 
        !           152: #if 0  
        !           153:                /* XXXXXXXX In real version should add something here */
        !           154:                if(pipeH->type != kUSBControlType)
        !           155:                {
        !           156:                        retVal = kUSBIncorrectTypeErr;
        !           157:                        break;
        !           158:                }
        !           159: #endif
        !           160:        
        !           161:                
        !           162:                retVal = kUSBNoErr;
        !           163: 
        !           164:                break;
        !           165:        }while(0); /* End error checking */
        !           166:        
        !           167:        return(retVal);
        !           168: }
        !           169: #endif
        !           170: 
        !           171: static OSStatus uslOpenInterruptEndpoint(USBPB *pb)
        !           172: {
        !           173: usbDevice *deviceP;
        !           174: OSStatus retVal = kUSBInternalErr;
        !           175: pipe *newPipe;
        !           176: 
        !           177:        do{     /* For error recovery */
        !           178:        
        !           179:                /* Validate device */
        !           180:                deviceP = getDevicePtr(pb->usbReference);
        !           181:                
        !           182:                if(deviceP == nil)
        !           183:                {
        !           184:                        retVal = kUSBUnknownDeviceErr;
        !           185:                        break;
        !           186:                }
        !           187:        
        !           188: #if 0
        !           189:                /* Validate endpoint */
        !           190:                if(deviceP->numberOfEndpoints >= endpoint)
        !           191:                {
        !           192:                        retVal = kUSBUnknownEndpointErr;
        !           193:                        break;
        !           194:                }
        !           195: #endif
        !           196: 
        !           197:                newPipe = getPipe(deviceP, pb->usbOther, kUSBIn);
        !           198:                
        !           199:                if(newPipe != nil)
        !           200:                {
        !           201:                        retVal = kUSBAlreadyOpenErr;
        !           202:                        break;
        !           203:                }
        !           204: 
        !           205:                /* This endpoint has not yet been opened. */
        !           206:                if(pb->usbOther == 0)   /* Int pipe can't be zero */
        !           207:                {
        !           208:                        retVal = kUSBIncorrectTypeErr;
        !           209:                        break;
        !           210:                }
        !           211: 
        !           212: 
        !           213:                /* Allocate a new pipe */
        !           214:                newPipe = AllocPipe(deviceP, pb->usbOther, kUSBIn);
        !           215:                if(newPipe == nil)
        !           216:                {
        !           217:                        retVal = kUSBTooManyPipesErr;
        !           218:                        break;
        !           219:                }
        !           220: 
        !           221:                /* Fill in pertinent information for this pipe instantiation */
        !           222:                newPipe->bus = deviceP->bus;
        !           223:                newPipe->devIntfRef = pb->usbReference;
        !           224:                newPipe->endPt = pb->usbOther;
        !           225:                newPipe->direction = kUSBIn;
        !           226:                newPipe->devAddress = deviceP->usbAddress;
        !           227:                newPipe->flags = pb->usbFlags;
        !           228:                newPipe->type = kUSBInterrupt;
        !           229:                newPipe->maxPacket = pb->usb.cntl.WValue;
        !           230:                pb->usbReference = 0;
        !           231:                
        !           232:                retVal = UIMInterruptEDCreate(newPipe->bus,
        !           233:                                        newPipe->devAddress, 
        !           234:                                        pb->usbOther,   /* User gives Endpoint number here */
        !           235:                                        pb->usb.cntl.WValue,    /* System fills in Max packet size here */
        !           236:                                        deviceP->speed);
        !           237: 
        !           238:                pb->usbStatus = retVal;
        !           239:                if(retVal != kUSBNoErr)
        !           240:                {
        !           241:                        deallocPipe(deviceP, pb->usbOther, kUSBIn);
        !           242:                        break;
        !           243:                }
        !           244: 
        !           245:                pb->usbReference = newPipe->ref;        
        !           246:                if(pb->usbCompletion != nil)
        !           247:                {
        !           248:                        (*pb->usbCompletion)(pb);
        !           249:                }
        !           250: 
        !           251:                break;
        !           252:        }while(0); /* End error checking */
        !           253:        
        !           254:        return(retVal);
        !           255: }
        !           256: 
        !           257: 
        !           258: static OSStatus uslOpenIsocEndpoint(USBPB *pb)
        !           259: {
        !           260: usbDevice *deviceP;
        !           261: OSStatus retVal = kUSBInternalErr;
        !           262: pipe *newPipe;
        !           263: USBDirection usbDirection;
        !           264: 
        !           265:        do{     /* For error recovery */
        !           266:        
        !           267:                /* Validate device */
        !           268:                deviceP = getDevicePtr(pb->usbReference);
        !           269:                
        !           270:                if(deviceP == nil)
        !           271:                {
        !           272:                        retVal = kUSBUnknownDeviceErr;
        !           273:                        break;
        !           274:                }
        !           275:        
        !           276: #if 0
        !           277:                /* Validate endpoint */
        !           278:                if(deviceP->numberOfEndpoints >= endpoint)
        !           279:                {
        !           280:                        retVal = kUSBUnknownEndpointErr;
        !           281:                        break;
        !           282:                }
        !           283: #endif
        !           284: 
        !           285:                usbDirection = pb->usbFlags & 0xff;
        !           286:                newPipe = getPipe(deviceP, pb->usbOther, usbDirection);
        !           287:                
        !           288:                if(newPipe != nil)
        !           289:                {
        !           290:                        retVal = kUSBAlreadyOpenErr;
        !           291:                        break;
        !           292:                }
        !           293: 
        !           294:                /* This endpoint has not yet been opened. */
        !           295:                if(pb->usbOther == 0)   /* Isoc pipe can't be zero */
        !           296:                {
        !           297:                        retVal = kUSBIncorrectTypeErr;
        !           298:                        break;
        !           299:                }
        !           300: 
        !           301: 
        !           302:                /* Allocate a new pipe */
        !           303:                newPipe = AllocPipe(deviceP, pb->usbOther, usbDirection);
        !           304:                if(newPipe == nil)
        !           305:                {
        !           306:                        retVal = kUSBTooManyPipesErr;
        !           307:                        break;
        !           308:                }
        !           309: 
        !           310:                /* Fill in pertinent information for this pipe instantiation */
        !           311:                newPipe->bus = deviceP->bus;
        !           312:                newPipe->devIntfRef = pb->usbReference;
        !           313:                newPipe->endPt = pb->usbOther;
        !           314:                newPipe->direction = usbDirection;
        !           315:                newPipe->devAddress = deviceP->usbAddress;
        !           316:                newPipe->flags = pb->usbFlags;
        !           317:                newPipe->type = kUSBIsoc;
        !           318:                newPipe->maxPacket = pb->usb.cntl.WValue;
        !           319:                pb->usbReference = 0;
        !           320:                
        !           321:                retVal = UIMIsocEDCreate(newPipe->bus,
        !           322:                                        newPipe->devAddress, 
        !           323:                                        pb->usbOther,                   /* User gives Endpoint number here */
        !           324:                                        usbDirection,
        !           325:                                        pb->usb.cntl.WValue);   /* System fills in Max packet size here */
        !           326: 
        !           327:                pb->usbStatus = retVal;
        !           328:                if(retVal != kUSBNoErr)
        !           329:                {
        !           330:                        deallocPipe(deviceP, pb->usbOther, usbDirection);
        !           331:                        break;
        !           332:                }
        !           333: 
        !           334:                pb->usbReference = newPipe->ref;        
        !           335:                if(pb->usbCompletion != nil)
        !           336:                {
        !           337:                        (*pb->usbCompletion)(pb);
        !           338:                }
        !           339: 
        !           340:                break;
        !           341:        }while(0); /* End error checking */
        !           342:        
        !           343:        return(retVal);
        !           344: }
        !           345: 
        !           346: 
        !           347: static OSStatus uslOpenBulkEndpoint(USBPB *pb)
        !           348: {
        !           349: usbDevice *deviceP;
        !           350: OSStatus retVal = kUSBInternalErr;
        !           351: pipe *newPipe;
        !           352: USBDirection usbDirection;
        !           353: 
        !           354:        do{     /* For error recovery */
        !           355:        
        !           356:                /* Validate device */
        !           357:                deviceP = getDevicePtr(pb->usbReference);
        !           358:                
        !           359:                if(deviceP == nil)
        !           360:                {
        !           361:                        retVal = kUSBUnknownDeviceErr;
        !           362:                        break;
        !           363:                }
        !           364:        
        !           365: #if 0
        !           366:                /* Validate endpoint */
        !           367:                if(deviceP->numberOfEndpoints >= endpoint)
        !           368:                {
        !           369:                        retVal = kUSBUnknownEndpointErr;
        !           370:                        break;
        !           371:                }
        !           372: #endif
        !           373:                
        !           374:                usbDirection = pb->usbFlags & 0xff;
        !           375:                
        !           376:                newPipe = getPipe(deviceP, pb->usbOther, usbDirection);
        !           377:                
        !           378:                if(newPipe != nil)
        !           379:                {
        !           380:                        retVal = kUSBAlreadyOpenErr;
        !           381:                        break;
        !           382:                }
        !           383: 
        !           384:                /* This endpoint has not yet been opened. */
        !           385:                if(pb->usbOther == 0)   /* Not default pipe */
        !           386:                {
        !           387:                        retVal = kUSBIncorrectTypeErr;
        !           388:                        break;
        !           389:                }
        !           390: 
        !           391: 
        !           392:                /* Allocate a new pipe */
        !           393:                newPipe = AllocPipe(deviceP, pb->usbOther, usbDirection );
        !           394:                if(newPipe == nil)
        !           395:                {
        !           396:                        retVal = kUSBTooManyPipesErr;
        !           397:                        break;
        !           398:                }
        !           399:                /* Fill in pertinent information for this pipe instantiation */
        !           400:                newPipe->bus = deviceP->bus;
        !           401:                newPipe->devIntfRef = pb->usbReference;
        !           402:                newPipe->endPt = pb->usbOther;
        !           403:                newPipe->direction = usbDirection;
        !           404:                newPipe->devAddress = deviceP->usbAddress;
        !           405:                newPipe->flags = pb->usbFlags;
        !           406:                newPipe->type = kUSBBulk;
        !           407:                newPipe->maxPacket = pb->usb.cntl.WValue;
        !           408: 
        !           409:                retVal = UIMBulkEDCreate(newPipe->bus,
        !           410:                                        newPipe->devAddress, 
        !           411:                                        pb->usbOther,   /* User gives Endpoint number here */
        !           412:                                        usbDirection,
        !           413:                                        pb->usb.cntl.WValue);
        !           414: 
        !           415:                if(retVal != kUSBNoErr)
        !           416:                {
        !           417:                        deallocPipe(deviceP, pb->usbOther, usbDirection );
        !           418:                        break;
        !           419:                }
        !           420: 
        !           421:                pb->usbReference = newPipe->ref;        
        !           422:                
        !           423:                retVal = kUSBNoErr;
        !           424:                if(pb->usbCompletion != nil)
        !           425:                {
        !           426:                        (*pb->usbCompletion)(pb);
        !           427:                }
        !           428: 
        !           429:                break;
        !           430:        }while(0); /* End error checking */
        !           431:        
        !           432:        return(retVal);
        !           433: }
        !           434: 
        !           435: static OSStatus usbSIControlPacket(void *p1, void *addrEp)
        !           436: {      // p1 is pointer to paramblock
        !           437:        // second param has addr and endpoint munged together
        !           438: UInt32 p2;
        !           439: UInt8 addr, endPt;
        !           440: OSStatus err;
        !           441: USBPB *pb;
        !           442: UInt32 bus;
        !           443: 
        !           444:        p2 = (UInt32)addrEp;
        !           445:        bus = p2 >> 16;
        !           446:        addr = (p2>>8)  & 0xff;
        !           447:        endPt = p2 & 0xf;
        !           448:        
        !           449:        err = usbControlPacket(bus, p1, addr, endPt);
        !           450:        if(err != noErr)
        !           451:        {
        !           452:                pb = p1;
        !           453:                if( (pb->usbCompletion != nil) && (pb->usbCompletion != (void *)-1) )
        !           454:                {
        !           455:                        pb->usbStatus = err;
        !           456:                        (*pb->usbCompletion)(pb);
        !           457:                }
        !           458:        }
        !           459:        return(noErr);
        !           460: }
        !           461: 
        !           462: /* We need to make sure these are queued as well */
        !           463: OSStatus xUSLControlRequest(UInt32 bus, USBPB *pb, pipe *thisPipe)
        !           464: {
        !           465: setupPacket *packet;
        !           466: OSStatus err = kUSBPending;
        !           467: 
        !           468: USBDirection direction;
        !           469: USBRqType type;
        !           470: USBRqRecipient recipient;
        !           471: USBRequest request;
        !           472: UInt16 transferSize;
        !           473:        
        !           474:        do{
        !           475:                direction = pb->usb.cntl.BMRequestType >> 7;
        !           476:                type = (pb->usb.cntl.BMRequestType >> 5) & 3;
        !           477:                recipient = pb->usb.cntl.BMRequestType & 31;
        !           478:                request = pb->usb.cntl.BRequest;
        !           479: 
        !           480:                /* FInd the packet in the param block */
        !           481:                packet = (void *)&pb->usb.cntl.BMRequestType;
        !           482:                
        !           483:                /* Check the direction flag */
        !           484:                if(kUSBNone == direction || pb->usbReqCount == 0 || pb->usbBuffer == nil)
        !           485:                {
        !           486:                        transferSize = 0;       /* Don't sit on reqcount and buffer */
        !           487:                        direction = kUSBOut;
        !           488:                } 
        !           489:                else
        !           490:                {
        !           491:                        transferSize = pb->usbReqCount;
        !           492:                }
        !           493: 
        !           494:                /* Put together the bitmap request type byte */
        !           495:                if(packet->byte[bmRqType] == 0xff)
        !           496:                {
        !           497:                        err = kUSBRqErr;
        !           498:                        break;
        !           499:                }
        !           500:  
        !           501:                /* Check the request is a valid one */
        !           502:                if( (type == kUSBStandard) &&
        !           503:                                (request < kUSBRqGetStatus || request > kUSBRqSyncFrame || 
        !           504:                                request == kUSBRqReserved1 || request == kUSBRqReserved2) )
        !           505:                {
        !           506:                        err = kUSBUnknownRequestErr;
        !           507:                        break;
        !           508:                }
        !           509:                
        !           510:                /* Put together the rest of the packet */
        !           511:                packet->word[wValue] = HostToUSBWord(pb->usb.cntl.WValue);
        !           512:                packet->word[wIndex] = HostToUSBWord(pb->usb.cntl.WIndex);
        !           513:                packet->word[wLength] = HostToUSBWord(transferSize);
        !           514:                 
        !           515:                pb->usbStatus = kUSBPending;
        !           516:                if(CurrentExecutionLevel() == kSecondaryInterruptLevel)
        !           517:                {
        !           518:                        err = usbControlPacket(bus, pb, thisPipe->devAddress, thisPipe->endPt);
        !           519:                }
        !           520:                else
        !           521:                {
        !           522: #if 0
        !           523:                static pipe *rootHub;
        !           524:                        // temp hack.
        !           525:                        // If we're not being called at secondary int, avoid reentrancy prob
        !           526:                        // by arranging to be called at secondary int.
        !           527:                        
        !           528:                        // First try to suppress root hub messages
        !           529:                        if(rootHub == nil)      // assume first seen pipe is root hub
        !           530:                        {
        !           531:                                rootHub = thisPipe;
        !           532:                        }
        !           533:                        if(thisPipe != rootHub)
        !           534:                        {
        !           535:                                USBExpertStatus(-1, "\pUSL - Queueing secondary interrupt Control", thisPipe->devAddress);
        !           536:                        }
        !           537: #endif                 
        !           538:                        // now queue the call back. address and endpoint munged into second parameter
        !           539:                        err = QueueSecondaryInterruptHandler(usbSIControlPacket, nil, pb, 
        !           540:                                                        (void *)( 
        !           541:                                                        (bus << 16) +
        !           542:                                                        ((UInt32)thisPipe->devAddress << 8) + 
        !           543:                                                        ((UInt32)thisPipe->endPt) 
        !           544:                                                        ) );
        !           545:                }
        !           546:                
        !           547:                /* Processing now continues in controlCallBack */
        !           548: 
        !           549: 
        !           550:        }while(0);
        !           551:        
        !           552:        if(err == noErr)
        !           553:        {
        !           554:                err = kUSBPending;
        !           555:        }
        !           556:        else
        !           557:        {
        !           558:                pb->usbStatus = err;
        !           559:        }
        !           560:        return(err);
        !           561: }
        !           562: 
        !           563: OSStatus uslDeviceRequest(USBPB *pb)
        !           564: {
        !           565: USBReference ref0, ref;
        !           566: pipe *thisPipe;
        !           567: OSStatus retVal = noErr;
        !           568: UInt32 bus=0;
        !           569: 
        !           570:        do{
        !           571:                ref = pb->usbReference;
        !           572: 
        !           573:                if((pb->usbFlags & kUSBAddressRequest) != 0)
        !           574:                {
        !           575:                USBRqRecipient recipient;
        !           576:                        recipient = pb->usb.cntl.BMRequestType & 31;
        !           577:                        if(recipient == kUSBInterface)
        !           578:                        {
        !           579:                        uslInterface *ifc;
        !           580:                                retVal = findInterface(ref, &ifc);
        !           581:                                if(ifc != nil)
        !           582:                                {
        !           583:                                        pb->usb.cntl.WIndex = ifc->interfaceNum;
        !           584:                                }
        !           585:                        }
        !           586:                        else if(recipient == kUSBEndpoint)
        !           587:                        {
        !           588:                                thisPipe = GetPipePtr(ref);
        !           589:                                if(thisPipe != 0)
        !           590:                                {
        !           591:                                        ref = thisPipe->devIntfRef;
        !           592:                                        pb->usb.cntl.WIndex = thisPipe->endPt;
        !           593:                                        if(thisPipe->direction == kUSBIn)
        !           594:                                        {
        !           595:                                                pb->usb.cntl.WIndex |= 0x80;
        !           596:                                        }
        !           597:                                }
        !           598:                                else
        !           599:                                {
        !           600:                                        retVal = kUSBUnknownPipeErr;
        !           601:                                }
        !           602:                        }
        !           603:                        else
        !           604:                        {
        !           605:                                retVal = paramErr;
        !           606:                        }
        !           607:                        if(retVal != noErr)
        !           608:                        {
        !           609:                                pb->usbStatus = retVal;
        !           610:                                break;
        !           611:                        }
        !           612:                }
        !           613:                
        !           614:                ref0 = getPipeZero(ref);
        !           615:                if(ref0 == nil)
        !           616:                {
        !           617:                        if(uslHubValidateDevZero(ref, &bus))
        !           618:                        {
        !           619:                                thisPipe = &pipeZeroZero;
        !           620:                                thisPipe->bus = bus;
        !           621:                        }
        !           622:                        else
        !           623:                        {
        !           624:                                retVal = kUSBUnknownDeviceErr;
        !           625:                                break;
        !           626:                        }
        !           627:                }
        !           628:                else
        !           629:                {
        !           630:                        thisPipe = GetPipePtr(ref0);
        !           631:                        if(thisPipe == nil)
        !           632:                        {
        !           633:                                pb->usbStatus = kUSBUnknownPipeErr;
        !           634:                                break;
        !           635:                        }
        !           636:                }
        !           637:                retVal = xUSLControlRequest(thisPipe->bus, pb, thisPipe);
        !           638:                if(retVal != kUSBPending)
        !           639:                {
        !           640:                        break;
        !           641:                }
        !           642:                
        !           643:        }while(0);
        !           644:        return(retVal);
        !           645: }
        !           646: 
        !           647: 
        !           648: 
        !           649: OSStatus USBDeviceRequest(USBPB *pb)
        !           650: {
        !           651:        if(!checkPBVersion(pb, kUSBAddressRequest))
        !           652:        {
        !           653:                return(pb->usbStatus);
        !           654:        }
        !           655: 
        !           656:        /* Short circuit config device requests */
        !           657:        if( (pb->pbVersion != 1) &&     // requires 0.02 PB
        !           658:                (pb->usb.cntl.BMRequestType == 0) &&
        !           659:                (pb->usb.cntl.BRequest == kUSBRqSetConfig) )
        !           660:        {
        !           661:                pb->usbReqCount = 0;
        !           662:                pb->usbActCount = 0;
        !           663:                
        !           664:                pb->addrStash = (UInt32)pb->usbBuffer;
        !           665:                pb->usbBuffer = 0;
        !           666:                return(uslOpenDevice(pb));
        !           667:        }
        !           668: 
        !           669:        return(uslDeviceRequest(pb));
        !           670: }
        !           671: 
        !           672: 
        !           673: /* xxxx do checking that params are correct, now we have config desc */
        !           674: 
        !           675: /* xxxx do checking that params are correct, now we have config desc */
        !           676: static OSStatus uslOpenPipe(USBPB *pb)
        !           677: {
        !           678: 
        !           679:        switch(pb->usbClassType)
        !           680:        {
        !           681:                case kUSBBulk:
        !           682:                        return(uslOpenBulkEndpoint(pb));
        !           683:                break;
        !           684:        
        !           685:                case kUSBInterrupt:
        !           686:                        return(uslOpenInterruptEndpoint(pb));
        !           687:                break;
        !           688:        
        !           689:                case kUSBIsoc:
        !           690:                        return(uslOpenIsocEndpoint(pb));
        !           691:                break;
        !           692:        
        !           693:                case kUSBControl:
        !           694:                        //OSStatus uslOpenControlEndpoint(USBPB *pb);
        !           695:                        return(kUSBIncorrectTypeErr);
        !           696:                break;
        !           697:        
        !           698:                default:
        !           699:                        return(kUSBIncorrectTypeErr);
        !           700:                break;
        !           701:        
        !           702:        }
        !           703: }
        !           704: 
        !           705: OSStatus USBOpenPipe(USBPB *pb)
        !           706: {
        !           707:        if(!checkPBVersion(pb, kUSBAnyDirn))
        !           708:        {
        !           709:                return(pb->usbStatus);
        !           710:        }
        !           711: 
        !           712:        return(uslOpenPipe(pb));
        !           713: 
        !           714: }
        !           715: 
        !           716: 
        !           717: OSStatus uslOpenPipeImmed(USBInterfaceRef intrfc, USBEndPointDescriptor *endp)
        !           718: {
        !           719:        /* this relies on USBOpenPipe, and the bulk and interrupt opens */
        !           720:        /* completing immediatly and not caring if the completion is zero */
        !           721: USBPB pb;
        !           722: 
        !           723:        pb.usbReference = intrfc;
        !           724:        pb.usbCompletion = nil;
        !           725:        
        !           726:        if((endp->endpointAddress & 0x80) == 0)
        !           727:        {
        !           728:                pb.usbFlags = kUSBOut;
        !           729:        }
        !           730:        else
        !           731:        {
        !           732:                pb.usbFlags = kUSBIn;
        !           733:        }
        !           734: 
        !           735:        pb.usbClassType = endp->attributes&3;   // endpoint type
        !           736:        pb.usbOther = endp->endpointAddress & 0xf;
        !           737:        pb.usb.cntl.WValue = USBToHostWord(endp->maxPacketSize);
        !           738:        return(uslOpenPipe(&pb));
        !           739: }
        !           740: 
        !           741: 
        !           742: void resolvePerformance(USBPB *pb)
        !           743: {
        !           744: pipe *thisPipe;
        !           745: OSStatus err;
        !           746: 
        !           747:        err = findPipe(pb->usbReference, &thisPipe);
        !           748:        if( (thisPipe != nil) && (thisPipe->monitorPerformance) )
        !           749:        {
        !           750:                pb->usbFrame = deltaFrames(pb->usbFrame, thisPipe->bus);
        !           751:                AddAtomic(pb->usbFrame, (void *)&thisPipe->transferTime);
        !           752:                AddAtomic(pb->usbActCount, (void *)&thisPipe->bytesTransfered);
        !           753:                pb->usbFlags = 0;
        !           754:        }
        !           755: }
        !           756: 
        !           757: OSStatus USBBulkRead(USBPB *pb)
        !           758: {
        !           759: pipe *thisPipe;
        !           760: OSStatus retVal;
        !           761:        if(!checkPBVersion(pb, 0))
        !           762:        {
        !           763:                return(pb->usbStatus);
        !           764:        }
        !           765: 
        !           766:        retVal = kUSBPending;
        !           767:        pb->usbStatus = retVal;
        !           768:        do{
        !           769:                /* Find our pipe structure for this */
        !           770:                retVal = findPipe(pb->usbReference, &thisPipe);
        !           771:                if(retVal != noErr)
        !           772:                {
        !           773:                        pb->usbStatus = retVal; 
        !           774:                        break;
        !           775:                }
        !           776: 
        !           777:                if(thisPipe->monitorPerformance)
        !           778:                {
        !           779:                        pb->usbFlags = 1;
        !           780:                        pb->usbFrame = deltaFrames(0, thisPipe->bus);
        !           781:                }
        !           782: 
        !           783:                /* Validate its a bulk out pipe */
        !           784:                if( (thisPipe->direction != kUSBIn) || (thisPipe->type != kUSBBulk) )
        !           785:                {
        !           786:                        retVal = kUSBIncorrectTypeErr;
        !           787:                        pb->usbStatus = retVal;
        !           788:                        break;
        !           789:                }
        !           790:                
        !           791:                /* BT 13Aug98, allow zero length transactions, they're valid. */        
        !           792: 
        !           793:                retVal = usbBulkPacket(thisPipe->bus, pb, thisPipe->devAddress, thisPipe->endPt, kUSBIn);
        !           794:                /* Processing now continues in bulkCallBack */
        !           795: 
        !           796: 
        !           797:        }while(0);
        !           798:        return(retVal);
        !           799: }
        !           800: 
        !           801: OSStatus USBIntRead(USBPB *pb)
        !           802: {
        !           803: pipe *thisPipe;
        !           804: OSStatus retVal;
        !           805: 
        !           806:        if(!checkPBVersion(pb, 0))
        !           807:        {
        !           808:                return(pb->usbStatus);
        !           809:        }
        !           810: 
        !           811:        retVal = kUSBPending;
        !           812:        pb->usbStatus = retVal;
        !           813:        do{
        !           814:                /* Find our pipe structure for this */
        !           815:                retVal = findPipe(pb->usbReference, &thisPipe);
        !           816:                if(retVal != noErr)
        !           817:                {
        !           818:                        pb->usbStatus = retVal; 
        !           819:                        break;
        !           820:                }
        !           821: 
        !           822:                if(thisPipe->monitorPerformance)
        !           823:                {
        !           824:                        pb->usbFrame = deltaFrames(0, thisPipe->bus);
        !           825:                }       
        !           826: 
        !           827:                /* Validate its a bulk out pipe */
        !           828:                if( (thisPipe->direction != kUSBIn) || (thisPipe->type != kUSBInterrupt) )
        !           829:                {
        !           830:                        retVal = kUSBIncorrectTypeErr;
        !           831:                        pb->usbStatus = retVal;
        !           832:                        break;
        !           833:                }
        !           834:                
        !           835:                /* BT 13Aug98, allow zero length transactions, they're valid. */        
        !           836: 
        !           837: 
        !           838:                retVal = usbIntPacket(thisPipe->bus, pb, thisPipe->devAddress, thisPipe->endPt, kUSBIn);
        !           839:                /* Processing now continues in intCallBack */
        !           840: 
        !           841: 
        !           842:        }while(0);
        !           843:        return(retVal);
        !           844: }
        !           845: 
        !           846: OSStatus USBIsocRead(USBPB *pb)
        !           847: {
        !           848: pipe *thisPipe;
        !           849: OSStatus retVal;
        !           850: 
        !           851:        if(!checkPBVersionIsoc(pb, 0))
        !           852:        {
        !           853:                return(pb->usbStatus);
        !           854:        }
        !           855: 
        !           856:        retVal = kUSBPending;
        !           857:        pb->usbStatus = retVal;
        !           858:        do{
        !           859:                /* Find our pipe structure for this */
        !           860:                retVal = findPipe(pb->usbReference, &thisPipe);
        !           861:                if(retVal != noErr)
        !           862:                {
        !           863:                        pb->usbStatus = retVal; 
        !           864:                        break;
        !           865:                }
        !           866: 
        !           867:                /* Validate its a bulk out pipe */
        !           868:                if( (thisPipe->direction != kUSBIn) || (thisPipe->type != kUSBIsoc) )
        !           869:                {
        !           870:                        retVal = kUSBIncorrectTypeErr;
        !           871:                        pb->usbStatus = retVal;
        !           872:                        break;
        !           873:                }
        !           874:                
        !           875:                retVal = usbIsocPacket(thisPipe->bus, pb, thisPipe->devAddress, thisPipe->endPt, kUSBIn);
        !           876:                /* Processing now continues in bulkCallBack */
        !           877: 
        !           878: 
        !           879:        }while(0);
        !           880:        return(retVal);
        !           881: }
        !           882: 
        !           883: OSStatus USBBulkWrite(USBPB *pb)
        !           884: {
        !           885: pipe *thisPipe;
        !           886: OSStatus retVal;
        !           887:        if(!checkPBVersion(pb, 0))
        !           888:        {
        !           889:                return(pb->usbStatus);
        !           890:        }
        !           891: 
        !           892:        retVal = kUSBPending;
        !           893:        pb->usbStatus = retVal;
        !           894:        do{
        !           895:                /* Find our pipe structure for this */
        !           896:                retVal = findPipe(pb->usbReference, &thisPipe);
        !           897:                if(retVal != noErr)
        !           898:                {
        !           899:                        pb->usbStatus = retVal; 
        !           900:                        break;
        !           901:                }
        !           902: 
        !           903:                if(thisPipe->monitorPerformance)
        !           904:                {
        !           905:                        pb->usbFlags = 1;
        !           906:                        pb->usbFrame = deltaFrames(0, thisPipe->bus);
        !           907:                }
        !           908: 
        !           909:                /* Validate its a bulk out pipe */
        !           910:                if( (thisPipe->direction != kUSBOut) || (thisPipe->type != kUSBBulk) )
        !           911:                {
        !           912:                        retVal = kUSBIncorrectTypeErr;
        !           913:                        pb->usbStatus = retVal;
        !           914:                        break;
        !           915:                }
        !           916:                
        !           917:                /* BT 13Aug98, allow zero length transactions, they're valid. */        
        !           918: 
        !           919:                retVal = usbBulkPacket(thisPipe->bus, pb, thisPipe->devAddress, thisPipe->endPt, kUSBOut);
        !           920:                /* Processing now continues in controlCallBack */
        !           921: 
        !           922: 
        !           923:        }while(0);
        !           924:        return(retVal);
        !           925: }
        !           926: 
        !           927: OSStatus USBIsocWrite(USBPB *pb)
        !           928: {
        !           929: pipe *thisPipe;
        !           930: OSStatus retVal;
        !           931:        if(!checkPBVersionIsoc(pb, 0))
        !           932:        {
        !           933:                return(pb->usbStatus);
        !           934:        }
        !           935: 
        !           936:        retVal = kUSBPending;
        !           937:        pb->usbStatus = retVal;
        !           938:        do{
        !           939:                /* Find our pipe structure for this */
        !           940:                retVal = findPipe(pb->usbReference, &thisPipe);
        !           941:                if(retVal != noErr)
        !           942:                {
        !           943:                        pb->usbStatus = retVal; 
        !           944:                        break;
        !           945:                }
        !           946: 
        !           947:                /* Validate its a bulk out pipe */
        !           948:                if( (thisPipe->direction != kUSBOut) || (thisPipe->type != kUSBIsoc) )
        !           949:                {
        !           950:                        retVal = kUSBIncorrectTypeErr;
        !           951:                        pb->usbStatus = retVal;
        !           952:                        break;
        !           953:                }
        !           954:                
        !           955:                retVal = usbIsocPacket(thisPipe->bus, pb, thisPipe->devAddress, thisPipe->endPt, kUSBOut);
        !           956:                /* Processing now continues in controlCallBack */
        !           957: 
        !           958: 
        !           959:        }while(0);
        !           960:        return(retVal);
        !           961: }
        !           962: 
        !           963: OSStatus uslMonitorBulkPerformanceByReference(USBPipeRef ref, UInt32 what, 
        !           964:                                        UInt32 *lastRead, UInt32 *bytesTransfered, UInt32 *transferTime)
        !           965: {
        !           966: pipe *thisPipe;
        !           967: OSStatus err = noErr;
        !           968: 
        !           969:        do{
        !           970:                        /* Note this can't be a device ref, they're automatically cleared */
        !           971:                        /* Find the pipe struct */
        !           972:                err = findPipe(ref, &thisPipe);
        !           973:                if(thisPipe == nil)
        !           974:                {
        !           975:                        break;
        !           976:                }
        !           977:                
        !           978:                /* Do something here */
        !           979:                switch(what)
        !           980:                {
        !           981:                        case 0:
        !           982:                        /* stop monitoring this pipe */
        !           983:                                if(thisPipe->monitorPerformance)
        !           984:                                {
        !           985:                                        thisPipe->monitorPerformance = false;
        !           986:                                }
        !           987:                                else
        !           988:                                {
        !           989:                                        err = kUSBNotFound;
        !           990:                                }
        !           991:                        break;
        !           992:                        
        !           993:                        case 1:
        !           994:                        /* Start monitoring pipe */
        !           995:                                if(thisPipe->monitorPerformance)
        !           996:                                {
        !           997:                                        err = kUSBAlreadyOpenErr;
        !           998:                                }
        !           999:                                else
        !          1000:                                {
        !          1001:                                        thisPipe->monitorPerformance = true;
        !          1002:                                        thisPipe->lastRead = deltaFrames(0, thisPipe->bus);
        !          1003:                                }
        !          1004:                        break;
        !          1005:                        
        !          1006:                        case 2:
        !          1007:                        /* Get stats, don't clear */
        !          1008:                                if(thisPipe->monitorPerformance)
        !          1009:                                {
        !          1010:                                        *lastRead = thisPipe->lastRead;
        !          1011:                                        thisPipe->lastRead = deltaFrames(0, thisPipe->bus);
        !          1012:                                        *bytesTransfered = thisPipe->bytesTransfered;
        !          1013:                                        *transferTime = thisPipe->transferTime;
        !          1014:                                }
        !          1015:                                else
        !          1016:                                {
        !          1017:                                        err = kUSBNotFound;
        !          1018:                                }
        !          1019:                        break;
        !          1020:                        
        !          1021:                        case 3:
        !          1022:                        /* Get stats clear */
        !          1023:                                if(thisPipe->monitorPerformance)
        !          1024:                                {
        !          1025:                                        thisPipe->monitorPerformance = true;
        !          1026:                                }
        !          1027:                                *lastRead = thisPipe->lastRead;
        !          1028:                                thisPipe->lastRead = deltaFrames(0, thisPipe->bus);
        !          1029:                                *bytesTransfered = thisPipe->bytesTransfered;
        !          1030:                                *transferTime = thisPipe->transferTime;
        !          1031:                                
        !          1032:                                AddAtomic(-*bytesTransfered, (void *)&thisPipe->bytesTransfered);
        !          1033:                                AddAtomic(-*transferTime, (void *)&thisPipe->transferTime);
        !          1034: 
        !          1035:                        break;
        !          1036:                        
        !          1037:                }
        !          1038:                
        !          1039:        }while(0);
        !          1040: 
        !          1041:        return(err);
        !          1042: }

unix.superglobalmegacorp.com

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