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

unix.superglobalmegacorp.com

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