Annotation of kernel/bsd/dev/ppc/drvUSBCMD/UIMrootHubSimulation.c, revision 1.1

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