Annotation of XNU/iokit/Drivers/usb/drvAppleOHCI/AppleOHCI_RootHub.cpp, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * The contents of this file constitute Original Code as defined in and
                      7:  * are subject to the Apple Public Source License Version 1.1 (the
                      8:  * "License").  You may not use this file except in compliance with the
                      9:  * License.  Please obtain a copy of the License at
                     10:  * http://www.apple.com/publicsource and read it before using this file.
                     11:  * 
                     12:  * This Original Code and all software distributed under the License are
                     13:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     14:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     15:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     16:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     17:  * License for the specific language governing rights and limitations
                     18:  * under the License.
                     19:  * 
                     20:  * @APPLE_LICENSE_HEADER_END@
                     21:  */
                     22: /*
                     23:  * Copyright (c) 1998 Apple Computer, Inc.  All rights reserved.
                     24:  *
                     25:  * HISTORY
                     26:  *
                     27:  */
                     28: 
                     29: 
                     30: #include "AppleOHCI.h"
                     31: #include <libkern/OSByteOrder.h>
                     32: 
                     33: #define nil (0)
                     34: #define DEBUGGING_LEVEL 0      // 1 = low; 2 = high; 3 = extreme
                     35: 
                     36: #define super IOUSBController
                     37: #define self this
                     38: 
                     39: /*
                     40:  * Root hub methods
                     41:  */
                     42: // FIXME  Should this routine go in the device?
                     43: IOReturn AppleOHCI::getRootHubDeviceDescriptor(IOUSBDeviceDescriptor *desc)
                     44: {
                     45:     IOUSBDeviceDescriptor newDesc =
                     46:     {
                     47:         sizeof(IOUSBDeviceDescriptor), // UInt8 length;
                     48:         kUSBDeviceDesc,                        // UInt8 descType;
                     49:         USB_CONSTANT16(kUSBRel10),     // UInt16 usbRel;
                     50:         kUSBHubClass,                  // UInt8 class;
                     51:         kUSBRootHubSubClass,           // UInt8 subClass;
                     52:         0,                             // UInt8 protocol;
                     53:         8,                             // UInt8 maxPacketSize;
                     54:         USB_CONSTANT16(_vendorID),     // UInt16 vendor;
                     55:         USB_CONSTANT16(_deviceID),     // UInt16 product;
                     56:         USB_CONSTANT16(_revisionID),   // UInt16 devRel;
                     57:         0,                             // UInt8 manuIdx;
                     58:         0,                             // UInt8 prodIdx;
                     59:         0,                             // UInt8 serialIdx;
                     60:         1                              // UInt8 numConf;
                     61:     };
                     62: 
                     63:     if (!desc)
                     64:         return(kIOReturnNoMemory);
                     65: 
                     66:     bcopy(&newDesc, desc, newDesc.length);
                     67: 
                     68:     return(kIOReturnSuccess);
                     69: }
                     70: 
                     71: IOReturn AppleOHCI::getRootHubDescriptor(IOUSBHubDescriptor *desc)
                     72: {
                     73:     IOUSBHubDescriptor hubDesc;
                     74:     UInt8 pps, nps, cd, ppoc, noc;
                     75:     UInt32 descriptorA, descriptorB;
                     76: 
                     77: 
                     78:     descriptorA = OSSwapInt32(pOHCIUIMData->pOHCIRegisters->hcRhDescriptorA);
                     79:     descriptorB = OSSwapInt32(pOHCIUIMData->pOHCIRegisters->hcRhDescriptorB);
                     80:     hubDesc.length = sizeof(IOUSBHubDescriptor);
                     81:     hubDesc.hubType = kUSBHubDescriptorType;
                     82:     hubDesc.numPorts = ((descriptorA & kOHCIHcRhDescriptorA_NDP)
                     83:                           >> kOHCIHcRhDescriptorA_NDPPhase);
                     84:     // Characteristics
                     85:     pps  = descriptorA & kOHCIHcRhDescriptorA_PSM;
                     86:     nps  = descriptorA & kOHCIHcRhDescriptorA_NPS;
                     87:     cd   = descriptorA & kOHCIHcRhDescriptorA_DT;
                     88:     ppoc = descriptorA & kOHCIHcRhDescriptorA_OCPM;
                     89:     noc  = descriptorA & kOHCIHcRhDescriptorA_NOCP;
                     90:     hubDesc.characteristics = 0;
                     91:     hubDesc.characteristics |= (pps  ? kPerPortSwitchingBit   : 0);
                     92:     hubDesc.characteristics |= (nps  ? kNoPowerSwitchingBit   : 0);
                     93:     hubDesc.characteristics |= (cd   ? kCompoundDeviceBit     : 0);
                     94:     hubDesc.characteristics |= (ppoc ? kPerPortOverCurrentBit : 0);
                     95:     hubDesc.characteristics |= (noc  ? kNoOverCurrentBit      : 0);
                     96:     hubDesc.characteristics = HostToUSBWord(hubDesc.characteristics);
                     97:     
                     98:     hubDesc.powerOnToGood = ((descriptorA & kOHCIHcRhDescriptorA_POTPGT)
                     99:                                >> kOHCIHcRhDescriptorA_POTPGTPhase);
                    100:     // the root hub has no power requirements
                    101:     hubDesc.hubCurrent = 0;
                    102: 
                    103:     // bitmap of removable ports
                    104:     *((UInt16*)&hubDesc.removablePortFlags[0]) =
                    105:         ((descriptorB & kOHCIHcRhDescriptorB_DR)
                    106:          >> kOHCIHcRhDescriptorB_DRPhase);
                    107:     *((UInt16 *)&hubDesc.removablePortFlags[2]) = 0;  // OHCI supports 15 ports
                    108:     *((UInt32 *)&hubDesc.removablePortFlags[4]) = 0;  // so zero out the rest
                    109: 
                    110:     // bitmap of power mode for each port
                    111:     *((UInt16 *)&hubDesc.pwrCtlPortFlags[0]) =
                    112:         ((descriptorB & kOHCIHcRhDescriptorB_PPCM)
                    113:          >> kOHCIHcRhDescriptorB_PPCMPhase);
                    114:     *((UInt16 *)&hubDesc.pwrCtlPortFlags[2]) = 0;  // OHCI supports 15 ports
                    115:     *((UInt32 *)&hubDesc.pwrCtlPortFlags[4]) = 0;  // so zero out the rest
                    116: 
                    117:     if (!desc)
                    118:         return(kIOReturnNoMemory);
                    119: 
                    120:     bcopy(&hubDesc, desc, hubDesc.length);
                    121: 
                    122: /*
                    123:     if (!buffer->appendBytes(&hubDesc,  hubDesc.length))
                    124:         return(kIOReturnNoMemory);
                    125: */
                    126:     
                    127:     return(kIOReturnSuccess);
                    128: }
                    129: 
                    130: IOReturn AppleOHCI::getRootHubConfDescriptor(OSData *desc)
                    131: {
                    132:     IOUSBConfigurationDescriptor confDesc =
                    133:     {
                    134:         sizeof(IOUSBConfigurationDescriptor),//UInt8 length;
                    135:         kUSBConfDesc,               //UInt8 descriptorType;
                    136:         USB_CONSTANT16(sizeof(IOUSBConfigurationDescriptor) +
                    137:                        sizeof(IOUSBInterfaceDescriptor) +
                    138:                        sizeof(IOUSBEndpointDescriptor)),   //UInt16 totalLength;
                    139:         1,                          //UInt8 numInterfaces;
                    140:         1,                          //UInt8 configValue;
                    141:         0,                          //UInt8 configStrIndex;
                    142:         0x60,                       //UInt8 attributes; self powered,
                    143:                                    //      supports remote wkup
                    144:         0,                          //UInt8 maxPower;
                    145:     };
                    146:     IOUSBInterfaceDescriptor intfDesc =
                    147:     {
                    148:         sizeof(IOUSBInterfaceDescriptor),//UInt8 length;
                    149:         kUSBInterfaceDesc,      //UInt8 descriptorType;
                    150:         0,                      //UInt8 interfaceNumber;
                    151:         0,                      //UInt8 alternateSetting;
                    152:         1,                      //UInt8 numEndpoints;
                    153:         kUSBHubClass,           //UInt8 interfaceClass;
                    154:         kUSBHubSubClass,        //UInt8 interfaceSubClass;
                    155:         1,                      //UInt8 interfaceProtocol;
                    156:         0                       //UInt8 interfaceStrIndex;
                    157:     };
                    158:     IOUSBEndpointDescriptor endptDesc =
                    159:     {
                    160:         sizeof(IOUSBEndpointDescriptor),//UInt8 length;
                    161:         kUSBEndpointDesc,       //UInt8 descriptorType;
                    162:         0x81,                   //UInt8  endpointAddress; In, 1
                    163:         kUSBInterrupt,          //UInt8 attributes;
                    164:         8, 0,                  //UInt16 maxPacketSize;
                    165:         255,                    //UInt8 interval;
                    166:     };
                    167: 
                    168:     if (!desc)
                    169:         return(kIOReturnNoMemory);
                    170: 
                    171:     if (!desc->appendBytes(&confDesc,  confDesc.length))
                    172:         return(kIOReturnNoMemory);
                    173: 
                    174:     if (!desc->appendBytes(&intfDesc,  intfDesc.length))
                    175:         return(kIOReturnNoMemory);
                    176: 
                    177:     if (!desc->appendBytes(&endptDesc, endptDesc.length))
                    178:         return(kIOReturnNoMemory);
                    179: 
                    180:     return(kIOReturnSuccess);
                    181: }
                    182: 
                    183: IOReturn AppleOHCI::setRootHubDescriptor(OSData * /*buffer*/)
                    184: {
                    185:     IOLog("%s: unimplemented set root hub descriptor\n", getName());
                    186:     return(kIOReturnSuccess);
                    187: }
                    188: 
                    189: IOReturn AppleOHCI::getRootHubStatus(IOUSBHubStatus *status)
                    190: {
                    191:     *(UInt32*)status = pOHCIUIMData->pOHCIRegisters->hcRhStatus;
                    192:     return(kIOReturnSuccess);
                    193: }
                    194: 
                    195: IOReturn AppleOHCI::setRootHubFeature(UInt16 wValue)
                    196: {
                    197:     switch(wValue)
                    198:     {
                    199:         case kUSBHubLocalPowerChangeFeature :
                    200:             IOLog("%s: unimplemented Set Power Change Feature\n", getName());
                    201:             // OHCIRootHubLPSChange(true);  // not implemented yet
                    202:             break;
                    203: 
                    204:         case kUSBHubOverCurrentChangeFeature :
                    205:             IOLog("%s: unimplemented Set Overcurrent Change Feature\n",
                    206:                   getName());
                    207:             // OHCIRootHubOCChange(true);  // not implemented yet
                    208:             break;
                    209: 
                    210:         default:
                    211:             IOLog("%s: Unknown hub set (%d) in root hub\n", getName(), wValue);
                    212:             break;
                    213:     }
                    214: 
                    215:     return(kIOReturnSuccess);
                    216: }
                    217: 
                    218: IOReturn AppleOHCI::clearRootHubFeature(UInt16 wValue)
                    219: {
                    220:     switch(wValue)
                    221:     {
                    222:         case kUSBHubLocalPowerChangeFeature :
                    223:             IOLog("%s: unimplemented Clear Power Change Feature\n", getName());
                    224:             // OHCIRootHubLPSChange(false);  // not implemented yet
                    225:             break;
                    226: 
                    227:         case kUSBHubOverCurrentChangeFeature :
                    228:             IOLog("%s: unimplemented Clear Overcurrent Change Feature\n",
                    229:                   getName());
                    230:             // OHCIRootHubOCChange(false);  // not implemented yet
                    231:             break;
                    232: 
                    233:         default:
                    234:             IOLog("%s: Unknown hub set (%d) in root hub\n", getName(), wValue);
                    235:             break;
                    236:     }
                    237: 
                    238:     return(kIOReturnSuccess);
                    239: }
                    240: 
                    241: IOReturn AppleOHCI::getRootHubPortStatus(IOUSBHubPortStatus *status, UInt16 port)
                    242: {
                    243:     if (port < 1 || port > 15)
                    244:         return(kIOReturnBadArgument);  // FIXME change error code
                    245:     *(UInt32*)status = pOHCIUIMData->pOHCIRegisters->hcRhPortStatus[port-1];
                    246:     return(kIOReturnSuccess);
                    247: }
                    248: 
                    249: IOReturn AppleOHCI::setRootHubPortFeature(UInt16 wValue, UInt16 wIndex)
                    250: {
                    251:     UInt16     port = wIndex-1;
                    252: 
                    253:     switch(wValue)
                    254:     {
                    255:         case kUSBHubPortSuspendFeature :
                    256:             OHCIRootHubPortSuspend(port, true);
                    257:             break;
                    258: 
                    259:         case kUSBHubPortResetFeature :
                    260:             OHCIRootHubResetPort(port);
                    261:             break;
                    262: 
                    263:         case kUSBHubPortEnableFeature :
                    264:             OHCIRootHubPortEnable(port, true);
                    265:             break;
                    266: 
                    267:         case kUSBHubPortPowerFeature :
                    268:             OHCIRootHubPortPower(port, true);
                    269:             OHCIRootHubPower(true);
                    270:             break;
                    271: 
                    272:         default:
                    273:             IOLog("%s: Unknown port set (%d) in root hub\n", getName(), wValue);
                    274:             break;
                    275:     }
                    276:     return(kIOReturnSuccess);
                    277: }
                    278: 
                    279: IOReturn AppleOHCI::clearRootHubPortFeature(UInt16 wValue, UInt16 wIndex)
                    280: {
                    281:     UInt16     port = wIndex-1;
                    282: 
                    283:     switch(wValue)
                    284:     {
                    285:         case kUSBHubPortEnableFeature :
                    286:             OHCIRootHubPortEnable(port, false);
                    287:             break;
                    288: 
                    289:         case kUSBHubPortSuspendFeature :
                    290:             OHCIRootHubPortSuspend(port, false);
                    291:             break;
                    292: 
                    293:         case kUSBHubPortPowerFeature :
                    294:             OHCIRootHubPortPower(port, false);
                    295:             // Now need to check if all ports are switched off and
                    296:             // gang off if in gang mode
                    297:             break;
                    298: 
                    299:         // ****** Change features *******
                    300:         case kUSBHubPortConnectionChangeFeature :
                    301:             OHCIRootHubResetChangeConnection(port);
                    302:             break;
                    303: 
                    304:         case kUSBHubPortEnableChangeFeature :
                    305:             OHCIRootHubResetEnableChange(port);
                    306:             break;
                    307: 
                    308:         case kUSBHubPortSuspendChangeFeature :
                    309:             OHCIRootHubResetSuspendChange(port);
                    310:             break;
                    311: 
                    312:         case kUSBHubPortOverCurrentChangeFeature :
                    313:             OHCIRootHubResetOverCurrentChange(port);
                    314:             break;
                    315: 
                    316:         case kUSBHubPortResetChangeFeature :
                    317:             OHCIRootHubResetResetChange(port);
                    318:             break;
                    319: 
                    320:         default:
                    321:             IOLog("%s: Unknown port clear (%d) in root hub\n", getName(), wValue);
                    322:             break;
                    323:     }
                    324:     return(kIOReturnSuccess);
                    325: }
                    326: 
                    327: IOReturn AppleOHCI::getRootHubPortState(UInt8 */*state*/, UInt16 /*port*/)
                    328: {
                    329:     IOLog("%s: unimplemented get hub bus state", getName());
                    330:     return(kIOReturnSuccess);
                    331: }
                    332: 
                    333: 
                    334: IOReturn AppleOHCI::setHubAddress(UInt16 wValue)
                    335: {
                    336:     pOHCIUIMData->rootHubFuncAddress = wValue;
                    337:     return (kIOReturnSuccess);
                    338: }
                    339: 
                    340: void AppleOHCI::OHCIRootHubPower(bool on)
                    341: {
                    342:     UInt32             value = 0;
                    343:     OHCIRegistersPtr   pOHCIRegisters = pOHCIUIMData->pOHCIRegisters;
                    344: 
                    345:     pOHCIRegisters->hcRhDescriptorA = OSSwapInt32 (OSSwapInt32(pOHCIUIMData->pOHCIRegisters->hcRhDescriptorA) | kOHCIHcRhDescriptorA_NPS); //FIXME ERIC
                    346: 
                    347:     if(on)
                    348:     {
                    349:         value |= kOHCIHcRhStatus_LPSC;/* power on to all ganged ports */
                    350:         value |= kOHCIHcRhStatus_CRWE;/* clear remove wakeup enable */
                    351:         value |= kOHCIHcRhStatus_OCIC;/* clear over current change indicator */
                    352:     }
                    353:     else
                    354:         value |= kOHCIHcRhStatus_LPS; /* turn global power off */
                    355: 
                    356:     pOHCIRegisters->hcRhStatus = OSSwapInt32 (value);
                    357: 
                    358:     return;
                    359: }
                    360: 
                    361: void AppleOHCI::OHCIRootHubResetChangeConnection(UInt16 port)
                    362: {
                    363:     UInt32             value = 0;
                    364:     OHCIRegistersPtr   pOHCIRegisters = pOHCIUIMData->pOHCIRegisters;
                    365: 
                    366:     
                    367:     value |= kOHCIHcRhPortStatus_CSC; /* clear status change */
                    368: 
                    369:     pOHCIRegisters->hcRhPortStatus[port] = OSSwapInt32 (value);
                    370:     IOSync();
                    371: 
                    372:     return;
                    373: }
                    374: 
                    375: 
                    376: void AppleOHCI::OHCIRootHubResetResetChange(UInt16 port)
                    377: {
                    378:     UInt32             value = 0;
                    379:     OHCIRegistersPtr   pOHCIRegisters = pOHCIUIMData->pOHCIRegisters;
                    380: 
                    381:     
                    382:     value |= kOHCIHcRhPortStatus_PRSC; /* clear reset status change */
                    383: 
                    384:     pOHCIRegisters->hcRhPortStatus[port] = OSSwapInt32 (value);
                    385:     IOSync();
                    386: 
                    387:     return;
                    388: }
                    389: 
                    390: void AppleOHCI::OHCIRootHubResetSuspendChange(UInt16 port)
                    391: {
                    392:     UInt32             value = 0;
                    393:     OHCIRegistersPtr   pOHCIRegisters = pOHCIUIMData->pOHCIRegisters;
                    394: 
                    395: 
                    396:     value |= kOHCIHcRhPortStatus_PSSC; /* clear suspend status change */
                    397: 
                    398:     pOHCIRegisters->hcRhPortStatus[port] = OSSwapInt32 (value);
                    399:     IOSync();
                    400: 
                    401:     return;
                    402: }
                    403: 
                    404: void AppleOHCI::OHCIRootHubResetEnableChange(UInt16 port)
                    405: {
                    406:     UInt32             value = 0;
                    407:     OHCIRegistersPtr   pOHCIRegisters = pOHCIUIMData->pOHCIRegisters;
                    408: 
                    409: 
                    410:     value |= kOHCIHcRhPortStatus_PESC; /* clear enable status change */
                    411: 
                    412:     pOHCIRegisters->hcRhPortStatus[port] = OSSwapInt32 (value);
                    413:     IOSync();
                    414: 
                    415:     return;
                    416: }
                    417: 
                    418:     
                    419: 
                    420: void AppleOHCI::OHCIRootHubResetOverCurrentChange(UInt16 port)
                    421: {
                    422:     UInt32             value = 0;
                    423:     OHCIRegistersPtr   pOHCIRegisters = pOHCIUIMData->pOHCIRegisters;
                    424: 
                    425: 
                    426:     value |= kOHCIHcRhPortStatus_OCIC; /* clear over current status change */
                    427: 
                    428:     pOHCIRegisters->hcRhPortStatus[port] = OSSwapInt32 (value);
                    429:     IOSync();
                    430: 
                    431:     return;
                    432: }
                    433: 
                    434: 
                    435: void AppleOHCI::OHCIRootHubResetPort (UInt16 port)
                    436: {
                    437:     UInt32             value = 0;
                    438:     OHCIRegistersPtr   pOHCIRegisters = pOHCIUIMData->pOHCIRegisters;
                    439: 
                    440: 
                    441:     value |= kOHCIHcRhPortStatus_PRS; /* sets Bit 8 in port root hub register */
                    442:     pOHCIRegisters->hcRhPortStatus[port] = OSSwapInt32 (value);
                    443:     IOSync();
                    444:     return;
                    445: 
                    446: }
                    447: 
                    448: void AppleOHCI::OHCIRootHubPortEnable(UInt16   port,
                    449:                                       bool     on)
                    450: {
                    451:     UInt32             value = 0;
                    452:     OHCIRegistersPtr   pOHCIRegisters = pOHCIUIMData->pOHCIRegisters;
                    453: 
                    454: 
                    455:     if(on)
                    456:         value |= kOHCIHcRhPortStatus_PES; /* enable port */
                    457:     else
                    458:         value |= kOHCIHcRhPortStatus_CCS; /* disable port */
                    459: 
                    460:     pOHCIRegisters->hcRhPortStatus[port] = OSSwapInt32 (value);
                    461:     IOSync();
                    462: 
                    463:     return;
                    464: }
                    465: 
                    466: void AppleOHCI::OHCIRootHubPortSuspend(UInt16  port,
                    467:                                        bool    on)
                    468: {
                    469:     UInt32             value = 0;
                    470:     OHCIRegistersPtr   pOHCIRegisters = pOHCIUIMData->pOHCIRegisters;
                    471: 
                    472: 
                    473:     if(on)
                    474:         value |= kOHCIHcRhPortStatus_PSS;  /* suspend port */
                    475:     else
                    476:         value |= kOHCIHcRhPortStatus_POCI; /* resume port */
                    477: 
                    478:     pOHCIRegisters->hcRhPortStatus[port] = OSSwapInt32 (value);
                    479:     IOSync();
                    480: 
                    481:     return;
                    482: }
                    483: 
                    484: void AppleOHCI::OHCIRootHubPortPower(UInt16    port,
                    485:                                      bool      on)
                    486: {
                    487:     UInt32             value = 0;
                    488:     OHCIRegistersPtr   pOHCIRegisters = pOHCIUIMData->pOHCIRegisters;
                    489: 
                    490: 
                    491:     if(on)
                    492:         value |= kOHCIHcRhPortStatus_PPS;  /* enable port power */
                    493:     else
                    494:         value |= kOHCIHcRhPortStatus_LSDA; /* disable port power */
                    495: 
                    496:     pOHCIRegisters->hcRhPortStatus[port] = OSSwapInt32 (value);
                    497:     IOSync();
                    498: 
                    499:     return;
                    500: }
                    501: 
                    502: /*
                    503:  * UIMRootHubStatusChange
                    504:  *
                    505:  * This method gets called when there is a change in the root hub status
                    506:  * or a change in the status of one of the ports.  It is assumed that the
                    507:  * interrupt will be cleared for us, but we don't clear the change
                    508:  * condition, we will get another interrupt.  So turn off the interrupt.
                    509:  * Entering this function means that someone turned on the RHSC interrupt
                    510:  * and that there is a client waiting in the queue.  The client expects a
                    511:  * status change bitmap.
                    512:  * To fix: currently there can only be one client in the queue.  The RHSC
                    513:  * interrupt should only be turned off if there is no one else in the queue,
                    514:  * or, all clients should be responded to with the one interrupt.
                    515:  */
                    516: void AppleOHCI::UIMRootHubStatusChange(void)
                    517: {
                    518:     OHCIRegistersPtr   pOHCIRegisters = pOHCIUIMData->pOHCIRegisters;
                    519:     UInt32             hubStatus, portStatus, statusBit;
                    520:     UInt16             statusChangedBitmap;   /* only have 15 ports in OHCI */
                    521:     UInt8              numPorts;
                    522:     unsigned int       index, port, move;
                    523:     struct InterruptTransaction last;
                    524:     UInt32             descriptorA;
                    525: 
                    526: 
                    527:     /* turn off RHSC interrupt */
                    528:     pOHCIRegisters->hcInterruptDisable = OSSwapInt32(kOHCIHcInterrupt_RHSC);
                    529:     IOSync();
                    530: 
                    531:     /*
                    532:      * Encode the status change bitmap.  The format of the bitmap:
                    533:      * bit0 = hub status changed
                    534:      * bit1 = port 1 status changed
                    535:      * bit2 = port 2 status changed
                    536:      * ...
                    537:      * See USB 1.0 spec section 11.8.3 for more info.
                    538:      */
                    539: 
                    540:     statusChangedBitmap = 0;
                    541:     statusBit = 1;
                    542: 
                    543:     getRootHubStatus((IOUSBHubStatus *)&hubStatus);
                    544:     if ((hubStatus & kOHCIHcRhStatus_Change ) != 0)
                    545:         statusChangedBitmap |= statusBit; /* Hub status change bit */
                    546: 
                    547:     descriptorA = OSSwapInt32(pOHCIRegisters->hcRhDescriptorA);
                    548:     numPorts = ((descriptorA & kOHCIHcRhDescriptorA_NDP)
                    549:                 >> kOHCIHcRhDescriptorA_NDPPhase);
                    550: 
                    551:     for (port = 1; port <= numPorts; port++)
                    552:     {
                    553:         statusBit <<= 1;    /* Next bit */
                    554: 
                    555:         getRootHubPortStatus((IOUSBHubPortStatus *)&portStatus, port);
                    556:         if ((portStatus & kOHCIHcRhPortStatus_Change) != 0)
                    557:             statusChangedBitmap |= statusBit; /* Hub status change bit */
                    558:     }
                    559: 
                    560:     /*
                    561:      * If a transaction is queued, handle it
                    562:      */
                    563:     if(_outstandingTrans[0].completion.action != nil)
                    564:     {
                    565:         last = _outstandingTrans[0];
                    566:         IOTakeLock(_intLock);
                    567:         for (index = 1; index < kMaxOutstandingTrans ; index++)
                    568:         {
                    569:             _outstandingTrans[index-1] = _outstandingTrans[index];
                    570:             if (_outstandingTrans[index].completion.action == nil)
                    571:                 break;
                    572:         }
                    573: 
                    574:         move = last.bufLen;
                    575:         if (move > sizeof(statusChangedBitmap))
                    576:             move = sizeof(statusChangedBitmap);
                    577:         if (numPorts < 8)
                    578:             move = 1;
                    579: 
                    580:         statusChangedBitmap = HostToUSBWord(statusChangedBitmap);
                    581:         last.buf->writeBytes(0,&statusChangedBitmap, move);
                    582:         IOUnlock(_intLock); /* Unlock the queue */
                    583:         complete(last.completion, kIOReturnSuccess, last.bufLen - move);
                    584:     }
                    585: }
                    586: 
                    587: /*
                    588:  * SimulateRootHubInt
                    589:  * Simulate the interrupt pipe (status change pipe) of a hub for the root
                    590:  * hub.  The basic concept is to simulate the UIMCreateInterruptTransfer
                    591:  * so we keep our own little queue -> _outstandingTrans.  We are turning
                    592:  * on the RHSC interrupt so UIMRootHubStatusChange() should handle the
                    593:  * dequeueing.
                    594:  */
                    595: void AppleOHCI::SimulateRootHubInt(
                    596:             UInt8                                      endpoint,
                    597:             IOMemoryDescriptor *                       buf,
                    598:             UInt32                                     bufLen,
                    599:             IOUSBCompletion                            completion)
                    600: {
                    601:     int                index;
                    602:     OHCIRegistersPtr   pOHCIRegisters = pOHCIUIMData->pOHCIRegisters;
                    603: 
                    604:     if (endpoint != 1)
                    605:     {
                    606:         complete(completion, -1, bufLen);
                    607:         return;
                    608:     }
                    609: 
                    610:     IOTakeLock(_intLock);
                    611:     
                    612:     for (index = 0; index < kMaxOutstandingTrans; index++)
                    613:     {
                    614:         if (_outstandingTrans[index].completion.action == nil)
                    615:         {
                    616:             /* found free trans */
                    617:             _outstandingTrans[index].buf = buf;
                    618:             _outstandingTrans[index].bufLen = bufLen;
                    619:             _outstandingTrans[index].completion = completion;
                    620:             IOUnlock(_intLock); /* Unlock the queue */
                    621: 
                    622:             /* turn on RHSC interrupt */
                    623:             pOHCIRegisters->hcInterruptEnable =pOHCIRegisters->hcInterruptEnable
                    624:                 | OSSwapInt32(kOHCIHcInterrupt_RHSC);
                    625:             IOSync();
                    626: 
                    627:             return;
                    628:         }
                    629:     }
                    630: 
                    631:     IOUnlock(_intLock); /* Unlock the queue */
                    632:     complete(completion, -1, bufLen); /* too many trans */
                    633: }
                    634: 

unix.superglobalmegacorp.com

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