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@
25 * This class implements SCSI hard disk functionality.
27 * Subclasses may modify the operations to handle device-specific variations.
30 #ifndef _IOSCSIHDDRIVE_H
31 #define _IOSCSIHDDRIVE_H
33 #include <IOKit/IOTypes.h>
34 #include <IOKit/scsi/IOSCSIDeviceInterface.h>
35 #include <IOKit/storage/scsi/IOBasicSCSI.h>
37 /* SCSI (inquiry) device type. */
40 kIOSCSIDeviceTypeDirectAccess
= 0x00
46 kIOSCSICommandTestUnitReady
= 0x00,
47 kIOSCSICommandFormatUnit
= 0x04,
48 kIOSCSICommandStartStopUnit
= 0x1b,
49 kIOSCSICommandPreventAllow
= 0x1e,
50 kIOSCSICommandSynchronizeCache
= 0x35,
51 kIOSCSICommandModeSelect
= 0x55,
52 kIOSCSICommandModeSense
= 0x5a,
53 kIOSCSICommandRead
= 0xa8,
54 kIOSCSICommandWrite
= 0xaa
58 UInt8 opcode
; /* 0x12 */
59 UInt8 lunbits
; /* lun and control bits */
66 struct IOPrevAllowcdb
{
75 struct IOStartStopcdb
{
82 /* Power Conditions */
83 static const UInt8 P_NOCHANGE
= 0x00; /* 0 - no change */
84 static const UInt8 P_ACTIVE
= 0x10; /* 1 - change to Active */
85 static const UInt8 P_IDLE
= 0x20; /* 2 - change to Idle */
86 static const UInt8 P_STANDBY
= 0x30; /* 3 - change to Standby */
87 static const UInt8 P_RESERVED4
= 0x40; /* 4 - reserved */
88 static const UInt8 P_SLEEP
= 0x50; /* 5 - change to Sleep */
89 static const UInt8 P_RESERVED6
= 0x60; /* 6 - reserved */
90 static const UInt8 P_LUNCONTROL
= 0x70; /* 7 - give pwr ctl to LUN */
91 static const UInt8 P_RESERVED8
= 0x80; /* 8 - reserved */
92 static const UInt8 P_RESERVED9
= 0x90; /* 9 - reserved */
93 static const UInt8 P_TIDLEZERO
= 0xa0; /* a - force Idle Cond Timer = 0 */
94 static const UInt8 P_TSTDBYZERO
= 0xb0; /* b - force Stby Cond Timer = 0 */
96 static const UInt8 C_LOEJ
= 0x02; /* load on start/eject on stop */
97 static const UInt8 C_SPINUP
= 0x01;
98 static const UInt8 C_SPINDOWN
= 0x00;
104 struct IOSyncCachecdb
{
107 UInt8 lba_3
; /* msb */
110 UInt8 lba_0
; /* lsb */
120 * We define and understand three basic, generic power states. A subclass may change
121 * the power management logic, but all power-management routines should be examined
122 * if anything is changed. The only routines that deal directly with these values
123 * are directly related to power management. All other functions merely ask for and
124 * pass along power state values.
126 * The power state for an all-off condition.
127 * @constant kElectronicsOn
128 * The power state for the electronics on, but the media off.
130 * The power state for the electronics and media on.
131 * @constant kNumberOfPowerStates
132 * The maximum enum value.
134 enum { /* electronics mechanical */
135 kAllOff
= 0, /* OFF OFF */
136 kElectronicsOn
= 1, /* ON OFF */
137 kAllOn
= 2, /* ON ON */
139 kNumberOfPowerStates
= 3
144 * IOSCSIHDDrive : public IOBasicSCSI
146 * SCSI Hard Disk driver.
148 * IOSCSIHDDrive derives from IOBasicSCSI and adds all functionality
149 * needed to support removable or fixed hard disk drives.
152 class IOSCSIHDDrive
: public IOBasicSCSI
{
154 OSDeclareDefaultStructors(IOSCSIHDDrive
)
158 /* Overrides from IOService: */
160 virtual bool init(OSDictionary
* properties
);
167 * We override IOBasicSCSI::start so we can initialize Power Management,
168 * then we call createNub to create an IOSCSIHDDriveNub.
170 virtual bool start(IOService
* provider
);
172 /* Overrides from IOBasicSCSI: */
175 * @function deviceTypeMatches
177 * Determine if device type matches expected type.
179 * We implement this function so we can return a match
180 * on the hard disk device type.
182 virtual bool deviceTypeMatches(UInt8 inqBuf
[],UInt32 inqLen
,SInt32
*score
);
185 * @function constructDeviceProperties
187 * Construct a set of properties about the device.
189 * This function creates a set of properties reflecting information
192 * This function is presently not used.
194 * A pointer to an OSDictionary containing the properties. The caller
195 * is responsible for releasing the OSDictionary.
197 virtual OSDictionary
*constructDeviceProperties(void);
200 * @function RWCompletion
202 * Asynchronous read/write completion routine.
204 * We implement this function in this class. It is called from the base
205 * class when an IO operation completes.
207 virtual void RWCompletion(struct context
*cx
);
209 /* End of IOBasicSCSI overrides */
211 /* Additional API added to IOBasicSCSI: */
214 * @function doAsyncReadWrite
216 * Start an asynchronous read or write operation.
218 * See IOBlockStorageDevice for details.
220 virtual IOReturn
doAsyncReadWrite(IOMemoryDescriptor
*buffer
,
221 UInt32 block
,UInt32 nblks
,
222 IOStorageCompletion completion
);
225 * @function doSyncReadWrite
227 * Perform a synchronous read or write operation.
229 * See IOBlockStorageDevice for details.
231 virtual IOReturn
doSyncReadWrite(IOMemoryDescriptor
*buffer
,UInt32 block
,UInt32 nblks
);
234 * @function doEjectMedia
238 * See IOBlockStorageDevice for details.
240 virtual IOReturn
doEjectMedia(void);
243 * @function doFormatMedia
245 * Format the media to the specified byte capacity.
247 * The default implementation calls standardFormatMedia.
248 * See IOBlockStorageDevice for details.
250 virtual IOReturn
doFormatMedia(UInt64 byteCapacity
);
253 * @function doGetFormatCapacities
255 * Return the allowable formatting byte capacities.
257 * The default implementation of this method returns a value of block
258 * size * max block, and a capacities count of 1.
259 * See IOBlockStorageDevice for details.
261 virtual UInt32
doGetFormatCapacities(UInt64
* capacities
,
262 UInt32 capacitiesMaxCount
) const;
265 * @function doLockUnlockMedia
267 * Lock or unlock the (removable) media in the drive.
269 * This method issues a standard SCSI Prevent/Allow command to lock
270 * or unlock the media in the drive.
271 * See IOBlockStorageDevice for details.
273 virtual IOReturn
doLockUnlockMedia(bool doLock
);
276 * @function doSynchronizeCache
278 * Force data blocks in the drive's buffer to be flushed to the media.
280 * This method issues a SCSI Synchronize Cache command, to ensure that
281 * all blocks in the device cache are written to the media.
282 * See IOBlockStorageDevice for details.
284 virtual IOReturn
doSynchronizeCache(void);
287 * @function reportMediaState
289 * Report the device's media state.
291 * This method reports whether media is present or not, and also
292 * whether the media state has changed since the last call to
293 * reportMediaState. The default implementation issues a SCSI Test
294 * Unit Ready command: depending on the result of that command, the
295 * following cases are reported:
297 * 1. TUR status == good completion: we report media present and return
300 * 2. TUR status != good completion, but good autosense returned:
302 * 2a: sense key says not ready: we report media not present
303 * and return kIOReturnSuccess.
305 * 2b: sense key is anything else: we report media not present
306 * and return kIOReturnIOError.
308 * 3. TUR status != good completion, and no autosense data: we do not
309 * set mediaPresent or changedState, and we return whatever result
310 * came back from the SCSI operation.
312 virtual IOReturn
reportMediaState(bool *mediaPresent
,bool *changed
);
314 /* --- end of additional API --- */
319 * @function createFormatCdb
321 * Create a SCSI CDB for a format operation.
323 * Override this to control the cdb created for a format operation.
324 * The default implementation creates a 6-byte format command with
325 * no data buffer, disconnect allowed, 8-byte autosense, and a 15-minute timeout.
327 * See also: allocateFormatBuffer, deleteFormatBuffer, composeFormatBuffer.
328 * @param byteCapacity
329 * The requested byte capacity to which the media should be formatted. This value
330 * should have been previously validated, otherwise the device may return an error.
332 * A pointer to the CDB bytes.
334 * The length of the CDB in bytes.
336 * The device block to be written.
338 * The number of blocks to be transferred.
339 * @param maxAutoSenseLength
340 * The maximum size of the autosense data, in bytes. A value of zero
341 * will disable autosense.
342 * @param timeoutSeconds
343 * The command timeout in seconds.
345 * The IOSCSICommandOptions returned will be used to issue the command.
347 virtual UInt32
createFormatCdb(
348 UInt64 byteCapacity
, /* in */
350 UInt32
*cdbLength
, /* out */
351 UInt8 buf
[], /* in */
352 UInt32 bufLen
, /* in */
353 UInt32
*maxAutoSenseLength
, /* out */
354 UInt32
*timeoutSeconds
); /* out */
358 * @function allocateFormatBuffer
360 * Create a data buffer to be used for formatting the media.
362 * If a format buffer is to be used, then "allocateFormatBuffer" and
363 * deleteFormatBuffer" must be overridden to manage the buffer. The
364 * buffer must be prepared for IO upon return from allocateFormatBuffer.
365 * The default implementations of these methods don't allocate a buffer.
367 * A pointer for the returned buffer pointer.
369 * The desired length of the buffer, in bytes.
371 virtual IOReturn
allocateFormatBuffer(UInt8
**buf
,UInt32
*buflen
);
374 * @function deleteFormatBuffer
376 * Delete the data buffer to be used for formatting the media.
378 * If a format buffer is to be used, then "allocateFormatBuffer" and
379 * deleteFormatBuffer" must be overridden to manage the buffer.
380 * The default implementation of this method does nothing.
382 * A pointer to the buffer to delete.
384 * The size of the buffer, in bytes.
386 virtual void deleteFormatBuffer(UInt8
*buf
,UInt32 buflen
);
389 * @function composeFormatBuffer
391 * Compose the data in the buffer used for the format command.
393 * This method will be called to compose the data in the format buffer.
395 * The default implementation of this method does nothing.
397 * A pointer to the format data buffer.
399 * The size of the format data buffer, in bytes.
401 * The return value should be the desired values for the "CmpLst" and Defect
402 * List Format bits in the CDB. The default implementation returns zero.
404 virtual UInt8
composeFormatBuffer(UInt8
*buf
,UInt32 buflen
);
406 /* Override these methods to save and restore the state of the device electronics
407 * when power is turned off and on. The defaults do nothing and return kIOReturnSuccess.
411 * @function restoreElectronicsState
413 * Restore the state of the device electronics when powering-up.
415 * This method is called just after the device transitions from a powered-off state.
417 * The default implementation of this method does nothing and returns kIOReturnSuccess.
419 virtual IOReturn
restoreElectronicsState(void);
422 * @function saveElectronicsState
424 * Save the state of the device electronics when powering-down.
426 * This method is called just before the device transitions to a powered-off state.
428 * The default implementation of this method does nothing and returns kIOReturnSuccess.
430 virtual IOReturn
saveElectronicsState(void);
433 * @function initialPowerStateForDomainState
435 * Return the initial power state for the device.
437 * This method is called to obtain the initial power state for the device,
438 * by calling getInitialPowerState.
440 * Power domain state flags.
442 * The return value must be a valid power state value.
444 virtual unsigned long initialPowerStateForDomainState ( IOPMPowerFlags domainState
);
447 * @function maxCapabilityForDomainState
449 * Return the maximum power level obtainable for the given state.
451 * This method is called to obtain the maximum power level obtainable for the
454 * Power domain state flags.
456 * The return value must be a valid power state value.
458 virtual unsigned long maxCapabilityForDomainState ( IOPMPowerFlags domainState
);
461 * @function powerStateForDomainState
462 * Return the maximum power level obtainable for the given state.
464 * This method is called to obtain the maximum power level obtainable for the
467 * Power domain state flags.
469 * The return value must be a valid power state value.
471 virtual unsigned long powerStateForDomainState ( IOPMPowerFlags domainState
);
474 * @function powerStateDidChangeTo
476 * React to a change in power state.
478 * This method is called when the power state changes. We call restoreElectronicsState
479 * if necessary, then call dequeueCommands if we have changed to a state that has power.
480 * @param stateOrdinal
481 * The power level to which we have changed.
483 virtual IOReturn
powerStateDidChangeTo ( unsigned long, unsigned long stateOrdinal
, IOService
* );
486 * @function powerStateWillChangeTo
488 * Prepare for a power state change.
490 * This method is called when the power state will change. If we are powering-up from kAllOff,
491 * we schedule a call to restoreElectronicsState. If, instead, we are powering-down from an "on" state,
492 * we schedule a call to saveElectronicsState.
493 * @param stateOrdinal
494 * The power level to which we will change.
496 virtual IOReturn
powerStateWillChangeTo ( unsigned long, unsigned long stateOrdinal
, IOService
* );
499 * @function setPowerState
501 * Set the power state to the specified state.
503 * This method is called to cause a change in power state. We handle changes to and from
504 * kAllOn and kElectronicsOn, which are done by spinning up and down the media.
505 * @param powerStateOrdinal
506 * The power level to which we must change.
508 virtual IOReturn
setPowerState ( unsigned long powerStateOrdinal
, IOService
* );
511 * @function powerTickle
512 * Check for the device power state currently being in the desired state.
514 * This method simply "tickles"
515 * the Power Management subsystem to ensure that the device transitions to the desired
516 * state if necessary.
518 virtual bool powerTickle(UInt32 desiredState
);
520 /* Override this method to report the initial device power state when its domain is
521 * powered up. The default implementation assumes the drive spins up.
525 * @function getInitialPowerState
527 * Report the initial power state of the device.
529 * The default implementation of this method returns kAllOn, assuming that the
530 * drive spindle spins up initially.
532 * The return value must be a valid power state value.
534 virtual unsigned long getInitialPowerState(void); /* default = kAllOn */
536 /* Override these to change power level required to do various commands. */
539 * @function getEjectPowerState
541 * Return the required device power level to determine eject the media.
543 * The default implementation of this method returns kElectronicsOn.
545 * The return value must be a valid power state value.
547 virtual UInt32
getEjectPowerState(void); /* default = kElectronicsOn */
550 * @function getExecuteCDBPowerState
555 * The return value must be a valid power state value.
557 virtual UInt32
getExecuteCDBPowerState(void); /* default = kAllOn */
560 * @function getFormatMediaPowerState
562 * Return the required device power level to execute a client CDB.
564 * The default implementation of this method returns kAllOn.
566 * The return value must be a valid power state value.
568 virtual UInt32
getFormatMediaPowerState(void); /* default = kAllOn */
571 * @function getInquiryPowerState
573 * Return the required device power level to execute an Inquiry command.
575 * The default implementation of this method returns kElectronicsOn.
577 * The return value must be a valid power state value.
579 virtual UInt32
getInquiryPowerState(void); /* default = kElectronicsOn */
582 * @function getLockUnlockMediaPowerState
584 * Return the required device power level to lock or unlock the media.
586 * The default implementation of this method returns kElectronicsOn.
588 * The return value must be a valid power state value.
590 virtual UInt32
getLockUnlockMediaPowerState(void); /* default = kElectronicsOn */
593 * @function getReadCapacityPowerState
595 * Return the required device power level to execute a Read-Capacity command.
597 * The default implementation of this method returns kElectronicsOn.
599 * The return value must be a valid power state value.
601 virtual UInt32
getReadCapacityPowerState(void); /* default = kElectronicsOn */
604 * @function getReadWritePowerState
606 * Return the required device power level to execute a Read or Write command.
608 * The default implementation of this method returns kAllOn.
610 * The return value must be a valid power state value.
612 virtual UInt32
getReadWritePowerState(void); /* default = kAllOn */
615 * @function getReportWriteProtectionPowerState
617 * Return the required device power level to report media write protection.
619 * The default implementation of this method returns kElectronicsOn.
621 * The return value must be a valid power state value.
623 virtual UInt32
getReportWriteProtectionPowerState(void); /* default = kElectronicsOn */
626 * @function getStartPowerState
628 * Return the required device power level to start (spin up) the media.
630 * The default implementation of this method returns kElectronicsOn.
632 * The return value must be a valid power state value.
634 virtual UInt32
getStartPowerState(void); /* default = kElectronicsOn */
637 * @function getStopPowerState
639 * Return the required device power level to stop (spin down) the media.
641 * The default implementation of this method returns kAllOn.
643 * The return value must be a valid power state value.
645 virtual UInt32
getStopPowerState(void); /* default = kAllOn */
648 * @function getSynchronizeCachePowerState
650 * Return the required device power level to issue a Synchronize-Cache command.
652 * The default implementation of this method returns kAllOn.
654 * The return value must be a valid power state value.
656 virtual UInt32
getSynchronizeCachePowerState(void); /* default = kAllOn */
659 * @function getTestUnitReadyPowerState
661 * Return the required device power level to issue a Test Unit Ready command.
663 * The default implementation of this method returns kElectronicsOn.
665 * The return value must be a valid power state value.
667 virtual UInt32
getTestUnitReadyPowerState(void); /* default = kElectronicsOn */
671 * Internally used methods.
675 * @function createNub
677 * Create, init, attach, and register the device nub.
679 * This method calls instantiateNub, then init, attach, and register.
681 * A pointer to the nub or NULL if something failed.
683 virtual IOService
* createNub(void);
686 * @function getDeviceTypeName
688 * Return a character string for the device type.
690 * The default implementation of this method returns
691 * kIOBlockStorageDeviceTypeGeneric.
693 virtual const char * getDeviceTypeName(void);
696 * @function instantiateNub
698 * Create the device nub.
700 * A subclass will override this method to change the type of nub created.
701 * A CD driver, for example, will instantiate an IOSCSICDDriveNub instead
702 * of the default implementation's IOSCSIHDDriveNub.
704 virtual IOService
* instantiateNub(void);
709 * Start (spin up) the media.
711 * This method calls doStartStop.
713 virtual IOReturn
doStart(void);
716 * @function doStartStop
718 * Perform the actual spin up/down command.
720 * This method issues a SCSI Start Stop Unit command to start or stop
721 * the device. Because the powerCondition value is only for use with
722 * SCSI-3 devices, the current implementation ignores powerCondition.
724 * True to start (spin-up) the media; False to stop (spin-down) the media.
726 * True to eject; False to not eject. This parameter is applicable only to a stop
728 * @param powerCondition
729 * The power condition to which the drive should transition. This is a SCSI-3
730 * capability; it is presently unused.
732 virtual IOReturn
doStartStop(bool start
,bool loadEject
,UInt8 powerCondition
);
737 * Stop (spin down) the media.
739 * This method calls doStartStop.
741 virtual IOReturn
doStop(void);
744 * @function standardFormatMedia
746 * Perform a standard media format operation.
748 * See doFormatMedia for further information.
750 virtual IOReturn
standardFormatMedia(UInt64 byteCapacity
);
753 * @function standardSynchronizeCache
755 * Perform a standard Synchronize-Cache operation.
757 * See doFormatMedia for further information.
759 virtual IOReturn
standardSynchronizeCache(void);
765 /* Device information : */
769 * True if media is present; False if media is not present.
774 * @var _startStopDisabled
775 * True if the start/stop commands are disabled due to an error.
777 bool _startStopDisabled
;
781 * True if we must restore the device electronics state after a power-up.
783 bool _restoreState
; /* true if we must restore after power-up */ };