]>
git.saurik.com Git - apple/xnu.git/blob - iokit/Families/IOATAStandard/IOATAStandardDriverDma.cpp
2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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.
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
20 * @APPLE_LICENSE_HEADER_END@
24 * IOATAStandardDriverDma.cpp
27 #include <IOKit/ata/IOATAStandardInterface.h>
29 /*----------------------------------- ATA DMA Protocol ------------------------------*/
35 void IOATAStandardDriver::doATAProtocolDma( IOATAStandardCommand
*cmd
)
41 setCommandLimit( currentDevice
, 1 );
43 cmd
->getTaskfile( &taskfile
);
45 regmask
= taskfile
.regmask
;
47 if ( regmask
& ATARegtoMask(kATARegDriveHead
) )
49 regmask
&= ~ATARegtoMask(kATARegDriveHead
);
50 if ( selectDrive( taskfile
.ataRegs
[kATARegDriveHead
] ) == false )
52 completeCmd( cmd
, kATAReturnBusyError
);
59 for ( i
= 0; regmask
; i
++ )
63 writeATAReg( i
, taskfile
.ataRegs
[i
] );
75 void IOATAStandardDriver::processATADmaInt()
79 ATAReturnCode rc
= kATAReturnSuccess
;
80 IOATAStandardCommand
*ataCmd
;
83 ataCmd
= findCommandWithNexus( currentDevice
, (UInt32
) -1 );
86 IOLog( "IOATAStandardDriver::processATADmaInt() - ATA Command not found\n\r" );
90 if ( waitForStatus( 0, kATAStatusBSY
, kATABusyTimeoutmS
) == false )
92 stopDma( ataCmd
, &xferCount
);
93 completeCmd( ataCmd
, kATAReturnBusyError
, xferCount
);
97 status
= readATAReg( kATARegStatus
);
99 ataCmd
->getPointers( 0, &reqCount
, 0 );
101 if ( stopDma( ataCmd
, &xferCount
) != true )
103 rc
= kATAReturnDMAError
;
106 else if ( status
& kATAStatusDRQ
)
108 rc
= kATAReturnDMAError
;
111 else if ( status
& kATAStatusERR
)
113 rc
= kATAReturnStatusError
;
116 else if ( reqCount
!= xferCount
)
118 rc
= kATAReturnProtocolError
;
121 completeCmd( ataCmd
, rc
, xferCount
);
124 /*----------------------------------- ATA DMA Queued Protocol ------------------------------*/
130 void IOATAStandardDriver::doATAProtocolDmaQueued( IOATAStandardCommand
*ataCmd
)
132 ATATaskfile taskfile
;
136 if ( dmaActive
== true )
138 setCommandLimit( currentDevice
, 0 );
139 rescheduleCommand( ataCmd
);
143 setCommandLimit( currentDevice
, 31 );
145 ataCmd
->getTaskfile( &taskfile
);
147 regmask
= taskfile
.regmask
;
149 regmask
&= ~(ATARegtoMask(kATARegDriveHead
) | ATARegtoMask(kATARegCommand
));
151 if ( selectDrive( taskfile
.ataRegs
[kATARegDriveHead
] ) == false )
153 completeCmd( ataCmd
, kATAReturnBusyError
);
157 programDma( ataCmd
);
161 taskfile
.ataRegs
[kATARegSectorCount
] = taskfile
.tag
<< 3;
163 for ( i
= 0; regmask
; i
++ )
167 writeATAReg( i
, taskfile
.ataRegs
[i
] );
172 writeATAReg( kATARegCommand
, taskfile
.ataRegs
[kATARegCommand
] );
176 waitForAltStatus( 0, kATAStatusBSY
, kATABusyTimeoutmS
);
184 void IOATAStandardDriver::processATADmaQueuedInt()
190 IOATAStandardCommand
*ataCmd
;
191 ATAReturnCode rc
= kATAReturnSuccess
;
195 status
= readATAReg( kATARegStatus
);
196 intReason
= readATAReg( kATARegSectorCount
);
197 tag
= intReason
/ kATATagBit
;
199 ataCmd
= findCommandWithNexus( currentDevice
, tag
);
201 if ( (intReason
& kATAPIIntReasonCD
) && (intReason
& kATAPIIntReasonIO
) && (dmaActive
== true) )
205 IOLog( "IOATAStandardDriver::processATADmaQueuedInt() - ATA Command not found\n\r" );
211 if ( stopDma( ataCmd
, &xferCount
) != true )
213 rc
= kATAReturnDMAError
;
216 else if ( status
& kATAStatusERR
)
218 rc
= kATAReturnStatusError
;
221 completeCmd( ataCmd
, rc
, xferCount
);
224 if ( (status
& kATAStatusDRQ
) != 0 )
228 IOLog( "IOATAStandardDriver::processATADmaQueuedInt() - ATA Command not found\n\r" );
232 programDma( ataCmd
);
238 if ( status
& kATAStatusSERV
)
242 writeATAReg( kATARegCommand
, kATACommandService
);
244 if ( waitForAltStatus( 0, kATAStatusBSY
, 500 ) == false )
251 if ( dmaActive
== false )
253 setCommandLimit( currentDevice
, 31 );
260 /*----------------------------------- ATAPI DMA Protocols ------------------------------*/
267 void IOATAStandardDriver::doATAPIProtocolDma( IOATAStandardCommand
*ataCmd
)
269 ATATaskfile taskfile
;
275 setCommandLimit( currentDevice
, 1 );
277 ataCmd
->getTaskfile( &taskfile
);
278 ataCmd
->getCDB( &atapiCmd
);
280 regmask
= taskfile
.regmask
;
282 if ( regmask
& ATARegtoMask(kATARegDriveHead
) )
284 regmask
&= ~ATARegtoMask(kATARegDriveHead
);
285 if ( selectDrive( taskfile
.ataRegs
[kATARegDriveHead
] ) == false )
287 completeCmd( ataCmd
, kATAReturnBusyError
);
292 // Wait for BSY = 0 and DRQ = 0 before issuing a packet command.
294 waitForStatus( 0, kATAStatusBSY
| kATAStatusDRQ
, kATABusyTimeoutmS
);
296 for ( i
= 0; regmask
; i
++ )
300 writeATAReg( i
, taskfile
.ataRegs
[i
] );
305 programDma( ataCmd
);
307 if ( ataCmd
->getDevice(kIOATAStandardDevice
)->getATAPIPktInt() == false )
309 rc
= sendATAPIPacket( ataCmd
);
311 if ( rc
!= kATAReturnSuccess
)
313 completeCmd( ataCmd
, rc
);
326 void IOATAStandardDriver::processATAPIDmaInt()
328 IOATAStandardCommand
*ataCmd
;
329 ATAReturnCode rc
= kATAReturnProtocolError
;
334 ataCmd
= findCommandWithNexus( currentDevice
, (UInt32
) -1 );
337 IOLog( "IOATAStandardDriver::processATAPIDmaInt() - ATA Command not found\n\r" );
341 if ( waitForStatus( 0, kATAStatusBSY
, kATABusyTimeoutmS
) == false )
343 completeCmd( ataCmd
, kATAReturnBusyError
, 0 );
347 status
= readATAReg( kATARegATAPIStatus
);
348 intReason
= readATAReg( kATARegATAPIIntReason
);
350 if ( (status
& kATAPIStatusDRQ
) && (intReason
& kATAPIIntReasonCD
) && !(intReason
& kATAPIIntReasonIO
) )
352 rc
= sendATAPIPacket( ataCmd
);
353 if ( rc
!= kATAReturnSuccess
)
355 completeCmd( ataCmd
, rc
);
358 else if ( startDma( ataCmd
) != true )
360 rc
= kATAReturnDMAError
;
361 completeCmd( ataCmd
, rc
);
365 else if ( !(status
& kATAPIStatusDRQ
) && (intReason
& kATAPIIntReasonCD
) && (intReason
& kATAPIIntReasonIO
) )
367 if ( stopDma( ataCmd
, &xferCount
) != true )
369 rc
= kATAReturnDMAError
;
374 rc
= (status
& kATAPIStatusCHK
) ? kATAReturnStatusError
: kATAReturnSuccess
;
377 completeCmd( ataCmd
, rc
, xferCount
);
381 stopDma( ataCmd
, &xferCount
);
382 completeCmd( ataCmd
, rc
, 0 );