|
|
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: OHCIRootHub.c ! 27: ! 28: Contains: xxx put contents here xxx ! 29: ! 30: Version: xxx put version here xxx ! 31: ! 32: Copyright: � 1998 by Apple Computer, Inc., all rights reserved. ! 33: ! 34: File Ownership: ! 35: ! 36: DRI: xxx put dri here xxx ! 37: ! 38: Other Contact: xxx put other contact here xxx ! 39: ! 40: Technology: xxx put technology here xxx ! 41: ! 42: Writers: ! 43: ! 44: (TC) Tom Clark ! 45: (BT) Barry Twycross ! 46: ! 47: Change History (most recent first): ! 48: ! 49: <USB8> 8/12/98 BT Move root hub into UIM again ! 50: <USB7> 7/10/98 TC Back out previous rev. ! 51: <USB6> 6/30/98 BT Move Root hub sim into UIM ! 52: <USB5> 6/11/98 BT Fix hub descriptor so it knows about overcurrent and power mode ! 53: <USB4> 4/23/98 BT Add reset portsuspend change ! 54: <USB3> 4/16/98 BT Channge to new headers ! 55: <USB2> 4/15/98 BT Add over current change reset ! 56: <1> 3/19/98 BT first checked in ! 57: */ ! 58: #include "USB.h" ! 59: #include "driverservices.h" ! 60: ! 61: #include "OHCIUIM.h" ! 62: #include "OHCIRootHub.h" ! 63: #include "pci.h" ! 64: ! 65: OHCIUIMDataPtr pOHCIUIMData; ! 66: ! 67: void IOSync(void); ! 68: UInt32 EndianSwap32Bit(UInt32 x); ! 69: static void parameterNotUsed(UInt32 notUsed) ! 70: { ! 71: notUsed = 0; ! 72: } ! 73: ! 74: //////////////////////////////////////////////////////////////////////////////// ! 75: // ! 76: // OHCIUIMGetRootHubDescriptor ! 77: // ! 78: // This proc returns the root hub descriptor fields. ! 79: // ! 80: ! 81: OSStatus OHCIGetRootDescriptor( ! 82: uslBusRef bus, /* which hub */ ! 83: uslRootHubDescriptorPtr descr) ! 84: { ! 85: OHCIRegistersPtr pOHCIRegisters; ! 86: UInt32 hcRhDescriptorA; ! 87: UInt32 hcRhDescriptorB; ! 88: UInt32 powerSwitching, ! 89: gangedSwitching, ! 90: compoundDevice, ! 91: overCurrent, ! 92: globalOverCurrent, ! 93: deviceRemovable, ! 94: gangedPower; ! 95: OSStatus status = noErr; ! 96: ! 97: parameterNotUsed(bus); ! 98: ! 99: pOHCIRegisters = pOHCIUIMData->pOHCIRegisters; ! 100: // Read hcRhDescriptorA registers. ! 101: hcRhDescriptorA = EndianSwap32Bit (pOHCIRegisters->hcRhDescriptorA); ! 102: hcRhDescriptorB = EndianSwap32Bit (pOHCIRegisters->hcRhDescriptorB); ! 103: ! 104: ! 105: // Copy data from hcRhDescriptorA masking out reserved bit fields. ! 106: // The hcRhDescriptorA register is the 32 bit byte swap of nbrPorts, ! 107: // hubCharacteristics, and pwrOn2PwrGood. ! 108: // could have problem with porting and overwriting of other bytes. ! 109: hcRhDescriptorA &= kOHCINumPortsMask; ! 110: descr->numPorts = hcRhDescriptorA; ! 111: ! 112: ! 113: //Now get NPS Field, Power Switching ! 114: hcRhDescriptorA = EndianSwap32Bit (pOHCIRegisters->hcRhDescriptorA); ! 115: powerSwitching = (hcRhDescriptorA & kOHCIPowerSwitchingMask) >> kOHCIPowerSwitchingOffset; ! 116: descr->powerSwitching = !((Boolean) powerSwitching); ! 117: ! 118: //Now Get Ganged Switching ! 119: gangedSwitching = (hcRhDescriptorA & kOHCIGangedSwitchingMask) >> kOHCIGangedSwitchingOffset; ! 120: descr->gangedSwitching = !(Boolean) gangedSwitching; ! 121: ! 122: /* ! 123: UInt32* myPointer; ! 124: ! 125: myPointer = (UInt32 *) &(descr->gangedSwitching); ! 126: ! 127: *myPointer = (Boolean) gangedSwitching; ! 128: */ ! 129: ! 130: ! 131: ! 132: //Is it a Compound device? ! 133: compoundDevice = (hcRhDescriptorA & kOHCICompoundDeviceMask) >> kOHCICompoundDeviceOffset; ! 134: descr->compoundDevice = (Boolean) compoundDevice; ! 135: ! 136: //Does it allow overcurrent ! 137: overCurrent = (hcRhDescriptorA & kOHCIOverCurrentMask) >> kOHCIOverCurrentOffset; ! 138: descr->overCurrent = !(Boolean) overCurrent; ! 139: ! 140: //Does it allow Global Over Current? ! 141: globalOverCurrent = (hcRhDescriptorA & kOHCIGlobalOverCurrentMask) >> kOHCIGlobalOverCurrentOffset; ! 142: descr->globalOverCurrent = !(Boolean) globalOverCurrent; ! 143: ! 144: //Find the device removable and ganged power flags and put into stuffed byte form ! 145: deviceRemovable = (hcRhDescriptorB & kOHCIDeviceRemovableMask) >> kOHCIDeviceRemovableOffset; ! 146: descr->portFlags[0] = (UInt8) deviceRemovable; ! 147: gangedPower = (hcRhDescriptorB & kOHCIGangedPowerMask) >> kOHCIGangedPowerOffset; ! 148: descr->portFlags[1] = (UInt8) gangedPower; ! 149: ! 150: ! 151: return (status); ! 152: } ! 153: ! 154: OSStatus OHCIGetInterruptStatus( ! 155: uslBusRef bus, ! 156: UInt32 *status) ! 157: { ! 158: OHCIRegistersPtr pOHCIRegisters; ! 159: ! 160: parameterNotUsed(bus); ! 161: ! 162: pOHCIRegisters = pOHCIUIMData->pOHCIRegisters; ! 163: *status = EndianSwap32Bit (pOHCIRegisters->hcInterruptStatus); ! 164: return(noErr); ! 165: } ! 166: ! 167: ! 168: OSStatus OHCIClearInterruptStatus( ! 169: uslBusRef bus, ! 170: UInt32 status) ! 171: { ! 172: OHCIRegistersPtr pOHCIRegisters; ! 173: ! 174: parameterNotUsed(bus); ! 175: ! 176: pOHCIRegisters = pOHCIUIMData->pOHCIRegisters; ! 177: pOHCIRegisters->hcInterruptStatus = EndianSwap32Bit (status); ! 178: return(noErr); ! 179: ! 180: } ! 181: ! 182: OSStatus OHCIGetRhStatus( ! 183: uslBusRef bus, ! 184: UInt32 *status) ! 185: { ! 186: OHCIRegistersPtr pOHCIRegisters; ! 187: ! 188: parameterNotUsed(bus); ! 189: ! 190: pOHCIRegisters = pOHCIUIMData->pOHCIRegisters; ! 191: *status = EndianSwap32Bit (pOHCIRegisters->hcRhStatus); ! 192: return(noErr); ! 193: ! 194: } ! 195: ! 196: ! 197: OSStatus OHCIRootHubGetPortStatus( ! 198: uslBusRef bus, ! 199: short port, ! 200: uslRootHubPortStatusPtr portStatus) ! 201: { ! 202: UInt32 portFlags; ! 203: UInt32 hcRhPortStatus; ! 204: OSStatus status = noErr; ! 205: ! 206: parameterNotUsed(bus); ! 207: ! 208: //adjust port number for array use ! 209: port--; ! 210: ! 211: hcRhPortStatus = EndianSwap32Bit (pOHCIUIMData->pOHCIRegisters->hcRhPortStatus[port]); ! 212: //zzz ! 213: // sprintf (debugStr, "OHCIUIMportstatus = %lx", hcRhPortStatus); ! 214: // DebugStr ((ConstStr255Param) c2pstr (debugStr)); ! 215: //zzz ! 216: portFlags = hcRhPortStatus & kOHCIPortFlagsMask; ! 217: portStatus->portFlags = (UInt16) portFlags; ! 218: portFlags = hcRhPortStatus >> kOHCIportChangeFlagsOffset; ! 219: portStatus->portChangeFlags = (UInt16) portFlags; ! 220: return (status); ! 221: ! 222: } ! 223: ! 224: OSStatus OHCIResetRootHub ( ! 225: uslBusRef bus) ! 226: { ! 227: UInt32 rootHubDescriptorA, savedControl; ! 228: OSStatus status = noErr; ! 229: OHCIRegistersPtr pOHCIRegisters; ! 230: UInt16 numDownstreamPorts; ! 231: UInt16 powerOnToGoodTime; ! 232: ! 233: parameterNotUsed(bus); ! 234: ! 235: pOHCIRegisters = pOHCIUIMData->pOHCIRegisters; ! 236: ! 237: rootHubDescriptorA = EndianSwap32Bit(pOHCIRegisters->hcRhDescriptorA); ! 238: ! 239: numDownstreamPorts = rootHubDescriptorA & kOHCIHcRhDescriptorA_NDP; ! 240: powerOnToGoodTime = 2 * ((rootHubDescriptorA & kOHCIHcRhDescriptorA_POTPGT) >> kOHCIHcRhDescriptorA_POTPGTPhase); ! 241: // should we wait for this time here? How about if the ports aren't powered on already? ! 242: kprintf("POTPGT val=%d\n",powerOnToGoodTime); ! 243: DelayForHardware(DurationToAbsolute(powerOnToGoodTime*durationMillisecond)); ! 244: // put USB into USB bus-reset state ! 245: savedControl = EndianSwap32Bit(pOHCIRegisters->hcControl) & ~(kOHCIHcControl_HCFS); ! 246: pOHCIRegisters->hcControl = EndianSwap32Bit (pOHCIRegisters->hcControl) & ~(kOHCIHcControl_HCFS); ! 247: ! 248: DelayForHardware(DurationToAbsolute(10*durationMillisecond)); ! 249: ! 250: // then go to the operational state ! 251: pOHCIRegisters->hcControl = EndianSwapImm32Bit((kOHCIFunctionalState_Operational << kOHCIHcControl_HCFSPhase) | savedControl) ; ! 252: ! 253: DelayForHardware(DurationToAbsolute(10*durationMillisecond)); // spec requires devices be ready within 10mS ! 254: ! 255: ! 256: ResetRootHubSimulation(); ! 257: ! 258: return (status); ! 259: } ! 260: ! 261: ! 262: OSStatus OHCIRootHubPower( ! 263: uslBusRef bus, ! 264: Boolean on) ! 265: { ! 266: UInt32 value; ! 267: OSStatus status = noErr; ! 268: OHCIRegistersPtr pOHCIRegisters; ! 269: ! 270: parameterNotUsed(bus); ! 271: ! 272: pOHCIRegisters = pOHCIUIMData->pOHCIRegisters; ! 273: ! 274: value = 0; ! 275: if(on) ! 276: { ! 277: value |= kOHCIBit16;/* power on to all ganged ports */ ! 278: } ! 279: else ! 280: { ! 281: value |= kOHCIBit0; /* turn global power off */ ! 282: } ! 283: // value |= kOHCIBit15;/* remote wakeup enable */ ! 284: // value |= kOHCIBit17;/* clear over current change indicator */ ! 285: // value |= kOHCIBit31;/* remote wakeup disabled */ ! 286: ! 287: pOHCIRegisters->hcRhStatus = EndianSwap32Bit (value); ! 288: ! 289: return (status); ! 290: ! 291: } ! 292: ! 293: OSStatus OHCIRootHubResetChangeConnection( ! 294: uslBusRef bus, ! 295: short port) ! 296: { ! 297: UInt32 value; ! 298: OSStatus status = noErr; ! 299: OHCIRegistersPtr pOHCIRegisters; ! 300: ! 301: parameterNotUsed(bus); ! 302: ! 303: pOHCIRegisters = pOHCIUIMData->pOHCIRegisters; ! 304: value = 0; ! 305: value |= kOHCIBit16;/* clear status change */ ! 306: ! 307: pOHCIRegisters->hcRhPortStatus[port-1] = EndianSwap32Bit (value); ! 308: ! 309: return (status); ! 310: } ! 311: ! 312: ! 313: OSStatus OHCIRootHubResetResetChange( ! 314: uslBusRef bus, ! 315: short port) ! 316: { ! 317: UInt32 value; ! 318: OSStatus status = noErr; ! 319: OHCIRegistersPtr pOHCIRegisters; ! 320: ! 321: parameterNotUsed(bus); ! 322: ! 323: ! 324: pOHCIRegisters = pOHCIUIMData->pOHCIRegisters; ! 325: value = 0; ! 326: value |= kOHCIBit20;/* clear reset status change */ ! 327: ! 328: pOHCIRegisters->hcRhPortStatus[port-1] = EndianSwap32Bit (value); ! 329: ! 330: return (status); ! 331: } ! 332: ! 333: OSStatus OHCIRootHubResetSuspendChange( ! 334: uslBusRef bus, ! 335: short port) ! 336: { ! 337: UInt32 value; ! 338: OSStatus status = noErr; ! 339: OHCIRegistersPtr pOHCIRegisters; ! 340: ! 341: parameterNotUsed(bus); ! 342: ! 343: ! 344: pOHCIRegisters = pOHCIUIMData->pOHCIRegisters; ! 345: value = 0; ! 346: value |= kOHCIBit18;/* clear suspend status change */ ! 347: ! 348: pOHCIRegisters->hcRhPortStatus[port-1] = EndianSwap32Bit (value); ! 349: ! 350: return (status); ! 351: } ! 352: ! 353: OSStatus OHCIRootHubResetEnableChange( ! 354: uslBusRef bus, ! 355: short port) ! 356: { ! 357: UInt32 value; ! 358: OSStatus status = noErr; ! 359: OHCIRegistersPtr pOHCIRegisters; ! 360: ! 361: parameterNotUsed(bus); ! 362: ! 363: ! 364: pOHCIRegisters = pOHCIUIMData->pOHCIRegisters; ! 365: value = 0; ! 366: value |= kOHCIBit17;/* clear enable status change */ ! 367: ! 368: pOHCIRegisters->hcRhPortStatus[port-1] = EndianSwap32Bit (value); ! 369: ! 370: return (status); ! 371: } ! 372: ! 373: ! 374: OSStatus OHCIRootHubResetOverCurrentChange( ! 375: uslBusRef bus, ! 376: short port) ! 377: { ! 378: UInt32 value; ! 379: OSStatus status = noErr; ! 380: OHCIRegistersPtr pOHCIRegisters; ! 381: ! 382: parameterNotUsed(bus); ! 383: ! 384: ! 385: pOHCIRegisters = pOHCIUIMData->pOHCIRegisters; ! 386: value = 0; ! 387: value |= kOHCIBit19;/* clear over current status change */ ! 388: ! 389: pOHCIRegisters->hcRhPortStatus[port-1] = EndianSwap32Bit (value); ! 390: ! 391: return (status); ! 392: } ! 393: ! 394: ! 395: OSStatus OHCIRootHubResetPort ( ! 396: uslBusRef bus, ! 397: short port) ! 398: { ! 399: OHCIRegistersPtr pOHCIRegisters; ! 400: OSStatus status = noErr; ! 401: ! 402: parameterNotUsed(bus); ! 403: ! 404: pOHCIRegisters = pOHCIUIMData->pOHCIRegisters; ! 405: ! 406: //sets Bit 8 in port root hub register ! 407: pOHCIRegisters->hcRhPortStatus[port-1] = EndianSwap32Bit (kOHCIBit4); ! 408: IOSync(); ! 409: return (status); ! 410: ! 411: } ! 412: ! 413: OSStatus OHCIRootHubPortEnable( ! 414: uslBusRef bus, ! 415: short port, ! 416: Boolean on) ! 417: { ! 418: UInt32 value; ! 419: OSStatus status = noErr; ! 420: OHCIRegistersPtr pOHCIRegisters; ! 421: pOHCIRegisters = pOHCIUIMData->pOHCIRegisters; ! 422: ! 423: parameterNotUsed(bus); ! 424: ! 425: value = 0; ! 426: if(on) ! 427: { ! 428: value |= kOHCIBit1;/* enable port */ ! 429: } ! 430: else ! 431: { ! 432: value |= kOHCIBit0; /* disable port */ ! 433: } ! 434: ! 435: pOHCIUIMData->pOHCIRegisters->hcRhPortStatus[port-1] = EndianSwap32Bit (value); ! 436: IOSync(); ! 437: ! 438: return (status); ! 439: } ! 440: ! 441: OSStatus OHCIRootHubPortSuspend( ! 442: uslBusRef bus, ! 443: short port, ! 444: Boolean on) ! 445: { ! 446: UInt32 value; ! 447: OSStatus status = noErr; ! 448: OHCIRegistersPtr pOHCIRegisters; ! 449: ! 450: parameterNotUsed(bus); ! 451: ! 452: pOHCIRegisters = pOHCIUIMData->pOHCIRegisters; ! 453: ! 454: value = 0; ! 455: if(on) ! 456: { ! 457: value |= kOHCIBit2;/* suspend port */ ! 458: } ! 459: else ! 460: { ! 461: value |= kOHCIBit3; /* resume port */ ! 462: } ! 463: ! 464: pOHCIUIMData->pOHCIRegisters->hcRhPortStatus[port-1] = EndianSwap32Bit (value); ! 465: ! 466: return (status); ! 467: } ! 468: ! 469: OSStatus OHCIRootHubPortPower( ! 470: uslBusRef bus, ! 471: short port, ! 472: Boolean on) ! 473: { ! 474: UInt32 value= 0; ! 475: OSStatus status = noErr; ! 476: OHCIRegistersPtr pOHCIRegisters; ! 477: ! 478: parameterNotUsed(bus); ! 479: ! 480: pOHCIRegisters = pOHCIUIMData->pOHCIRegisters; ! 481: ! 482: if(on) ! 483: { ! 484: value |= kOHCIBit8;/* enable port power */ ! 485: } ! 486: else ! 487: { ! 488: value |= kOHCIBit9; /* disable port power */ ! 489: } ! 490: ! 491: pOHCIUIMData->pOHCIRegisters->hcRhPortStatus[port-1] = EndianSwap32Bit (value); ! 492: ! 493: return (status); ! 494: } ! 495: ! 496:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.