]> git.saurik.com Git - apple/xnu.git/blob - iokit/Families/IOATAHDDrive/IOATAHDCommand.cpp
8cfd30563b1a8f92f8172feb0aa0bb8fae12bef9
[apple/xnu.git] / iokit / Families / IOATAHDDrive / IOATAHDCommand.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 * IOATAHDCommand.cpp - Performs ATA command processing.
26 *
27 * HISTORY
28 * Aug 27, 1999 jliu - Ported from AppleATADrive.
29 */
30
31 #include <IOKit/assert.h>
32 #include <IOKit/IOSyncer.h>
33 #include <IOKit/storage/ata/IOATAHDDrive.h>
34
35 // Enable this define to generate debugging messages.
36 // #define DEBUG_LOG 1
37
38 //---------------------------------------------------------------------------
39 // Select the device timing protocol.
40
41 bool
42 IOATAHDDrive::selectTimingProtocol()
43 {
44 bool ret;
45 UInt8 ataReadCmd;
46 UInt8 ataWriteCmd;
47 ATATimingProtocol timing;
48 char * protocolName;
49
50 ret = _ataDevice->getTimingsSupported(&timing);
51 if (ret == false)
52 {
53 IOLog("%s: getTimingsSupported() error\n", getName());
54 timing = kATATimingPIO;
55 }
56
57 // IOLog("%s: device supported timings: %08x\n", getName(), timing);
58
59 if (timing & (kATATimingUltraDMA66 | kATATimingUltraDMA33 | kATATimingDMA))
60 {
61 if (timing & kATATimingUltraDMA66)
62 {
63 protocolName = "U-DMA/66";
64 timing = kATATimingUltraDMA66;
65 }
66 else if (timing & kATATimingUltraDMA33)
67 {
68 protocolName = "U-DMA/33";
69 timing = kATATimingUltraDMA33;
70 }
71 else
72 {
73 protocolName = "DMA";
74 timing = kATATimingDMA;
75 }
76
77 selectCommandProtocol(true);
78
79 switch ( _ataProtocol )
80 {
81 case kATAProtocolDMAQueued:
82 ataReadCmd = kIOATACommandReadDMAQueued;
83 ataWriteCmd = kIOATACommandWriteDMAQueued;
84 break;
85
86 case kATAProtocolDMA:
87 default:
88 ataReadCmd = kIOATACommandReadDMA;
89 ataWriteCmd = kIOATACommandWriteDMA;
90 }
91 }
92 else
93 {
94 protocolName = "PIO";
95 timing = kATATimingPIO;
96 ataReadCmd = kIOATACommandReadPIO;
97 ataWriteCmd = kIOATACommandWritePIO;
98 selectCommandProtocol(false);
99 }
100
101 _timingProtocol = timing;
102 _ataReadCmd = ataReadCmd;
103 _ataWriteCmd = ataWriteCmd;
104 ret = true;
105
106 // Select device timing.
107 //
108 ret = _ataDevice->selectTiming( _timingProtocol, false );
109
110 if (ret == false)
111 {
112 IOLog("%s: %s selectTiming() failed\n", getName(), protocolName);
113
114 if (_timingProtocol != kATATimingPIO)
115 {
116 // Non PIO mode selection failed, defaulting to PIO mode and
117 // try one more time.
118
119 protocolName = "PIO";
120 _timingProtocol = kATATimingPIO;
121 _ataReadCmd = kIOATACommandReadPIO;
122 _ataWriteCmd = kIOATACommandWritePIO;
123 selectCommandProtocol(false);
124
125 ret = _ataDevice->selectTiming( _timingProtocol, false );
126 if (ret == false)
127 IOLog("%s: %s selectTiming() retry failed\n",
128 getName(), protocolName);
129 }
130 }
131
132 if (ret && _logSelectedTimingProtocol)
133 IOLog("%s: Using %s transfers\n", getName(), protocolName);
134
135 return ret;
136 }
137
138 //---------------------------------------------------------------------------
139 // Select the command protocol to use (e.g. ataProtocolPIO, ataProtocolDMA).
140
141 bool
142 IOATAHDDrive::selectCommandProtocol(bool isDMA)
143 {
144 ATAProtocol protocolsSupported;
145
146 if ( _ataDevice->getProtocolsSupported( &protocolsSupported ) == false )
147 {
148 IOLog("%s: getProtocolsSupported() failed\n", getName());
149 return false;
150 }
151
152 if ( (protocolsSupported & kATAProtocolDMAQueued) != 0 )
153 {
154 #if 0
155 _ataProtocol = kATAProtocolDMAQueued;
156 #else
157 _ataProtocol = kATAProtocolDMA;
158 #endif
159 }
160 else if ( (protocolsSupported & kATAProtocolDMA) != 0 )
161 {
162 _ataProtocol = kATAProtocolDMA;
163 }
164 else
165 {
166 _ataProtocol = kATAProtocolPIO;
167 }
168
169 return true;
170 }
171
172 //---------------------------------------------------------------------------
173 // Configure the ATA/ATAPI device when the driver is initialized, and
174 // after every device reset.
175
176 bool
177 IOATAHDDrive::configureDevice(IOATADevice * device)
178 {
179 bool ret;
180
181 // Select device timing.
182 //
183 ret = device->selectTiming( _timingProtocol, true );
184 if (ret == false) {
185 IOLog("%s: selectTiming() failed\n", getName());
186 return false;
187 }
188
189 return true;
190 }
191
192 //---------------------------------------------------------------------------
193 // Setup an ATATaskFile from the parameters given, and write the taskfile
194 // to the ATATaskfile structure pointer provided.
195 //
196 // taskfile - pointer to a taskfile structure.
197 // protocol - An ATA transfer protocol (ataProtocolPIO, ataProtocolDMA, etc)
198 // command - ATA command byte.
199 // block - Initial transfer block.
200 // nblks - Number of blocks to transfer.
201
202 void
203 IOATAHDDrive::setupReadWriteTaskFile(ATATaskfile * taskfile,
204 ATAProtocol protocol,
205 UInt8 command,
206 UInt32 block,
207 UInt32 nblks)
208 {
209 bzero( taskfile, sizeof(ATATaskfile) );
210
211 taskfile->protocol = protocol;
212
213 // Mask of all taskfile registers that shall contain valid
214 // data and should be written to the hardware registers.
215 //
216 taskfile->regmask = ATARegtoMask(kATARegSectorNumber) |
217 ATARegtoMask(kATARegCylinderLow) |
218 ATARegtoMask(kATARegCylinderHigh) |
219 ATARegtoMask(kATARegDriveHead) |
220 ATARegtoMask(kATARegSectorCount) |
221 ATARegtoMask(kATARegFeatures) |
222 ATARegtoMask(kATARegCommand);
223
224 taskfile->resultmask = 0;
225
226 taskfile->ataRegs[kATARegSectorNumber] = block & 0x0ff;
227 taskfile->ataRegs[kATARegCylinderLow] = (block >> 8) & 0xff;
228 taskfile->ataRegs[kATARegCylinderHigh] = (block >> 16) & 0xff;
229 taskfile->ataRegs[kATARegDriveHead] = ((block >> 24) & 0x0f) |
230 kATAModeLBA | (_unit << 4);
231
232 if ( protocol == kATAProtocolDMAQueued )
233 {
234 taskfile->ataRegs[kATARegFeatures] =
235 (nblks == kIOATAMaxBlocksPerXfer) ? 0 : nblks;
236 taskfile->ataRegs[kATARegSectorCount] = 0;
237 }
238 else
239 {
240 taskfile->ataRegs[kATARegFeatures] = 0;
241 taskfile->ataRegs[kATARegSectorCount] =
242 (nblks == kIOATAMaxBlocksPerXfer) ? 0 : nblks;
243 }
244
245 taskfile->ataRegs[kATARegCommand] = command;
246 }
247
248 //---------------------------------------------------------------------------
249 // Allocate and return an IOATACommand that is initialized to perform
250 // a read/write operation.
251 //
252 // buffer - IOMemoryDescriptor object describing this transfer.
253 // block - Initial transfer block.
254 // nblks - Number of blocks to transfer.
255
256 IOATACommand *
257 IOATAHDDrive::ataCommandReadWrite(IOMemoryDescriptor * buffer,
258 UInt32 block,
259 UInt32 nblks)
260 {
261 ATATaskfile taskfile;
262 bool isWrite;
263 IOATACommand * cmd = allocateCommand();
264
265 assert(buffer);
266
267 if (!cmd) return 0; // error, command allocation failed.
268
269 isWrite = (buffer->getDirection() == kIODirectionOut) ?
270 true : false;
271
272 #ifdef DEBUG_LOG
273 IOLog("%s::ataCommandReadWrite %08x (%d) %s %d %d\n",
274 getName(),
275 buffer,
276 buffer->getLength(),
277 isWrite ? "WR" : "RD",
278 block,
279 nblks);
280 #endif
281
282 #if 0 // used for testing - force PIO mode
283 setupReadWriteTaskFile(&taskfile,
284 kATAProtocolPIO,
285 isWrite ? kIOATACommandWritePIO :
286 kIOATACommandReadPIO,
287 block,
288 nblks);
289 #else
290
291 // Setup the taskfile structure with the size and direction of the
292 // transfer. This structure will be written to the actual taskfile
293 // registers when this command is processed.
294 //
295 setupReadWriteTaskFile(&taskfile,
296 _ataProtocol,
297 isWrite ? _ataWriteCmd : _ataReadCmd,
298 block,
299 nblks);
300 #endif
301
302 // Get a pointer to the client data buffer, and record parameters
303 // which shall be later used by the completion routine.
304 //
305 ATA_CLIENT_DATA(cmd)->buffer = buffer;
306
307 cmd->setTaskfile(&taskfile);
308
309 cmd->setPointers(buffer, /* (IOMemoryDescriptor *) */
310 buffer->getLength(), /* transferCount (bytes) */
311 isWrite); /* isWrite */
312
313 return cmd;
314 }
315
316 //---------------------------------------------------------------------------
317 // Allocate and return a ATA SetFeatures command.
318
319 IOATACommand *
320 IOATAHDDrive::ataCommandSetFeatures(UInt8 features,
321 UInt8 SectorCount,
322 UInt8 SectorNumber,
323 UInt8 CylinderLow,
324 UInt8 CyclinderHigh)
325 {
326 ATATaskfile taskfile;
327 IOATACommand * cmd = allocateCommand();
328
329 if (!cmd) return 0; // error, command allocation failed.
330
331 taskfile.protocol = kATAProtocolPIO;
332
333 taskfile.regmask = ATARegtoMask(kATARegSectorNumber) |
334 ATARegtoMask(kATARegCylinderLow) |
335 ATARegtoMask(kATARegCylinderHigh) |
336 ATARegtoMask(kATARegDriveHead) |
337 ATARegtoMask(kATARegSectorCount) |
338 ATARegtoMask(kATARegCommand);
339
340 taskfile.resultmask = ATARegtoMask(kATARegError) |
341 ATARegtoMask(kATARegStatus);
342
343 taskfile.ataRegs[kATARegFeatures] = features;
344 taskfile.ataRegs[kATARegSectorNumber] = SectorNumber;
345 taskfile.ataRegs[kATARegCylinderLow] = CylinderLow;
346 taskfile.ataRegs[kATARegCylinderHigh] = CyclinderHigh;
347 taskfile.ataRegs[kATARegDriveHead] = kATAModeLBA | (_unit << 4);
348 taskfile.ataRegs[kATARegSectorCount] = SectorCount;
349 taskfile.ataRegs[kATARegCommand] = kIOATACommandSetFeatures;
350
351 cmd->setTaskfile(&taskfile);
352
353 // This is a way to issue a command which will wait
354 // for an interrupt, but does no data transfer.
355
356 cmd->setPointers(0, 0, false);
357
358 return cmd;
359 }
360
361 //---------------------------------------------------------------------------
362 // Return a Flush Cache command.
363
364 IOATACommand *
365 IOATAHDDrive::ataCommandFlushCache()
366 {
367 ATATaskfile taskfile;
368 IOATACommand * cmd = allocateCommand();
369
370 if (!cmd) return 0; // error, command allocation failed.
371
372 // kATAProtocolSetRegs does not wait for an interrupt from the drive.
373
374 taskfile.protocol = kATAProtocolPIO;
375
376 taskfile.regmask = ATARegtoMask(kATARegDriveHead) |
377 ATARegtoMask(kATARegCommand);
378
379 taskfile.resultmask = ATARegtoMask(kATARegError) |
380 ATARegtoMask(kATARegSectorNumber) |
381 ATARegtoMask(kATARegCylinderLow) |
382 ATARegtoMask(kATARegCylinderHigh) |
383 ATARegtoMask(kATARegDriveHead) |
384 ATARegtoMask(kATARegStatus);
385
386 taskfile.ataRegs[kATARegDriveHead] = kATAModeLBA | (_unit << 4);
387 taskfile.ataRegs[kATARegCommand] = kIOATACommandFlushCache;
388
389 cmd->setTaskfile(&taskfile);
390
391 // This is a way to issue a command which will wait
392 // for an interrupt, but does no data transfer.
393
394 cmd->setPointers(0, 0, false);
395
396 return cmd;
397 }
398
399 //---------------------------------------------------------------------------
400 // Return a STANDBY IMMEDIATE command.
401
402 IOATACommand *
403 IOATAHDDrive::ataCommandStandby()
404 {
405 ATATaskfile taskfile;
406 IOATACommand * cmd = allocateCommand();
407
408 if (!cmd) return 0; // error, command allocation failed.
409
410 // kATAProtocolSetRegs does not wait for an interrupt from the drive.
411
412 taskfile.protocol = kATAProtocolPIO;
413
414 taskfile.regmask = ATARegtoMask(kATARegDriveHead) |
415 ATARegtoMask(kATARegCommand);
416
417 taskfile.resultmask = ATARegtoMask(kATARegError) |
418 ATARegtoMask(kATARegStatus);
419
420 taskfile.ataRegs[kATARegDriveHead] = kATAModeLBA | (_unit << 4);
421 taskfile.ataRegs[kATARegCommand] = kIOATACommandStandbyImmediate;
422
423 cmd->setTaskfile(&taskfile);
424
425 // This is a way to issue a command which will wait
426 // for an interrupt, but does no data transfer.
427
428 cmd->setPointers(0, 0, false);
429
430 return cmd;
431 }
432
433 //---------------------------------------------------------------------------
434 // This routine is called by our provider when a command processing has
435 // completed.
436
437 void
438 IOATAHDDrive::sHandleCommandCompletion(IOATAHDDrive * self,
439 IOATACommand * cmd)
440 {
441 ATAResults results;
442 IOATADevice * device;
443 IOATAClientData * clientData;
444
445 assert(cmd);
446 device = cmd->getDevice(kIOATADevice);
447 assert(device);
448
449 clientData = ATA_CLIENT_DATA(cmd);
450 assert(clientData);
451
452 if ((cmd->getResults(&results) != kIOReturnSuccess) &&
453 (clientData->maxRetries-- > 0))
454 {
455 cmd->execute();
456 return;
457 }
458
459 #if 0
460 // Force command retry to test retry logic.
461 // Controller will reset the IOMemoryDescriptor's position, right?
462 //
463 cmd->getResults(&results);
464 if (clientData->maxRetries-- > 2) {
465 cmd->execute();
466 return;
467 }
468 #endif
469
470 #ifdef DEBUG_LOG
471 IOLog("%s: sHandleCommandCompletion %08x %08x %08x %08x %d\n",
472 getName(), device, cmd, refcon, results.returnCode,
473 results.bytesTransferred);
474 #endif
475
476 // Return IOReturn for sync commands.
477 //
478 clientData->returnCode = results.returnCode;
479
480 if (clientData->isSync) {
481 // For sync commands, unblock the client thread.
482 //
483 assert(clientData->completion.syncLock);
484 clientData->completion.syncLock->signal(); // unblock the client.
485 }
486 else {
487 // Signal the completion routine that the request has been completed.
488 //
489
490 IOStorage::complete(clientData->completion.async,
491 results.returnCode,
492 (UInt64) results.bytesTransferred);
493 }
494
495 // Release the IOMemoryDescriptor.
496 //
497 if (clientData->buffer)
498 clientData->buffer->release();
499
500 // Command processing is complete, release the command object.
501 //
502 cmd->release();
503 }
504
505 //---------------------------------------------------------------------------
506 // Issue a synchronous ATA command.
507
508 IOReturn
509 IOATAHDDrive::syncExecute(IOATACommand * cmd, /* command object */
510 UInt32 timeout, /* timeout in ms */
511 UInt retries, /* max retries */
512 IOMemoryDescriptor * senseData)
513 {
514 IOATAClientData * clientData = ATA_CLIENT_DATA(cmd);
515
516 if ( _pmReady )
517 {
518 activityTickle( kIOPMSuperclassPolicy1, 1 );
519 }
520
521 // Bump the retain count on the command. The completion handler
522 // will decrement the retain count.
523 //
524 cmd->retain();
525
526 // Set timeout and register the completion handler.
527 //
528 cmd->setPointers(senseData,
529 senseData ? senseData->getLength() : 0,
530 false, /* isWrite */
531 true ); /* isSense */
532 cmd->setTimeout(timeout);
533 cmd->setCallback(this,
534 (CallbackFn) &IOATAHDDrive::sHandleCommandCompletion,
535 (void *) cmd);
536
537 // Increment the retain count on the IOMemoryDescriptor.
538 // Release when the completion routine gets called.
539 //
540 if (clientData->buffer)
541 clientData->buffer->retain();
542
543 // Set the max retry count. If retry count is 0, then the command shall
544 // not be retried if an error occurs.
545 //
546 clientData->maxRetries = retries;
547 clientData->completion.syncLock = IOSyncer::create();
548 clientData->isSync = true;
549
550 cmd->execute();
551
552 // Block client thread on lock until the completion handler
553 // receives an indication that the processing is complete.
554 //
555 clientData->completion.syncLock->wait();
556
557 return clientData->returnCode;
558 }
559
560 //---------------------------------------------------------------------------
561 // Issue an asynchronous ATA command.
562
563 IOReturn
564 IOATAHDDrive::asyncExecute(IOATACommand * cmd, /* command object */
565 IOStorageCompletion completion,
566 UInt32 timeout, /* timeout in ms */
567 UInt retries) /* max retries */
568 {
569 IOATAClientData * clientData = ATA_CLIENT_DATA(cmd);
570
571 if ( _pmReady )
572 {
573 activityTickle( kIOPMSuperclassPolicy1, 1 );
574 }
575
576 // Bump the retain count on the command. The completion handler
577 // will decrement the retain count.
578 //
579 cmd->retain();
580
581 // Set timeout and register the completion handler.
582 //
583 cmd->setTimeout(timeout);
584 cmd->setCallback(this,
585 (CallbackFn) &IOATAHDDrive::sHandleCommandCompletion,
586 (void *) cmd);
587
588 // Increment the retain count on the IOMemoryDescriptor.
589 // Release when the completion routine gets called.
590 //
591 if (clientData->buffer)
592 clientData->buffer->retain();
593
594 // Set the max retry count. If retry count is 0, then the command shall
595 // not be retried if an error occurs.
596 //
597 clientData->maxRetries = retries;
598 clientData->isSync = false;
599
600 clientData->completion.async = completion;
601
602 return (cmd->execute() ? kIOReturnSuccess : kIOReturnNoResources);
603 }
604
605 //---------------------------------------------------------------------------
606 // Allocate an IOATACommand object with a fixed client data area.
607
608 IOATACommand *
609 IOATAHDDrive::allocateCommand()
610 {
611 return _ataDevice->allocCommand(kIOATADevice, sizeof(IOATAClientData));
612 }