]> git.saurik.com Git - apple/xnu.git/blob - iokit/Families/IOATAHDDrive/IOATAHDDrive.cpp
xnu-123.5.tar.gz
[apple/xnu.git] / iokit / Families / IOATAHDDrive / IOATAHDDrive.cpp
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 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
24 *
25 * IOATAHDDrive.cpp - Generic ATA disk driver.
26 *
27 * HISTORY
28 * Aug 27, 1999 jliu - Ported from AppleATADrive.
29 */
30
31 #include <IOKit/assert.h>
32 #include <IOKit/storage/ata/IOATAHDDrive.h>
33 #include <IOKit/storage/ata/IOATAHDDriveNub.h>
34
35 #define super IOService
36 OSDefineMetaClassAndStructors( IOATAHDDrive, IOService )
37
38 //---------------------------------------------------------------------------
39 // C to C++ glue.
40
41 void
42 IOATAHDDrive::sHandleConfigureDevice(IOATAHDDrive * self)
43 {
44 self->configureDevice(self->_ataDevice);
45 }
46
47 //---------------------------------------------------------------------------
48 // init() method.
49
50 bool
51 IOATAHDDrive::init(OSDictionary * properties)
52 {
53 return (super::init(properties));
54 }
55
56 //---------------------------------------------------------------------------
57 // Override probe() method inherited from IOService.
58
59 IOService *
60 IOATAHDDrive::probe(IOService * provider, SInt32 * score)
61 {
62 if (!super::probe(provider, score))
63 return 0;
64
65 // Our provider must be a IOATADevice nub, most likely created
66 // by an IOATAController instance.
67 //
68 IOATADevice * device = OSDynamicCast(IOATADevice, provider);
69 if (device == 0)
70 return 0; // Provider is not an IOATADevice.
71
72 // Do ATA device type matching. Does the nub match my device type?
73 //
74 if (device->getDeviceType() != reportATADeviceType())
75 return 0; // error, type mismatch (probably ATAPI).
76
77 // Cache the drive unit number (master/slave assignment).
78 //
79 _unit = device->getUnit();
80
81 return this; // probe successful.
82 }
83
84 //---------------------------------------------------------------------------
85 // Starts up the driver and spawn a nub.
86
87 bool
88 IOATAHDDrive::start(IOService * provider)
89 {
90 // First call start() in our superclass.
91 //
92 if (super::start(provider) == false)
93 return false;
94
95 _configThreadCall = (void *) thread_call_allocate(
96 (thread_call_func_t) sHandleConfigureDevice,
97 (thread_call_param_t) this);
98 if (!_configThreadCall)
99 return false;
100
101 // Cache our provider.
102 //
103 _ataDevice = OSDynamicCast(IOATADevice, provider);
104 if (_ataDevice == 0)
105 return false;
106
107 // Open our provider.
108 //
109 _ataDevice->retain();
110 if (_ataDevice->open(this) == false)
111 return false;
112
113 // Inspect the provider.
114 //
115 if (inspectDevice(_ataDevice) == false)
116 return false;
117
118 // Select ATA timing.
119 //
120 _logSelectedTimingProtocol = true;
121
122 if (selectTimingProtocol() == false)
123 return false;
124
125 // Create an IOCommandGate (for power management support) and attach
126 // this event source to the provider's workloop.
127 //
128 _cmdGate = IOCommandGate::commandGate(this);
129 if (_cmdGate == 0)
130 return false;
131
132 IOWorkLoop * workloop = _ataDevice->getWorkLoop();
133 if ((workloop == 0) ||
134 (workloop->addEventSource(_cmdGate) != kIOReturnSuccess))
135 return false;
136
137 // Starts up in the active state.
138 //
139 _currentATAPowerState = kIOATAPowerStateActive;
140
141 // A policy-maker must make these calls to join the PM tree,
142 // and to initialize its state.
143 //
144 PMinit(); /* initialize power management variables */
145 provider->joinPMtree(this); /* join power management tree */
146 setIdleTimerPeriod(300); /* 300 sec inactivity timer */
147
148 if (_supportedFeatures & kIOATAFeaturePowerManagement)
149 initForPM();
150
151 return (createNub(provider));
152 }
153
154 //---------------------------------------------------------------------------
155 // Stop the driver.
156
157 void
158 IOATAHDDrive::stop(IOService * provider)
159 {
160 PMstop();
161
162 super::stop(provider);
163 }
164
165 //---------------------------------------------------------------------------
166 // Release allocated resources.
167
168 void
169 IOATAHDDrive::free()
170 {
171 if (_configThreadCall) {
172 thread_call_cancel((thread_call_t) _configThreadCall);
173 thread_call_free((thread_call_t) _configThreadCall);
174 }
175
176 if (_cmdGate) {
177 if (_ataDevice && (_ataDevice->getWorkLoop()))
178 _ataDevice->getWorkLoop()->removeEventSource(_cmdGate);
179 _cmdGate->release();
180 }
181
182 if (_ataDevice)
183 _ataDevice->release();
184
185 super::free();
186 }
187
188 //---------------------------------------------------------------------------
189 // Fetch information about the ATA device nub.
190
191 bool
192 IOATAHDDrive::inspectDevice(IOATADevice * ataDevice)
193 {
194 OSString * string;
195 ATAIdentify * identify;
196
197 // Fetch ATA device information from the nub.
198 //
199 string = OSDynamicCast(OSString,
200 ataDevice->getProperty(kATAPropertyModelNumber));
201 if (string) {
202 strncpy(_model, string->getCStringNoCopy(), 40);
203 _model[40] = '\0';
204 }
205
206 string = OSDynamicCast(OSString,
207 ataDevice->getProperty(kATAPropertyFirmwareRev));
208 if (string) {
209 strncpy(_revision, string->getCStringNoCopy(), 8);
210 _revision[8] = '\0';
211 }
212
213 // Fetch Word 82 (commandSetsSupported1) in Identify data.
214 //
215 identify = (ATAIdentify *) IOMalloc(sizeof(*identify));
216 if (!identify)
217 return false;
218
219 ataDevice->getIdentifyData(identify);
220
221 if (identify->commandSetsSupported1 & 0x8)
222 _supportedFeatures |= kIOATAFeaturePowerManagement;
223
224 if (identify->commandSetsSupported1 & 0x20)
225 _supportedFeatures |= kIOATAFeatureWriteCache;
226
227 IOFree(identify, sizeof(*identify));
228
229 // Add an OSNumber property indicating the supported features.
230 //
231 setProperty(kIOATASupportedFeaturesKey,
232 _supportedFeatures,
233 sizeof(_supportedFeatures) * 8);
234
235 return true;
236 }
237
238 //---------------------------------------------------------------------------
239 // Report the type of ATA device (ATA vs. ATAPI).
240
241 ATADeviceType
242 IOATAHDDrive::reportATADeviceType() const
243 {
244 return kATADeviceATA;
245 }
246
247 //---------------------------------------------------------------------------
248 // Returns the device type.
249
250 const char *
251 IOATAHDDrive::getDeviceTypeName()
252 {
253 return kIOBlockStorageDeviceTypeGeneric;
254 }
255
256 //---------------------------------------------------------------------------
257 // Instantiate an ATA specific subclass of IOBlockStorageDevice.
258
259 IOService * IOATAHDDrive::instantiateNub()
260 {
261 IOService * nub = new IOATAHDDriveNub;
262 return nub;
263 }
264
265 //---------------------------------------------------------------------------
266 // Returns an IOATAHDDriveNub.
267
268 bool IOATAHDDrive::createNub(IOService * provider)
269 {
270 IOService * nub;
271
272 // Instantiate a generic hard disk nub so a generic driver
273 // can match above us.
274 //
275 nub = instantiateNub();
276
277 if (nub == 0) {
278 IOLog("%s: instantiateNub() failed\n", getName());
279 return false;
280 }
281
282 nub->init();
283
284 if (!nub->attach(this))
285 IOPanic("IOATAHDDrive::createNub() unable to attach nub");
286
287 nub->registerService();
288
289 return true;
290 }
291
292 //---------------------------------------------------------------------------
293 // Handles read/write requests.
294
295 IOReturn IOATAHDDrive::doAsyncReadWrite(IOMemoryDescriptor * buffer,
296 UInt32 block,
297 UInt32 nblks,
298 IOStorageCompletion completion)
299 {
300 IOReturn ret;
301 IOATACommand * cmd = ataCommandReadWrite(buffer, block, nblks);
302
303 if (cmd == 0)
304 return kIOReturnNoMemory;
305
306 ret = asyncExecute(cmd, completion);
307
308 cmd->release();
309
310 return ret;
311 }
312
313 IOReturn IOATAHDDrive::doSyncReadWrite(IOMemoryDescriptor * buffer,
314 UInt32 block,
315 UInt32 nblks)
316 {
317 IOReturn ret;
318 IOATACommand * cmd = ataCommandReadWrite(buffer, block, nblks);
319
320 if (cmd == 0)
321 return kIOReturnNoMemory;
322
323 ret = syncExecute(cmd);
324
325 cmd->release();
326
327 return ret;
328 }
329
330 //---------------------------------------------------------------------------
331 // Eject the media in the drive.
332
333 IOReturn IOATAHDDrive::doEjectMedia()
334 {
335 return kIOReturnUnsupported; // No support for removable ATA devices.
336 }
337
338 //---------------------------------------------------------------------------
339 // Format the media in the drive.
340 // ATA devices does not support low level formatting.
341
342 IOReturn IOATAHDDrive::doFormatMedia(UInt64 byteCapacity)
343 {
344 return kIOReturnUnsupported;
345 }
346
347 //---------------------------------------------------------------------------
348 // Returns disk capacity.
349
350 UInt32 IOATAHDDrive::doGetFormatCapacities(UInt64 * capacities,
351 UInt32 capacitiesMaxCount) const
352 {
353 UInt32 blockCount = 0;
354 UInt32 blockSize = 0;
355
356 assert(_ataDevice);
357
358 if (_ataDevice->getDeviceCapacity(&blockCount, &blockSize) &&
359 (capacities != NULL) && (capacitiesMaxCount > 0))
360 {
361 UInt64 count = blockCount;
362 UInt64 size = blockSize;
363
364 *capacities = size * (count + 1);
365
366 return 1;
367 }
368
369 return 0;
370 }
371
372 //---------------------------------------------------------------------------
373 // Lock the media and prevent a user-initiated eject.
374
375 IOReturn IOATAHDDrive::doLockUnlockMedia(bool doLock)
376 {
377 return kIOReturnUnsupported; // No removable ATA device support.
378 }
379
380 //---------------------------------------------------------------------------
381 // Flush the write-cache to the physical media.
382
383 IOReturn IOATAHDDrive::doSynchronizeCache()
384 {
385 IOReturn ret;
386 IOATACommand * cmd = ataCommandFlushCache();
387
388 if (cmd == 0)
389 return kIOReturnNoMemory;
390
391 ret = syncExecute(cmd, 60000);
392
393 cmd->release();
394
395 return ret;
396 }
397
398 //---------------------------------------------------------------------------
399 // Handle a Start Unit command.
400
401 IOReturn
402 IOATAHDDrive::doStart()
403 {
404 return kIOReturnSuccess;
405 }
406
407 //---------------------------------------------------------------------------
408 // Handle a Stop Unit command.
409
410 IOReturn
411 IOATAHDDrive::doStop()
412 {
413 return kIOReturnSuccess;
414 }
415
416 //---------------------------------------------------------------------------
417 // Return device identification strings.
418
419 char * IOATAHDDrive::getAdditionalDeviceInfoString()
420 {
421 return ("[ATA]");
422 }
423
424 char * IOATAHDDrive::getProductString()
425 {
426 return _model;
427 }
428
429 char * IOATAHDDrive::getRevisionString()
430 {
431 return _revision;
432 }
433
434 char * IOATAHDDrive::getVendorString()
435 {
436 return NULL;
437 }
438
439 //---------------------------------------------------------------------------
440 // Report the device block size in bytes. We ask the device nub for the
441 // block size. We expect this to be 512-bytes.
442
443 IOReturn IOATAHDDrive::reportBlockSize(UInt64 * blockSize)
444 {
445 UInt32 blkCount = 0;
446 UInt32 blkSize = 0;
447
448 assert(_ataDevice);
449
450 if (!_ataDevice->getDeviceCapacity(&blkCount, &blkSize))
451 return kIOReturnNoDevice;
452
453 *blockSize = blkSize;
454 return kIOReturnSuccess;
455 }
456
457 //---------------------------------------------------------------------------
458 // Report the media in the ATA device as non-ejectable.
459
460 IOReturn IOATAHDDrive::reportEjectability(bool * isEjectable)
461 {
462 *isEjectable = false;
463 return kIOReturnSuccess;
464 }
465
466 //---------------------------------------------------------------------------
467 // Fixed media, locking is invalid.
468
469 IOReturn IOATAHDDrive::reportLockability(bool * isLockable)
470 {
471 *isLockable = false;
472 return kIOReturnSuccess;
473 }
474
475 //---------------------------------------------------------------------------
476 // Report the polling requirements for a removable media.
477
478 IOReturn IOATAHDDrive::reportPollRequirements(bool * pollRequired,
479 bool * pollIsExpensive)
480 {
481 *pollIsExpensive = false;
482 *pollRequired = false;
483
484 return kIOReturnSuccess;
485 }
486
487 //---------------------------------------------------------------------------
488 // Report the max number of bytes transferred for an ATA read command.
489
490 IOReturn IOATAHDDrive::reportMaxReadTransfer(UInt64 blocksize, UInt64 * max)
491 {
492 *max = blocksize * kIOATAMaxBlocksPerXfer;
493 return kIOReturnSuccess;
494 }
495
496 //---------------------------------------------------------------------------
497 // Report the max number of bytes transferred for an ATA write command.
498
499 IOReturn IOATAHDDrive::reportMaxWriteTransfer(UInt64 blocksize, UInt64 * max)
500 {
501 // Same as read transfer limits.
502 //
503 return reportMaxReadTransfer(blocksize, max);
504 }
505
506 //---------------------------------------------------------------------------
507 // Returns the maximum addressable sector number.
508
509 IOReturn IOATAHDDrive::reportMaxValidBlock(UInt64 * maxBlock)
510 {
511 UInt32 blockCount = 0;
512 UInt32 blockSize = 0;
513
514 assert(_ataDevice && maxBlock);
515
516 if (!_ataDevice->getDeviceCapacity(&blockCount, &blockSize))
517 return kIOReturnNoDevice;
518
519 *maxBlock = blockCount;
520
521 return kIOReturnSuccess;
522 }
523
524 //---------------------------------------------------------------------------
525 // Report whether the media is currently present, and whether a media
526 // change has been registered since the last reporting.
527
528 IOReturn IOATAHDDrive::reportMediaState(bool * mediaPresent, bool * changed)
529 {
530 *mediaPresent = true;
531 *changed = true;
532
533 return kIOReturnSuccess;
534 }
535
536 //---------------------------------------------------------------------------
537 // Report whether the media is removable.
538
539 IOReturn IOATAHDDrive::reportRemovability(bool * isRemovable)
540 {
541 *isRemovable = false;
542 return kIOReturnSuccess;
543 }
544
545 //---------------------------------------------------------------------------
546 // Report if the media is write-protected.
547
548 IOReturn IOATAHDDrive::reportWriteProtection(bool * isWriteProtected)
549 {
550 *isWriteProtected = false;
551 return kIOReturnSuccess;
552 }
553
554 //---------------------------------------------------------------------------
555 // Handles messages from our provider.
556
557 IOReturn
558 IOATAHDDrive::message(UInt32 type, IOService * provider, void * argument)
559 {
560 IOReturn ret = kIOReturnSuccess;
561
562 // IOLog("IOATAHDDrive::message %p %lx\n", this, type);
563
564 switch (type)
565 {
566 case kATAClientMsgBusReset:
567 _ataDevice->holdQueue(kATAQTypeNormalQ);
568 break;
569
570 case kATAClientMsgBusReset | kATAClientMsgDone:
571 configureDevice( _ataDevice );
572 break;
573
574 case kATAClientMsgSelectTiming | kATAClientMsgDone:
575 _ataDevice->releaseQueue(kATAQTypeNormalQ);
576 break;
577
578 default:
579 ret = super::message(type, provider, argument);
580 break;
581 }
582
583 return ret;
584 }