|
|
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: * AppleATADma.cpp ! 25: * ! 26: */ ! 27: #include "AppleATA.h" ! 28: ! 29: /*----------------------------------- ATA DMA Protocol ------------------------------*/ ! 30: ! 31: /* ! 32: * ! 33: * ! 34: */ ! 35: void AppleATA::doATAProtocolDma( 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: xferCount = 0; ! 56: xferInts = 1; ! 57: ! 58: programDma( cmd ); ! 59: ! 60: xferInts = 1; ! 61: ! 62: if ( cmd->getTimeout() != 0 ) ! 63: { ! 64: xferCmdTimer = cmd->getTimeout() / ATATimerIntervalmS + 1; ! 65: } ! 66: ! 67: for ( i = 0; regmask; i++ ) ! 68: { ! 69: if ( regmask & 1 ) ! 70: { ! 71: writeATAReg( i, taskfile.ataRegs[i] ); ! 72: } ! 73: regmask >>= 1; ! 74: } ! 75: ! 76: startDma( cmd ); ! 77: } ! 78: ! 79: /* ! 80: * ! 81: * ! 82: */ ! 83: void AppleATA::processATADmaInt() ! 84: { ! 85: UInt32 status; ! 86: UInt32 reqCount; ! 87: ATAReturnCode rc = ataReturnNoError; ! 88: ! 89: if ( waitForStatus( 0, ataStatusBSY, ataBusyTimeoutmS ) == false ) ! 90: { ! 91: completeCmd( xferCmd, ataReturnErrorBusy, xferCount ); ! 92: return; ! 93: } ! 94: ! 95: status = readATAReg( ataRegStatus ); ! 96: ! 97: xferCmd->getPointers( 0, &reqCount, 0 ); ! 98: ! 99: if ( stopDma( xferCmd, &xferCount ) != true ) ! 100: { ! 101: rc = ataReturnErrorDMA; ! 102: } ! 103: ! 104: else if ( status & ataStatusDRQ ) ! 105: { ! 106: rc = ataReturnErrorDMA; ! 107: } ! 108: ! 109: else if ( status & ataStatusERR ) ! 110: { ! 111: rc = ataReturnErrorStatus; ! 112: } ! 113: ! 114: else if ( reqCount != xferCount ) ! 115: { ! 116: rc = ataReturnErrorProtocol; ! 117: } ! 118: ! 119: completeCmd( xferCmd, rc, xferCount ); ! 120: } ! 121: ! 122: /*----------------------------------- ATAPI DMA Protocols ------------------------------*/ ! 123: ! 124: /* ! 125: * ! 126: * ! 127: * ! 128: */ ! 129: void AppleATA::doATAPIProtocolDma( IOATACommand *cmd ) ! 130: { ! 131: ATATaskfile taskfile; ! 132: ATAPICmd atapiCmd; ! 133: UInt16 *pCDB = NULL; ! 134: UInt32 regmask; ! 135: UInt32 i; ! 136: UInt32 status = 0; ! 137: ! 138: xferCount = 0; ! 139: ! 140: cmd->getTaskfile( &taskfile ); ! 141: cmd->getATAPICmd( &atapiCmd ); ! 142: ! 143: regmask = taskfile.regmask; ! 144: ! 145: if ( regmask & ATARegtoMask(ataRegDriveHead) ) ! 146: { ! 147: regmask &= ~ATARegtoMask(ataRegDriveHead); ! 148: if ( selectDrive( taskfile.ataRegs[ataRegDriveHead] ) == false ) ! 149: { ! 150: completeCmd( cmd, ataReturnErrorBusy ); ! 151: return; ! 152: } ! 153: } ! 154: ! 155: xferInts = 1; ! 156: ! 157: if ( cmd->getTimeout() != 0 ) ! 158: { ! 159: xferCmdTimer = cmd->getTimeout() / ATATimerIntervalmS + 1; ! 160: } ! 161: ! 162: for ( i = 0; regmask; i++ ) ! 163: { ! 164: if ( regmask & 1 ) ! 165: { ! 166: writeATAReg( i, taskfile.ataRegs[i] ); ! 167: } ! 168: regmask >>= 1; ! 169: } ! 170: ! 171: xferCount = 0; ! 172: ! 173: programDma( cmd ); ! 174: ! 175: if ( cmd->getDevice()->getATAPIPktInt() == false ) ! 176: { ! 177: do ! 178: { ! 179: status = readATAReg( ataRegStatus ); ! 180: } ! 181: while ( (status & atapiStatusBSY) || !(status & atapiStatusDRQ) ); ! 182: ! 183: pCDB = (UInt16 *)atapiCmd.cdb; ! 184: for ( i = 0; i < atapiCmd.cdbLength >> 1; i++ ) ! 185: { ! 186: writeATAReg( ataRegData, *pCDB++ ); ! 187: } ! 188: ! 189: startDma( cmd ); ! 190: } ! 191: } ! 192: ! 193: ! 194: /* ! 195: * ! 196: * ! 197: */ ! 198: void AppleATA::processATAPIDmaInt() ! 199: { ! 200: ATAReturnCode rc = ataReturnErrorProtocol; ! 201: UInt32 status; ! 202: UInt32 intReason; ! 203: ! 204: if ( waitForStatus( 0, ataStatusBSY, ataBusyTimeoutmS ) == false ) ! 205: { ! 206: completeCmd( xferCmd, ataReturnErrorBusy, xferCount ); ! 207: return; ! 208: } ! 209: ! 210: status = readATAReg( atapiRegStatus ); ! 211: intReason = readATAReg( atapiRegIntReason ); ! 212: ! 213: if ( !xferInts ) return; ! 214: ! 215: if ( (status & atapiStatusDRQ) && (intReason & atapiIntReasonCD) && !(intReason & atapiIntReasonIO) ) ! 216: { ! 217: rc = sendATAPIPacket(); ! 218: if ( rc != ataReturnNoError ) ! 219: { ! 220: completeCmd( xferCmd, rc ); ! 221: } ! 222: ! 223: else if ( startDma( xferCmd ) != true ) ! 224: { ! 225: rc = ataReturnErrorDMA; ! 226: completeCmd( xferCmd, rc ); ! 227: } ! 228: } ! 229: ! 230: else if ( !(status & atapiStatusDRQ) && (intReason & atapiIntReasonCD) && (intReason & atapiIntReasonIO) ) ! 231: { ! 232: xferInts = 0; ! 233: ! 234: if ( stopDma( xferCmd, &xferCount ) != true ) ! 235: { ! 236: rc = ataReturnErrorDMA; ! 237: xferCount = 0; ! 238: } ! 239: else ! 240: { ! 241: rc = (status & atapiStatusCHK) ? ataReturnErrorStatus : ataReturnNoError; ! 242: } ! 243: ! 244: if ( rc == ataReturnErrorStatus ) ! 245: { ! 246: updateCmdStatus( xferCmd, rc, xferCount ); ! 247: ! 248: if ( doRequestSense( xferCmd ) == false ) ! 249: { ! 250: completeCmd( xferCmd ); ! 251: } ! 252: } ! 253: else ! 254: { ! 255: completeCmd( xferCmd, rc, xferCount ); ! 256: } ! 257: } ! 258: ! 259: else ! 260: { ! 261: stopDma( xferCmd, &xferCount ); ! 262: completeCmd( xferCmd, rc, 0 ); ! 263: } ! 264: } ! 265:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.