Annotation of kernel/bsd/dev/ppc/drvUSBCMD/Library/uslpipe.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
                      7:  * Reserved.  This file contains Original Code and/or Modifications of
                      8:  * Original Code as defined in and that are subject to the Apple Public
                      9:  * Source License Version 1.1 (the "License").  You may not use this file
                     10:  * except in compliance with the License.  Please obtain a copy of the
                     11:  * License at http://www.apple.com/publicsource and read it before using
                     12:  * this file.
                     13:  * 
                     14:  * The Original Code and all software distributed under the License are
                     15:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     19:  * License for the specific language governing rights and limitations
                     20:  * under the License.
                     21:  * 
                     22:  * @APPLE_LICENSE_HEADER_END@
                     23:  */
                     24: 
                     25: /*
                     26:        File:           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.