Annotation of kernel/bsd/dev/ppc/drvUSBCMD/Library/rootHubSimulation.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:           rootHubSimulation.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:         <USB27>         6/14/98        DF              change implemented spelling.
        !            52:         <USB26>         5/20/98        BT              Fix alt settings field of interface descriptor
        !            53:         <USB25>         5/17/98        BT              Make get conf descriptor more forgiving. Fix hub endpoint desc
        !            54:         <USB24>         5/14/98        DF              Add status messages for unimplemented root hub stuff, also use
        !            55:                                                                        info from the UIM when getting the hub status.
        !            56:         <USB23>         4/23/98        BT              Fix reset portsuspend change feature
        !            57:         <USB22>         4/20/98        BT              Add device status
        !            58:         <USB21>         4/16/98        BT              Eliminate debugger
        !            59:         <USB20>         4/15/98        BT              More root hub capabilities
        !            60:         <USB19>          4/9/98        BT              Use USB.h
        !            61:                <18>      4/2/98        BT              Do OPTI chip gang switching, fix sim stall error number
        !            62:                <17>     3/19/98        BT              Split UIM into UIM and root hub parts
        !            63:                <16>     3/18/98        BT              Add port enable and clear port enable change features
        !            64:                <15>     3/11/98        BT              interrupt transaction simulation
        !            65:                <14>      3/9/98        BT              Eliminate one set of redundant descriptors
        !            66:                <13>     2/27/98        BT              Add string descriptors
        !            67:                <12>     2/25/98        BT              Add Apple product codes.
        !            68:                <11>     2/24/98        BT              Change Apple vendor ID.
        !            69:                <10>     2/23/98        BT              Simulate root hub to not corrupt reqCount
        !            70:          <USB9>          2/9/98        DKF             Byte swap configuration descriptor totalLength field
        !            71:                 <8>      2/8/98        BT              More Power allocation stuff
        !            72:                 <7>      2/4/98        BT              Cope with multiple configs
        !            73:                 <6>     1/30/98        BT              Put Apple vendor ID in root hub device descriptor
        !            74:                 <5>     1/26/98        CJK             Change to use USBDeviceDescriptor (instead of just
        !            75:                                                                        devicedescriptor)
        !            76:                 <4>     1/26/98        BT              Mangle names after design review
        !            77:                 <3>     1/20/98        BT              Endian swap port status, and other fixes
        !            78:                 <2>     1/20/98        BT              More root hub simulation
        !            79:                 <1>     1/19/98        BT              first checked in
        !            80: */
        !            81: 
        !            82: #include <USB.h>
        !            83: #include <USBpriv.h>
        !            84: #include "OHCIUIM.h"
        !            85: #include "OHCIRootHub.h"
        !            86: #include "uimpriv.h"
        !            87: #include "uslpriv.h"
        !            88: #include "hub.h"
        !            89: #include <DriverServices.h>
        !            90: 
        !            91: static UInt16 configuration;
        !            92: 
        !            93: static Boolean SimulateSetConfiguration(UInt16 value)
        !            94: {
        !            95:        if((value == 1) || (value == 0) )
        !            96:        {
        !            97:                configuration = value;
        !            98:                return(false);
        !            99:        }
        !           100:        return(true);
        !           101: }
        !           102: 
        !           103: static Boolean SimulateGetDeviceDescriptor(UInt8 *buf, UInt32 *bufLen, UInt32 descIndex)
        !           104: {
        !           105: UInt32 length;
        !           106: static USBDeviceDescriptor desc ={
        !           107:        18,                                     // UInt8 length;
        !           108:        kUSBDeviceDesc,         // UInt8 descType;
        !           109:        USB_CONSTANT16(kUSBRel10),                      // UInt16 usbRel;
        !           110:        kUSBHubClass,           // UInt8 class;
        !           111:        kUSBHubSubClass,        // UInt8 subClass;
        !           112:        0,                                      // UInt8 protocol;
        !           113:        8,                                      // UInt8 maxPacketSize;
        !           114:        USB_CONSTANT16(kAppleVendorID),         // UInt16 vendor;       Apple = 1452 (decimal, swapped)
        !           115:        USB_CONSTANT16(kPrdRootHubCMD),         // UInt16 product;      0x8001
        !           116:        USB_CONSTANT16(0x0100),                         // UInt16 devRel;       1.00
        !           117:        0,                                      // UInt8 manuIdx;
        !           118:        0,                                      // UInt8 prodIdx;
        !           119:        0,                                      // UInt8 serialIdx;
        !           120:        1,                                      // UInt8 numConf;
        !           121:        0                                       // UInt16 end;
        !           122:        };
        !           123: 
        !           124:        if(descIndex != 0)
        !           125:        {
        !           126:                return(true);
        !           127:        }
        !           128: 
        !           129:        length = sizeof(desc);
        !           130:        if(*bufLen < length)
        !           131:        {
        !           132:                length = *bufLen;
        !           133:        }
        !           134:        usb_BlockMoveData(&desc, buf, length);
        !           135:        *bufLen -= length;
        !           136:        
        !           137:        return(false);
        !           138: }
        !           139: 
        !           140: static Boolean SimulateGetConfDescriptor(UInt8 *buf, UInt32 *bufLen, UInt32 descIndex)
        !           141: {
        !           142: UInt32 length;
        !           143: #define totalLen  (9+9+7)
        !           144: static USBConfigurationDescriptor confDesc ={
        !           145:        9,                                                      //UInt8 length;
        !           146:        kUSBConfDesc,                           //UInt8 descriptorType;
        !           147:        USB_CONSTANT16(totalLen),       //UInt16 totalLength;
        !           148:        1,                                                      //UInt8 numInterfaces;
        !           149:        1,                                                      //UInt8 configValue;
        !           150:        0,                                                      //UInt8 configStrIndex;
        !           151:        0x60,                                           //UInt8 attributes; self powered, supports remote wkup
        !           152:        0,                                                      //UInt8 maxPower;
        !           153:        };
        !           154: static USBInterfaceDescriptor intfDesc ={
        !           155:        9,                                              //UInt8 length;
        !           156:        kUSBInterfaceDesc,              //UInt8 descriptorType;
        !           157:        1,                                              //UInt8 interfaceNumber;
        !           158:        0,                                              //UInt8 alternateSetting;
        !           159:        1,                                              //UInt8 numEndpoints;
        !           160:        kUSBHubClass,                   //UInt8 interfaceClass;
        !           161:        kUSBHubSubClass,                //UInt8 interfaceSubClass;
        !           162:        1,                                              //UInt8 interfaceProtocol;
        !           163:        0                                               //UInt8 interfaceStrIndex;
        !           164:        };
        !           165: static USBEndPointDescriptor endptDesc ={
        !           166:        7,                                              //UInt8 length;
        !           167:        kUSBEndpointDesc,               //UInt8 descriptorType;
        !           168:        0x81,                                   //UInt8  endpointAddress; In, 1
        !           169:        kUSBInterrupt,                  //UInt8 attributes;
        !           170:        USB_CONSTANT16(8),              //UInt16 maxPacketSize;
        !           171:        255,                                    //UInt8 interval;
        !           172:        };
        !           173: UInt8 confBuf[totalLen];
        !           174:        
        !           175:        if(descIndex != 0)
        !           176:        {
        !           177:                //return(true); // temp don't make this fail while debugging root hub
        !           178:        }
        !           179:        if(totalLen != confDesc.length+intfDesc.length+endptDesc.length)
        !           180:        {
        !           181:                return(true);
        !           182:        }
        !           183:        usb_BlockMoveData(&confDesc, &confBuf[0], confDesc.length);
        !           184:        usb_BlockMoveData(&intfDesc, &confBuf[confDesc.length], intfDesc.length);
        !           185:        usb_BlockMoveData(&endptDesc, &confBuf[confDesc.length+intfDesc.length], endptDesc.length);
        !           186:        
        !           187:        length = totalLen;
        !           188:        if(*bufLen < length)
        !           189:        {
        !           190:                length = *bufLen;
        !           191:        }
        !           192:        usb_BlockMoveData(&confBuf, buf, length);
        !           193:        *bufLen -= length;
        !           194:        
        !           195:        return(false);
        !           196: }
        !           197: 
        !           198: static Boolean SimulateGetADeviceDescriptor(setupPacket *packet, UInt8 *buf, UInt32 *bufLen)
        !           199: {
        !           200: UInt8 descType, descIndex;
        !           201:        descType = USBToHostWord(packet->word[wValue]) >> 8;
        !           202:        descIndex = USBToHostWord(packet->word[wValue]) & 0xff;
        !           203:        if( (packet->word[wIndex] != 0) || (descType != kUSBStringDesc) )
        !           204:        {
        !           205:                /* This is not a string descriptor and its is not a string descriptor */
        !           206:                if(descType == kUSBDeviceDesc)
        !           207:                {
        !           208:                        return(SimulateGetDeviceDescriptor(buf, bufLen, descIndex));
        !           209:                }
        !           210:                else if(descType == kUSBConfDesc)
        !           211:                {
        !           212:                        return(SimulateGetConfDescriptor(buf, bufLen, descIndex));
        !           213:                }
        !           214:                else
        !           215:                {
        !           216:                        return(true);   /* Unknown dscriptor */
        !           217:                }
        !           218:        }
        !           219:        else if(descType == kUSBStringDesc)
        !           220:        {
        !           221:                /* cope with string descriptor */
        !           222:                return(true);
        !           223:        }
        !           224: 
        !           225:        /* Non zero index with non string descriptor */
        !           226:        return(true);
        !           227:  
        !           228: }
        !           229: 
        !           230: static Boolean SimulateGetHubDescriptor(setupPacket *packet, UInt8 *buf, UInt32 *bufLen)
        !           231: {
        !           232: uslRootHubDescriptor   descr;
        !           233: int bytesOfFlags, copy, length;
        !           234: 
        !           235:        if(packet->word[wValue] == 0)
        !           236:        {
        !           237:        
        !           238:                if(UIMGetRootDescriptor(&descr) != noErr)
        !           239:                {
        !           240:                        return(true);
        !           241:                }
        !           242:                
        !           243:                length = *bufLen;
        !           244:                
        !           245:                if(length > 0)
        !           246:                {
        !           247:                        /* Descriptor length */
        !           248:                        bytesOfFlags = (descr.numPorts+1)/8+1;
        !           249:                        buf[0] = bytesOfFlags*2 + 7;
        !           250:                        length--;
        !           251:                }
        !           252:                if(length > 0)
        !           253:                {
        !           254:                        /* Descriptor type */
        !           255:                        buf[1] = kUSBHubDescriptorType;
        !           256:                        length--;
        !           257:                }
        !           258:                if(length > 0)
        !           259:                {
        !           260:                        buf[2] = descr.numPorts;
        !           261:                        length--;
        !           262:                }
        !           263:                if(length > 0)
        !           264:                {
        !           265:                        if(descr.powerSwitching)
        !           266:                        {
        !           267:                                buf[3] = !descr.gangedSwitching;
        !           268:                        }
        !           269:                        else
        !           270:                        {
        !           271:                                buf[3] = 2;
        !           272:                        }
        !           273:                        if(descr.compoundDevice)
        !           274:                        {
        !           275:                                buf[3] |= 4;
        !           276:                        }
        !           277:                        if(descr.overCurrent)
        !           278:                        {
        !           279:                                buf[3] = (!descr.globalOverCurrent) << 3;
        !           280:                        }
        !           281:                        else
        !           282:                        {
        !           283:                                buf[3] |= 0x10;
        !           284:                        }
        !           285:                        length--;
        !           286:                }
        !           287:                if(length > 0)
        !           288:                {
        !           289:                        /* Flags high byte */                   
        !           290:                        buf[4] = 0;
        !           291:                        length--;
        !           292:                }
        !           293:                if(length > 0)
        !           294:                {
        !           295:                        /* power on to good */
        !           296:                        buf[5] = 50;    /* 100 ms? */
        !           297:                        length--;
        !           298:                }
        !           299:                if(length > 0)
        !           300:                {
        !           301:                        /* Hub controller current */
        !           302:                        buf[6] = 0;     /* no cuurrent from bus */
        !           303:                        length--;
        !           304:                }
        !           305:                if(length > 0)
        !           306:                {
        !           307:                        copy = length;
        !           308:                        if(copy > bytesOfFlags)
        !           309:                        {
        !           310:                                copy = bytesOfFlags;
        !           311:                        }
        !           312:                        usb_BlockMoveData(&descr.portFlags[0], &buf[7], copy);
        !           313:                        length -= copy;
        !           314:                }
        !           315:                if(length > 0)
        !           316:                {
        !           317:                int copy2;
        !           318:                        copy2 = length;
        !           319:                        if(copy2 > bytesOfFlags)
        !           320:                        {
        !           321:                                copy2 = bytesOfFlags;
        !           322:                        }
        !           323:                        usb_BlockMoveData(&descr.portFlags[copy], &buf[7+copy], copy2);
        !           324:                        length -= copy2;
        !           325:                }
        !           326:                
        !           327:                *bufLen -= length;
        !           328:                return(false);
        !           329:        }
        !           330:        
        !           331:        return(true);
        !           332: 
        !           333: 
        !           334: }
        !           335: static Boolean SimulateClearPortFeature(setupPacket *packet)
        !           336: {
        !           337: UInt16 feature, port;
        !           338: OSStatus err = -1;
        !           339:        feature = USBToHostWord(packet->word[wValue]);
        !           340:        port = USBToHostWord(packet->word[wIndex]);
        !           341:        
        !           342:        switch(feature)
        !           343:        {
        !           344:                case kUSBHubPortConnectionChangeFeature :
        !           345:                        err =UIMRootHubResetChangeConnection(port);
        !           346:                break;
        !           347:                
        !           348:                case kUSBHubPortSuspendChangeFeature :
        !           349:                        err =UIMRootHubResetChangeSuspend(port);
        !           350:                break;
        !           351:                
        !           352:                case kUSBHubPortEnablenFeature :
        !           353:                        err =UIMRootHubPortEnable(port, false);
        !           354:                break;
        !           355:                
        !           356:                case kUSBHubPortPowerFeature :
        !           357:                        err =UIMRootHubPortPower(port, false);
        !           358:                        // Now need to check if all ports are switched off and 
        !           359:                        // gang off if in gang mode
        !           360:                break;
        !           361: 
        !           362:                case kUSBHubPortResetChangeFeature :
        !           363:                        err =UIMRootHubResetResetChange(port);
        !           364:                break;
        !           365: 
        !           366:                case kUSBHubPortEnableChangeFeature :
        !           367:                        err =UIMRootHubResetEnableChange(port);
        !           368:                break;
        !           369:                
        !           370:                case kUSBHubPortOverCurrentChangeFeature :
        !           371:                        err =UIMRootHubResetOverCurrentChange(port);
        !           372:                break;
        !           373:                
        !           374: 
        !           375:        defualt:
        !           376:                //DebugStr("\pUnknown port clear");
        !           377:                USBExpertStatus(0,"\pUSL - Unknown port clear in root hub simulation", 0);
        !           378:                break;
        !           379:        }
        !           380:        return(err != noErr);
        !           381: }
        !           382: 
        !           383: static Boolean SimulateGetHubStatus(setupPacket *packet, UInt8 *buf, UInt32 *bufLen)
        !           384: {
        !           385: OSStatus err = -1;
        !           386: static struct{
        !           387:        UInt16 status;
        !           388:        UInt16 change;
        !           389:        }hubStatus = {0,0};     /* Change this is overcurrent is implimeneted */
        !           390: UInt32 rhStatus;
        !           391: 
        !           392:        if( (packet->word[wValue] == 0) && (packet->word[wIndex] == 0) )
        !           393:        {
        !           394:                if ((err = UIMGetRhStatus(&rhStatus)) == noErr){
        !           395:                
        !           396:                        // wouldn't it be handy to have HostToUSBLong
        !           397:                        hubStatus.status = HostToUSBWord(rhStatus & 0x0FFFF);
        !           398:                        hubStatus.change = HostToUSBWord((rhStatus >> 16) & 0x0FFFF);
        !           399:                        
        !           400:                        if(*bufLen > sizeof(hubStatus))
        !           401:                        {
        !           402:                                *bufLen = sizeof(hubStatus);
        !           403:                        }
        !           404:                        usb_BlockMoveData(&hubStatus, buf, *bufLen);
        !           405:                        err = noErr;
        !           406:                }
        !           407:        }
        !           408:        return(err != noErr);
        !           409: }
        !           410: 
        !           411: 
        !           412: static Boolean SimulateGetPortStatus(setupPacket *packet, UInt8 *buf, UInt32 *bufLen)
        !           413: {
        !           414: uslRootHubPortStatus stat;
        !           415: OSStatus err = -1;
        !           416: UInt32 length;
        !           417: 
        !           418:        if(packet->word[wValue] == 0)
        !           419:        {
        !           420:                err = UIMRootHubGetPortStatus(USBToHostWord(packet->word[wIndex]), &stat);
        !           421:                stat.portChangeFlags = USBToHostWord(stat.portChangeFlags);
        !           422:                stat.portFlags = USBToHostWord(stat.portFlags);
        !           423:                if(err == noErr)
        !           424:                {
        !           425:                        length = *bufLen;
        !           426:                        if(length > sizeof(stat))
        !           427:                        {
        !           428:                                length = sizeof(stat);
        !           429:                        }
        !           430:                        usb_BlockMoveData(&stat, buf, length);
        !           431:                        *bufLen -= length;
        !           432:                }
        !           433:        }
        !           434:        return(err != noErr);
        !           435: }
        !           436: static Boolean SimulateSetPortFeature(setupPacket *packet)
        !           437: {
        !           438: UInt16 feature, port;
        !           439: OSStatus err = -1;
        !           440:        feature = USBToHostWord(packet->word[wValue]);
        !           441:        port = USBToHostWord(packet->word[wIndex]);
        !           442:        switch(feature)
        !           443:        {
        !           444:                case kUSBHubPortSuspecdFeature :
        !           445:                        err = UIMRootHubPortSuspend(port, true);
        !           446:                break;
        !           447:                
        !           448:                case kUSBHubPortResetFeature :
        !           449:                        err = UIMRootHubResetPort(port);
        !           450:                break;
        !           451:                
        !           452:                case kUSBHubPortEnablenFeature :
        !           453:                        err = UIMRootHubPortEnable(port, true);
        !           454:                break;
        !           455:                
        !           456:                case kUSBHubPortPowerFeature :
        !           457:                        err = UIMRootHubPortPower(port, true);
        !           458:                        if(err == noErr)
        !           459:                        {
        !           460:                                err = UIMRootHubPower(true);
        !           461:                        }
        !           462:                break;
        !           463:        
        !           464:        default:
        !           465:                //      DebugStr("\pUnknown port set");
        !           466:                USBExpertStatus(0,"\pUSL - Unknown port set in root hub simulation", 0);
        !           467:                break;
        !           468:        }
        !           469:        return(err != noErr);
        !           470: }
        !           471: 
        !           472: static Boolean SimulateHubClearFeature(setupPacket *packet)
        !           473: {
        !           474: OSStatus err = -1;
        !           475:        if(packet->word[wValue] == kUSBHubLocalPowerChangeFeature)
        !           476:        {       
        !           477:                USBExpertStatus(0,"\pRoot hub simulation - unimplemented Clear Power Change Feature", 0);
        !           478:                // err = UIMRootHubLPSChange(false);    // not implemented yet
        !           479:        }
        !           480:        if(packet->word[wValue] == kUSBHubOverCurrentChangeFeature)
        !           481:        {       
        !           482:                USBExpertStatus(0,"\pRoot hub simulation - unimplemented Clear Overcurrent Change Feature", 0);
        !           483:                // err = UIMRootHubOCChange(false);     // not implemented yet
        !           484:        }       
        !           485:        return(err != noErr);
        !           486: }
        !           487: static Boolean SimulateHubSetFeature(setupPacket *packet)
        !           488: {
        !           489: OSStatus err = -1;
        !           490:        if(packet->word[wValue] == kUSBHubLocalPowerChangeFeature)
        !           491:        {       
        !           492:                USBExpertStatus(0,"\pRoot hub simulation - unimplemented Set Power Change Feature", 0);
        !           493:                // err = UIMRootHubLPSChange(true);     // not implemented yet
        !           494:        }
        !           495:        if(packet->word[wValue] == kUSBHubOverCurrentChangeFeature)
        !           496:        {       
        !           497:                USBExpertStatus(0,"\pRoot hub simulation - unimplemented Set Overcurrent Change Feature", 0);
        !           498:                // err = UIMRootHubOCChange(true);      // not implemented yet
        !           499:        }       
        !           500:        return(err != noErr);
        !           501: }
        !           502: 
        !           503: typedef struct{
        !           504:        UInt8 *buf;
        !           505:        UInt32 bufLen;
        !           506:        CallBackFuncPtr handler;
        !           507:        UInt32 refCon;
        !           508:        }intTrans;
        !           509: #define kMaxOutstandingTrans 4
        !           510: 
        !           511: static intTrans outstanding[kMaxOutstandingTrans];
        !           512: 
        !           513: static UInt32 intLock;
        !           514: 
        !           515: 
        !           516: static void rootHubStatusChangeHandler(void)
        !           517: {      /* Only called if the RHSC bit is set at int. */
        !           518: UInt16 statusChanged;  /* only have 15 ports in OHCI */
        !           519: UInt32 status, statusBit;
        !           520: uslRootHubDescriptor   descr;
        !           521: static numPorts;
        !           522: int index, move;
        !           523: uslRootHubPortStatus stat;
        !           524: intTrans last;
        !           525:        
        !           526:        last = outstanding[0];
        !           527:        if(last.handler == nil)
        !           528:        {
        !           529:                return;
        !           530:        }
        !           531:        
        !           532:        if(CompareAndSwap(0, 1, &intLock))
        !           533:        {
        !           534:                for(index = 1; index < kMaxOutstandingTrans ; index++)
        !           535:                {
        !           536:                        outstanding[index-1] = outstanding[index];
        !           537:                        if(outstanding[index].handler == nil)
        !           538:                        {
        !           539:                                break;
        !           540:                        }
        !           541:                }
        !           542:        
        !           543:                statusChanged = 0;
        !           544:                statusBit = 1;
        !           545:                if(UIMGetRhStatus(&status) == noErr)
        !           546:                {
        !           547:                        if( (status & kOHCIHcRhStatus_Change ) != 0)
        !           548:                        {
        !           549:                                statusChanged |= statusBit;     /* Hub status change bit */
        !           550:                        }
        !           551:                        
        !           552:                        if(numPorts == 0)
        !           553:                        {
        !           554:                                if(UIMGetRootDescriptor(&descr) == noErr)
        !           555:                                {
        !           556:                                        numPorts = descr.numPorts;
        !           557:                                }
        !           558:                                else
        !           559:                                {
        !           560:                                        //DebugStr("\pRoot hub int simulation hosed. No ports, tell Barry");
        !           561:                                        USBExpertStatus(0,"\pUSL - Root hub int simulation hosed. No ports, tell Barry", 0);
        !           562:                                }
        !           563:                        }
        !           564: 
        !           565:                        for(index = 1; index <= numPorts; index++)
        !           566:                        {
        !           567:                                statusBit <<= 1;        /* Next bit */
        !           568:                                
        !           569:                                if(UIMRootHubGetPortStatus(index, &stat) == noErr)
        !           570:                                {
        !           571:                                        if(stat.portChangeFlags != 0)
        !           572:                                        {
        !           573:                                                statusChanged |= statusBit;     /* Hub status change bit */
        !           574:                                        }
        !           575:                                }
        !           576:                                
        !           577:                        }
        !           578:                        
        !           579:                }
        !           580:                
        !           581:                move = last.bufLen;
        !           582:                if(move > sizeof(statusChanged))
        !           583:                {
        !           584:                        move = sizeof(statusChanged);
        !           585:                }
        !           586:                if(numPorts < 8)
        !           587:                {
        !           588:                        move = 1;
        !           589:                }
        !           590:                statusChanged = HostToUSBWord(statusChanged);
        !           591:                usb_BlockMoveData(&statusChanged, last.buf, move);
        !           592:                CompareAndSwap(1, 0, &intLock); /* Unlock the queue */
        !           593:                (*last.handler)(last.refCon, noErr, last.bufLen - move);
        !           594:        }
        !           595: }
        !           596: 
        !           597: 
        !           598: 
        !           599: 
        !           600: void pollRootHubSim(void)
        !           601: {
        !           602: UInt32 intrStatus;
        !           603: 
        !           604:        if(outstanding[0].handler != nil)
        !           605:        {
        !           606:                if( (UIMGetInterruptStatus(&intrStatus) == noErr) &&
        !           607:                    ((intrStatus & kOHCIHcInterrupt_RHSC) != 0) )
        !           608:                {
        !           609:                        UIMClearInterruptStatus(kOHCIHcInterrupt_RHSC);
        !           610:                        rootHubStatusChangeHandler();
        !           611:                }
        !           612:        }
        !           613: }
        !           614: 
        !           615: void SimulateRootHubInt(UInt8 endpoint, UInt8 *buf, UInt32 bufLen,
        !           616:                                                CallBackFuncPtr handler, UInt32 refCon)
        !           617: {
        !           618: int index;
        !           619: 
        !           620:        if(endpoint != 1)
        !           621:        {
        !           622:                (*handler)(refCon, -1, bufLen);
        !           623:                return;
        !           624:        }
        !           625: 
        !           626:        if(!CompareAndSwap(0, 1, &intLock))
        !           627:        {       /* Busy */
        !           628:                (*handler)(refCon, -1, bufLen);
        !           629:                return;
        !           630:        }
        !           631: 
        !           632:        for(index = 0; index < kMaxOutstandingTrans; index++)
        !           633:        {
        !           634:                if(outstanding[0].handler == nil)
        !           635:                {
        !           636:                        /* found free trans */
        !           637:                        outstanding[0].buf = buf;
        !           638:                        outstanding[0].bufLen = bufLen;
        !           639:                        outstanding[0].handler = handler;
        !           640:                        outstanding[0].refCon = refCon;
        !           641:                        CompareAndSwap(1, 0, &intLock); /* Unlock the queue */
        !           642:                        return;
        !           643:                }
        !           644:        }
        !           645: 
        !           646:        CompareAndSwap(1, 0, &intLock); /* Unlock the queue */
        !           647:        (*handler)(refCon, -1, bufLen); /* too many trans */
        !           648:        
        !           649: }
        !           650: 
        !           651: void SimulateRootHub(setupPacket *packet, UInt8 endpoint, UInt8 *buf, UInt32 inBufLen,
        !           652:                                                CallBackFuncPtr handler, UInt32 refCon)
        !           653: {
        !           654: UInt8 dirn, type, recipient;
        !           655: Boolean stall;
        !           656: UInt32 *bufLen;
        !           657:        if(endpoint != 0)
        !           658:        {
        !           659:                return;
        !           660:        }
        !           661:        bufLen = &inBufLen;     /* Barry, was stamping on param block field */
        !           662: 
        !           663: #if 0
        !           664: typedef union{
        !           665:        UInt8 byte[8];
        !           666:        UInt16 word[4];
        !           667:        }setupPacket;
        !           668: 
        !           669: enum{
        !           670: /* Byte offsets */
        !           671:        bmRqType = 0,
        !           672:        bUsedFlag = bmRqType,
        !           673:        bRequest,
        !           674: /* Word offsets */
        !           675:        wValue =1,      
        !           676:        wIndex,
        !           677:        wLength
        !           678:        };
        !           679: #endif
        !           680: 
        !           681:        stall = false;
        !           682:        dirn = (packet->byte[bmRqType] >> kUSBRqDirnShift) & kUSBRqDirnMask;
        !           683:        type = (packet->byte[bmRqType] >> kUSBRqTypeShift) & kUSBRqTypeMask;
        !           684:        recipient = packet->byte[bmRqType] & kUSBRqRecipientMask;
        !           685: 
        !           686:        if(type == kUSBStandard)
        !           687:        {
        !           688: 
        !           689: #if 0
        !           690: Standard Requests
        !           691: 
        !           692: bmRequestType bRequest wValue wIndex wLength Data
        !           693: 00000000B              CLEAR_FEATURE   device
        !           694: 00000001B                                              Interface
        !           695: 00000010B                                              Endpoint
        !           696: 
        !           697: 10000000B GET_CONFIGURATION Zero Zero One Configuration
        !           698: 10000000B GET_DESCRIPTOR Descriptor
        !           699: 10000001B GET_INTERFACE Zero Interface One Alternate
        !           700: 
        !           701: 10000000B              GET_STATUS              device
        !           702: 10000001B                                              Interface
        !           703: 10000010B                                              Endpoint
        !           704: 
        !           705: 00000000B SET_ADDRESS Device
        !           706: 00000000B SET_CONFIGURATION Configuration
        !           707: 00000000B SET_DESCRIPTOR Descriptor
        !           708: 
        !           709: 00000000B              SET_FEATURE             device
        !           710: 00000001B                                              Interface
        !           711: 00000010B                                              Endpoint
        !           712: 
        !           713: 00000001B SET_INTERFACE Alternate
        !           714: 10000010B SYNCH_FRAME Zero Endpoint Two Frame Number#endif
        !           715: #endif
        !           716:                switch(packet->byte[bRequest])
        !           717:                {
        !           718:                        case kUSBRqClearFeature:
        !           719:                                if(packet->byte[bmRqType] == 0x00)
        !           720:                                {
        !           721:                                        /* Clear Device Feature */
        !           722:                                        stall = SimulateHubClearFeature(packet);
        !           723:                                }
        !           724:                                else if(packet->byte[bmRqType] == 0x01)
        !           725:                                {
        !           726:                                        /* Clear Interface Feature */
        !           727:                                        stall = true;
        !           728:                                        //DebugStr("\pRoot hub not implemented yet 2");
        !           729:                                        USBExpertStatus(0,"\pUSL - Root hub not implemented yet 2", 0);
        !           730:                                }
        !           731:                                else if(packet->byte[bmRqType] == 0x02)
        !           732:                                {
        !           733:                                        /* Clear Endpoint Feature */
        !           734:                                        stall = true;
        !           735:                                        //DebugStr("\pRoot hub not implemented yet 3");
        !           736:                                        USBExpertStatus(0,"\pUSL - Root hub not implemented yet 3", 0);
        !           737:                                }
        !           738:                                else
        !           739:                                {
        !           740:                                        stall = true;
        !           741:                                }
        !           742:                        break;
        !           743:                
        !           744:                        case kUSBRqGetConfig:
        !           745:                                if(packet->byte[bmRqType] == 0x80)
        !           746:                                {
        !           747:                                        /* Get configuration */
        !           748:                                        stall = true;
        !           749:                                        //DebugStr("\pRoot hub not implemented yet 4");
        !           750:                                        USBExpertStatus(0,"\pUSL - Root hub not implemented yet 4", 0);
        !           751:                                }
        !           752:                                else
        !           753:                                {
        !           754:                                        stall = true;
        !           755:                                }
        !           756:                        break;
        !           757:                
        !           758:                        case kUSBRqGetDescriptor:
        !           759:                                if(packet->byte[bmRqType] == 0x80)
        !           760:                                {
        !           761:                                        /* Get descriptor */
        !           762:                                        stall = SimulateGetADeviceDescriptor(packet, buf, bufLen);
        !           763:                                }
        !           764:                                else
        !           765:                                {
        !           766:                                        stall = true;
        !           767:                                }
        !           768:                        
        !           769:                        break;
        !           770:                
        !           771:                        case kUSBRqGetInterface:
        !           772:                                if(packet->byte[bmRqType] == 0x81)
        !           773:                                {
        !           774:                                        /* Get interface */
        !           775:                                        stall = true;
        !           776:                                        //DebugStr("\pRoot hub not implemented yet 6");
        !           777:                                        USBExpertStatus(0,"\pUSL - Root hub not implemented yet 6", 0);
        !           778:                                }
        !           779:                                else
        !           780:                                {
        !           781:                                        stall = true;
        !           782:                                }
        !           783:                        break;
        !           784:                
        !           785:                        case kUSBRqGetStatus:
        !           786:                                if(packet->byte[bmRqType] == 0x80)
        !           787:                                {
        !           788:                                UInt16 status;
        !           789:                                int copy;
        !           790:                                        /* Get Device Status */
        !           791:                                        stall = false;
        !           792:                                        status = USB_CONSTANT16(1);             // self powered
        !           793:                                        copy = sizeof(status);
        !           794:                                        if(copy > *bufLen)
        !           795:                                        {
        !           796:                                                copy = *bufLen;
        !           797:                                        }
        !           798:                                        usb_BlockMoveData(&status, buf, copy);
        !           799:                                        *bufLen -= copy;
        !           800:                                        
        !           801:                                }
        !           802:                                else if(packet->byte[bmRqType] == 0x81)
        !           803:                                {
        !           804:                                        /* Get Interface Status */
        !           805:                                        stall = true;
        !           806:                                        //DebugStr("\pRoot hub not implemented yet 8");
        !           807:                                        USBExpertStatus(0,"\pUSL - Root hub not implemented yet 8", 0);
        !           808:                                }
        !           809:                                else if(packet->byte[bmRqType] == 0x82)
        !           810:                                {
        !           811:                                        /* Get Endpoint Status */
        !           812:                                        stall = true;
        !           813:                                        //DebugStr("\pRoot hub not implemented yet 9");
        !           814:                                        USBExpertStatus(0,"\pUSL - Root hub not implemented yet 9", 0);
        !           815:                                }
        !           816:                                else
        !           817:                                {
        !           818:                                        stall = true;
        !           819:                                }
        !           820:                        break;
        !           821:                
        !           822:                        case kUSBRqSetAddress:
        !           823:                                if(packet->byte[bmRqType] == 0x00)
        !           824:                                {
        !           825:                                        /* Set address */
        !           826:                                        stall = UIMSetOurAddress(USBToHostWord(packet->word[wValue]));
        !           827:                                }
        !           828:                                else
        !           829:                                {
        !           830:                                        stall = true;
        !           831:                                }                       
        !           832:                        break;
        !           833:                
        !           834:                        case kUSBRqSetConfig:
        !           835:                                if(packet->byte[bmRqType] == 0x00)
        !           836:                                {
        !           837:                                        /* Set configuration */
        !           838:                                        stall = SimulateSetConfiguration(USBToHostWord(packet->word[wValue]));
        !           839:                                }
        !           840:                                else
        !           841:                                {
        !           842:                                        stall = true;
        !           843:                                }                       
        !           844:                        break;
        !           845:                
        !           846:                        case kUSBRqSetDescriptor:
        !           847:                                if(packet->byte[bmRqType] == 0x00)
        !           848:                                {
        !           849:                                        /* Set descriptor */
        !           850:                                        stall = true;
        !           851:                                        //DebugStr("\pRoot hub not implemented yet 12");
        !           852:                                        USBExpertStatus(0,"\pUSL - Root hub not implemented yet 12", 0);
        !           853:                                }
        !           854:                                else
        !           855:                                {
        !           856:                                        stall = true;
        !           857:                                }                       
        !           858:                        break;
        !           859:                
        !           860:                        case kUSBRqSetFeature:
        !           861:                                if(packet->byte[bmRqType] == 0x00)
        !           862:                                {
        !           863:                                        /* Set Device Feature */
        !           864:                                        stall = SimulateHubSetFeature(packet);
        !           865:                                }
        !           866:                                else if(packet->byte[bmRqType] == 0x01)
        !           867:                                {
        !           868:                                        /* Set Interface Feature */
        !           869:                                        stall = true;
        !           870:                                        //DebugStr("\pRoot hub not implemented yet 14");
        !           871:                                        USBExpertStatus(0,"\pUSL - Root hub not implemented yet 14", 0);
        !           872:                                }
        !           873:                                else if(packet->byte[bmRqType] == 0x02)
        !           874:                                {
        !           875:                                        /* Set Endpoint Feature */
        !           876:                                        stall = true;
        !           877:                                        //DebugStr("\pRoot hub not implemented yet 15");
        !           878:                                        USBExpertStatus(0,"\pUSL - Root hub not implemented yet 15", 0);
        !           879:                                }
        !           880:                                else
        !           881:                                {
        !           882:                                        stall = true;
        !           883:                                }
        !           884:                        break;
        !           885:                
        !           886:                        case kUSBRqSetInterface:
        !           887:                                if(packet->byte[bmRqType] == 0x01)
        !           888:                                {
        !           889:                                        /* Set interface */
        !           890:                                        stall = true;
        !           891:                                        //DebugStr("\pRoot hub not implemented yet 16");
        !           892:                                        USBExpertStatus(0,"\pUSL - Root hub not implemented yet 16", 0);
        !           893:                                }
        !           894:                                else
        !           895:                                {
        !           896:                                        stall = true;
        !           897:                                }                       
        !           898:                        break;
        !           899:                
        !           900:                        case kUSBRqSyncFrame:
        !           901:                                stall = true;
        !           902:                        break;
        !           903: 
        !           904:                        default:
        !           905:                                stall = true;
        !           906:                        break;
        !           907: 
        !           908:                }
        !           909:        }
        !           910:        else if(type == kUSBClass)
        !           911:        {
        !           912: 
        !           913: #if 0
        !           914: Class-specific Requests
        !           915: 
        !           916: ClearHubFeature  0010 0000B CLEAR_FEATURE Feature
        !           917: ClearPortFeature 0010 0011B CLEAR_FEATURE Feature
        !           918: GetBusState      1010 0011B GET_STATE Zero Port One Per Port
        !           919: GetHubDescriptor 1010 0000B GET_DESCRIPTOR Descriptor
        !           920: GetHubStatus     1010 0000B GET_STATUS Zero Zero Four Hub Status
        !           921: GetPortStatus    1010 0011B GET_STATUS Zero Port Four Port Status
        !           922: SetHubDescriptor 0010 0000B SET_DESCRIPTOR Descriptor
        !           923: SetHubFeature    0010 0000B SET_FEATURE Feature
        !           924: SetPortFeature   0010 0011B SET_FEATURE Feature
        !           925: #endif         
        !           926:                switch(packet->byte[bRequest])
        !           927:                {
        !           928:                        case kUSBRqClearFeature:
        !           929:                                if(packet->byte[bmRqType] == 0x20)
        !           930:                                {
        !           931:                                        /* ClearHubFeature */
        !           932:                                        stall = true;
        !           933:                                        //DebugStr("\pRoot hub not implemented yet 17");
        !           934:                                        USBExpertStatus(0,"\pUSL - Root hub not implemented yet 17", 0);
        !           935:                                }
        !           936:                                else if(packet->byte[bmRqType] == 0x23)
        !           937:                                {
        !           938:                                        stall = SimulateClearPortFeature(packet);
        !           939:                                }
        !           940:                                else
        !           941:                                {
        !           942:                                        stall = true;
        !           943:                                }
        !           944:                        
        !           945:                        break;
        !           946:                                
        !           947:                        case kUSBRqReserved1 /*GET_STATE*/:
        !           948:                                if(packet->byte[bmRqType] == 0xA3)
        !           949:                                {
        !           950:                                        /* GetBusState */
        !           951:                                        stall = true;
        !           952:                                        //DebugStr("\pRoot hub not implemented yet 18");
        !           953:                                        USBExpertStatus(0,"\pUSL - Root hub not implemented yet 18", 0);
        !           954:                                }
        !           955:                                else
        !           956:                                {
        !           957:                                        stall = true;
        !           958:                                }
        !           959:                        break;
        !           960:                                
        !           961:                        case kUSBRqGetDescriptor:
        !           962:                                if(packet->byte[bmRqType] == 0xA0)
        !           963:                                {
        !           964:                                        /* GetHubDescriptor */
        !           965:                                        SimulateGetHubDescriptor(packet, buf, bufLen);
        !           966:                                }
        !           967:                                else
        !           968:                                {
        !           969:                                        stall = true;
        !           970:                                }
        !           971:                        
        !           972:                        break;
        !           973:                                
        !           974:                        case kUSBRqGetStatus:
        !           975:                                if(packet->byte[bmRqType] == 0xA0)
        !           976:                                {
        !           977:                                        /* GetHubStatus */
        !           978:                                        stall = SimulateGetHubStatus(packet, buf, bufLen);
        !           979:                                }
        !           980:                                else if(packet->byte[bmRqType] == 0xA3)
        !           981:                                {
        !           982:                                        stall = SimulateGetPortStatus(packet, buf, bufLen);
        !           983:                                }
        !           984:                                else
        !           985:                                {
        !           986:                                        stall = true;
        !           987:                                }
        !           988:                        
        !           989:                        break;
        !           990:                                
        !           991:                        case kUSBRqSetDescriptor:
        !           992:                                if(packet->byte[bmRqType] == 0x20)
        !           993:                                {
        !           994:                                        /* SetHubDescriptor */
        !           995:                                        stall = true;
        !           996:                                        //DebugStr("\pRoot hub not implemented yet 20");
        !           997:                                        USBExpertStatus(0,"\pUSL - Root hub not implemented yet 20", 0);
        !           998:                                }
        !           999:                                else
        !          1000:                                {
        !          1001:                                        stall = true;
        !          1002:                                }
        !          1003:                        
        !          1004:                        break;
        !          1005:                                
        !          1006:                        case kUSBRqSetFeature :
        !          1007:                                if(packet->byte[bmRqType] == 0x20)
        !          1008:                                {
        !          1009:                                        /* SetHubFeature */
        !          1010:                                        stall = true;
        !          1011:                                        //DebugStr("\pRoot hub not implemented yet 21");
        !          1012:                                        USBExpertStatus(0,"\pUSL - Root hub not implemented yet 21", 0);
        !          1013:                                }
        !          1014:                                else if(packet->byte[bmRqType] == 0x23)
        !          1015:                                {
        !          1016:                                        stall = SimulateSetPortFeature(packet);
        !          1017:                                }
        !          1018:                                else
        !          1019:                                {
        !          1020:                                        stall = true;
        !          1021:                                }
        !          1022:                        break;
        !          1023: 
        !          1024:                        default:
        !          1025:                                stall = true;
        !          1026:                        break;
        !          1027:                }
        !          1028: 
        !          1029:        }
        !          1030:        else
        !          1031:        {
        !          1032:                stall = true;
        !          1033:        }
        !          1034:        
        !          1035:        if(stall)
        !          1036:        {
        !          1037:                //DebugStr("\pSim Stall");
        !          1038:                USBExpertStatus(0,"\pUSL - Root hub simulated stall", 0);
        !          1039:        }
        !          1040:        (*handler)(refCon, stall?4:noErr, *bufLen);
        !          1041: }
        !          1042: 
        !          1043: void ResetRootHubSimulation(void)
        !          1044: {
        !          1045:        int     index;
        !          1046:        
        !          1047:        for(index = 0; index < kMaxOutstandingTrans; index++)
        !          1048:        {
        !          1049:                outstanding[0].handler = nil; // clear out any outstanding transactions
        !          1050:        }
        !          1051:        intLock = 0;
        !          1052: }
        !          1053: 

unix.superglobalmegacorp.com

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