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:         <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.