|
|
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.