Annotation of kernel/bsd/dev/ppc/drvUSBCMD/UIMrootHubSimulation.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:           UIMRootHubSimulation.c
                     27: 
                     28:        Contains:       Packet level simulation of root hub functions
                     29: 
                     30:        Version:        Neptune 1.0
                     31: 
                     32:        Copyright:      � 1998 by Apple Computer, Inc., all rights reserved.
                     33: 
                     34:        File Ownership:
                     35: 
                     36:                DRI:                            Barry Twycross
                     37: 
                     38:                Other Contact:          xxx put other contact here xxx
                     39: 
                     40:                Technology:                     USB
                     41: 
                     42:        Writers:
                     43: 
                     44:                (DF)    David Ferguson
                     45:                (DKF)   David Ferguson
                     46:                (CJK)   Craig Keithley
                     47:                (BT)    Barry Twycross
                     48: 
                     49:        Change History (most recent first):
                     50: 
                     51:          <USB4>         8/25/98        BT              Isoc name changes
                     52:          <USB3>         8/12/98        BT              Allow more than 1 control at a time.
                     53:          <USB2>         6/30/98        BT              Tidy up
                     54:          <USB1>         6/30/98        BT              first checked in
                     55: */
                     56: 
                     57: 
                     58: /*
                     59: 
                     60:        // UIMrootHubSimulation is USL's rootHubSimulation moved across 
                     61: 
                     62:         <USB27>         6/14/98        DF              change implemented spelling.
                     63:         <USB26>         5/20/98        BT              Fix alt settings field of interface descriptor
                     64:         <USB25>         5/17/98        BT              Make get conf descriptor more forgiving. Fix hub endpoint desc
                     65:         <USB24>         5/14/98        DF              Add status messages for unimplemented root hub stuff, also use
                     66:                                                                        info from the UIM when getting the hub status.
                     67:         <USB23>         4/23/98        BT              Fix reset portsuspend change feature
                     68:         <USB22>         4/20/98        BT              Add device status
                     69:         <USB21>         4/16/98        BT              Eliminate debugger
                     70:         <USB20>         4/15/98        BT              More root hub capabilities
                     71:         <USB19>          4/9/98        BT              Use USB.h
                     72:                <18>      4/2/98        BT              Do OPTI chip gang switching, fix sim stall error number
                     73:                <17>     3/19/98        BT              Split UIM into UIM and root hub parts
                     74:                <16>     3/18/98        BT              Add port enable and clear port enable change features
                     75:                <15>     3/11/98        BT              interrupt transaction simulation
                     76:                <14>      3/9/98        BT              Eliminate one set of redundant descriptors
                     77:                <13>     2/27/98        BT              Add string descriptors
                     78:                <12>     2/25/98        BT              Add Apple product codes.
                     79:                <11>     2/24/98        BT              Change Apple vendor ID.
                     80:                <10>     2/23/98        BT              Simulate root hub to not corrupt reqCount
                     81:          <USB9>          2/9/98        DKF             Byte swap configuration descriptor totalLength field
                     82:                 <8>      2/8/98        BT              More Power allocation stuff
                     83:                 <7>      2/4/98        BT              Cope with multiple configs
                     84:                 <6>     1/30/98        BT              Put Apple vendor ID in root hub device descriptor
                     85:                 <5>     1/26/98        CJK             Change to use USBDeviceDescriptor (instead of just
                     86:                                                                        devicedescriptor)
                     87:                 <4>     1/26/98        BT              Mangle names after design review
                     88:                 <3>     1/20/98        BT              Endian swap port status, and other fixes
                     89:                 <2>     1/20/98        BT              More root hub simulation
                     90:                 <1>     1/19/98        BT              first checked in
                     91: */
                     92: 
                     93: #include "driverservices.h"  //naga
                     94: #include "USB.h"
                     95: #include "USBpriv.h"
                     96: #include "OHCIUIM.h"
                     97: #include "OHCIRootHub.h"
                     98: 
                     99: //naga#include "driverservices.h"
                    100: 
                    101: // Need some way of talking to the outside here
                    102: #define USBExpertStatus(a,b, c)
                    103: 
                    104: // This isn't used at the moment
                    105: #define UIM_Bus 0
                    106: 
                    107: // Put these in globals struct????
                    108: typedef struct{
                    109:        UInt8 *buf;
                    110:        UInt32 bufLen;
                    111:        CallBackFuncPtr handler;
                    112:        UInt32 refCon;
                    113:        }intTrans;
                    114: #define kMaxOutstandingTrans 4
                    115: static intTrans outstanding[kMaxOutstandingTrans];
                    116: static UInt32 intLock;
                    117: //naga typedef UInt32 *QHdrPtr;   //naga temporary
                    118: static QHdrPtr simCallbackQueue;
                    119: static UInt16 configuration;
                    120: 
                    121: UInt16 Swap16(UInt16 value);
                    122: UInt16 Swap16(UInt16 value)
                    123: {
                    124:        return( (value << 8) | (value >> 8) );
                    125: }
                    126: #define HostToUSBWord Swap16
                    127: #define USBToHostWord Swap16
                    128: 
                    129: 
                    130: #if 0
                    131:        if(simCallbackQueue == nil)
                    132:        {
                    133:                if( (PBQueueCreate(&simCallbackQueue) != noErr) ||
                    134:                        (PBQueueInit(simCallbackQueue) != noErr) )
                    135:                {
                    136:                        /* Panic */
                    137:                        USBExpertStatus(0,"\pUSL - failed to initialise root simulation queue", 0);
                    138:                }
                    139:        }
                    140: 
                    141: 
                    142: OSStatus UIMProcessDoneQueue(void)
                    143: {
                    144: USBPB *pb;
                    145: 
                    146:        if( (simCallbackQueue != nil) && (simCallbackQueue->qHead != nil) )
                    147:        {
                    148:                while(PBDequeueFirst(simCallbackQueue, (void *)&pb) == noErr)
                    149:                {
                    150:                        uslInterruptPriority(-1);
                    151: 
                    152:                        if(pb == nil)
                    153:                        {
                    154:                                USBExpertStatus(-1, "\pNil pb", 0);
                    155:                        }
                    156:                        else
                    157:                        {
                    158:                                if (pb->usbCompletion && (pb->usbCompletion != kUSBNoCallBack))
                    159:                                        (*pb->usbCompletion)(pb);
                    160:                        }
                    161:                }
                    162:        }
                    163: #if 0
                    164: #if CHECK_UIM
                    165: static void **UIM, *UIM1;
                    166:        checkUIMMoved(&UIM, &UIM1, (void *)&UIMPlugIn->uimProcessDoneQueueProc);
                    167: #endif
                    168: 
                    169:        if(UIMPlugIn != nil)
                    170:        {
                    171:                return(*UIMPlugIn->uimProcessDoneQueueProc)();
                    172:        }
                    173:        return(-1);
                    174: #else
                    175:        return(noErr);
                    176: #endif
                    177: }
                    178:        
                    179: static void simIntPktHandler(long refCon, OSStatus status, short shortfall)
                    180: {
                    181: USBPB *pb;
                    182: 
                    183:        if(refCon == 0)
                    184:        {
                    185:                return;
                    186:        }
                    187: 
                    188:        pb = (void *)refCon;
                    189:        status = doUSLStatus(status, pb->usbReference);
                    190: 
                    191:        pb->usbStatus = status;
                    192:        pb->usbActCount = pb->usbReqCount - shortfall;
                    193:        uslInterruptPriority(+1);
                    194:        PBEnqueueLast((void *)pb, simCallbackQueue);
                    195: }
                    196: 
                    197: static void simPktHandler(long refCon, OSStatus status, short shortfall)
                    198: {
                    199: USBPB *pb;
                    200: 
                    201:        if(refCon == 0)
                    202:        {
                    203:                return;
                    204:        }
                    205:        
                    206: 
                    207:        pb = (void *)refCon;
                    208:        status = doUSLStatus(status, pb->usbReference);
                    209: 
                    210:        pb->usbStatus = status;
                    211:        pb->usbActCount = pb->usbReqCount - shortfall;
                    212: 
                    213:        pb->usb.cntl.WIndex = USBToHostWord(pb->usb.cntl.WIndex);
                    214:        pb->usb.cntl.WValue = USBToHostWord(pb->usb.cntl.WValue);
                    215:        uslInterruptPriority(+1);
                    216:        PBEnqueueLast((void *)pb, simCallbackQueue);
                    217: }
                    218: 
                    219: 
                    220: 
                    221: #endif
                    222: 
                    223: 
                    224: // *********
                    225: 
                    226: static Boolean SimulateSetConfiguration(UInt16 value)
                    227: {
                    228:        if((value == 1) || (value == 0) )
                    229:        {
                    230:                configuration = value;
                    231:                return(false);
                    232:        }
                    233:        return(true);
                    234: }
                    235: 
                    236: static Boolean SimulateGetDeviceDescriptor(UInt8 *buf, UInt32 *bufLen, UInt32 descIndex)
                    237: {
                    238: UInt32 length;
                    239: static USBDeviceDescriptor desc ={
                    240:        18,                                     // UInt8 length;
                    241:        kUSBDeviceDesc,         // UInt8 descType;
                    242:        USB_CONSTANT16(kUSBRel10),                      // UInt16 usbRel;
                    243:        kUSBHubClass,           // UInt8 class;
                    244:        kUSBHubSubClass,        // UInt8 subClass;
                    245:        0,                                      // UInt8 protocol;
                    246:        8,                                      // UInt8 maxPacketSize;
                    247:        USB_CONSTANT16(kAppleVendorID),         // UInt16 vendor;       Apple = 1452 (decimal, swapped)
                    248:        USB_CONSTANT16(kPrdRootHubCMD),         // UInt16 product;      0x8001
                    249:        USB_CONSTANT16(0x0100),                         // UInt16 devRel;       1.00
                    250:        0,                                      // UInt8 manuIdx;
                    251:        0,                                      // UInt8 prodIdx;
                    252:        0,                                      // UInt8 serialIdx;
                    253:        1,                                      // UInt8 numConf;
                    254:        0                                       // UInt16 end;
                    255:        };
                    256: 
                    257:        if(descIndex != 0)
                    258:        {
                    259:                return(true);
                    260:        }
                    261: 
                    262:        length = sizeof(desc);
                    263:        if(*bufLen < length)
                    264:        {
                    265:                length = *bufLen;
                    266:        }
                    267:        usb_BlockMoveData(&desc, buf, length);
                    268:        *bufLen -= length;
                    269:        
                    270:        return(false);
                    271: }
                    272: 
                    273: static Boolean SimulateGetConfDescriptor(UInt8 *buf, UInt32 *bufLen, UInt32 descIndex)
                    274: {
                    275: UInt32 length;
                    276: #define totalLen  (9+9+7)
                    277: static USBConfigurationDescriptor confDesc ={
                    278:        9,                                                      //UInt8 length;
                    279:        kUSBConfDesc,                           //UInt8 descriptorType;
                    280:        USB_CONSTANT16(totalLen),       //UInt16 totalLength;
                    281:        1,                                                      //UInt8 numInterfaces;
                    282:        1,                                                      //UInt8 configValue;
                    283:        0,                                                      //UInt8 configStrIndex;
                    284:        0x60,                                           //UInt8 attributes; self powered, supports remote wkup
                    285:        0,                                                      //UInt8 maxPower;
                    286:        };
                    287: static USBInterfaceDescriptor intfDesc ={
                    288:        9,                                              //UInt8 length;
                    289:        kUSBInterfaceDesc,              //UInt8 descriptorType;
                    290:        1,                                              //UInt8 interfaceNumber;
                    291:        0,                                              //UInt8 alternateSetting;
                    292:        1,                                              //UInt8 numEndpoints;
                    293:        kUSBHubClass,                   //UInt8 interfaceClass;
                    294:        kUSBHubSubClass,                //UInt8 interfaceSubClass;
                    295:        1,                                              //UInt8 interfaceProtocol;
                    296:        0                                               //UInt8 interfaceStrIndex;
                    297:        };
                    298: static USBEndPointDescriptor endptDesc ={
                    299:        7,                                              //UInt8 length;
                    300:        kUSBEndpointDesc,               //UInt8 descriptorType;
                    301:        0x81,                                   //UInt8  endpointAddress; In, 1
                    302:        kUSBInterrupt,                  //UInt8 attributes;
                    303:        USB_CONSTANT16(8),              //UInt16 maxPacketSize;
                    304:        255,                                    //UInt8 interval;
                    305:        };
                    306: UInt8 confBuf[totalLen];
                    307:        
                    308:        if(descIndex != 0)
                    309:        {
                    310:                //return(true); // temp don't make this fail while debugging root hub
                    311:        }
                    312:        if(totalLen != confDesc.length+intfDesc.length+endptDesc.length)
                    313:        {
                    314:                return(true);
                    315:        }
                    316:        usb_BlockMoveData(&confDesc, &confBuf[0], confDesc.length);
                    317:        usb_BlockMoveData(&intfDesc, &confBuf[confDesc.length], intfDesc.length);
                    318:        usb_BlockMoveData(&endptDesc, &confBuf[confDesc.length+intfDesc.length], endptDesc.length);
                    319:        
                    320:        length = totalLen;
                    321:        if(*bufLen < length)
                    322:        {
                    323:                length = *bufLen;
                    324:        }
                    325:        usb_BlockMoveData(&confBuf, buf, length);
                    326:        *bufLen -= length;
                    327:        
                    328:        return(false);
                    329: }
                    330: 
                    331: static Boolean SimulateGetADeviceDescriptor(setupPacket *packet, UInt8 *buf, UInt32 *bufLen)
                    332: {
                    333: UInt8 descType, descIndex;
                    334:        descType = USBToHostWord(packet->word[wValue]) >> 8;
                    335:        descIndex = USBToHostWord(packet->word[wValue]) & 0xff;
                    336:        if( (packet->word[wIndex] != 0) || (descType != kUSBStringDesc) )
                    337:        {
                    338:                /* This is not a string descriptor and its is not a string descriptor */
                    339:                if(descType == kUSBDeviceDesc)
                    340:                {
                    341:                        return(SimulateGetDeviceDescriptor(buf, bufLen, descIndex));
                    342:                }
                    343:                else if(descType == kUSBConfDesc)
                    344:                {
                    345:                        return(SimulateGetConfDescriptor(buf, bufLen, descIndex));
                    346:                }
                    347:                else
                    348:                {
                    349:                        return(true);   /* Unknown dscriptor */
                    350:                }
                    351:        }
                    352:        else if(descType == kUSBStringDesc)
                    353:        {
                    354:                /* cope with string descriptor */
                    355:                return(true);
                    356:        }
                    357: 
                    358:        /* Non zero index with non string descriptor */
                    359:        return(true);
                    360:  
                    361: }
                    362: 
                    363: 
                    364: static Boolean SimulateGetHubDescriptor(setupPacket *packet, UInt8 *buf, UInt32 *bufLen)
                    365: {
                    366: struct uslRootHubDescriptor    descr; //naga struct added
                    367: int bytesOfFlags, copy, length;
                    368: 
                    369:        if(packet->word[wValue] == 0)
                    370:        {
                    371:        
                    372:                if(OHCIGetRootDescriptor(UIM_Bus, &descr) != noErr)
                    373:                {
                    374:                        return(true);
                    375:                }
                    376:                
                    377:                length = *bufLen;
                    378:                
                    379:                if(length > 0)
                    380:                {
                    381:                        /* Descriptor length */
                    382:                        bytesOfFlags = (descr.numPorts+1)/8+1;
                    383:                        buf[0] = bytesOfFlags*2 + 7;
                    384:                        length--;
                    385:                }
                    386:                if(length > 0)
                    387:                {
                    388:                        /* Descriptor type */
                    389:                        buf[1] = kUSBHubDescriptorType;
                    390:                        length--;
                    391:                }
                    392:                if(length > 0)
                    393:                {
                    394:                        buf[2] = descr.numPorts;
                    395:                        length--;
                    396:                }
                    397:                if(length > 0)
                    398:                {
                    399:                        if(descr.powerSwitching)
                    400:                        {
                    401:                                buf[3] = !descr.gangedSwitching;
                    402:                        }
                    403:                        else
                    404:                        {
                    405:                                buf[3] = 2;
                    406:                        }
                    407:                        if(descr.compoundDevice)
                    408:                        {
                    409:                                buf[3] |= 4;
                    410:                        }
                    411:                        if(descr.overCurrent)
                    412:                        {
                    413:                                buf[3] = (!descr.globalOverCurrent) << 3;
                    414:                        }
                    415:                        else
                    416:                        {
                    417:                                buf[3] |= 0x10;
                    418:                        }
                    419:                        length--;
                    420:                }
                    421:                if(length > 0)
                    422:                {
                    423:                        /* Flags high byte */                   
                    424:                        buf[4] = 0;
                    425:                        length--;
                    426:                }
                    427:                if(length > 0)
                    428:                {
                    429:                        /* power on to good */
                    430:                        buf[5] = 50;    /* 100 ms? */
                    431:                        length--;
                    432:                }
                    433:                if(length > 0)
                    434:                {
                    435:                        /* Hub controller current */
                    436:                        buf[6] = 0;     /* no cuurrent from bus */
                    437:                        length--;
                    438:                }
                    439:                if(length > 0)
                    440:                {
                    441:                        copy = length;
                    442:                        if(copy > bytesOfFlags)
                    443:                        {
                    444:                                copy = bytesOfFlags;
                    445:                        }
                    446:                        usb_BlockMoveData(&descr.portFlags[0], &buf[7], copy);
                    447:                        length -= copy;
                    448:                }
                    449:                if(length > 0)
                    450:                {
                    451:                int copy2;
                    452:                        copy2 = length;
                    453:                        if(copy2 > bytesOfFlags)
                    454:                        {
                    455:                                copy2 = bytesOfFlags;
                    456:                        }
                    457:                        usb_BlockMoveData(&descr.portFlags[copy], &buf[7+copy], copy2);
                    458:                        length -= copy2;
                    459:                }
                    460:                
                    461:                *bufLen -= length;
                    462:                return(false);
                    463:        }
                    464:        
                    465:        return(true);
                    466: 
                    467: 
                    468: }
                    469: static Boolean SimulateClearPortFeature(setupPacket *packet)
                    470: {
                    471: UInt16 feature, port;
                    472: OSStatus err = -1;
                    473:        feature = USBToHostWord(packet->word[wValue]);
                    474:        port = USBToHostWord(packet->word[wIndex]);
                    475:        
                    476:        switch(feature)
                    477:        {
                    478:                case kUSBHubPortConnectionChangeFeature :
                    479:                        err =OHCIRootHubResetChangeConnection(UIM_Bus, port);
                    480:                break;
                    481:                
                    482:                case kUSBHubPortSuspendChangeFeature :
                    483:                        err =OHCIRootHubResetSuspendChange(UIM_Bus, port);
                    484:                break;
                    485:                
                    486:                case kUSBHubPortEnablenFeature :
                    487:                        err =OHCIRootHubPortEnable(UIM_Bus, port, false);
                    488:                break;
                    489:                
                    490:                case kUSBHubPortPowerFeature :
                    491:                        err =OHCIRootHubPortPower(UIM_Bus, port, false);
                    492:                        // Now need to check if all ports are switched off and 
                    493:                        // gang off if in gang mode
                    494:                break;
                    495: 
                    496:                case kUSBHubPortResetChangeFeature :
                    497:                        err =OHCIRootHubResetResetChange(UIM_Bus, port);
                    498:                break;
                    499: 
                    500:                case kUSBHubPortEnableChangeFeature :
                    501:                        err =OHCIRootHubResetEnableChange(UIM_Bus, port);
                    502:                break;
                    503:                
                    504:                case kUSBHubPortOverCurrentChangeFeature :
                    505:                        err =OHCIRootHubResetOverCurrentChange(UIM_Bus, port);
                    506:                break;
                    507:                
                    508: 
                    509:        default:
                    510:                //DebugStr("\pUnknown port clear");
                    511:                USBExpertStatus(0,"\pUSL - Unknown port clear in root hub simulation", 0);
                    512:                break;
                    513:        }
                    514:        return(err != noErr);
                    515: }
                    516: 
                    517: static Boolean SimulateGetHubStatus(setupPacket *packet, UInt8 *buf, UInt32 *bufLen)
                    518: {
                    519: OSStatus err = -1;
                    520: static struct{
                    521:        UInt16 status;
                    522:        UInt16 change;
                    523:        }hubStatus = {0,0};     /* Change this is overcurrent is implimeneted */
                    524: UInt32 rhStatus;
                    525: 
                    526:        if( (packet->word[wValue] == 0) && (packet->word[wIndex] == 0) )
                    527:        {
                    528:                if ((err = OHCIGetRhStatus(UIM_Bus, &rhStatus)) == noErr){
                    529:                
                    530:                        // wouldn't it be handy to have HostToUSBLong
                    531:                        hubStatus.status = HostToUSBWord(rhStatus & 0x0FFFF);
                    532:                        hubStatus.change = HostToUSBWord((rhStatus >> 16) & 0x0FFFF);
                    533:                        
                    534:                        if(*bufLen > sizeof(hubStatus))
                    535:                        {
                    536:                                *bufLen = sizeof(hubStatus);
                    537:                        }
                    538:                        usb_BlockMoveData(&hubStatus, buf, *bufLen);
                    539:                        err = noErr;
                    540:                }
                    541:        }
                    542:        return(err != noErr);
                    543: }
                    544: 
                    545: 
                    546: static Boolean SimulateGetPortStatus(setupPacket *packet, UInt8 *buf, UInt32 *bufLen)
                    547: {
                    548: struct uslRootHubPortStatus stat;   //naga added struct
                    549: OSStatus err = -1;
                    550: UInt32 length;
                    551: 
                    552:        if(packet->word[wValue] == 0)
                    553:        {
                    554:                err = OHCIRootHubGetPortStatus(UIM_Bus, USBToHostWord(packet->word[wIndex]), &stat);
                    555:                stat.portChangeFlags = USBToHostWord(stat.portChangeFlags);
                    556:                stat.portFlags = USBToHostWord(stat.portFlags);
                    557:                if(err == noErr)
                    558:                {
                    559:                        length = *bufLen;
                    560:                        if(length > sizeof(stat))
                    561:                        {
                    562:                                length = sizeof(stat);
                    563:                        }
                    564:                        usb_BlockMoveData(&stat, buf, length);
                    565:                        *bufLen -= length;
                    566:                }
                    567:        }
                    568:        return(err != noErr);
                    569: }
                    570: static Boolean SimulateSetPortFeature(setupPacket *packet)
                    571: {
                    572: UInt16 feature, port;
                    573: OSStatus err = -1;
                    574:        feature = USBToHostWord(packet->word[wValue]);
                    575:        port = USBToHostWord(packet->word[wIndex]);
                    576:        switch(feature)
                    577:        {
                    578:                case kUSBHubPortSuspecdFeature :
                    579:                        err = OHCIRootHubPortSuspend(UIM_Bus, port, true);
                    580:                break;
                    581:                
                    582:                case kUSBHubPortResetFeature :
                    583:                        err = OHCIRootHubResetPort(UIM_Bus, port);
                    584:                break;
                    585:                
                    586:                case kUSBHubPortEnablenFeature :
                    587:                        err = OHCIRootHubPortEnable(UIM_Bus, port, true);
                    588:                break;
                    589:                
                    590:                case kUSBHubPortPowerFeature :
                    591:                        err = OHCIRootHubPortPower(UIM_Bus, port, true);
                    592:                        if(err == noErr)
                    593:                        {
                    594:                                err = OHCIRootHubPower(UIM_Bus, true);
                    595:                        }
                    596:                break;
                    597:        
                    598:        default:
                    599:                //      DebugStr("\pUnknown port set");
                    600:                USBExpertStatus(0,"\pUSL - Unknown port set in root hub simulation", 0);
                    601:                break;
                    602:        }
                    603:        return(err != noErr);
                    604: }
                    605: 
                    606: static Boolean SimulateHubClearFeature(setupPacket *packet)
                    607: {
                    608: OSStatus err = -1;
                    609:        if(packet->word[wValue] == kUSBHubLocalPowerChangeFeature)
                    610:        {       
                    611:                USBExpertStatus(0,"\pRoot hub simulation - unimplemented Clear Power Change Feature", 0);
                    612:                // err = OHCIRootHubLPSChange(UIM_Bus, false);  // not implemented yet
                    613:        }
                    614:        if(packet->word[wValue] == kUSBHubOverCurrentChangeFeature)
                    615:        {       
                    616:                USBExpertStatus(0,"\pRoot hub simulation - unimplemented Clear Overcurrent Change Feature", 0);
                    617:                // err = OHCIRootHubOCChange(UIM_Bus, false);   // not implemented yet
                    618:        }       
                    619:        return(err != noErr);
                    620: }
                    621: static Boolean SimulateHubSetFeature(setupPacket *packet)
                    622: {
                    623: OSStatus err = -1;
                    624:        if(packet->word[wValue] == kUSBHubLocalPowerChangeFeature)
                    625:        {       
                    626:                USBExpertStatus(0,"\pRoot hub simulation - unimplemented Set Power Change Feature", 0);
                    627:                // err = OHCIRootHubLPSChange(UIM_Bus, true);   // not implemented yet
                    628:        }
                    629:        if(packet->word[wValue] == kUSBHubOverCurrentChangeFeature)
                    630:        {       
                    631:                USBExpertStatus(0,"\pRoot hub simulation - unimplemented Set Overcurrent Change Feature", 0);
                    632:                // err = OHCIRootHubOCChange(UIM_Bus, true);    // not implemented yet
                    633:        }       
                    634:        return(err != noErr);
                    635: }
                    636: 
                    637: 
                    638: void rootHubStatusChangeHandler(void)
                    639: {      /* Only called if the RHSC bit is set at int. */
                    640: UInt16 statusChanged;  /* only have 15 ports in OHCI */
                    641: UInt32 status, statusBit;
                    642: struct uslRootHubDescriptor    descr;   //naga added struct
                    643: static numPorts=0;
                    644: int index, move;
                    645: struct uslRootHubPortStatus stat;  //naga added struct
                    646: intTrans last;
                    647:        
                    648:        last = outstanding[0];
                    649: /*naga
                    650: */
                    651:        if(last.handler == nil)
                    652:        {
                    653: kprintf("rootHubStatusChangeHandler: last handler = nil\n");
                    654:                return;
                    655:        }
                    656:        if(CompareAndSwap(0, 1, &intLock))
                    657:        {
                    658:                for(index = 1; index < kMaxOutstandingTrans ; index++)
                    659:                {
                    660:                        outstanding[index-1] = outstanding[index];
                    661:                        if(outstanding[index].handler == nil)
                    662:                        {
                    663:                                break;
                    664:                        }
                    665:                }
                    666:        
                    667:                statusChanged = 0;
                    668:                statusBit = 1;
                    669:                if(OHCIGetRhStatus(UIM_Bus, &status) == noErr)
                    670:                {
                    671:                        if( (status & kOHCIHcRhStatus_Change ) != 0)
                    672:                        {
                    673: kprintf("Hub status change bit set to 1 \n");
                    674:                                statusChanged |= statusBit;     /* Hub status change bit */
                    675:                        }
                    676:                        
                    677:                        if(numPorts == 0)
                    678:                        {
                    679:                                if(OHCIGetRootDescriptor(UIM_Bus, &descr) == noErr)
                    680:                                {
                    681:                                        numPorts = descr.numPorts;
                    682: kprintf("#ports=%d\n",numPorts);
                    683:                                }
                    684:                                else
                    685:                                {
                    686:                                        //DebugStr("\pRoot hub int simulation hosed. No ports, tell Barry");
                    687:                                        kprintf("USL - Root hub int simulation hosed. No ports, tell Barry");
                    688:                                }
                    689:                        }
                    690: 
                    691:                        for(index = 1; index <= numPorts; index++)
                    692:                        {
                    693:                                statusBit <<= 1;        /* Next bit */
                    694:                                
                    695:                                if(OHCIRootHubGetPortStatus(UIM_Bus, index, &stat) == noErr)
                    696:                                {
                    697:                                        if(stat.portChangeFlags != 0)
                    698:                                        {
                    699:                                                statusChanged |= statusBit;     /* Hub status change bit */
                    700:                                        }
                    701:                                }
                    702:                                
                    703:                        }
                    704:                        
                    705:                }
                    706:                
                    707:                move = last.bufLen;
                    708:                if(move > sizeof(statusChanged))
                    709:                {
                    710:                        move = sizeof(statusChanged);
                    711:                }
                    712:                if(numPorts < 8)
                    713:                {
                    714:                        move = 1;
                    715:                }
                    716:                statusChanged = HostToUSBWord(statusChanged);
                    717:                usb_BlockMoveData(&statusChanged, last.buf, move);
                    718:                CompareAndSwap(1, 0, &intLock); /* Unlock the queue */
                    719: //naga         (*last.handler)(last.refCon, noErr, last.bufLen - move);
                    720:                (*last.handler)(last.refCon, noErr, last.bufLen - move);
                    721:        }
                    722: }
                    723: 
                    724: 
                    725: 
                    726: void pollRootHubSim(void)
                    727: {
                    728: UInt32 intrStatus;
                    729: //naga if(outstanding[0].handler != nil)
                    730:        if(outstanding[0].handler != nil)
                    731:        {
                    732:                if( (OHCIGetInterruptStatus(UIM_Bus, &intrStatus) == noErr) &&
                    733:                    ((intrStatus & kOHCIHcInterrupt_RHSC) != 0) )
                    734:                {
                    735:                        OHCIClearInterruptStatus(UIM_Bus, kOHCIHcInterrupt_RHSC);
                    736: //kprintf("calling rootHubStatusChange handler\n");
                    737:                        rootHubStatusChangeHandler();
                    738:                }
                    739:        }
                    740: }
                    741: 
                    742: void SimulateRootHubInt(UInt8 endpoint, UInt8 *buf, UInt32 bufLen,
                    743:                                                CallBackFuncPtr handler, UInt32 refCon)
                    744: {
                    745: int index;
                    746: 
                    747:        if(endpoint != 1)
                    748:        {
                    749:                (*handler)(refCon, -1, bufLen);
                    750:                return;
                    751:        }
                    752: 
                    753:        if(!CompareAndSwap(0, 1, &intLock))
                    754:        {       /* Busy */
                    755:                (*handler)(refCon, -1, bufLen);
                    756:                return;
                    757:        }
                    758: 
                    759:        for(index = 0; index < kMaxOutstandingTrans; index++)
                    760:        {
                    761:                if(outstanding[0].handler == nil)
                    762:                {
                    763:                        /* found free trans */
                    764:                        outstanding[0].buf = buf;
                    765:                        outstanding[0].bufLen = bufLen;
                    766:                        outstanding[0].handler = handler;
                    767:                        outstanding[0].refCon = refCon;
                    768:                        CompareAndSwap(1, 0, &intLock); /* Unlock the queue */
                    769:                        return;
                    770:                }
                    771:        }
                    772: 
                    773:        CompareAndSwap(1, 0, &intLock); /* Unlock the queue */
                    774:        (*handler)(refCon, -1, bufLen); /* too many trans */
                    775:        
                    776: }
                    777: 
                    778: static Boolean SimulateRootHub(setupPacket *packet, UInt8 *buf, UInt32 *bufLen)
                    779: {
                    780: UInt8 dirn, type, recipient;
                    781: Boolean stall;
                    782: 
                    783: #if 0
                    784: typedef union{
                    785:        UInt8 byte[8];
                    786:        UInt16 word[4];
                    787:        }setupPacket;
                    788: 
                    789: enum{
                    790: /* Byte offsets */
                    791:        bmRqType = 0,
                    792:        bUsedFlag = bmRqType,
                    793:        bRequest,
                    794: /* Word offsets */
                    795:        wValue =1,      
                    796:        wIndex,
                    797:        wLength
                    798:        };
                    799: #endif
                    800: 
                    801:        stall = false;
                    802:        dirn = (packet->byte[bmRqType] >> kUSBRqDirnShift) & kUSBRqDirnMask;
                    803:        type = (packet->byte[bmRqType] >> kUSBRqTypeShift) & kUSBRqTypeMask;
                    804:        recipient = packet->byte[bmRqType] & kUSBRqRecipientMask;
                    805: //kprintf("SimulateRootHub:request=0x%x,type=0x%x\n",packet->byte[bRequest],type);
                    806:        if(type == kUSBStandard)
                    807:        {
                    808: 
                    809: #if 0
                    810: Standard Requests
                    811: 
                    812: bmRequestType bRequest wValue wIndex wLength Data
                    813: 00000000B              CLEAR_FEATURE   device
                    814: 00000001B                                              Interface
                    815: 00000010B                                              Endpoint
                    816: 
                    817: 10000000B GET_CONFIGURATION Zero Zero One Configuration
                    818: 10000000B GET_DESCRIPTOR Descriptor
                    819: 10000001B GET_INTERFACE Zero Interface One Alternate
                    820: 
                    821: 10000000B              GET_STATUS              device
                    822: 10000001B                                              Interface
                    823: 10000010B                                              Endpoint
                    824: 
                    825: 00000000B SET_ADDRESS Device
                    826: 00000000B SET_CONFIGURATION Configuration
                    827: 00000000B SET_DESCRIPTOR Descriptor
                    828: 
                    829: 00000000B              SET_FEATURE             device
                    830: 00000001B                                              Interface
                    831: 00000010B                                              Endpoint
                    832: 
                    833: 00000001B SET_INTERFACE Alternate
                    834: 10000010B SYNCH_FRAME Zero Endpoint Two Frame Number#endif
                    835: #endif
                    836:                switch(packet->byte[bRequest])
                    837:                {
                    838:                        case kUSBRqClearFeature:
                    839:                                if(packet->byte[bmRqType] == 0x00)
                    840:                                {
                    841:                                        /* Clear Device Feature */
                    842:                                        stall = SimulateHubClearFeature(packet);
                    843:                                }
                    844:                                else if(packet->byte[bmRqType] == 0x01)
                    845:                                {
                    846:                                        /* Clear Interface Feature */
                    847:                                        stall = true;
                    848:                                        //DebugStr("\pRoot hub not implemented yet 2");
                    849:                                        USBExpertStatus(0,"\pUSL - Root hub not implemented yet 2", 0);
                    850:                                }
                    851:                                else if(packet->byte[bmRqType] == 0x02)
                    852:                                {
                    853:                                        /* Clear Endpoint Feature */
                    854:                                        stall = true;
                    855:                                        //DebugStr("\pRoot hub not implemented yet 3");
                    856:                                        USBExpertStatus(0,"\pUSL - Root hub not implemented yet 3", 0);
                    857:                                }
                    858:                                else
                    859:                                {
                    860:                                        stall = true;
                    861:                                }
                    862:                        break;
                    863:                
                    864:                        case kUSBRqGetConfig:
                    865:                                if(packet->byte[bmRqType] == 0x80)
                    866:                                {
                    867:                                        /* Get configuration */
                    868:                                        stall = true;
                    869:                                        //DebugStr("\pRoot hub not implemented yet 4");
                    870:                                        USBExpertStatus(0,"\pUSL - Root hub not implemented yet 4", 0);
                    871:                                }
                    872:                                else
                    873:                                {
                    874:                                        stall = true;
                    875:                                }
                    876:                        break;
                    877:                
                    878:                        case kUSBRqGetDescriptor:
                    879:                                if(packet->byte[bmRqType] == 0x80)
                    880:                                {
                    881:                                        /* Get descriptor */
                    882:                                        stall = SimulateGetADeviceDescriptor(packet, buf, bufLen);
                    883:                                }
                    884:                                else
                    885:                                {
                    886:                                        stall = true;
                    887:                                }
                    888:                        
                    889:                        break;
                    890:                
                    891:                        case kUSBRqGetInterface:
                    892:                                if(packet->byte[bmRqType] == 0x81)
                    893:                                {
                    894:                                        /* Get interface */
                    895:                                        stall = true;
                    896:                                        //DebugStr("\pRoot hub not implemented yet 6");
                    897:                                        USBExpertStatus(0,"\pUSL - Root hub not implemented yet 6", 0);
                    898:                                }
                    899:                                else
                    900:                                {
                    901:                                        stall = true;
                    902:                                }
                    903:                        break;
                    904:                
                    905:                        case kUSBRqGetStatus:
                    906:                                if(packet->byte[bmRqType] == 0x80)
                    907:                                {
                    908:                                UInt16 status;
                    909:                                int copy;
                    910:                                        /* Get Device Status */
                    911:                                        stall = false;
                    912:                                        status = USB_CONSTANT16(1);             // self powered
                    913:                                        copy = sizeof(status);
                    914:                                        if(copy > *bufLen)
                    915:                                        {
                    916:                                                copy = *bufLen;
                    917:                                        }
                    918:                                        usb_BlockMoveData(&status, buf, copy);
                    919:                                        *bufLen -= copy;
                    920:                                        
                    921:                                }
                    922:                                else if(packet->byte[bmRqType] == 0x81)
                    923:                                {
                    924:                                        /* Get Interface Status */
                    925:                                        stall = true;
                    926:                                        //DebugStr("\pRoot hub not implemented yet 8");
                    927:                                        USBExpertStatus(0,"\pUSL - Root hub not implemented yet 8", 0);
                    928:                                }
                    929:                                else if(packet->byte[bmRqType] == 0x82)
                    930:                                {
                    931:                                        /* Get Endpoint Status */
                    932:                                        stall = true;
                    933:                                        //DebugStr("\pRoot hub not implemented yet 9");
                    934:                                        USBExpertStatus(0,"\pUSL - Root hub not implemented yet 9", 0);
                    935:                                }
                    936:                                else
                    937:                                {
                    938:                                        stall = true;
                    939:                                }
                    940:                        break;
                    941:                
                    942:                        case kUSBRqSetAddress:
                    943:                                if(packet->byte[bmRqType] == 0x00)
                    944:                                {
                    945:                                        /* Set address */
                    946:                                        stall = OHCISetOurAddress(UIM_Bus, USBToHostWord(packet->word[wValue]));
                    947:                                }
                    948:                                else
                    949:                                {
                    950:                                        stall = true;
                    951:                                }                       
                    952:                        break;
                    953:                
                    954:                        case kUSBRqSetConfig:
                    955:                                if(packet->byte[bmRqType] == 0x00)
                    956:                                {
                    957:                                        /* Set configuration */
                    958:                                        stall = SimulateSetConfiguration(USBToHostWord(packet->word[wValue]));
                    959:                                }
                    960:                                else
                    961:                                {
                    962:                                        stall = true;
                    963:                                }                       
                    964:                        break;
                    965:                
                    966:                        case kUSBRqSetDescriptor:
                    967:                                if(packet->byte[bmRqType] == 0x00)
                    968:                                {
                    969:                                        /* Set descriptor */
                    970:                                        stall = true;
                    971:                                        //DebugStr("\pRoot hub not implemented yet 12");
                    972:                                        USBExpertStatus(0,"\pUSL - Root hub not implemented yet 12", 0);
                    973:                                }
                    974:                                else
                    975:                                {
                    976:                                        stall = true;
                    977:                                }                       
                    978:                        break;
                    979:                
                    980:                        case kUSBRqSetFeature:
                    981:                                if(packet->byte[bmRqType] == 0x00)
                    982:                                {
                    983:                                        /* Set Device Feature */
                    984:                                        stall = SimulateHubSetFeature(packet);
                    985:                                }
                    986:                                else if(packet->byte[bmRqType] == 0x01)
                    987:                                {
                    988:                                        /* Set Interface Feature */
                    989:                                        stall = true;
                    990:                                        //DebugStr("\pRoot hub not implemented yet 14");
                    991:                                        USBExpertStatus(0,"\pUSL - Root hub not implemented yet 14", 0);
                    992:                                }
                    993:                                else if(packet->byte[bmRqType] == 0x02)
                    994:                                {
                    995:                                        /* Set Endpoint Feature */
                    996:                                        stall = true;
                    997:                                        //DebugStr("\pRoot hub not implemented yet 15");
                    998:                                        USBExpertStatus(0,"\pUSL - Root hub not implemented yet 15", 0);
                    999:                                }
                   1000:                                else
                   1001:                                {
                   1002:                                        stall = true;
                   1003:                                }
                   1004:                        break;
                   1005:                
                   1006:                        case kUSBRqSetInterface:
                   1007:                                if(packet->byte[bmRqType] == 0x01)
                   1008:                                {
                   1009:                                        /* Set interface */
                   1010:                                        stall = true;
                   1011:                                        //DebugStr("\pRoot hub not implemented yet 16");
                   1012:                                        USBExpertStatus(0,"\pUSL - Root hub not implemented yet 16", 0);
                   1013:                                }
                   1014:                                else
                   1015:                                {
                   1016:                                        stall = true;
                   1017:                                }                       
                   1018:                        break;
                   1019:                
                   1020:                        case kUSBRqSyncFrame:
                   1021:                                stall = true;
                   1022:                        break;
                   1023: 
                   1024:                        default:
                   1025:                                stall = true;
                   1026:                        break;
                   1027: 
                   1028:                }
                   1029:        }
                   1030:        else if(type == kUSBClass)
                   1031:        {
                   1032: 
                   1033: #if 0
                   1034: Class-specific Requests
                   1035: 
                   1036: ClearHubFeature  0010 0000B CLEAR_FEATURE Feature
                   1037: ClearPortFeature 0010 0011B CLEAR_FEATURE Feature
                   1038: GetBusState      1010 0011B GET_STATE Zero Port One Per Port
                   1039: GetHubDescriptor 1010 0000B GET_DESCRIPTOR Descriptor
                   1040: GetHubStatus     1010 0000B GET_STATUS Zero Zero Four Hub Status
                   1041: GetPortStatus    1010 0011B GET_STATUS Zero Port Four Port Status
                   1042: SetHubDescriptor 0010 0000B SET_DESCRIPTOR Descriptor
                   1043: SetHubFeature    0010 0000B SET_FEATURE Feature
                   1044: SetPortFeature   0010 0011B SET_FEATURE Feature
                   1045: #endif         
                   1046:                switch(packet->byte[bRequest])
                   1047:                {
                   1048:                        case kUSBRqClearFeature:
                   1049:                                if(packet->byte[bmRqType] == 0x20)
                   1050:                                {
                   1051:                                        /* ClearHubFeature */
                   1052:                                        stall = true;
                   1053:                                        //DebugStr("\pRoot hub not implemented yet 17");
                   1054:                                        USBExpertStatus(0,"\pUSL - Root hub not implemented yet 17", 0);
                   1055:                                }
                   1056:                                else if(packet->byte[bmRqType] == 0x23)
                   1057:                                {
                   1058:                                        stall = SimulateClearPortFeature(packet);
                   1059:                                }
                   1060:                                else
                   1061:                                {
                   1062:                                        stall = true;
                   1063:                                }
                   1064:                        
                   1065:                        break;
                   1066:                                
                   1067:                        case kUSBRqReserved1 /*GET_STATE*/:
                   1068:                                if(packet->byte[bmRqType] == 0xA3)
                   1069:                                {
                   1070:                                        /* GetBusState */
                   1071:                                        stall = true;
                   1072:                                        //DebugStr("\pRoot hub not implemented yet 18");
                   1073:                                        USBExpertStatus(0,"\pUSL - Root hub not implemented yet 18", 0);
                   1074:                                }
                   1075:                                else
                   1076:                                {
                   1077:                                        stall = true;
                   1078:                                }
                   1079:                        break;
                   1080:                                
                   1081:                        case kUSBRqGetDescriptor:
                   1082:                                if(packet->byte[bmRqType] == 0xA0)
                   1083:                                {
                   1084:                                        /* GetHubDescriptor */
                   1085:                                        SimulateGetHubDescriptor(packet, buf, bufLen);
                   1086:                                }
                   1087:                                else
                   1088:                                {
                   1089:                                        stall = true;
                   1090:                                }
                   1091:                        
                   1092:                        break;
                   1093:                                
                   1094:                        case kUSBRqGetStatus:
                   1095:                                if(packet->byte[bmRqType] == 0xA0)
                   1096:                                {
                   1097:                                        /* GetHubStatus */
                   1098:                                        stall = SimulateGetHubStatus(packet, buf, bufLen);
                   1099:                                }
                   1100:                                else if(packet->byte[bmRqType] == 0xA3)
                   1101:                                {
                   1102:                                        stall = SimulateGetPortStatus(packet, buf, bufLen);
                   1103:                                }
                   1104:                                else
                   1105:                                {
                   1106:                                        stall = true;
                   1107:                                }
                   1108:                        
                   1109:                        break;
                   1110:                                
                   1111:                        case kUSBRqSetDescriptor:
                   1112:                                if(packet->byte[bmRqType] == 0x20)
                   1113:                                {
                   1114:                                        /* SetHubDescriptor */
                   1115:                                        stall = true;
                   1116:                                        //DebugStr("\pRoot hub not implemented yet 20");
                   1117:                                        USBExpertStatus(0,"\pUSL - Root hub not implemented yet 20", 0);
                   1118:                                }
                   1119:                                else
                   1120:                                {
                   1121:                                        stall = true;
                   1122:                                }
                   1123:                        
                   1124:                        break;
                   1125:                                
                   1126:                        case kUSBRqSetFeature :
                   1127:                                if(packet->byte[bmRqType] == 0x20)
                   1128:                                {
                   1129:                                        /* SetHubFeature */
                   1130:                                        stall = true;
                   1131:                                        //DebugStr("\pRoot hub not implemented yet 21");
                   1132:                                        USBExpertStatus(0,"\pUSL - Root hub not implemented yet 21", 0);
                   1133:                                }
                   1134:                                else if(packet->byte[bmRqType] == 0x23)
                   1135:                                {
                   1136:                                        stall = SimulateSetPortFeature(packet);
                   1137:                                }
                   1138:                                else
                   1139:                                {
                   1140:                                        stall = true;
                   1141:                                }
                   1142:                        break;
                   1143: 
                   1144:                        default:
                   1145:                                stall = true;
                   1146:                        break;
                   1147:                }
                   1148: 
                   1149:        }
                   1150:        else
                   1151:        {
                   1152:                stall = true;
                   1153:        }
                   1154:        
                   1155:        if(stall)
                   1156:        {
                   1157:                //DebugStr("\pSim Stall");
                   1158:                USBExpertStatus(0,"\pUSL - Root hub simulated stall", 0);
                   1159:        }
                   1160: 
                   1161:        return(stall);
                   1162: }
                   1163: 
                   1164: typedef struct{
                   1165:   setupPacket *packet;
                   1166:   UInt8 *buf;
                   1167:   UInt32 bufLen;
                   1168:   CallBackFuncPtr handler1;
                   1169:   UInt32 refCon1;
                   1170:   CallBackFuncPtr handler2;
                   1171:   UInt32 refCon2;
                   1172:   CallBackFuncPtr handler3;
                   1173:   UInt32 refCon3;
                   1174:   Boolean stall;
                   1175:   int state;
                   1176:        } RHTransaction;
                   1177:        
                   1178: static RHTransaction tr;
                   1179: #define kMaxRHtr 16
                   1180: static RHTransaction RHDone[kMaxRHtr];
                   1181: static UInt32 inUse[kMaxRHtr];
                   1182: 
                   1183: enum{
                   1184:        kNone = 0,
                   1185:        kSetupReceived,
                   1186:        kDataRecevied,
                   1187:        kStatusDone
                   1188:        };
                   1189: 
                   1190: 
                   1191: static void cleanState(RHTransaction *tr)
                   1192: {
                   1193:        if( (tr->state != kDataRecevied) && (tr->state != kStatusDone) )
                   1194:        {
                   1195:                tr->buf = nil;
                   1196:                tr->bufLen = 0;
                   1197:                tr->handler2 = nil;
                   1198:                tr->refCon2 = 0;
                   1199:                tr->handler3 = nil;
                   1200:                tr->refCon3 = 0;
                   1201:                if(tr->state != kSetupReceived)
                   1202:                {
                   1203:                        tr->handler1 = nil;
                   1204:                        tr->refCon1 = 0;
                   1205:                        tr->packet = nil;
                   1206:                        tr->state = kNone;
                   1207:                }
                   1208:        }
                   1209: }
                   1210: 
                   1211: 
                   1212: static RHTransaction *queueTR(RHTransaction *tr)
                   1213: {
                   1214: int i;
                   1215: 
                   1216:        for(i = 0; i< kMaxRHtr; i++)
                   1217:        {
                   1218:                if(CompareAndSwap(0, 1, &inUse[i]))
                   1219:                {
                   1220:                        RHDone[i] = *tr;
                   1221:                        tr->state = kNone;
                   1222:                        cleanState(tr);
                   1223:                        inUse[i]++;
                   1224:                        return(&RHDone[i]);
                   1225:                }
                   1226:        }
                   1227:        return(tr);
                   1228: }
                   1229: 
                   1230: OSStatus UIMSimulateRootHubStages(
                   1231:        UInt32                                          refcon,
                   1232:        CallBackFuncPtr                         handler,
                   1233:        UInt32                                          CBP,
                   1234:        Boolean                                         bufferRounding,
                   1235:        short                                           endpointNumber,
                   1236:        short                                           bufferSize,
                   1237:        short                                           direction);
                   1238: OSStatus UIMSimulateRootHubStages(
                   1239:        UInt32                                          refcon,
                   1240:        CallBackFuncPtr                         handler,
                   1241:        UInt32                                          CBP,
                   1242:        Boolean                                         bufferRounding,
                   1243:        short                                           endpointNumber,
                   1244:        short                                           bufferSize,
                   1245:        short                                           direction)
                   1246: {
                   1247: static directionReceived;
                   1248: RHTransaction *trOut;
                   1249: 
                   1250:        if(endpointNumber != 0)
                   1251:        {
                   1252:                bufferRounding = 0;             // stop annoying warning
                   1253:                return(-1);
                   1254:        }
                   1255: 
                   1256:        if( (direction != kUSBIn) && (direction != kUSBOut))    // setup packet
                   1257:        {       /* Setup packet over rides any previous state */
                   1258:        
                   1259:                if(tr.state != kNone)   // no queues we only cope with one (complete) control per frame.
                   1260:                {
                   1261:                        return(kUSBDeviceBusy);
                   1262:                }
                   1263:                cleanState(&tr);
                   1264:                
                   1265:                if(bufferSize != 8)
                   1266:                {
                   1267:                        tr.state = kNone;
                   1268:                }
                   1269:                
                   1270:                tr.packet = (void *)CBP;
                   1271:                tr.handler1 = handler;
                   1272:                tr.refCon1 = refcon;
                   1273:                tr.state = kSetupReceived;
                   1274:                
                   1275:                directionReceived = (((*(UInt8 *)CBP) & 0x80) == 0)?kUSBOut:kUSBIn;
                   1276: 
                   1277: 
                   1278:        }
                   1279:        else
                   1280:        {
                   1281:                if(directionReceived != direction)      // status phase is reverse data 
                   1282:                {
                   1283:                        tr.handler3 = handler;
                   1284:                        tr.refCon3 = refcon;
                   1285:                        trOut = queueTR(&tr);
                   1286:                        trOut->stall = SimulateRootHub(trOut->packet, trOut->buf, &trOut->bufLen);
                   1287:                        directionReceived = 0;
                   1288:                        trOut->state = kStatusDone;
                   1289:                        OHCISetFrameInterrupt();
                   1290:                        return(noErr);
                   1291:                }
                   1292:                else if(tr.state == kSetupReceived)
                   1293:                {
                   1294:                        tr.buf = (void *)CBP;
                   1295:                        tr.bufLen = bufferSize;
                   1296:                        tr.handler2 = handler;
                   1297:                        tr.refCon2 = refcon;
                   1298:                        tr.state = kDataRecevied;
                   1299:                }
                   1300:                else 
                   1301:                {
                   1302:                        tr.state = kNone;
                   1303:                }
                   1304:        
                   1305:        }
                   1306: 
                   1307:        cleanState(&tr);
                   1308:        return(noErr);
                   1309: }
                   1310: 
                   1311: 
                   1312: static void rootHubDispatch(RHTransaction *tr)
                   1313: {
                   1314: CallBackFuncPtr handler;
                   1315: UInt32 refCon;
                   1316: UInt32 retBufLen;
                   1317:        if(tr->state != kStatusDone)
                   1318:        {
                   1319:                return;
                   1320:        }
                   1321: 
                   1322:        // need to sync to end of frame here
                   1323:        if(tr->handler1 != nil)
                   1324:                (*tr->handler1)(tr->refCon1, noErr, 0);
                   1325:        if(tr->handler2 != nil)
                   1326:                (*tr->handler2)(tr->refCon2, noErr, 0);
                   1327:        handler = tr->handler3;
                   1328:        refCon = tr->refCon3;
                   1329:        retBufLen = tr->bufLen;
                   1330:        tr->state = kNone;
                   1331:        cleanState(tr);
                   1332:        if(handler != nil)
                   1333:        {
                   1334:                (*handler)(refCon, tr->stall?4:noErr, retBufLen);
                   1335:        }
                   1336: 
                   1337: }
                   1338: 
                   1339: OSStatus RootHubFrame(void *p1, void *p2)
                   1340: {
                   1341: int i;
                   1342: 
                   1343:        p1 = 0;
                   1344:        p2 = 0;
                   1345: 
                   1346:        for(i = 0; i< kMaxRHtr; i++)
                   1347:        {
                   1348:                if(inUse[i] == 2)
                   1349:                {
                   1350:                        rootHubDispatch(&RHDone[i]);
                   1351:                        cleanState(&RHDone[i]);
                   1352:                        inUse[i] = 0;
                   1353:                }       
                   1354:        }
                   1355: 
                   1356:        rootHubDispatch(&tr);
                   1357:        return(noErr);
                   1358: }
                   1359: 
                   1360: 
                   1361: 
                   1362: OSStatus RootHubStatusChange(void *p1, void *p2)
                   1363: {
                   1364:        p1 = 0;
                   1365:        p2 = 0;
                   1366: //SysDebug();                  
                   1367:        if(outstanding[0].handler != nil)
                   1368:        {
                   1369:                rootHubStatusChangeHandler();
                   1370:        }
                   1371:        return(noErr);
                   1372: }
                   1373: 
                   1374: void OHCIPollRootHubSim(uslBusRef bus)
                   1375: {
                   1376: bus = 0;
                   1377:        RootHubFrame(nil, nil);
                   1378:        pollRootHubSim();
                   1379: }
                   1380: 
                   1381: 
                   1382: 
                   1383: void ResetRootHubSimulation(void)
                   1384: {
                   1385:        int     index;
                   1386:        
                   1387:        for(index = 0; index < kMaxOutstandingTrans; index++)
                   1388:        {
                   1389:                outstanding[0].handler = nil; // clear out any outstanding transactions
                   1390:        }
                   1391:        intLock = 0;
                   1392:        OHCISetOurAddress(0, 0);
                   1393: }
                   1394: 

unix.superglobalmegacorp.com

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