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 * IOATAStandardDriver.cpp
27 #include <IOKit/ata/IOATAStandardInterface.h>
30 #define super IOATAStandardController
32 OSDefineMetaClass( IOATAStandardDriver
, IOATAStandardController
);
33 OSDefineAbstractStructors( IOATAStandardDriver
, IOATAStandardController
);
36 static UInt32 dropInt
=0;
43 void IOATAStandardDriver::executeCommand( IOATAStandardCommand
*cmd
)
45 IOATAStandardDevice
*newDevice
;
46 ATAProtocol newProtocol
;
47 ATATimingProtocol timingProtocol
;
50 newDevice
= cmd
->getDevice(kIOATAStandardDevice
);
51 newProtocol
= cmd
->getProtocol();
54 IOLog("IOATAStandardDriver::%s() - Cmd = %08x Device = %08x Count = %d\n\r",
55 __FUNCTION__
, (int) cmd
, (int) newDevice
, getCommandCount() );
58 if ( getCommandCount() > 1 )
60 if ( currentDevice
!= newDevice
|| currentProtocol
!= newProtocol
)
62 suspendDevice( newDevice
);
63 rescheduleCommand( cmd
);
68 currentProtocol
= newProtocol
;
70 if ( currentDevice
!= newDevice
)
72 newDeviceSelected( newDevice
);
73 currentDevice
= newDevice
;
76 if ( (cmd
->getFlags() & kATACmdFlagTimingChanged
) != 0 )
78 currentDevice
->getTimingSelected( &timingProtocol
);
79 selectTiming( currentDevice
->getUnit(), timingProtocol
);
80 newDeviceSelected( newDevice
);
83 bzero( &results
, sizeof(ATAResults
) );
84 cmd
->setResults( &results
);
86 switch ( currentProtocol
)
88 case kATAProtocolSetRegs
:
89 doProtocolSetRegs( cmd
);
93 doATAProtocolPio( cmd
);
97 doATAProtocolDma( cmd
);
100 case kATAProtocolDMAQueued
:
101 doATAProtocolDmaQueued( cmd
);
104 case kATAProtocolATAPIPIO
:
105 doATAPIProtocolPio( cmd
);
108 case kATAProtocolATAPIDMA
:
109 doATAPIProtocolDma( cmd
);
113 doProtocolNotSupported( cmd
);
123 void IOATAStandardDriver::resetCommand( IOATAStandardCommand
*cmd
)
129 currentProtocol
= kATAProtocolNone
;
138 void IOATAStandardDriver::abortCommand( IOATAStandardCommand
*ataCmd
)
141 doATAReset( ataCmd
);
148 void IOATAStandardDriver::cancelCommand( IOATAStandardCommand
*ataCmd
)
151 IOATAStandardCommand
*origCmd
;
153 origCmd
= ataCmd
->getOriginalCmd();
156 completeCmd( origCmd
);
159 bzero( &results
, sizeof(ATAResults
) );
160 ataCmd
->setResults( &results
);
161 completeCmd( ataCmd
);
169 void IOATAStandardDriver::interruptOccurred()
172 if ( dropInt
++ > 20 )
176 IOLog("IOATAStandardDriver::%s() - Dropping interrupt\n\r", __FUNCTION__
);
177 status
= readATAReg( kATARegStatus
);
183 if ( currentDevice
== 0 )
185 IOLog( "IOATAStandardDriver::interruptOccurred - Spurious interrupt - ATA Status = %04lx\n\r", readATAReg( kATARegStatus
) );
189 switch ( currentProtocol
)
191 case kATAProtocolPIO
:
195 case kATAProtocolDMA
:
199 case kATAProtocolDMAQueued
:
200 processATADmaQueuedInt();
203 case kATAProtocolATAPIPIO
:
204 processATAPIPioInt();
207 case kATAProtocolATAPIDMA
:
208 processATAPIDmaInt();
212 IOLog( "IOATAStandardDriver::interruptOccurred - Spurious interrupt - ATA Status = %04lx\n\r", readATAReg( kATARegStatus
) );
221 void IOATAStandardDriver::doProtocolNotSupported( IOATAStandardCommand
*cmd
)
223 completeCmd( cmd
, kATAReturnNotSupported
);
231 void IOATAStandardDriver::completeCmd( IOATAStandardCommand
*cmd
, ATAReturnCode returnCode
, UInt32 bytesTransferred
)
233 updateCmdStatus( cmd
, returnCode
, bytesTransferred
);
241 void IOATAStandardDriver::updateCmdStatus( IOATAStandardCommand
*cmd
, ATAReturnCode returnCode
, UInt32 bytesTransferred
)
247 bzero( &result
, sizeof(result
) );
249 resultmask
= cmd
->getResultMask();
251 if ( cmd
->getProtocol() != kATAProtocolSetRegs
)
253 if ( waitForStatus( 0, kATAStatusBSY
, kATABusyTimeoutmS
) == false )
255 if ( returnCode
== kATAReturnSuccess
)
257 kprintf("IOATAStandardDriver::updateCmdStatus is going to return kATAReturnBusyError;\n");
258 returnCode
= kATAReturnBusyError
;
263 for ( i
=0; resultmask
; i
++ )
265 if ( resultmask
& 1 )
267 result
.ataRegs
[i
] = readATAReg( i
);
272 result
.adapterStatus
= returnCode
;
273 result
.bytesTransferred
= bytesTransferred
;
274 cmd
->setResults( &result
);
281 void IOATAStandardDriver::completeCmd( IOATAStandardCommand
*cmd
)
283 IOATAStandardDevice
*device
;
284 ATAResults ataResult
;
286 cmd
->getResults( &ataResult
);
287 ataResult
.returnCode
= getIOReturnCode( ataResult
.adapterStatus
);
288 cmd
->setResults( &ataResult
);
290 if ( getCommandCount() == 1 )
292 currentProtocol
= kATAProtocolNone
;
294 device
= selectDevice();
297 resumeDevice( device
);
308 IOReturn
IOATAStandardDriver::getIOReturnCode( ATAReturnCode code
)
312 case kATAReturnSuccess
:
313 return kIOReturnSuccess
;
315 case kATAReturnNotSupported
:
316 return kIOReturnUnsupported
;
318 case kATAReturnNoResource
:
319 return kIOReturnNoResources
;
321 case kATAReturnBusyError
:
322 return kIOReturnBusy
;
324 case kATAReturnInterruptTimeout
:
325 return kIOReturnTimeout
;
327 case kATAReturnRetryPIO
:
328 case kATAReturnStatusError
:
329 case kATAReturnProtocolError
:
333 return kIOReturnIOError
;
340 void IOATAStandardDriver::newDeviceSelected( IOATAStandardDevice
* )
349 bool IOATAStandardDriver::programDma( IOATAStandardCommand
* )
351 IOLog( "IOATAStandardDriver::%s - Subclass must implement\n\r", __FUNCTION__
);
360 bool IOATAStandardDriver::startDma( IOATAStandardCommand
* )
362 IOLog( "IOATAStandardDriver::%s - Subclass must implement\n\r", __FUNCTION__
);
371 bool IOATAStandardDriver::stopDma( IOATAStandardCommand
*, UInt32
* )
373 IOLog( "IOATAStandardDriver::%s - Subclass must implement\n\r", __FUNCTION__
);
381 bool IOATAStandardDriver::checkDmaActive()
383 IOLog( "IOATAStandardDriver::%s - Subclass must implement\n\r", __FUNCTION__
);
391 bool IOATAStandardDriver::resetDma()
400 bool IOATAStandardDriver::getProtocolsSupported( ATAProtocol
*forProtocol
)
402 *(UInt32
*) forProtocol
= ( kATAProtocolSetRegs
405 | kATAProtocolDMAQueued
406 | kATAProtocolATAPIPIO
407 | kATAProtocolATAPIDMA
);
416 ATAReturnCode
IOATAStandardDriver::waitForDRQ( UInt32 timeoutmS
)
418 AbsoluteTime currentTime
, endTime
;
420 ATAReturnCode rc
= kATAReturnBusyError
;
422 clock_interval_to_deadline( timeoutmS
, 1000000, &endTime
);
425 status
= readATAReg( kATARegStatus
);
426 if ( (status
& kATAPIStatusBSY
) == 0 )
428 if ( (status
& kATAStatusERR
) != 0 )
430 rc
= kATAReturnStatusError
;
433 if ( (status
& kATAStatusDRQ
) != 0 )
435 rc
= kATAReturnSuccess
;
439 clock_get_uptime( ¤tTime
);
441 while ( CMP_ABSOLUTETIME( &endTime
, ¤tTime
) > 0 );
443 if (rc
== kATAReturnBusyError
)
444 kprintf("IOATAStandardDriver::waitForDRQ is going to return kATAReturnBusyError;\n");
454 bool IOATAStandardDriver::waitForStatus( UInt32 statusBitsOn
, UInt32 statusBitsOff
, UInt32 timeoutmS
)
456 AbsoluteTime currentTime
, endTime
;
459 clock_interval_to_deadline( timeoutmS
, 1000000, &endTime
);
463 status
= readATAReg( kATARegStatus
);
465 if ( (status
& statusBitsOn
) == statusBitsOn
466 && (status
& statusBitsOff
) == 0 )
471 clock_get_uptime( ¤tTime
);
473 } while ( CMP_ABSOLUTETIME( &endTime
, ¤tTime
) > 0 );
482 bool IOATAStandardDriver::waitForAltStatus( UInt32 statusBitsOn
, UInt32 statusBitsOff
, UInt32 timeoutmS
)
484 AbsoluteTime currentTime
, endTime
;
487 clock_interval_to_deadline( timeoutmS
, 1000000, &endTime
);
491 status
= readATAReg( kATARegAltStatus
);
493 if ( (status
& statusBitsOn
) == statusBitsOn
494 && (status
& statusBitsOff
) == 0 )
499 clock_get_uptime( ¤tTime
);
501 } while ( CMP_ABSOLUTETIME( &endTime
, ¤tTime
) > 0 );
510 bool IOATAStandardDriver::start (IOService
*provider
)
513 PMinit(); // initialize superclass variables
514 provider
->joinPMtree(this); // attach into the power management hierarchy
516 #define number_of_power_states 2
518 static IOPMPowerState ourPowerStates
[number_of_power_states
] = {
519 {1,0,0,0,0,0,0,0,0,0,0,0},
520 {1,IOPMDeviceUsable
,IOPMPowerOn
,IOPMPowerOn
,0,0,0,0,0,0,0,0}
524 // register ourselves with ourself as policy-maker
526 registerPowerDriver(this, ourPowerStates
, number_of_power_states
);
529 // We are starting up, so not waking up:
530 wakingUpFromSleep
= false;
532 if (!super::start (provider
))
543 IOReturn
IOATAStandardDriver::setPowerState(unsigned long powerStateOrdinal
, IOService
* whatDevice
)
545 // Do not do anything if the state is inavalid.
546 if (powerStateOrdinal
>= 2)
547 return IOPMNoSuchState
;
549 if ( powerStateOrdinal
== 0 )
551 kprintf("IOATAStandardDriver would be powered off here\n");
552 wakingUpFromSleep
= true;
554 // Let's pretend we did something:
555 return IOPMAckImplied
;
558 if ( ( powerStateOrdinal
== 1 ) && ( wakingUpFromSleep
) )
560 wakingUpFromSleep
= false;
561 disableControllerInterrupts();
563 enableControllerInterrupts();
564 return IOPMAckImplied
;
567 return IOPMCannotRaisePower
;