|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.