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@
23 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
25 * IOATAPIHDDrive.h - Generic ATAPI Direct-Access driver.
28 * Sep 2, 1999 jliu - Ported from AppleATAPIDrive.
31 #include <IOKit/assert.h>
32 #include <IOKit/storage/ata/IOATAPIHDDrive.h>
33 #include <IOKit/storage/ata/IOATAPIHDDriveNub.h>
35 #define super IOATAHDDrive
36 OSDefineMetaClassAndStructors( IOATAPIHDDrive
, IOATAHDDrive
)
38 //---------------------------------------------------------------------------
39 // Override the init() method in IOATAHDDrive.
42 IOATAPIHDDrive::init(OSDictionary
* properties
)
44 _mediaPresent
= false;
47 return super::init(properties
);
50 //---------------------------------------------------------------------------
51 // Override probe() method inherited from IOATAHDDrive. We need to
52 // perform additional matching on ATAPI device type based on the
53 // Inquiry data revealed by an ATA(PI) device nub.
56 IOATAPIHDDrive::probe(IOService
* provider
, SInt32
* score
)
60 bool wasOpened
= false;
62 // Let superclass have a go at probe first.
64 if (!super::probe(provider
, score
))
67 // Our provider must be a IOATADevice nub, most likely created
68 // by an IOATAController instance.
70 _ataDevice
= OSDynamicCast(IOATADevice
, provider
);
72 return 0; // IOATADevice nub not found.
75 // Since we may issue command to the IOATADevice to perform
76 // device matching, we express interest in using the device by
77 // performing an open.
79 if (_ataDevice
->open(this) == false)
84 // Perform ATAPI type matching, CD-ROM, Direct-Access, Tape, etc.
86 if (!_ataDevice
->getInquiryData(1, (ATAPIInquiry
*) &deviceType
) ||
87 !matchATAPIDeviceType(deviceType
& 0x1f, score
))
95 _ataDevice
->close(this);
102 //---------------------------------------------------------------------------
103 // Report as an ATAPI device.
106 IOATAPIHDDrive::reportATADeviceType() const
108 return kATADeviceATAPI
;
111 //---------------------------------------------------------------------------
112 // Looks for an ATAPI device which is a direct-access device.
115 IOATAPIHDDrive::matchATAPIDeviceType(UInt8 type
, SInt32
* score
)
117 if (type
== kIOATAPIDeviceTypeDirectAccess
)
123 //---------------------------------------------------------------------------
124 // Gather information about the ATAPI device nub.
127 IOATAPIHDDrive::inspectDevice(IOATADevice
* device
)
131 // Fetch ATAPI device information from the nub.
133 string
= OSDynamicCast(OSString
,
134 device
->getProperty(kATAPropertyVendorName
));
136 strncpy(_vendor
, string
->getCStringNoCopy(), 8);
140 string
= OSDynamicCast(OSString
,
141 device
->getProperty(kATAPropertyProductName
));
143 strncpy(_product
, string
->getCStringNoCopy(), 16);
147 string
= OSDynamicCast(OSString
,
148 device
->getProperty(kATAPropertyProductRevision
));
150 strncpy(_revision
, string
->getCStringNoCopy(), 4);
154 // Device wants to be power-managed.
156 _supportedFeatures
|= kIOATAFeaturePowerManagement
;
161 //---------------------------------------------------------------------------
162 // Async read/write requests.
165 IOATAPIHDDrive::doAsyncReadWrite(IOMemoryDescriptor
* buffer
,
168 IOStorageCompletion completion
)
171 IOATACommand
* cmd
= atapiCommandReadWrite(buffer
, block
, nblks
);
174 return kIOReturnNoMemory
;
176 ret
= asyncExecute(cmd
, completion
);
183 //---------------------------------------------------------------------------
184 // Sync read/write requests.
187 IOATAPIHDDrive::doSyncReadWrite(IOMemoryDescriptor
* buffer
,
192 IOATACommand
* cmd
= atapiCommandReadWrite(buffer
, block
, nblks
);
195 return kIOReturnNoMemory
;
197 ret
= syncExecute(cmd
);
204 //---------------------------------------------------------------------------
205 // Eject the media in the removable drive.
208 IOATAPIHDDrive::doEjectMedia()
211 IOATACommand
* cmd
= atapiCommandStartStopUnit(false, /* start unit */
212 true, /* Load/Eject */
213 false); /* Immediate */
216 return kIOReturnNoMemory
;
218 ret
= syncExecute(cmd
);
225 //---------------------------------------------------------------------------
226 // Format the media in the drive.
229 IOATAPIHDDrive::doFormatMedia(UInt64 byteCapacity
,
230 IOMemoryDescriptor
* formatData
= 0)
233 IOATACommand
* cmd
= atapiCommandFormatUnit(0, 0, 0, formatData
);
236 return kIOReturnNoMemory
;
238 ret
= syncExecute(cmd
, 15 * 60 * 1000); // 15 min timeout
245 //---------------------------------------------------------------------------
246 // Lock/unlock the media in the removable drive.
249 IOATAPIHDDrive::doLockUnlockMedia(bool doLock
)
252 IOATACommand
* cmd
= atapiCommandPreventAllowRemoval(doLock
);
255 return kIOReturnNoMemory
;
257 ret
= syncExecute(cmd
);
261 // Cache the state on the media lock, and restore it when
262 // the driver wakes up from sleep.
269 //---------------------------------------------------------------------------
270 // Sync the write cache.
273 IOATAPIHDDrive::doSynchronizeCache()
276 IOATACommand
* cmd
= atapiCommandSynchronizeCache();
279 return kIOReturnNoMemory
;
281 ret
= syncExecute(cmd
);
288 //---------------------------------------------------------------------------
289 // Start up the drive.
292 IOATAPIHDDrive::doStart()
294 return doStartStop(true);
297 //---------------------------------------------------------------------------
301 IOATAPIHDDrive::doStop()
303 return doStartStop(false);
306 //---------------------------------------------------------------------------
307 // Issue a START/STOP Unit command.
310 IOATAPIHDDrive::doStartStop(bool doStart
)
315 cmd
= atapiCommandStartStopUnit(doStart
, /* start unit */
316 false, /* Load/Eject */
317 false); /* Immediate operation */
319 if (!cmd
) return kIOReturnNoMemory
;
321 ret
= syncExecute(cmd
);
328 //---------------------------------------------------------------------------
329 // Return device identification strings
331 char * IOATAPIHDDrive::getVendorString()
336 char * IOATAPIHDDrive::getProductString()
341 char * IOATAPIHDDrive::getRevisionString()
346 char * IOATAPIHDDrive::getAdditionalDeviceInfoString()
351 //---------------------------------------------------------------------------
352 // Report whether the media in the drive is ejectable.
355 IOATAPIHDDrive::reportEjectability(bool * isEjectable
)
357 *isEjectable
= true; /* default: if it's removable, it's ejectable */
358 return kIOReturnSuccess
;
361 //---------------------------------------------------------------------------
362 // Report whether the drive can prevent user-initiated ejects by locking
363 // the media in the drive.
366 IOATAPIHDDrive::reportLockability(bool * isLockable
)
368 *isLockable
= true; /* default: if it's removable, it's lockable */
369 return kIOReturnSuccess
;
372 //---------------------------------------------------------------------------
373 // Report our polling requirments.
376 IOATAPIHDDrive::reportPollRequirements(bool * pollRequired
,
377 bool * pollIsExpensive
)
379 *pollIsExpensive
= false;
380 *pollRequired
= _isRemovable
;
381 return kIOReturnSuccess
;
384 //---------------------------------------------------------------------------
385 // Report the current state of the media.
388 IOATAPIHDDrive::reportMediaState(bool * mediaPresent
,
391 IOATACommand
* cmd
= 0;
392 IOMemoryDescriptor
* senseData
= 0;
397 assert(mediaPresent
&& changed
);
400 ret
= kIOReturnNoMemory
;
402 bzero((void *) senseBuf
, sizeof(senseBuf
));
403 senseData
= IOMemoryDescriptor::withAddress(senseBuf
,
409 cmd
= atapiCommandTestUnitReady();
413 // Execute the Test Unit Ready command with no retries.
415 syncExecute(cmd
, kATADefaultTimeout
, kATAZeroRetry
, senseData
);
417 ret
= kIOReturnSuccess
;
419 if (cmd
->getResults(&results
) == kIOReturnSuccess
)
421 *mediaPresent
= true;
422 *changed
= (*mediaPresent
!= _mediaPresent
);
423 _mediaPresent
= true;
427 UInt8 errorCode
= senseBuf
[0];
428 UInt8 senseKey
= senseBuf
[2];
431 UInt8 senseCode
= senseBuf
[12];
432 UInt8 senseQualifier
= senseBuf
[13];
434 IOLog("-- IOATAPIHDDrive::reportMediaState --\n");
435 IOLog("Error code: %02x\n", errorCode
);
436 IOLog("Sense Key : %02x\n", senseKey
);
437 IOLog("ASC : %02x\n", senseCode
);
438 IOLog("ASCQ : %02x\n", senseQualifier
);
441 *mediaPresent
= false;
442 *changed
= (*mediaPresent
!= _mediaPresent
);
443 _mediaPresent
= false;
445 // The error code field for ATAPI request sense should always
446 // be 0x70 or 0x71. Otherwise ignore the sense data.
448 if ((errorCode
== 0x70) || (errorCode
== 0x71))
451 case 5: /* Invalid ATAPI command */
452 ret
= kIOReturnIOError
;
455 case 2: /* Not ready */
470 senseData
->release();
473 IOLog("%s: media present %s, changed %s\n", getName(),
474 *mediaPresent
? "Y" : "N",
482 //---------------------------------------------------------------------------
483 // Report media removability.
486 IOATAPIHDDrive::reportRemovability(bool * isRemovable
)
490 *isRemovable
= false;
492 if (_ataDevice
->getInquiryData(sizeof(inqBuf
), (ATAPIInquiry
*) inqBuf
))
494 if (inqBuf
[1] & 0x80)
495 *isRemovable
= _isRemovable
= true;
497 *isRemovable
= _isRemovable
= false;
500 return kIOReturnSuccess
;
503 //---------------------------------------------------------------------------
504 // Report whether media is write-protected.
507 IOATAPIHDDrive::reportWriteProtection(bool * isWriteProtected
)
509 *isWriteProtected
= false; // defaults to read-write
510 return kIOReturnSuccess
;
513 //---------------------------------------------------------------------------
514 // Instantiate an ATAPI specific subclass of IOBlockStorageDevice.
517 IOATAPIHDDrive::instantiateNub()
519 IOService
* nub
= new IOATAPIHDDriveNub
;
523 //---------------------------------------------------------------------------
524 // Override the handleActiveStateTransition() method in IOATAHDDrive and
525 // perform ATAPI specific handling.
528 IOATAPIHDDrive::handleActiveStateTransition( UInt32 stage
, IOReturn status
)
530 // Restore the lock on the media after the ATAPI device wakes up from
531 // sleep. Assume that the drive will always power up in the unlocked state.
532 // Technically, some drives may have a jumper to set the default state
535 if ( ( stage
== kIOATAActiveStage0
) && _isLocked
)
537 IOStorageCompletion completion
;
539 IOATACommand
* cmd
= atapiCommandPreventAllowRemoval( true );
541 completion
.target
= this;
542 completion
.action
= sHandleActiveStateTransition
;
543 completion
.parameter
= (void *) kIOATAActiveStage1
;
547 cmd
->setQueueInfo( kATAQTypeBypassQ
);
548 ret
= asyncExecute( cmd
, completion
);
554 super::handleActiveStateTransition( stage
, status
);