|
|
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: * ! 24: * AppleATAPPC.cpp ! 25: * ! 26: */ ! 27: #include "AppleATAPPC.h" ! 28: ! 29: #undef super ! 30: #define super AppleATA ! 31: ! 32: extern pmap_t kernel_pmap; ! 33: ! 34: OSDefineMetaClassAndStructors( AppleATAPPC, AppleATA ) ! 35: ! 36: static inline int rnddiv( int x, int y ) ! 37: { ! 38: if ( x < 0 ) ! 39: return 0; ! 40: else ! 41: return ( (x / y) + (( x % y ) ? 1 : 0) ); ! 42: } ! 43: ! 44: ! 45: /* ! 46: * ! 47: * ! 48: */ ! 49: bool AppleATAPPC::configure( IOService *forProvider, UInt32 *controllerDataSize ) ! 50: { ! 51: *controllerDataSize = 0; ! 52: ! 53: provider = forProvider; ! 54: ! 55: if ( identifyController() == false ) ! 56: { ! 57: return false; ! 58: } ! 59: ! 60: ioMapATA = provider->mapDeviceMemoryWithIndex(0); ! 61: if ( ioMapATA == NULL ) return false; ! 62: ioBaseATA = (volatile UInt32 *)ioMapATA->getVirtualAddress(); ! 63: ! 64: ioMapDMA = provider->mapDeviceMemoryWithIndex(1); ! 65: if ( ioMapDMA == NULL ) return false; ! 66: ioBaseDMA = (volatile IODBDMAChannelRegisters *)ioMapDMA->getVirtualAddress(); ! 67: ! 68: dmaDescriptors = (IODBDMADescriptor *)kalloc(page_size); ! 69: if ( dmaDescriptors == 0 ) ! 70: { ! 71: return false; ! 72: } ! 73: ! 74: dmaDescriptorsPhys = (UInt32) pmap_extract(kernel_pmap, (vm_offset_t) dmaDescriptors); ! 75: ! 76: if ( (UInt32)dmaDescriptors & (page_size - 1) ) ! 77: { ! 78: IOLog("AppleATAPPC::%s() - DMA Descriptor memory not page aligned!!", __FUNCTION__); ! 79: return false; ! 80: } ! 81: ! 82: bzero( dmaDescriptors, page_size ); ! 83: ! 84: numDescriptors = page_size/sizeof(IODBDMADescriptor); ! 85: ! 86: dmaMemoryCursor = IOBigMemoryCursor::withSpecification( 64*1024-2, 0xffffffff ); ! 87: if ( dmaMemoryCursor == NULL ) ! 88: { ! 89: return false; ! 90: } ! 91: ! 92: bitBucketAddr = IOMalloc(32); ! 93: if ( bitBucketAddr == 0 ) ! 94: { ! 95: return false; ! 96: } ! 97: bitBucketAddrPhys = (UInt32) pmap_extract(kernel_pmap, (vm_offset_t) (((UInt32)bitBucketAddr + 0xf) & ~0x0f)); ! 98: ! 99: return true; ! 100: } ! 101: ! 102: ! 103: /* ! 104: * ! 105: * ! 106: */ ! 107: bool AppleATAPPC::identifyController() ! 108: { ! 109: OSData *compatibleEntry, *modelEntry; ! 110: ! 111: do ! 112: { ! 113: controllerType = kControllerTypeDBDMAVersion1; ! 114: ! 115: compatibleEntry = OSDynamicCast( OSData, provider->getProperty( "compatible" ) ); ! 116: if ( compatibleEntry == 0 ) break; ! 117: ! 118: if ( compatibleEntry->isEqualTo( "keylargo-ata", sizeof("keylargo-ata")-1 ) == true ) ! 119: { ! 120: controllerType = kControllerTypeDBDMAVersion2; ! 121: ! 122: modelEntry = OSDynamicCast( OSData, provider->getProperty("model") ); ! 123: if ( modelEntry == 0 ) break; ! 124: ! 125: if ( modelEntry->isEqualTo( "ata-4", sizeof("ata-4")-1 ) == true ) ! 126: { ! 127: controllerType = kControllerTypeUltra66DBDMA; ! 128: } ! 129: } ! 130: } while ( 0 ); ! 131: ! 132: return true; ! 133: } ! 134: ! 135: ! 136: /* ! 137: * ! 138: * ! 139: */ ! 140: bool AppleATAPPC::createWorkLoop( IOWorkLoop **workLoop ) ! 141: { ! 142: if ( super::createWorkLoop( workLoop ) != true ) ! 143: { ! 144: return false; ! 145: } ! 146: ! 147: interruptEventSource = IOInterruptEventSource::interruptEventSource( (OSObject *) this, ! 148: (IOInterruptEventAction) &AppleATAPPC::interruptOccurred, ! 149: (IOService *) provider, ! 150: (int) 0 ); ! 151: ! 152: if ( interruptEventSource == NULL ) ! 153: { ! 154: return false; ! 155: } ! 156: ! 157: disableControllerInterrupts(); ! 158: ! 159: (*workLoop)->addEventSource( interruptEventSource ); ! 160: ! 161: timerEventSource = IOTimerEventSource::timerEventSource( this, (IOTimerEventSource::Action) &AppleATAPPC::ataTimer ); ! 162: if ( timerEventSource == NULL ) ! 163: { ! 164: return false; ! 165: } ! 166: (*workLoop)->addEventSource( timerEventSource ); ! 167: ! 168: ataTimer( timerEventSource ); ! 169: ! 170: return true; ! 171: } ! 172: ! 173: ! 174: /* ! 175: * ! 176: * ! 177: */ ! 178: bool AppleATAPPC::provideProtocols( ATAProtocol *protocolsSupported ) ! 179: { ! 180: return false; ! 181: } ! 182: ! 183: ! 184: /* ! 185: * ! 186: * ! 187: */ ! 188: bool AppleATAPPC::provideTimings( UInt32 *numTimings, ATATiming *timingsSupported ) ! 189: { ! 190: return false; ! 191: } ! 192: ! 193: ! 194: /* ! 195: * ! 196: * ! 197: */ ! 198: bool AppleATAPPC::calculateTiming( UInt32 deviceNum, ATATiming *pTiming ) ! 199: { ! 200: bool rc = false; ! 201: ! 202: switch ( controllerType ) ! 203: { ! 204: case kControllerTypeDBDMAVersion1: ! 205: case kControllerTypeDBDMAVersion2: ! 206: switch ( pTiming->timingProtocol ) ! 207: { ! 208: case ataTimingPIO: ! 209: rc = calculatePIOTiming( deviceNum, pTiming ); ! 210: break; ! 211: ! 212: case ataTimingDMA: ! 213: rc = calculateDMATiming( deviceNum, pTiming ); ! 214: break; ! 215: ! 216: default: ! 217: ; ! 218: } ! 219: break; ! 220: ! 221: case kControllerTypeUltra66DBDMA: ! 222: switch ( pTiming->timingProtocol ) ! 223: { ! 224: case ataTimingPIO: ! 225: rc = calculateUltra66PIOTiming( deviceNum, pTiming ); ! 226: break; ! 227: ! 228: case ataTimingDMA: ! 229: rc = calculateUltra66DMATiming( deviceNum, pTiming ); ! 230: break; ! 231: ! 232: case ataTimingUltraDMA66: ! 233: rc = calculateUltra66UDMATiming( deviceNum, pTiming ); ! 234: break; ! 235: ! 236: default: ! 237: ; ! 238: } ! 239: break; ! 240: ! 241: default: ! 242: ; ! 243: } ! 244: ! 245: return rc; ! 246: } ! 247: ! 248: ! 249: /* ! 250: * ! 251: * ! 252: */ ! 253: bool AppleATAPPC::calculatePIOTiming( UInt32 unitNum, ATATiming *pTiming ) ! 254: { ! 255: int accessTime; ! 256: int accessTicks; ! 257: int recTime; ! 258: int recTicks; ! 259: int cycleTime; ! 260: ! 261: /* ! 262: * Calc PIO access time >= minDataAccess in SYSCLK increments ! 263: */ ! 264: accessTicks = rnddiv(pTiming->minDataAccess, IDE_SYSCLK_NS); ! 265: /* ! 266: * Hardware limits access times to >= 120 ns ! 267: */ ! 268: accessTicks -= IDE_PIO_ACCESS_BASE; ! 269: if (accessTicks < IDE_PIO_ACCESS_MIN ) ! 270: { ! 271: accessTicks = IDE_PIO_ACCESS_MIN; ! 272: } ! 273: accessTime = (accessTicks + IDE_PIO_ACCESS_BASE) * IDE_SYSCLK_NS; ! 274: ! 275: /* ! 276: * Calc recovery time in SYSCLK increments based on time remaining in cycle ! 277: */ ! 278: recTime = pTiming->minDataCycle - accessTime; ! 279: recTicks = rnddiv( recTime, IDE_SYSCLK_NS ); ! 280: /* ! 281: * Hardware limits recovery time to >= 150ns ! 282: */ ! 283: recTicks -= IDE_PIO_RECOVERY_BASE; ! 284: if ( recTicks < IDE_PIO_RECOVERY_MIN ) ! 285: { ! 286: recTicks = IDE_PIO_RECOVERY_MIN; ! 287: } ! 288: ! 289: cycleTime = (recTicks + IDE_PIO_RECOVERY_BASE + accessTicks + IDE_PIO_ACCESS_BASE) * IDE_SYSCLK_NS; ! 290: ! 291: ideTimingWord[unitNum] &= ~0x7ff; ! 292: ideTimingWord[unitNum] |= accessTicks | (recTicks << 5); ! 293: ! 294: #if 0 ! 295: IOLog("AppleATAPPC::%s() Unit %1d PIO Requested Timings: Access: %3dns Cycle: %3dns \n\r", ! 296: __FUNCTION__, (int)unitNum, (int)pTiming->minDataAccess, (int)pTiming->minDataCycle); ! 297: IOLog("AppleATAPPC::%s() PIO Actual Timings: Access: %3dns Cycle: %3dns\n\r", ! 298: __FUNCTION__, accessTime, cycleTime ); ! 299: #endif ! 300: ! 301: return true; ! 302: } ! 303: ! 304: ! 305: /* ! 306: * ! 307: * ! 308: */ ! 309: bool AppleATAPPC::calculateDMATiming( UInt32 unitNum, ATATiming *pTiming ) ! 310: { ! 311: int accessTime; ! 312: int accessTicks; ! 313: int recTime; ! 314: int recTicks; ! 315: int cycleTime; ! 316: int cycleTimeOrig; ! 317: int halfTick = 0; ! 318: ! 319: /* ! 320: * Calc DMA access time >= minDataAccess in SYSCLK increments ! 321: */ ! 322: ! 323: /* ! 324: * OHare II erata - Cant handle write cycle times below 150ns ! 325: */ ! 326: cycleTimeOrig = pTiming->minDataCycle; ! 327: #if 0 ! 328: if ( IsPowerStar() ) ! 329: { ! 330: if ( cycleTimeOrig < 150 ) pTiming->minDataCycle = 150; ! 331: } ! 332: #endif ! 333: ! 334: accessTicks = rnddiv(pTiming->minDataAccess, IDE_SYSCLK_NS); ! 335: ! 336: accessTicks -= IDE_DMA_ACCESS_BASE; ! 337: if ( accessTicks < IDE_DMA_ACCESS_MIN ) ! 338: { ! 339: accessTicks = IDE_DMA_ACCESS_MIN; ! 340: } ! 341: accessTime = (accessTicks + IDE_DMA_ACCESS_BASE) * IDE_SYSCLK_NS; ! 342: ! 343: /* ! 344: * Calc recovery time in SYSCLK increments based on time remaining in cycle ! 345: */ ! 346: recTime = pTiming->minDataCycle - accessTime; ! 347: recTicks = rnddiv( recTime, IDE_SYSCLK_NS ); ! 348: ! 349: recTicks -= IDE_DMA_RECOVERY_BASE; ! 350: if ( recTicks < IDE_DMA_RECOVERY_MIN ) ! 351: { ! 352: recTicks = IDE_DMA_RECOVERY_MIN; ! 353: } ! 354: cycleTime = (recTicks + IDE_DMA_RECOVERY_BASE + accessTicks + IDE_DMA_ACCESS_BASE) * IDE_SYSCLK_NS; ! 355: ! 356: /* ! 357: * If our calculated access time is at least SYSCLK/2 > than what the disk requires, ! 358: * see if selecting the 1/2 Clock option will help. This adds SYSCLK/2 to ! 359: * the access time and subtracts SYSCLK/2 from the recovery time. ! 360: * ! 361: * By setting the H-bit and subtracting one from the current access tick count, ! 362: * we are reducing the current access time by SYSCLK/2 and the current recovery ! 363: * time by SYSCLK/2. Now, check if the new cycle time still meets the disk's requirements. ! 364: */ ! 365: if ( controllerType == kControllerTypeDBDMAVersion1 ) ! 366: { ! 367: if ( (accessTicks > IDE_DMA_ACCESS_MIN) && ((UInt32)(accessTime - IDE_SYSCLK_NS/2) >= pTiming->minDataAccess) ) ! 368: { ! 369: if ( (UInt32)(cycleTime - IDE_SYSCLK_NS) >= pTiming->minDataCycle ) ! 370: { ! 371: halfTick = 1; ! 372: accessTicks--; ! 373: accessTime -= IDE_SYSCLK_NS/2; ! 374: cycleTime -= IDE_SYSCLK_NS; ! 375: } ! 376: } ! 377: } ! 378: ! 379: ideTimingWord[unitNum] &= ~0xffff800; ! 380: ideTimingWord[unitNum] |= (accessTicks | (recTicks << 5) | (halfTick << 10)) << 11; ! 381: ! 382: #if 0 ! 383: IOLog("AppleATAPPC::%s() Unit %1d DMA Requested Timings: Access: %3dns Cycle: %3dns \n\r", ! 384: __FUNCTION__, (int)unitNum, (int)pTiming->minDataAccess, (int)cycleTimeOrig); ! 385: IOLog("AppleATAPPC::%s() DMA Actual Timings: Access: %3dns Cycle: %3dns\n\r", ! 386: __FUNCTION__, accessTime, cycleTime ); ! 387: IOLog("AppleATAPPC::%s() Ide DMA Timings = %08lx\n\r", __FUNCTION__, ideTimingWord[unitNum] ); ! 388: #endif ! 389: ! 390: return true; ! 391: } ! 392: ! 393: ! 394: /* ! 395: * ! 396: * ! 397: */ ! 398: bool AppleATAPPC::calculateUltra66PIOTiming( UInt32 unitNum, ATATiming *pTiming ) ! 399: { ! 400: int accessTime; ! 401: int accessTicks; ! 402: int recTime; ! 403: int recTicks; ! 404: int cycleTime; ! 405: ! 406: /* ! 407: * Calc PIO access time >= pioAccessTime in SYSCLK increments ! 408: */ ! 409: accessTicks = rnddiv(pTiming->minDataAccess * 1000, IDE_ULTRA66_CLOCK_PS ); ! 410: accessTime = accessTicks * IDE_ULTRA66_CLOCK_PS; ! 411: ! 412: /* ! 413: * Calc recovery time in SYSCLK increments based on time remaining in cycle ! 414: */ ! 415: recTime = pTiming->minDataCycle * 1000 - accessTime; ! 416: recTicks = rnddiv( recTime, IDE_ULTRA66_CLOCK_PS ); ! 417: ! 418: cycleTime = (recTicks + accessTicks ) * IDE_ULTRA66_CLOCK_PS; ! 419: ! 420: ideTimingWord[unitNum] &= ~0xe00003ff; ! 421: ideTimingWord[unitNum] |= accessTicks | (recTicks << 5); ! 422: ! 423: #if 0 ! 424: IOLog("AppleATAPPC::%s() Unit %1d PIO Requested Timings: Access: %3dns Cycle: %3dns \n\r", ! 425: __FUNCTION__, (int)unitNum, (int)pTiming->minDataAccess, (int)pTiming->minDataCycle); ! 426: IOLog("AppleATAPPC::%s() PIO Actual Timings: Access: %3dns Cycle: %3dns\n\r", ! 427: __FUNCTION__, accessTime / 1000, cycleTime / 1000 ); ! 428: IOLog("AppleATAPPC::%s() Ide PIO Timings = %08lx\n\r", __FUNCTION__, ideTimingWord[unitNum] ); ! 429: #endif ! 430: ! 431: return true; ! 432: } ! 433: ! 434: ! 435: /* ! 436: * ! 437: * ! 438: */ ! 439: bool AppleATAPPC::calculateUltra66DMATiming( UInt32 unitNum, ATATiming *pTiming ) ! 440: { ! 441: int accessTime; ! 442: int accessTicks; ! 443: int recTime; ! 444: int recTicks; ! 445: int cycleTime; ! 446: ! 447: /* ! 448: * Calc DMA access time >= dmaAccessTime in SYSCLK increments ! 449: */ ! 450: accessTicks = rnddiv(pTiming->minDataAccess * 1000, IDE_ULTRA66_CLOCK_PS); ! 451: accessTime = accessTicks * IDE_ULTRA66_CLOCK_PS; ! 452: ! 453: /* ! 454: * Calc recovery time in SYSCLK increments based on time remaining in cycle ! 455: */ ! 456: recTime = pTiming->minDataCycle * 1000 - accessTime; ! 457: recTicks = rnddiv( recTime, IDE_ULTRA66_CLOCK_PS ); ! 458: ! 459: cycleTime = (recTicks + accessTicks) * IDE_ULTRA66_CLOCK_PS; ! 460: ! 461: ideTimingWord[unitNum] &= ~0x001ffc00; ! 462: ideTimingWord[unitNum] |= (accessTicks | (recTicks << 5)) << 10; ! 463: ! 464: #if 0 ! 465: IOLog("AppleATAPPC::%s() Unit %1d DMA Requested Timings: Access: %3dns Cycle: %3dns \n\r", ! 466: __FUNCTION__, (int)unitNum, (int)pTiming->minDataAccess, (int)pTiming->minDataCycle); ! 467: IOLog("AppleATAPPC::%s() DMA Actual Timings: Access: %3dns Cycle: %3dns\n\r", ! 468: __FUNCTION__, accessTime / 1000, cycleTime / 1000 ); ! 469: IOLog("AppleATAPPC::%s() Ide DMA Timings = %08lx\n\r", __FUNCTION__, ideTimingWord[unitNum] ); ! 470: #endif ! 471: ! 472: return true; ! 473: } ! 474: ! 475: ! 476: /* ! 477: * ! 478: * ! 479: */ ! 480: bool AppleATAPPC::calculateUltra66UDMATiming( UInt32 unitNum, ATATiming *pTiming ) ! 481: { ! 482: int rdyToPauseTicks; ! 483: int rdyToPauseTime; ! 484: int cycleTime; ! 485: int cycleTicks; ! 486: ! 487: /* ! 488: * Ready to Pause delay in PCI_66_CLOCK / 2 increments ! 489: */ ! 490: rdyToPauseTicks = rnddiv(pTiming->minDataAccess * 1000, IDE_ULTRA66_CLOCK_PS); ! 491: rdyToPauseTime = rdyToPauseTicks * IDE_ULTRA66_CLOCK_PS; ! 492: ! 493: /* ! 494: * Calculate cycle time in PCI_66_CLOCK / 2 increments ! 495: */ ! 496: cycleTicks = rnddiv(pTiming->minDataCycle * 1000, IDE_ULTRA66_CLOCK_PS); ! 497: cycleTime = cycleTicks * IDE_ULTRA66_CLOCK_PS; ! 498: ! 499: ideTimingWord[unitNum] &= ~0x1ff00000; ! 500: ideTimingWord[unitNum] |= ((rdyToPauseTicks << 5) | (cycleTicks << 1) | 1) << 20; ! 501: ! 502: #if 0 ! 503: IOLog("AppleATAPPC::%s() Unit %1d UDMA66 Requested Timings: ReadyToPause: %3dns Cycle: %3dns \n\r", ! 504: __FUNCTION__, (int)unitNum, (int)pTiming->minDataAccess, (int)pTiming->minDataCycle); ! 505: IOLog("AppleATAPPC::%s() UDMA66 Actual Timings: ReadyToPause: %3dns Cycle: %3dns\n\r", ! 506: __FUNCTION__, rdyToPauseTime / 1000, cycleTime / 1000 ); ! 507: IOLog("AppleATAPPC::%s() Ide DMA Timings = %08lx\n\r", __FUNCTION__, ideTimingWord[unitNum] ); ! 508: #endif ! 509: ! 510: return true; ! 511: } ! 512: ! 513: ! 514: /* ! 515: * ! 516: * ! 517: */ ! 518: void AppleATAPPC::newDeviceSelected( IOATADevice *newDevice ) ! 519: { ! 520: OSWriteSwapInt32( ioBaseATA, 0x200, ideTimingWord[newDevice->getUnit()] ); ! 521: eieio(); ! 522: } ! 523: ! 524: ! 525: /* ! 526: * ! 527: * ! 528: */ ! 529: bool AppleATAPPC::selectTiming( UInt32 unitNum, ATATimingProtocol timingProtocol ) ! 530: { ! 531: if ( controllerType == kControllerTypeUltra66DBDMA ) ! 532: { ! 533: switch ( timingProtocol ) ! 534: { ! 535: case ataTimingUltraDMA66: ! 536: ideTimingWord[unitNum] |= 0x00100000; ! 537: break; ! 538: case ataTimingDMA: ! 539: ideTimingWord[unitNum] &= ~0x00100000; ! 540: break; ! 541: default: ! 542: ; ! 543: } ! 544: } ! 545: ! 546: currentDevice = (IOATADevice *)NULL; ! 547: return true; ! 548: } ! 549: ! 550: ! 551: /* ! 552: * ! 553: * ! 554: */ ! 555: void AppleATAPPC::ataTimer( IOTimerEventSource * /* sender */ ) ! 556: { ! 557: if ( xferCmdTimer != 0 ) ! 558: { ! 559: if ( --xferCmdTimer == 0 ) ! 560: { ! 561: IOLog("AppleATAPPC::%s() - Timeout occurred\n\r", __FUNCTION__ ); ! 562: ! 563: if ( xferCmdSave != NULL ) ! 564: { ! 565: xferCmd = xferCmdSave; ! 566: xferCmdSave = NULL; ! 567: } ! 568: ! 569: updateCmdStatus( xferCmd, ataReturnErrorInterruptTimeout, xferCount ); ! 570: ! 571: resetBusRequest(); ! 572: ! 573: completeCmd( xferCmd ); ! 574: } ! 575: } ! 576: ! 577: timerEventSource->setTimeoutMS(ATATimerIntervalmS); ! 578: } ! 579: ! 580: /* ! 581: * ! 582: * ! 583: */ ! 584: bool AppleATAPPC::programDma( IOATACommand *cmd ) ! 585: { ! 586: IOMemoryDescriptor *memoryDesc; ! 587: IODBDMADescriptor *dmaDesc; ! 588: UInt32 dmaCmd; ! 589: bool isWrite; ! 590: IOPhysicalSegment physSeg; ! 591: IOByteCount offset; ! 592: UInt32 i; ! 593: ! 594: IODBDMAReset( ioBaseDMA ); ! 595: ! 596: cmd->getPointers( &memoryDesc, &dmaReqLength, &isWrite ); ! 597: ! 598: if ( dmaReqLength == 0 ) ! 599: { ! 600: return true; ! 601: } ! 602: ! 603: offset = 0; ! 604: ! 605: dmaCmd = (isWrite == true) ? kdbdmaOutputMore : kdbdmaInputMore; ! 606: dmaDesc = dmaDescriptors; ! 607: ! 608: for ( i = 0; i < numDescriptors; i++, dmaDesc++ ) ! 609: { ! 610: if ( dmaMemoryCursor->getPhysicalSegments( memoryDesc, offset, &physSeg, 1 ) != 1 ) ! 611: { ! 612: break; ! 613: } ! 614: ! 615: IOMakeDBDMADescriptor( dmaDesc, ! 616: dmaCmd, ! 617: kdbdmaKeyStream0, ! 618: kdbdmaIntNever, ! 619: kdbdmaBranchNever, ! 620: kdbdmaWaitNever, ! 621: physSeg.length, ! 622: physSeg.location ); ! 623: offset += physSeg.length; ! 624: } ! 625: ! 626: if ( i == numDescriptors ) ! 627: { ! 628: return false; ! 629: } ! 630: ! 631: /* ! 632: * Note: ATAPI always transfers even byte-counts. Send the extra byte to/from the bit-bucket ! 633: * if the requested transfer length is odd. ! 634: */ ! 635: if ( dmaReqLength & 1 ) ! 636: { ! 637: i++; ! 638: IOMakeDBDMADescriptor( dmaDesc++, ! 639: dmaCmd, ! 640: kdbdmaKeyStream0, ! 641: kdbdmaIntNever, ! 642: kdbdmaBranchNever, ! 643: kdbdmaWaitNever, ! 644: 1, ! 645: bitBucketAddrPhys ); ! 646: } ! 647: ! 648: ! 649: if ( i == numDescriptors ) ! 650: { ! 651: return false; ! 652: } ! 653: ! 654: ! 655: IOMakeDBDMADescriptor( dmaDesc, ! 656: kdbdmaStop, ! 657: kdbdmaKeyStream0, ! 658: kdbdmaIntNever, ! 659: kdbdmaBranchNever, ! 660: kdbdmaWaitNever, ! 661: 0, ! 662: 0 ); ! 663: ! 664: IOSetDBDMACommandPtr( ioBaseDMA, dmaDescriptorsPhys ); ! 665: ! 666: ! 667: return true; ! 668: } ! 669: ! 670: ! 671: /* ! 672: * ! 673: * ! 674: */ ! 675: bool AppleATAPPC::startDma( IOATACommand * ) ! 676: { ! 677: if ( dmaReqLength != 0 ) ! 678: { ! 679: IODBDMAContinue( ioBaseDMA ); ! 680: } ! 681: return true; ! 682: } ! 683: ! 684: ! 685: /* ! 686: * ! 687: * ! 688: */ ! 689: bool AppleATAPPC::stopDma( IOATACommand *, UInt32 *transferCount ) ! 690: { ! 691: UInt32 i; ! 692: UInt32 ccResult; ! 693: UInt32 byteCount = 0; ! 694: ! 695: *transferCount = 0; ! 696: ! 697: if ( dmaReqLength == 0 ) ! 698: { ! 699: return true; ! 700: } ! 701: ! 702: IODBDMAStop( ioBaseDMA ); ! 703: ! 704: for ( i=0; i < numDescriptors; i++ ) ! 705: { ! 706: ccResult = IOGetCCResult( &dmaDescriptors[i] ); ! 707: ! 708: if ( !(ccResult & kdbdmaStatusRun) ) ! 709: { ! 710: break; ! 711: } ! 712: byteCount += (IOGetCCOperation( &dmaDescriptors[i] ) & kdbdmaReqCountMask) - (ccResult & kdbdmaResCountMask); ! 713: } ! 714: ! 715: *transferCount = byteCount; ! 716: ! 717: return true; ! 718: } ! 719: ! 720: /* ! 721: * ! 722: * ! 723: */ ! 724: void AppleATAPPC::disableControllerInterrupts() ! 725: { ! 726: interruptEventSource->disable(); ! 727: } ! 728: ! 729: /* ! 730: * ! 731: * ! 732: */ ! 733: void AppleATAPPC::enableControllerInterrupts() ! 734: { ! 735: interruptEventSource->enable(); ! 736: } ! 737: ! 738: /* ! 739: * ! 740: * ! 741: */ ! 742: void AppleATAPPC::free() ! 743: { ! 744: if ( interruptEventSource != 0 ) ! 745: { ! 746: interruptEventSource->disable(); ! 747: interruptEventSource->release(); ! 748: } ! 749: ! 750: if ( timerEventSource != 0 ) ! 751: { ! 752: timerEventSource->release(); ! 753: } ! 754: ! 755: if ( ioMapATA != 0 ) ! 756: { ! 757: ioMapATA->release(); ! 758: } ! 759: ! 760: if ( ioMapDMA != 0 ) ! 761: { ! 762: ioMapDMA->release(); ! 763: } ! 764: ! 765: if ( bitBucketAddr != 0 ) ! 766: { ! 767: IOFree( bitBucketAddr, 32 ); ! 768: } ! 769: ! 770: if ( dmaDescriptors != 0 ) ! 771: { ! 772: kfree( (void *)dmaDescriptors, page_size ); ! 773: } ! 774: } ! 775: ! 776: /* ! 777: * ! 778: * ! 779: */ ! 780: void AppleATAPPC::writeATAReg( UInt32 regIndex, UInt32 regValue ) ! 781: { ! 782: regIndex += (regIndex >= ataRegDeviceControl ) ? (kCS3RegBase - ataRegDeviceControl + 6) : 0; ! 783: ! 784: if ( regIndex ) ! 785: { ! 786: *((volatile UInt8 *)ioBaseATA + (regIndex<<4)) = regValue; ! 787: } ! 788: else ! 789: { ! 790: *(volatile UInt16 *)ioBaseATA = regValue; ! 791: } ! 792: eieio(); ! 793: } ! 794: ! 795: UInt32 AppleATAPPC::readATAReg( UInt32 regIndex ) ! 796: { ! 797: regIndex += (regIndex >= ataRegAltStatus ) ? (kCS3RegBase - ataRegAltStatus + 6) : 0; ! 798: ! 799: if ( regIndex ) ! 800: { ! 801: return *((volatile UInt8 *)ioBaseATA + (regIndex<<4)); ! 802: } ! 803: else ! 804: { ! 805: return *(volatile UInt16 *)ioBaseATA; ! 806: } ! 807: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.