|
|
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: * AppleATAPio.cpp ! 25: * ! 26: */ ! 27: #include "AppleATA.h" ! 28: ! 29: /*----------------------------------- ATA SetRegs Protocol ------------------------------*/ ! 30: ! 31: /* ! 32: * ! 33: * ! 34: */ ! 35: void AppleATA::doProtocolSetRegs( IOATACommand *cmd ) ! 36: { ! 37: ATATaskfile taskfile; ! 38: UInt32 regmask; ! 39: UInt32 i; ! 40: ! 41: cmd->getTaskfile( &taskfile ); ! 42: ! 43: regmask = taskfile.regmask; ! 44: ! 45: if ( regmask & ATARegtoMask(ataRegDriveHead) ) ! 46: { ! 47: regmask &= ~ATARegtoMask(ataRegDriveHead); ! 48: if ( selectDrive( taskfile.ataRegs[ataRegDriveHead] ) == false ) ! 49: { ! 50: completeCmd( cmd, ataReturnErrorBusy ); ! 51: return; ! 52: } ! 53: } ! 54: ! 55: for ( i = 0; regmask; i++ ) ! 56: { ! 57: if ( regmask & 1 ) ! 58: { ! 59: writeATAReg( i, taskfile.ataRegs[i] ); ! 60: } ! 61: regmask >>= 1; ! 62: } ! 63: ! 64: IODelay( 100 ); ! 65: ! 66: completeCmd( cmd, ataReturnNoError ); ! 67: } ! 68: ! 69: /*----------------------------------- ATA PIO Protocol ------------------------------*/ ! 70: ! 71: /* ! 72: * ! 73: * ! 74: */ ! 75: void AppleATA::doATAProtocolPio( IOATACommand *cmd ) ! 76: { ! 77: ATATaskfile taskfile; ! 78: UInt32 regmask; ! 79: UInt32 i; ! 80: UInt32 status = 0; ! 81: ! 82: cmd->getTaskfile( &taskfile ); ! 83: ! 84: regmask = taskfile.regmask; ! 85: ! 86: if ( regmask & ATARegtoMask(ataRegDriveHead) ) ! 87: { ! 88: regmask &= ~ATARegtoMask(ataRegDriveHead); ! 89: if ( selectDrive( taskfile.ataRegs[ataRegDriveHead] ) == false ) ! 90: { ! 91: completeCmd( cmd, ataReturnErrorBusy ); ! 92: return; ! 93: } ! 94: } ! 95: ! 96: xferCount = 0; ! 97: cmd->getPointers( &xferDesc, &xferRemaining, &xferIsWrite ); ! 98: ! 99: xferInts = ( xferRemaining ) ? xferRemaining / 512 : 1; ! 100: ! 101: if ( cmd->getTimeout() != 0 ) ! 102: { ! 103: xferCmdTimer = cmd->getTimeout() / ATATimerIntervalmS + 1; ! 104: } ! 105: ! 106: for ( i = 0; regmask; i++ ) ! 107: { ! 108: if ( regmask & 1 ) ! 109: { ! 110: writeATAReg( i, taskfile.ataRegs[i] ); ! 111: } ! 112: regmask >>= 1; ! 113: } ! 114: ! 115: if ( xferIsWrite ) ! 116: { ! 117: do ! 118: { ! 119: status = readATAReg( ataRegStatus ); ! 120: } ! 121: while ( !(status & ataStatusDRQ) ); ! 122: ! 123: xferInts++; ! 124: interruptOccurred(); ! 125: } ! 126: } ! 127: ! 128: ! 129: /* ! 130: * ! 131: * ! 132: */ ! 133: void AppleATA::processATAPioInt() ! 134: { ! 135: UInt16 tmpBuffer[256]; ! 136: UInt32 status; ! 137: UInt32 i; ! 138: ATAReturnCode rc = ataReturnNoError; ! 139: UInt32 reqCount; ! 140: ! 141: if ( waitForStatus( 0, ataStatusBSY, ataBusyTimeoutmS ) == false ) ! 142: { ! 143: completeCmd( xferCmd, ataReturnErrorBusy, xferCount ); ! 144: return; ! 145: } ! 146: ! 147: status = readATAReg( ataRegStatus ); ! 148: ! 149: if ( status & ataStatusDRQ ) ! 150: { ! 151: if ( xferIsWrite == true ) ! 152: { ! 153: xferDesc->readBytes( xferCount, tmpBuffer, 512 ); ! 154: ! 155: for ( i=0; i < 256; i++ ) ! 156: { ! 157: writeATAReg( ataRegData, tmpBuffer[i] ); ! 158: } ! 159: } ! 160: else ! 161: { ! 162: for ( i=0; i < 256; i++ ) ! 163: { ! 164: tmpBuffer[i] = readATAReg( ataRegData ); ! 165: } ! 166: xferDesc->writeBytes( xferCount, tmpBuffer, 512 ); ! 167: } ! 168: ! 169: xferCount += 512; ! 170: xferRemaining -= 512; ! 171: } ! 172: ! 173: if ( status & ataStatusERR ) ! 174: { ! 175: completeCmd( xferCmd, ataReturnErrorStatus, xferCount ); ! 176: } ! 177: else if ( !--xferInts ) ! 178: { ! 179: xferCmd->getPointers( 0, &reqCount, 0 ); ! 180: if ( xferCount != reqCount ) ! 181: { ! 182: rc = ataReturnErrorProtocol; ! 183: } ! 184: ! 185: completeCmd( xferCmd, rc, xferCount ); ! 186: } ! 187: } ! 188: ! 189: /*----------------------------------- ATAPI PIO Protocols ------------------------------*/ ! 190: ! 191: /* ! 192: * ! 193: * ! 194: * ! 195: */ ! 196: void AppleATA::doATAPIProtocolPio( IOATACommand *cmd ) ! 197: { ! 198: ATATaskfile taskfile; ! 199: ATAPICmd atapiCmd; ! 200: UInt16 *pCDB = NULL; ! 201: UInt32 regmask; ! 202: UInt32 status; ! 203: UInt32 i; ! 204: ! 205: xferCount = 0; ! 206: ! 207: cmd->getTaskfile( &taskfile ); ! 208: cmd->getATAPICmd( &atapiCmd ); ! 209: ! 210: ! 211: regmask = taskfile.regmask; ! 212: ! 213: if ( regmask & ATARegtoMask(ataRegDriveHead) ) ! 214: { ! 215: regmask &= ~ATARegtoMask(ataRegDriveHead); ! 216: if ( selectDrive( taskfile.ataRegs[ataRegDriveHead] ) == false ) ! 217: { ! 218: completeCmd( cmd, ataReturnErrorBusy ); ! 219: return; ! 220: } ! 221: } ! 222: ! 223: xferInts = 1; ! 224: ! 225: if ( cmd->getTimeout() != 0 ) ! 226: { ! 227: xferCmdTimer = cmd->getTimeout() / ATATimerIntervalmS + 1; ! 228: } ! 229: ! 230: for ( i = 0; regmask; i++ ) ! 231: { ! 232: if ( regmask & 1 ) ! 233: { ! 234: writeATAReg( i, taskfile.ataRegs[i] ); ! 235: } ! 236: regmask >>= 1; ! 237: } ! 238: ! 239: xferCount = 0; ! 240: cmd->getPointers( &xferDesc, &xferRemaining, &xferIsWrite ); ! 241: ! 242: if ( cmd->getDevice()->getATAPIPktInt() == false ) ! 243: { ! 244: do ! 245: { ! 246: status = readATAReg( ataRegStatus ); ! 247: } ! 248: while ( (status & atapiStatusBSY) || !(status & atapiStatusDRQ) ); ! 249: ! 250: pCDB = (UInt16 *)atapiCmd.cdb; ! 251: for ( i = 0; i < atapiCmd.cdbLength >> 1; i++ ) ! 252: { ! 253: writeATAReg( ataRegData, *pCDB++ ); ! 254: } ! 255: } ! 256: } ! 257: ! 258: /* ! 259: * ! 260: * ! 261: */ ! 262: void AppleATA::processATAPIPioInt() ! 263: { ! 264: ATAReturnCode rc = ataReturnErrorProtocol; ! 265: UInt32 status; ! 266: UInt32 intReason; ! 267: UInt32 n; ! 268: ! 269: if ( waitForStatus( 0, ataStatusBSY, ataBusyTimeoutmS ) == false ) ! 270: { ! 271: completeCmd( xferCmd, ataReturnErrorBusy, xferCount ); ! 272: return; ! 273: } ! 274: ! 275: status = readATAReg( atapiRegStatus ); ! 276: intReason = readATAReg( atapiRegIntReason ); ! 277: ! 278: if ( !xferInts ) return; ! 279: ! 280: if ( status & atapiStatusDRQ ) ! 281: { ! 282: if ( intReason & atapiIntReasonCD ) ! 283: { ! 284: if ( !(intReason & atapiIntReasonIO) ) ! 285: { ! 286: rc = sendATAPIPacket(); ! 287: } ! 288: } ! 289: else ! 290: { ! 291: n = readATAReg( atapiRegByteCountLow ) | (readATAReg( atapiRegByteCountHigh ) << 8); ! 292: n = (n+1) & ~0x01; ! 293: ! 294: if ( !(intReason & atapiIntReasonIO) && (xferIsWrite == true) ) ! 295: { ! 296: rc = writeATAPIDevice( n ); ! 297: } ! 298: else if ( (intReason & atapiIntReasonIO) && (xferIsWrite == false) ) ! 299: { ! 300: rc = readATAPIDevice( n ); ! 301: } ! 302: } ! 303: } ! 304: else if ( (intReason & atapiIntReasonCD) && (intReason & atapiIntReasonIO) ) ! 305: { ! 306: xferInts = 0; ! 307: rc = (status & atapiStatusCHK) ? ataReturnErrorStatus : ataReturnNoError; ! 308: ! 309: if ( rc == ataReturnErrorStatus ) ! 310: { ! 311: updateCmdStatus( xferCmd, rc, xferCount ); ! 312: ! 313: if ( doRequestSense( xferCmd ) == false ) ! 314: { ! 315: completeCmd( xferCmd ); ! 316: } ! 317: } ! 318: else ! 319: { ! 320: completeCmd( xferCmd, rc, xferCount ); ! 321: } ! 322: } ! 323: } ! 324: ! 325: /* ! 326: * ! 327: * ! 328: */ ! 329: ATAReturnCode AppleATA::sendATAPIPacket() ! 330: { ! 331: UInt32 i; ! 332: ATAPICmd atapiCmd; ! 333: UInt16 *pCDB; ! 334: ! 335: xferCmd->getATAPICmd( &atapiCmd ); ! 336: ! 337: pCDB = (UInt16 *)atapiCmd.cdb; ! 338: for ( i=0; i < atapiCmd.cdbLength >> 1; i++ ) ! 339: { ! 340: writeATAReg( ataRegData, *pCDB++ ); ! 341: } ! 342: return ataReturnNoError; ! 343: } ! 344: ! 345: ! 346: /* ! 347: * ! 348: * ! 349: */ ! 350: ATAReturnCode AppleATA::readATAPIDevice( UInt32 n ) ! 351: { ! 352: UInt16 tmpBuffer[256]; ! 353: UInt32 i,j,k; ! 354: ! 355: while ( n ) ! 356: { ! 357: j = (n < 512) ? n : 512; ! 358: ! 359: j >>= 1; ! 360: for ( i=0; i < j; i++ ) ! 361: { ! 362: tmpBuffer[i] = readATAReg( ataRegData ); ! 363: } ! 364: j <<= 1; ! 365: n -= j; ! 366: ! 367: k = (j > xferRemaining ) ? xferRemaining : j; ! 368: ! 369: xferDesc->writeBytes( xferCount, tmpBuffer, k ); ! 370: ! 371: xferCount += k; ! 372: xferRemaining -= k; ! 373: } ! 374: ! 375: return ataReturnNoError; ! 376: } ! 377: ! 378: /* ! 379: * ! 380: * ! 381: */ ! 382: ATAReturnCode AppleATA::writeATAPIDevice( UInt32 n ) ! 383: { ! 384: UInt16 tmpBuffer[256]; ! 385: UInt32 i,j,k; ! 386: ! 387: ! 388: while ( n ) ! 389: { ! 390: j = (n < 512) ? n : 512; ! 391: ! 392: k = (j > xferRemaining ) ? xferRemaining : j; ! 393: ! 394: xferDesc->readBytes( xferCount, tmpBuffer, k ); ! 395: ! 396: j >>= 1; ! 397: for ( i=0; i < j; i++ ) ! 398: { ! 399: writeATAReg( ataRegData, tmpBuffer[i] ); ! 400: } ! 401: j <<= 1; ! 402: n -= j; ! 403: ! 404: xferCount += k; ! 405: xferRemaining -= k; ! 406: } ! 407: ! 408: return ataReturnNoError; ! 409: } ! 410: ! 411: ! 412: /* ! 413: * ! 414: * ! 415: */ ! 416: bool AppleATA::selectDrive( UInt32 driveHeadReg ) ! 417: { ! 418: bool isBusy = true; ! 419: UInt32 i; ! 420: UInt32 status; ! 421: ! 422: writeATAReg( ataRegDriveHead, driveHeadReg ); ! 423: ! 424: for ( i=0; i < 10; i++ ) ! 425: { ! 426: status = readATAReg( ataRegStatus ); ! 427: isBusy = ((status & ataStatusBSY) != 0); ! 428: if ( isBusy == false ) ! 429: { ! 430: break; ! 431: } ! 432: IODelay( 10 ); ! 433: } ! 434: ! 435: return !isBusy; ! 436: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.