]> git.saurik.com Git - apple/xnu.git/blame - iokit/Families/IOATAStandard/IOATAStandardDevice.cpp
xnu-201.42.3.tar.gz
[apple/xnu.git] / iokit / Families / IOATAStandard / IOATAStandardDevice.cpp
CommitLineData
1c79356b
A
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 * IOATAStandardDevice.cpp
24 *
25 */
26
27#include <IOKit/IOSyncer.h>
28#include <IOKit/ata/IOATAStandardInterface.h>
29#include <IOKit/ata/ata-standard/ATAStandardPrivate.h>
30
31#undef super
32#define super IOATADevice
33
34#ifndef MIN
35#define MIN(a,b) ((a <= b) ? a : b)
36#endif
37
38#define round(x,y) (((int)(x) + (y) - 1) & ~((y)-1))
39
40extern EndianTable AppleIdentifyEndianTable[];
41
42extern UInt32 AppleNumPIOModes;
43extern ATAModeTable ApplePIOModes[];
44extern UInt32 AppleNumDMAModes;
45extern ATAModeTable AppleDMAModes[];
46extern UInt32 AppleNumUltraModes;
47extern ATAModeTable AppleUltraModes[];
48
49OSDefineMetaClassAndAbstractStructors( IOATADevice, IOCDBDevice )
50OSDefineMetaClassAndStructors( IOATAStandardDevice, IOATADevice )
51
52/*
53 *
54 *
55 *
56 */
57bool IOATAStandardDevice::init( IOATAStandardController *forController, ATAUnit forUnit )
58{
59 ATATaskfile taskfile;
60 ATACDBInfo ataCDB;
61
62 controller = forController;
63 unit = forUnit;
64
65 target = &controller->targets[unit];
66
67 queue_init( &deviceList );
68 queue_init( &bypassList );
69 queue_init( &activeList );
70 queue_init( &abortList );
71 queue_init( &cancelList );
72
73 clientSem = IORWLockAlloc();
74 if ( clientSem == 0 )
75 {
76 return false;
77 }
78
79 if ( super::init() == false )
80 {
81 return false;
82 }
83
84 if ( controller->controllerInfo.devicePrivateDataSize != 0 )
85 {
86 devicePrivateData = IOMallocContiguous( controller->controllerInfo.devicePrivateDataSize, 16, 0 );
87 if ( devicePrivateData == 0 )
88 {
89 return false;
90 }
91 }
92
93 bzero( &ataCDB, sizeof(ataCDB) );
94
95 probeCmd = allocCommand(kIOATAStandardDevice, 0);
96 if ( probeCmd == 0 )
97 {
98 return false;
99 }
100
101 abortCmd = allocCommand(kIOATAStandardDevice, 0);
102 if ( abortCmd == 0 )
103 {
104 return false;
105 }
106 abortCmd->setTimeout( kATAAbortTimeoutmS );
107
108 cancelCmd = allocCommand(kIOATAStandardDevice, 0);
109 if ( cancelCmd == 0 )
110 {
111 return false;
112 }
113 cancelCmd->setTimeout( 0 );
114 cancelCmd->cmdType = kATACommandCancel;
115
116 reqSenseCmd = allocCommand(kIOATAStandardDevice, 0);
117 if ( reqSenseCmd == 0 )
118 {
119 return false;
120 }
121
122 bzero( &taskfile, sizeof(taskfile) );
123 taskfile.protocol = kATAProtocolATAPIPIO;
124 taskfile.tagType = kATATagTypeNone;
125
126 taskfile.resultmask = ATARegtoMask( kATARegStatus );
127
128 taskfile.regmask = ATARegtoMask( kATARegATAPIFeatures )
129 | ATARegtoMask( kATARegATAPIByteCountLow )
130 | ATARegtoMask( kATARegATAPIByteCountHigh )
131 | ATARegtoMask( kATARegATAPIDeviceSelect )
132 | ATARegtoMask( kATARegATAPICommand );
133
134 taskfile.ataRegs[kATARegATAPIFeatures] = 0;
135 taskfile.ataRegs[kATARegATAPIByteCountLow] = 0xfe;
136 taskfile.ataRegs[kATARegATAPIByteCountHigh] = 0xff;
137 taskfile.ataRegs[kATARegATAPIDeviceSelect] = kATAModeLBA | (getUnit() << 4);
138 taskfile.ataRegs[kATARegATAPICommand] = kATACommandATAPIPacket;
139
140 reqSenseCmd->setTaskfile( &taskfile );
141
142 ataCDB.cdbLength = 12;
143 ataCDB.cdb[0] = kATAPICmdRequestSense;
144
145 reqSenseCmd->setTimeout( kATAReqSenseTimeoutmS );
146 reqSenseCmd->cmdType = kATACommandReqSense;
147 reqSenseCmd->setCDB( &ataCDB );
148
149 deviceGate = IOCommandGate::commandGate( this, (IOCommandGate::Action) &IOATAStandardDevice::receiveCommand );
150 if ( deviceGate == 0 )
151 {
152 return false;
153 }
154
155 if ( controller->workLoop->addEventSource( deviceGate ) != kIOReturnSuccess )
156 {
157 return false;
158 }
159
160 commandLimitSave = commandLimit = 1;
161
162 idleNotifyActive = false;
163
164 normalQHeld = 0;
165 bypassQHeld = 0;
166
167 currentTiming = kATATimingPIO;
168
169 return true;
170}
171
172IOReturn IOATAStandardDevice::probeDevice()
173{
174 OSDictionary *propTable = 0;
175
176 if ( doIdentify( (void **)&identifyData ) != kIOReturnSuccess )
177 {
178 goto probeDevice_error;
179 }
180
181 if ( deviceType == kATADeviceATA )
182 {
183 doSpinUp();
184 }
185
186 else if ( deviceType == kATADeviceATAPI )
187 {
188 atapiPktInt = ((identifyData->generalConfiguration & kATAPIPktProtocolIntDRQ) != 0);
189
190 if ( doInquiry( (void **)&inquiryData ) != kIOReturnSuccess )
191 {
192 goto probeDevice_error;
193 }
194 }
195
196 if ( getATATimings() != true )
197 {
198 goto probeDevice_error;
199 }
200
201 if ( maxTags != 0 )
202 {
203 tagArraySize = round( maxTags, 32 ) / 8;
204 tagArray = (UInt32 *)IOMalloc( tagArraySize );
205 if ( tagArray == 0 )
206 {
207 goto probeDevice_error;
208 }
209 bzero( tagArray, tagArraySize );
210 }
211
212 propTable = createProperties();
213 if ( !propTable )
214 {
215 goto probeDevice_error;
216 }
217
218 setPropertyTable( propTable );
219
220 propTable->release();
221
222 close( this, 0 );
223
224 return true;
225
226probeDevice_error: ;
227 close( this, 0 );
228 return false;
229}
230
231/*
232 *
233 *
234 *
235 */
236ATADeviceType IOATAStandardDevice::probeDeviceType()
237{
238 ATATaskfile taskfile;
239 ATAResults results;
240
241 bzero( (void *)&taskfile, sizeof(taskfile) );
242
243 taskfile.protocol = kATAProtocolSetRegs;
244 taskfile.regmask = ATARegtoMask(kATARegDriveHead);
245
246 taskfile.resultmask = ATARegtoMask(kATARegSectorCount)
247 | ATARegtoMask(kATARegSectorNumber)
248 | ATARegtoMask(kATARegCylinderLow)
249 | ATARegtoMask(kATARegCylinderHigh)
250 | ATARegtoMask(kATARegStatus);
251
252 taskfile.flags = kATACmdFlagTimingChanged;
253
254 taskfile.ataRegs[kATARegDriveHead] = kATAModeLBA | (getUnit() << 4);
255
256 probeCmd->setQueueInfo();
257 probeCmd->setTaskfile( &taskfile );
258 probeCmd->execute();
259
260 if ( probeCmd->getResults( &results ) != kIOReturnSuccess )
261 {
262 return (deviceType = kATADeviceNone);
263 }
264
265 if ( results.ataRegs[kATARegSectorCount] == kATASignatureSectorCount
266 && results.ataRegs[kATARegSectorNumber] == kATASignatureSectorNumber
267 && results.ataRegs[kATARegCylinderLow] == kATASignatureCylinderLow
268 && results.ataRegs[kATARegCylinderHigh] == kATASignatureCylinderHigh )
269 {
270 if ( !(results.ataRegs[kATARegStatus] & kATAStatusBSY)
271 && (results.ataRegs[kATARegStatus] & kATAStatusDRDY) )
272 {
273 return (deviceType = kATADeviceATA);
274 }
275 }
276
277 if ( results.ataRegs[kATARegCylinderLow] == kATAPISignatureCylinderLow
278 && results.ataRegs[kATARegCylinderHigh] == kATAPISignatureCylinderHigh )
279 {
280 return (deviceType = kATADeviceATAPI);
281 }
282
283 return (deviceType = kATADeviceNone);
284}
285
286
287/*
288 *
289 *
290 *
291 */
292IOReturn IOATAStandardDevice::doSpinUp()
293{
294 void *buffer = NULL;
295 IOReturn rc;
296
297 rc = doSectorCommand( kATACommandReadSector, 0, 1, &buffer );
298
299 if ( rc != kIOReturnSuccess )
300 {
301 return rc;
302 }
303
304 IOFree( buffer, 512 );
305
306 return rc ;
307}
308
309/*
310 *
311 *
312 *
313 */
314IOReturn IOATAStandardDevice::doIdentify( void **dataPtr )
315{
316 ATACommand ataCmd;
317 IOReturn rc;
318
319 ataCmd = (deviceType == kATADeviceATA) ? kATACommandIdentify : kATACommandATAPIIdentify;
320
321 rc = doSectorCommand( ataCmd, 0, 1, dataPtr );
322
323 if ( rc != kIOReturnSuccess )
324 {
325 return rc;
326 }
327
328 endianConvertData( *dataPtr, AppleIdentifyEndianTable );
329
330 return rc;
331}
332
333
334
335/*
336 *
337 *
338 *
339 */
340IOReturn IOATAStandardDevice::doSectorCommand( ATACommand ataCmd, UInt32 ataLBA, UInt32 ataCount, void **dataPtr )
341{
342 ATATaskfile taskfile;
343 ATAResults result;
344 IOMemoryDescriptor *desc;
345 UInt32 size;
346 void *data;
347 UInt32 i;
348 IOReturn rc;
349
350 *dataPtr = NULL;
351
352 size = ataCount * 512;
353
354 if ( !(data = (void *)IOMalloc(size)) )
355 {
356 return kIOReturnNoMemory;
357 }
358
359 bzero( &taskfile, sizeof(taskfile) );
360
361 desc = IOMemoryDescriptor::withAddress( data, size, kIODirectionIn );
362 if ( desc == NULL )
363 {
364 rc = kIOReturnNoMemory;
365 goto doSectorCommand_error;
366 }
367
368
369 taskfile.protocol = kATAProtocolPIO;
370 taskfile.regmask = ATARegtoMask(kATARegDriveHead)
371 | ATARegtoMask(kATARegSectorCount)
372 | ATARegtoMask(kATARegSectorNumber)
373 | ATARegtoMask(kATARegCylinderLow)
374 | ATARegtoMask(kATARegCylinderHigh)
375 | ATARegtoMask(kATARegFeatures)
376 | ATARegtoMask(kATARegCommand);
377
378
379 taskfile.resultmask = ATARegtoMask(kATARegError)
380 | ATARegtoMask(kATARegStatus);
381
382 taskfile.ataRegs[kATARegSectorCount] = ataCount;
383 taskfile.ataRegs[kATARegSectorNumber] = ataLBA & 0xff;
384 taskfile.ataRegs[kATARegCylinderLow] = (ataLBA >> 8) & 0xff;
385 taskfile.ataRegs[kATARegCylinderHigh] = (ataLBA >> 16) & 0xff;
386 taskfile.ataRegs[kATARegDriveHead] = (ataLBA >> 24) & 0x0f;
387
388 taskfile.ataRegs[kATARegDriveHead] |= kATAModeLBA | (getUnit() << 4);
389 taskfile.ataRegs[kATARegCommand] = ataCmd;
390
391 probeCmd->setQueueInfo();
392
393 for ( i = 0; i < 2; i++ )
394 {
395 probeCmd->setTimeout( 25000 );
396 probeCmd->setTaskfile( &taskfile );
397 probeCmd->setPointers( desc, size, false );
398 probeCmd->execute();
399
400 rc = probeCmd->getResults( &result );
401 if ( rc == kIOReturnSuccess )
402 {
403 break;
404 }
405 }
406
407
408doSectorCommand_error: ;
409
410 desc->release();
411
412 if ( rc != kIOReturnSuccess )
413 {
414 IOFree( data, size );
415 return result.returnCode;
416 }
417
418 *dataPtr = data;
419
420 return kIOReturnSuccess;
421}
422
423
424/*
425 *
426 *
427 */
428IOReturn IOATAStandardDevice::doInquiry( void **dataPtr )
429{
430 ATATaskfile taskfile;
431 ATACDBInfo atapiCmd;
432 ATAResults result;
433 void *data;
434 IOMemoryDescriptor *desc;
435 UInt32 size = sizeof(ATAPIInquiry);
436
437 *dataPtr = 0;
438
439 if ( !(data = (void *)IOMalloc(size)) )
440 {
441 return kIOReturnNoMemory;
442 }
443
444 bzero( data, size );
445 bzero( &taskfile, sizeof(taskfile) );
446 bzero( &atapiCmd, sizeof(atapiCmd) );
447
448 desc = IOMemoryDescriptor::withAddress( data, size, kIODirectionIn );
449
450 taskfile.protocol = kATAProtocolATAPIPIO;
451 taskfile.regmask = ATARegtoMask(kATARegATAPIDeviceSelect)
452 | ATARegtoMask(kATARegATAPICommand)
453 | ATARegtoMask(kATARegATAPIByteCountLow)
454 | ATARegtoMask(kATARegATAPIByteCountHigh)
455 | ATARegtoMask(kATARegATAPIFeatures);
456 taskfile.ataRegs[kATARegATAPIDeviceSelect] = kATAModeLBA | (getUnit() << 4);
457 taskfile.ataRegs[kATARegATAPICommand] = kATACommandATAPIPacket;
458 taskfile.ataRegs[kATARegATAPIFeatures] = 0;
459 taskfile.ataRegs[kATARegATAPIByteCountLow] = 0xfe;
460 taskfile.ataRegs[kATARegATAPIByteCountHigh] = 0xff;
461
462 atapiCmd.cdbLength = 12; // Fix 16 byte cmdpkts??
463 atapiCmd.cdb[0] = 0x12;
464 atapiCmd.cdb[4] = size;
465
466 probeCmd->setCDB( &atapiCmd );
467 probeCmd->setTaskfile( &taskfile );
468 probeCmd->setPointers( desc, size, false );
469 probeCmd->setTimeout( 5000 );
470 probeCmd->setQueueInfo();
471 probeCmd->execute();
472
473 if ( probeCmd->getResults(&result) == kIOReturnSuccess )
474 {
475 *dataPtr = data;
476 }
477 else if ( ( result.returnCode == kIOReturnUnderrun ) &&
478 ( result.bytesTransferred >= 36 ) )
479 {
480 // The standard INQUIRY contain 36 required bytes,
481 // the rest is optional and vendor specific.
482
483 result.returnCode = kIOReturnSuccess;
484 *dataPtr = data;
485 }
486 else
487 {
488 IOFree( data, size );
489 }
490
491 desc->release();
492
493 return result.returnCode;
494}
495
496/*
497 *
498 *
499 */
500bool IOATAStandardDevice::getDeviceCapacity( UInt32 *blockMax, UInt32 *blockSize )
501{
502 UInt32 i;
503 UInt32 data[2];
504
505 if ( deviceType == kATADeviceATA )
506 {
507 if ( identifyData != NULL )
508 {
509 *blockMax = *(UInt32 *)identifyData->userAddressableSectors - 1;
510 *blockSize = 512;
511 return true;
512 }
513 }
514
515 if ( deviceType == kATADeviceATAPI )
516 {
517 for ( i=0; i < 8; i++ )
518 {
519 if ( doTestUnitReady() == kIOReturnSuccess )
520 {
521 break;
522 }
523 }
524
525 if ( doReadCapacity( data ) == kIOReturnSuccess )
526 {
527 *blockMax = OSSwapBigToHostInt32( data[0] );
528 *blockSize = OSSwapBigToHostInt32( data[1] );
529 return true;
530 }
531 }
532
533 return false;
534}
535
536
537IOReturn IOATAStandardDevice::doTestUnitReady()
538{
539 ATATaskfile taskfile;
540 ATACDBInfo atapiCmd;
541 ATAResults result;
542
543 bzero( &taskfile, sizeof(taskfile) );
544 bzero( &atapiCmd, sizeof(atapiCmd) );
545
546 taskfile.protocol = kATAProtocolATAPIPIO;
547
548 taskfile.regmask = ATARegtoMask(kATARegATAPIDeviceSelect)
549 | ATARegtoMask(kATARegATAPICommand)
550 | ATARegtoMask(kATARegATAPIByteCountLow)
551 | ATARegtoMask(kATARegATAPIByteCountHigh)
552 | ATARegtoMask(kATARegATAPIFeatures);
553
554 taskfile.ataRegs[kATARegATAPIDeviceSelect] = kATAModeLBA | (getUnit() << 4);
555 taskfile.ataRegs[kATARegATAPICommand] = kATACommandATAPIPacket;
556 taskfile.ataRegs[kATARegATAPIFeatures] = 0;
557 taskfile.ataRegs[kATARegATAPIByteCountLow] = 0xfe;
558 taskfile.ataRegs[kATARegATAPIByteCountHigh] = 0xff;
559
560 atapiCmd.cdbLength = 12; // Fix 16 byte cmdpkts??
561 atapiCmd.cdb[0] = 0x00;
562
563 probeCmd->setCDB( &atapiCmd );
564 probeCmd->setTaskfile( &taskfile );
565 probeCmd->setPointers( (IOMemoryDescriptor *)NULL, 0, false );
566 probeCmd->setTimeout( 5000 );
567 probeCmd->setQueueInfo();
568 probeCmd->execute();
569 probeCmd->getResults(&result);
570
571 return result.returnCode;
572}
573
574
575/*
576 *
577 *
578 */
579IOReturn IOATAStandardDevice::doReadCapacity( void *data )
580{
581 ATATaskfile taskfile;
582 ATACDBInfo atapiCmd;
583 ATAResults result;
584 IOMemoryDescriptor *dataDesc;
585 UInt32 size = 8;
586
587
588 bzero( &taskfile, sizeof(taskfile) );
589 bzero( &atapiCmd, sizeof(atapiCmd) );
590
591 dataDesc = IOMemoryDescriptor::withAddress( data, size, kIODirectionIn );
592 if ( dataDesc == NULL )
593 {
594 return kIOReturnNoMemory;
595 }
596
597 taskfile.protocol = kATAProtocolATAPIPIO;
598 taskfile.regmask = ATARegtoMask(kATARegATAPIDeviceSelect)
599 | ATARegtoMask(kATARegATAPICommand)
600 | ATARegtoMask(kATARegATAPIByteCountLow)
601 | ATARegtoMask(kATARegATAPIByteCountHigh)
602 | ATARegtoMask(kATARegATAPIFeatures);
603 taskfile.ataRegs[kATARegATAPIDeviceSelect] = kATAModeLBA | (getUnit() << 4);
604 taskfile.ataRegs[kATARegATAPICommand] = kATACommandATAPIPacket;
605 taskfile.ataRegs[kATARegATAPIFeatures] = 0;
606 taskfile.ataRegs[kATARegATAPIByteCountLow] = 0xfe;
607 taskfile.ataRegs[kATARegATAPIByteCountHigh] = 0xff;
608
609 atapiCmd.cdbLength = 12; // Fix 16 byte cmdpkts??
610 atapiCmd.cdb[0] = 0x25;
611
612 probeCmd->setCDB( &atapiCmd );
613 probeCmd->setTaskfile( &taskfile );
614 probeCmd->setPointers( dataDesc, size, false );
615 probeCmd->setTimeout( 5000 );
616 probeCmd->setQueueInfo();
617 probeCmd->execute();
618
619 probeCmd->getResults(&result);
620
621 dataDesc->release();
622
623 return result.returnCode;
624}
625
626/*
627 *
628 *
629 */
630bool IOATAStandardDevice::getTimingsSupported( ATATimingProtocol *timingsSupported )
631{
632 UInt32 i;
633
634 *(UInt32 *)timingsSupported = 0;
635
636 for ( i=0; i < numTimings; i++ )
637 {
638 *(UInt32 *) timingsSupported |= (UInt32)ataTimings[i].timingProtocol;
639 }
640
641 return true;
642}
643
644/*
645 *
646 *
647 */
648bool IOATAStandardDevice::getTimingSelected( ATATimingProtocol *timingSelected )
649{
650 *timingSelected = currentTiming;
651 return true;
652}
653
654/*
655 *
656 *
657 */
658bool IOATAStandardDevice::getProtocolsSupported( ATAProtocol *forProtocolsSupported )
659{
660 *(UInt32 *)forProtocolsSupported = protocolsSupported;
661 return true;
662}
663
664/*
665 *
666 *
667 */
668bool IOATAStandardDevice::getTiming( ATATimingProtocol *timingProtocol, ATATiming *timing )
669{
670 UInt32 i;
671
672 for ( i=0; i < numTimings; i++ )
673 {
674 if ( ataTimings[i].timingProtocol == *timingProtocol )
675 {
676 bcopy( &ataTimings[i], timing, sizeof(ATATiming) );
677 return true;
678 }
679 }
680
681 return false;
682}
683
684
685/*
686 *
687 *
688 */
689bool IOATAStandardDevice::selectTiming( ATATimingProtocol timingProtocol, bool fNotifyMsg )
690{
691 ATATaskfile taskfile;
692 bool rc = false;
693 UInt32 i;
694 IOATAStandardCommand * ataCmd;
695
696 for ( i=0; i < numTimings; i++ )
697 {
698 if ( ataTimings[i].timingProtocol == timingProtocol )
699 {
700 rc = true;
701 break;
702 }
703 }
704
705 if ( rc == false )
706 {
707 return false;
708 }
709
710 ataCmd = allocCommand(kIOATAStandardDevice, 0);
711 if ( ataCmd == 0 ) return false;
712
713 currentTiming = timingProtocol;
714
715 bzero( &taskfile, sizeof(taskfile) );
716
717 taskfile.protocol = kATAProtocolPIO;
718 taskfile.regmask = ATARegtoMask(kATARegFeatures)
719 | ATARegtoMask(kATARegSectorCount)
720 | ATARegtoMask(kATARegDriveHead)
721 | ATARegtoMask(kATARegCommand);
722
723 taskfile.ataRegs[kATARegSectorCount] = ataTimings[i].featureSetting;
724 taskfile.ataRegs[kATARegFeatures] = kATAFeatureTransferMode;
725 taskfile.ataRegs[kATARegDriveHead] = kATAModeLBA | (getUnit() << 4);
726 taskfile.ataRegs[kATARegCommand] = kATACommandSetFeatures;
727
728 taskfile.flags = kATACmdFlagTimingChanged;
729
730 ataCmd->setTaskfile( &taskfile );
731 ataCmd->setPointers( (IOMemoryDescriptor *)NULL, 0, false );
732 ataCmd->setTimeout( 5000 );
733 ataCmd->setQueueInfo( kATAQTypeBypassQ );
734
735 if ( fNotifyMsg == false )
736 {
737 ataCmd->setCallback();
738 ataCmd->execute();
739 if ( ataCmd->getResults( (ATAResults *) 0 ) != kIOReturnSuccess )
740 {
741 rc = false;
742 }
743 ataCmd->release();
744 }
745 else
746 {
747 ataCmd->setCallback( this, (CallbackFn)&IOATAStandardDevice::selectTimingDone, ataCmd );
748 ataCmd->execute();
749 }
750 return rc;
751}
752
753/*
754 *
755 *
756 */
757void IOATAStandardDevice::selectTimingDone( IOATAStandardCommand *ataCmd )
758{
759 bool rc;
760
761 rc = (ataCmd->getResults( (ATAResults *)0 ) == kIOReturnSuccess);
762
763 client->message( kATAClientMsgSelectTiming | kATAClientMsgDone, this, (void *)rc );
764
765 ataCmd->release();
766}
767
768/*
769 *
770 *
771 */
772bool IOATAStandardDevice::getATATimings()
773{
774 int i, n;
775 UInt32 mode = 0;
776 UInt32 cycleTime = 0;
777
778 ATATiming *pTimings;
779
780 if ( controller->getProtocolsSupported( (ATAProtocol *)&protocolsSupported ) == false )
781 {
782 return false;
783 }
784
785 pTimings = ataTimings;
786
787 /*
788 * PIO Cycle timing......
789 *
790 * 1. Try to match Word 51 (pioCycleTime) with cycle timings
791 * in our pioModes table to get mode/CycleTime. (Valid for Modes 0-2)
792 * 2. If Words 64-68 are supported and Mode 3 or 4 supported check,
793 * update CycleTime with Word 68 (CycleTimeWithIORDY).
794 */
795
796 cycleTime = identifyData->pioMode;
797
798 if ( cycleTime > 2 )
799 {
800 for ( i=AppleNumPIOModes-1; i != -1; i-- )
801 {
802 if ( cycleTime <= ApplePIOModes[i].minDataCycle )
803 {
804 mode = i;
805 break;
806 }
807 }
808
809 if ( i == -1 )
810 {
811 cycleTime = ApplePIOModes[mode].minDataCycle;
812 }
813 }
814 else
815 {
816 mode = cycleTime;
817 cycleTime = ApplePIOModes[mode].minDataCycle;
818 }
819
820
821 if ( identifyData->validFields & identifyWords_64to70_Valid )
822 {
823 if (identifyData->advancedPIOModes & advPIOModes_Mode4_Supported)
824 mode = 4;
825 else if (identifyData->advancedPIOModes & advPIOModes_Mode3_Supported)
826 mode = 3;
827
828 if ( (mode >= 3) && identifyData->minPIOCyclcTimeIORDY )
829 {
830 cycleTime = identifyData->minPIOCyclcTimeIORDY;
831 }
832 }
833
834 pTimings->timingProtocol = kATATimingPIO;
835 pTimings->mode = mode;
836 pTimings->featureSetting = mode | kATATransferModePIOwFC;
837 pTimings->minDataCycle = cycleTime;
838 pTimings->minDataAccess = ApplePIOModes[mode].minDataAccess;
839
840 if ( ((protocolsSupported & kATAProtocolPIO) == 0)
841 || (controller->calculateTiming( getUnit(), pTimings ) == false) )
842 {
843 IOLog("IOATAStandardDevice::%s() - Controller driver must support PIO protocol\n\r", __FUNCTION__);
844 return false;
845 }
846
847 pTimings++;
848 numTimings++;
849
850 /*
851 * Multiword DMA timing.....
852 *
853 * 1. Check Word 63(7:0) (Multiword DMA Modes Supported). Lookup
854 * CycleTime for highest mode we support.
855 * 2. If Words 64-68 supported, update CycleTime from Word 66
856 * (RecommendedMultiWordCycleTime) if specified.
857 */
858
859 n = identifyData->dmaModes & dmaModes_Supported;
860 if ( n )
861 {
862 for ( i=0; n; i++, n>>=1 )
863 ;
864
865 mode = i - 1;
866 if ( mode > AppleNumDMAModes-1 )
867 {
868 mode = AppleNumDMAModes-1;
869 }
870 cycleTime = AppleDMAModes[mode].minDataCycle;
871
872 if (identifyData->validFields & identifyWords_64to70_Valid)
873 {
874 if ( identifyData->recDMACycleTime )
875 {
876 cycleTime = identifyData->recDMACycleTime;
877 }
878 }
879 pTimings->timingProtocol = kATATimingDMA;
880 pTimings->mode = mode;
881 pTimings->featureSetting = mode | kATATransferModeDMA;
882 pTimings->minDataCycle = cycleTime;
883 pTimings->minDataAccess = AppleDMAModes[mode].minDataAccess;
884
885 if ( ((protocolsSupported & kATAProtocolDMA) != 0)
886 && (controller->calculateTiming( getUnit(), pTimings ) == true) )
887 {
888 pTimings++;
889 numTimings++;
890 }
891 }
892
893 /*
894 * Ultra DMA timing.....
895 *
896 */
897 if ( identifyData->validFields & identifyWords_88to88_Valid )
898 {
899 n = identifyData->ultraDMAModes & ultraDMAModes_Supported;
900 if ( n )
901 {
902 for ( i=0; n; i++, n>>=1 )
903 ;
904
905 mode = i - 1;
906 if ( mode > AppleNumUltraModes-1 )
907 {
908 mode = AppleNumUltraModes-1;
909 }
910
911 /*
912 * Build a separate timing entry for Ultra DMA/33 (mode <= 2) and Ultra DMA/66
913 */
914 while ( 1 )
915 {
916 cycleTime = AppleUltraModes[mode].minDataCycle;
917
918 pTimings->timingProtocol = (mode > 2) ? kATATimingUltraDMA66 : kATATimingUltraDMA33;
919 pTimings->mode = mode;
920 pTimings->featureSetting = mode | kATATransferModeUltraDMA33;
921 pTimings->minDataCycle = cycleTime;
922 pTimings->minDataAccess = AppleUltraModes[mode].minDataAccess;
923
924 if ( ((protocolsSupported & kATAProtocolDMA) != 0)
925 && (controller->calculateTiming( getUnit(), pTimings ) == true) )
926 {
927 pTimings++;
928 numTimings++;
929 }
930
931 if ( mode < 3 ) break;
932
933 mode = 2;
934 }
935 }
936 }
937
938 maxTags = 0;
939
940 if ( deviceType == kATADeviceATA )
941 {
942 if ( ((identifyData->commandSetsSupported2 & commandSetsSupported2_ValidMask) == commandSetsSupported2_Valid)
943 && ((identifyData->commandSetsSupported3 & commandSetsSupported3_ValidMask) == commandSetsSupported3_Valid) )
944 {
945 if ( ((identifyData->commandSetsSupported2 & commandSetsSupported2_DMAQueued) != 0)
946 && ((identifyData->commandSetsEnabled2 & commandSetsEnabled2_DMAQueued) != 0) )
947 {
948 maxTags = identifyData->queueDepth + 1;
949 }
950 }
951 }
952
953 if ( maxTags == 0 )
954 {
955 protocolsSupported &= ~(kATAProtocolDMAQueued | kATAProtocolDMAQueuedRelease);
956 }
957
958
959 return true;
960}
961
962/*
963 *
964 *
965 *
966 */
967ATAUnit IOATAStandardDevice::getUnit()
968{
969 return unit;
970}
971
972/*
973 *
974 *
975 */
976ATADeviceType IOATAStandardDevice::getDeviceType()
977{
978 return deviceType;
979}
980
981/*
982 *
983 *
984 */
985bool IOATAStandardDevice::getATAPIPktInt()
986{
987 return atapiPktInt;
988}
989
990/*
991 *
992 *
993 */
994bool IOATAStandardDevice::getIdentifyData( ATAIdentify *identifyBuffer )
995{
996 if ( identifyData == NULL )
997 {
998 bzero( identifyBuffer, sizeof(ATAIdentify) );
999 return false;
1000 }
1001
1002 bcopy( identifyData, identifyBuffer, sizeof(ATAIdentify) );
1003 return true;
1004}
1005
1006/*
1007 *
1008 *
1009 */
1010bool IOATAStandardDevice::getInquiryData( UInt32 inquiryBufLength, ATAPIInquiry *inquiryBuffer )
1011{
1012 bzero( inquiryBuffer, inquiryBufLength );
1013
1014 if ( inquiryData == NULL )
1015 {
1016 return false;
1017 }
1018
1019 bcopy( inquiryData, inquiryBuffer, inquiryBufLength );
1020
1021 return true;
1022}
1023
1024
1025/*
1026 *
1027 *
1028 *
1029 */
1030void IOATAStandardDevice::setupTarget()
1031{
1032}
1033
1034/*
1035 *
1036 *
1037 *
1038 */
1039void IOATAStandardDevice::getInquiryData( void *clientBuf, UInt32 clientBufSize, UInt32 *clientDataSize )
1040{
1041 UInt32 len;
1042
1043 bzero( clientBuf, clientBufSize );
1044
1045 len = MIN( clientBufSize, inquiryDataSize );
1046
1047 bcopy( inquiryData, clientBuf, len );
1048
1049 *clientDataSize = len;
1050}
1051
1052/*
1053 *
1054 *
1055 *
1056 */
1057void IOATAStandardDevice::abort()
1058{
1059 submitCommand( kATACommandAbortAll, 0 );
1060}
1061
1062/*
1063 *
1064 *
1065 *
1066 */
1067void IOATAStandardDevice::reset()
1068{
1069 submitCommand( kATACommandDeviceReset, 0 );
1070}
1071
1072/*
1073 *
1074 *
1075 *
1076 */
1077void IOATAStandardDevice::holdQueue( UInt32 queueType )
1078{
1079 if ( getWorkLoop()->inGate() == false )
1080 {
1081 IOPanic( "IOATAStandardDevice::holdQueue() - must be called from workloop!!\n\r");
1082 }
1083
1084 if ( queueType == kATAQTypeBypassQ )
1085 {
1086 bypassQHeld++;
1087 }
1088 else if ( queueType == kATAQTypeNormalQ )
1089 {
1090 normalQHeld++;
1091 }
1092}
1093
1094/*
1095 *
1096 *
1097 *
1098 */
1099void IOATAStandardDevice::releaseQueue( UInt32 queueType )
1100{
1101 bool doDispatchRequest = false;
1102
1103 if ( getWorkLoop()->inGate() == false )
1104 {
1105 IOPanic( "IOATAStandardDevice::releaseQueue() - must be called from workloop!!\n\r");
1106 }
1107
1108 if ( queueType == kATAQTypeBypassQ )
1109 {
1110 if ( bypassQHeld && (--bypassQHeld == 0) )
1111 doDispatchRequest = true;
1112 }
1113 else if ( queueType == kATAQTypeNormalQ )
1114 {
1115 if ( normalQHeld && (--normalQHeld == 0) )
1116 doDispatchRequest = true;
1117 }
1118
1119 if ( doDispatchRequest ) dispatchRequest();
1120}
1121
1122/*
1123 *
1124 *
1125 *
1126 */
1127void IOATAStandardDevice::notifyIdle( void *target = 0, CallbackFn callback = 0, void *refcon = 0 )
1128{
1129 if ( getWorkLoop()->inGate() == false )
1130 {
1131 IOPanic( "IOATAStandardDevice:::notifyIdle() - must be called from workloop!!\n\r");
1132 }
1133
1134 if ( callback == 0 )
1135 {
1136 idleNotifyActive = false;
1137 return;
1138 }
1139
1140 if ( idleNotifyActive == true )
1141 {
1142 IOPanic( "IOATAStandardDevice:::notifyIdle() - only one idle notify may be active\n\r");
1143 }
1144
1145 idleNotifyActive = true;
1146 idleNotifyTarget = target;
1147 idleNotifyCallback = callback;
1148 idleNotifyRefcon = refcon;
1149
1150 checkIdleNotify();
1151}
1152
1153
1154/*
1155 *
1156 *
1157 *
1158 */
1159void IOATAStandardDevice::submitCommand( UInt32 cmdType, IOATAStandardCommand *ataCmd, UInt32 cmdSequenceNumber )
1160{
1161 deviceGate->runCommand( (void *)cmdType, (void *)ataCmd, (void *) cmdSequenceNumber, (void *) 0 );
1162}
1163
1164/*
1165 *
1166 *
1167 *
1168 */
1169void IOATAStandardDevice::receiveCommand( UInt32 cmdType, IOATAStandardCommand *ataCmd, UInt32 cmdSequenceNumber, void *p3 )
1170{
1171 queue_head_t *queue;
1172
1173 switch ( cmdType )
1174 {
1175 case kATACommandExecute:
1176 ataCmd->cmdType = (ATACommandType) cmdType;
1177
1178 queue = (ataCmd->queueType == kATAQTypeBypassQ) ? &bypassList : &deviceList;
1179
1180 if ( ataCmd->queuePosition == kATAQPositionHead )
1181 {
1182 stackCommand( queue, ataCmd );
1183 }
1184 else
1185 {
1186 addCommand( queue, ataCmd );
1187 }
1188
1189 dispatchRequest();
1190 break;
1191
1192 case kATACommandAbortAll:
1193 abortAllCommands( kATACommandAbortAll );
1194 break;
1195
1196 case kATACommandAbort:
1197 abortCommand( ataCmd, cmdSequenceNumber );
1198 break;
1199
1200 case kATACommandDeviceReset:
1201 abortAllCommands( kATACommandDeviceReset );
1202 break;
1203
1204 default:
1205 /* ??? */
1206 break;
1207 }
1208}
1209
1210/*
1211 *
1212 *
1213 *
1214 */
1215void IOATAStandardDevice::abortCommand( IOATAStandardCommand *ataCmd, UInt32 sequenceNumber )
1216{
1217 if ( ataCmd->list == (queue_head_t *)deviceGate )
1218 {
1219 if ( ataCmd->sequenceNumber != sequenceNumber )
1220 {
1221 return;
1222 }
1223 ataCmd->results.returnCode = kIOReturnAborted;
1224 }
1225 else if ( ataCmd->list == &deviceList )
1226 {
1227 if ( ataCmd->sequenceNumber != sequenceNumber )
1228 {
1229 return;
1230 }
1231
1232 deleteCommand( &deviceList, ataCmd );
1233 ataCmd->results.returnCode = kIOReturnAborted;
1234 finishCommand( ataCmd );
1235 }
1236 else if ( ataCmd->list == &activeList )
1237 {
1238 if ( ataCmd->sequenceNumber != sequenceNumber )
1239 {
1240 return;
1241 }
1242
1243 moveCommand( &activeList, &abortList, ataCmd );
1244
1245 dispatchRequest();
1246 }
1247}
1248
1249
1250/*
1251 *
1252 *
1253 *
1254 */
1255void IOATAStandardDevice::abortAllCommands( ATACommandType cmdType )
1256{
1257
1258 abortCmdPending = cmdType;
1259
1260 if ( abortCmdPending == kATACommandAbortAll )
1261 {
1262 if ( client != 0 )
1263 {
1264 client->message( kATAClientMsgDeviceAbort, this );
1265 }
1266 }
1267 else if ( abortCmdPending == kATACommandDeviceReset )
1268 {
1269 if ( client != 0 )
1270 {
1271 client->message( kATAClientMsgDeviceReset, this );
1272 }
1273 }
1274
1275 dispatchRequest();
1276}
1277
1278/*
1279 *
1280 *
1281 *
1282 */
1283void IOATAStandardDevice::resetOccurred( ATAClientMessage clientMsg )
1284{
1285 moveAllCommands( &activeList, &cancelList, kIOReturnAborted );
1286 moveAllCommands( &abortList, &cancelList, kIOReturnAborted );
1287
1288 abortState = kStateIdle;
1289 reqSenseState = kStateIdle;
1290 commandLimit = 1;
1291
1292 isSuspended = false;
1293 AbsoluteTime_to_scalar( &suspendTime ) = 0;
1294
1295 if ( (client != 0) && (clientMsg != kATAClientMsgNone) )
1296 {
1297 client->message( clientMsg, this );
1298 }
1299
1300 dispatchRequest();
1301}
1302
1303void IOATAStandardDevice::resetComplete()
1304{
1305 if ( client != 0 )
1306 {
1307 client->message( kATAClientMsgBusReset | kATAClientMsgDone, this );
1308 }
1309}
1310
1311
1312/*
1313 *
1314 *
1315 *
1316 */
1317bool IOATAStandardDevice::checkAbortQueue()
1318{
1319 IOATAStandardCommand *origCmd;
1320
1321 if ( abortState == kStateActive )
1322 {
1323 return true;
1324 }
1325
1326 if ( abortCmdPending != kATACommandNone )
1327 {
1328 abortCmd->origCommand = 0;
1329 abortCmd->taskfile.tagType = kATATagTypeNone;
1330 abortCmd->cmdType = abortCmdPending;
1331
1332 abortCmd->timer = ( abortCmd->timeout != 0 ) ?
1333 abortCmd->timeout / kATATimerIntervalmS + 1 : 0;
1334
1335 bzero( &abortCmd->results, sizeof(ATAResults) );
1336
1337 abortState = kStateActive;
1338
1339 addCommand( &activeList, abortCmd );
1340
1341 if ( (abortCmdPending == kATACommandDeviceReset) ||
1342 (abortCmdPending == kATACommandAbortAll) && (queue_empty( &abortList ) == false) )
1343 {
1344 controller->abortCommand( abortCmd );
1345 }
1346 else
1347 {
1348 abortCmd->complete();
1349 }
1350 }
1351 else if ( queue_empty( &abortList ) == false )
1352 {
1353 origCmd = (IOATAStandardCommand *)queue_first( &abortList );
1354 abortCmd->origCommand = origCmd;
1355
1356 abortCmd->cmdType = kATACommandAbort;
1357 abortCmd->taskfile.tagType = origCmd->taskfile.tagType;
1358 abortCmd->taskfile.tag = origCmd->taskfile.tag;
1359
1360 abortCmd->timer = ( abortCmd->timeout != 0 ) ?
1361 abortCmd->timeout / kATATimerIntervalmS + 1 : 0;
1362
1363 bzero( &abortCmd->results, sizeof(ATAResults) );
1364
1365 abortState = kStateActive;
1366
1367 addCommand( &activeList, abortCmd );
1368 controller->abortCommand( abortCmd );
1369 }
1370 else
1371 {
1372 return false;
1373 }
1374
1375 return true;
1376}
1377
1378/*
1379 *
1380 *
1381 *
1382 */
1383void IOATAStandardDevice::checkCancelQueue()
1384{
1385 if ( cancelState != kStateIdle )
1386 {
1387 return;
1388 }
1389
1390 if ( queue_empty( &cancelList ) == true )
1391 {
1392 return;
1393 }
1394
1395 if ( controller->controllerInfo.disableCancelCommands == true )
1396 {
1397 return;
1398 }
1399
1400 cancelCmd->origCommand = (IOATAStandardCommand *)queue_first( &cancelList );
1401 bzero( &cancelCmd->results, sizeof(ATAResults) );
1402
1403 cancelState = kStateActive;
1404 controller->cancelCommand( cancelCmd );
1405}
1406
1407/*
1408 *
1409 *
1410 *
1411 */
1412bool IOATAStandardDevice::checkReqSense()
1413{
1414 IOMemoryDescriptor *senseData;
1415 UInt32 senseLength;
1416
1417 if ( reqSenseState == kStateIssue )
1418 {
1419 reqSenseCmd->origCommand = reqSenseOrigCmd;
1420 bzero( &reqSenseCmd->results, sizeof(ATAResults) );
1421
1422 reqSenseOrigCmd->getPointers( &senseData, &senseLength, 0, true );
1423 reqSenseCmd->setPointers( senseData, senseLength, false );
1424
1425 reqSenseCmd->timer = ( reqSenseCmd->timeout != 0 ) ?
1426 reqSenseCmd->timeout / kATATimerIntervalmS + 1 : 0;
1427
1428 reqSenseCmd->ataCmd.cdb[3] = (senseLength >> 8) & 0xff;
1429 reqSenseCmd->ataCmd.cdb[4] = senseLength & 0xff;
1430
1431 reqSenseState = kStatePending;
1432 }
1433
1434 if ( reqSenseState == kStatePending )
1435 {
1436 reqSenseState = kStateActive;
1437
1438 addCommand( &activeList, reqSenseCmd );
1439
1440 commandCount++;
1441 controller->commandCount++;
1442
1443 controller->executeCommand( reqSenseCmd );
1444 }
1445
1446 return (reqSenseState != kStateIdle);
1447}
1448
1449
1450/*
1451 *
1452 *
1453 *
1454 */
1455bool IOATAStandardDevice::checkDeviceQueue( UInt32 *dispatchAction )
1456{
1457 IOATAStandardCommand *ataCmd = 0;
1458 queue_head_t *queue;
1459 UInt32 i;
1460 bool rc = true;
1461 UInt32 queueHeld;
1462
1463 do
1464 {
1465 if ( isSuspended == true )
1466 {
1467 *dispatchAction = kDispatchNextDevice;
1468 break;
1469 }
1470
1471 if ( controller->commandCount >= controller->commandLimit )
1472 {
1473 *dispatchAction = kDispatchStop;
1474 break;
1475 }
1476
1477 *dispatchAction = kDispatchNextDevice;
1478
1479 if ( commandCount >= commandLimit )
1480 {
1481 break;
1482 }
1483
1484 for ( i=0; i < 2; i++ )
1485 {
1486 queueHeld = (i == 0) ? bypassQHeld : normalQHeld;
1487 queue = (i == 0) ? &bypassList : &deviceList;
1488
1489 if ( queueHeld > 0 )
1490 {
1491 continue;
1492 }
1493
1494 ataCmd = checkCommand( queue );
1495 if ( ataCmd != 0 )
1496 {
1497 *dispatchAction = kDispatchNextCommand;
1498 break;
1499 }
1500 }
1501
1502 if ( i == 2 )
1503 {
1504 rc = false;
1505 break;
1506 }
1507
1508
1509 if ( checkTag( ataCmd ) == false )
1510 {
1511 *dispatchAction = kDispatchNextDevice;
1512 break;
1513 }
1514
1515 getCommand( queue );
1516
1517 ataCmd->timer = ( ataCmd->timeout != 0 ) ? ataCmd->timeout / kATATimerIntervalmS + 1 : 0;
1518
1519 commandCount++;
1520 controller->commandCount++;
1521
1522 addCommand( &activeList, ataCmd );
1523
1524 controller->executeCommand( ataCmd );
1525
1526 } while ( 0 );
1527
1528 return rc;
1529}
1530
1531/*
1532 *
1533 *
1534 *
1535 */
1536void IOATAStandardDevice::suspend()
1537{
1538 if ( AbsoluteTime_to_scalar( &suspendTime ) == 0 )
1539 {
1540 clock_get_uptime( &suspendTime );
1541 }
1542
1543 isSuspended = true;
1544}
1545
1546/*
1547 *
1548 *
1549 *
1550 */
1551void IOATAStandardDevice::resume()
1552{
1553 AbsoluteTime_to_scalar( &suspendTime ) = 0;
1554 isSuspended = false;
1555
1556 dispatchRequest();
1557}
1558
1559
1560/*
1561 *
1562 *
1563 *
1564 */
1565void IOATAStandardDevice::rescheduleCommand( IOATAStandardCommand *ataCmd )
1566{
1567 queue_head_t *queue;
1568
1569 if ( ataCmd->list != &activeList )
1570 {
1571 IOLog( "IOATAStandardController::rescheduleCommand() - Command not active. Cmd = %08x\n\r", (int)ataCmd );
1572 return;
1573 }
1574
1575 deleteCommand( &activeList, ataCmd );
1576
1577 switch ( ataCmd->cmdType )
1578 {
1579 case kATACommandExecute:
1580 if ( ataCmd->taskfile.tagType != kATATagTypeNone )
1581 {
1582 freeTag( ataCmd->taskfile.tag );
1583 ataCmd->taskfile.tag = kATATagTypeNone;
1584 }
1585
1586 queue = (ataCmd->queueType == kATAQTypeBypassQ) ? &bypassList : &deviceList;
1587
1588 stackCommand( queue, ataCmd );
1589
1590 controller->commandCount--;
1591 commandCount--;
1592 break;
1593
1594 case kATACommandReqSense:
1595 reqSenseState = kStatePending;
1596 commandCount--;
1597 controller->commandCount--;
1598 break;
1599
1600 case kATACommandAbortAll:
1601 case kATACommandDeviceReset:
1602 abortCmdPending = ataCmd->cmdType;
1603
1604 case kATACommandAbort:
1605 abortState = kStateIdle;
1606 break;
1607
1608 default:
1609 ;
1610 }
1611
1612 dispatchRequest();
1613
1614}
1615
1616/*
1617 *
1618 *
1619 *
1620 */
1621bool IOATAStandardDevice::checkTag( IOATAStandardCommand *ataCmd )
1622{
1623 ATACDBInfo ataCDB;
1624 bool rc = true;
1625 ATAProtocol protocol;
1626
1627 ataCmd->getCDB( &ataCDB );
1628
1629 ataCmd->taskfile.tagType = kATATagTypeNone;
1630
1631 protocol = ataCmd->getProtocol();
1632
1633 do
1634 {
1635 if ( protocol != kATAProtocolDMAQueued && protocol != kATAProtocolDMAQueuedRelease )
1636 {
1637 break;
1638 }
1639 if ( allocTag( &ataCmd->taskfile.tag ) == false )
1640 {
1641 rc = false;
1642 break;
1643 }
1644
1645 ataCmd->taskfile.tagType = kATATagTypeSimple;
1646 }
1647 while ( 0 );
1648
1649 ataCmd->setCDB( &ataCDB );
1650
1651 return rc;
1652}
1653
1654/*
1655 *
1656 *
1657 *
1658 */
1659bool IOATAStandardDevice::allocTag( UInt32 *tagId )
1660{
1661 UInt32 i;
1662 UInt32 tagIndex;
1663 UInt32 tagMask;
1664 UInt32 *tags = 0;
1665
1666 tags = tagArray;
1667
1668 if ( tags == 0 ) return false;
1669
1670 for ( i = 0; i < maxTags; i++ )
1671 {
1672 tagIndex = i / 32;
1673 tagMask = 1 << (i % 32);
1674 if ( !(tags[tagIndex] & tagMask) )
1675 {
1676 tags[tagIndex] |= tagMask;
1677 *tagId = i;
1678 return true;
1679 }
1680 }
1681 return false;
1682}
1683
1684/*
1685 *
1686 *
1687 *
1688 */
1689void IOATAStandardDevice::freeTag( UInt32 tagId )
1690{
1691 UInt32 *tags = 0;
1692
1693 tags = tagArray;
1694
1695 if ( tags == 0 ) return;
1696
1697 tags[tagId/32] &= ~(1 << (tagId % 32));
1698}
1699
1700/*
1701 *
1702 *
1703 *
1704 */
1705IOATAStandardCommand *IOATAStandardDevice::findCommandWithNexus( UInt32 tagValue )
1706{
1707 IOATAStandardCommand *ataCmd;
1708 UInt32 tag;
1709
1710 queue_iterate( &activeList, ataCmd, IOATAStandardCommand *, nextCommand )
1711 {
1712 switch ( ataCmd->cmdType )
1713 {
1714 case kATACommandExecute:
1715 case kATACommandReqSense:
1716 tag = (ataCmd->taskfile.tagType == kATATagTypeNone) ? (UInt32) -1 : ataCmd->taskfile.tag;
1717 if ( tag == tagValue )
1718 {
1719 return ataCmd;
1720 }
1721 break;
1722 default:
1723 ;
1724 }
1725 }
1726
1727 queue_iterate( &abortList, ataCmd, IOATAStandardCommand *, nextCommand )
1728 {
1729 switch ( ataCmd->cmdType )
1730 {
1731 case kATACommandExecute:
1732 case kATACommandReqSense:
1733 if ( ataCmd->taskfile.tag == tagValue )
1734 {
1735 return ataCmd;
1736 }
1737 break;
1738 default:
1739 ;
1740 }
1741 }
1742
1743 return 0;
1744}
1745
1746/*
1747 *
1748 *
1749 *
1750 */
1751void IOATAStandardDevice::timer()
1752{
1753 IOATAStandardCommand *ataCmd, *tmp = 0;
1754
1755 queue_iterate( &activeList, ataCmd, IOATAStandardCommand *, nextCommand )
1756 {
1757 tmp = (IOATAStandardCommand *)queue_prev( &ataCmd->nextCommand );
1758
1759 if ( ataCmd->timer )
1760 {
1761 if ( !--ataCmd->timer )
1762 {
1763 IOLog("Timeout: Unit = %d Cmd = %08x Cmd Type = %d\n\r",
1764 unit, (int)ataCmd, ataCmd->cmdType );
1765
1766 controller->busResetState = kStateIssue;
1767 dispatchRequest();
1768 }
1769 }
1770
1771 if ( queue_end( &activeList, (queue_head_t *)ataCmd ) == true )
1772 {
1773 break;
1774 }
1775 }
1776}
1777
1778/*
1779 *
1780 *
1781 *
1782 */
1783void IOATAStandardDevice::dispatchRequest()
1784{
1785 target->state = kStateActive;
1786 controller->dispatchRequest();
1787}
1788
1789/*
1790 *
1791 *
1792 *
1793 */
1794bool IOATAStandardDevice::dispatch( UInt32 *dispatchAction )
1795{
1796 bool rc;
1797
1798 checkCancelQueue();
1799
1800 if ( controller->checkBusReset() == true )
1801 {
1802 *dispatchAction = kDispatchStop;
1803 return true;
1804 }
1805
1806 if ( checkAbortQueue() == true )
1807 {
1808 *dispatchAction = kDispatchNextDevice;
1809 return true;
1810 }
1811
1812 do
1813 {
1814 if ( (rc = controller->commandDisable) == true )
1815 {
1816 *dispatchAction = kDispatchStop;
1817 break;
1818 }
1819
1820 if ( isSuspended == true )
1821 {
1822 *dispatchAction = kDispatchNextDevice;
1823 break;
1824 }
1825
1826 if ( (rc = checkReqSense()) == true )
1827 {
1828 *dispatchAction = kDispatchNextDevice;
1829 break;
1830 }
1831
1832 rc = checkDeviceQueue( dispatchAction );
1833
1834 } while ( *dispatchAction == kDispatchNextCommand );
1835
1836 return rc;
1837}
1838
1839
1840/*
1841 *
1842 *
1843 *
1844 */
1845void IOATAStandardDevice::completeCommand( IOATAStandardCommand *ataCmd )
1846{
1847 ATACommandType cmdType;
1848
1849 cmdType = ataCmd->cmdType;
1850 switch ( cmdType )
1851 {
1852 case kATACommandExecute:
1853 executeCommandDone( ataCmd );
1854 break;
1855
1856 case kATACommandReqSense:
1857 executeReqSenseDone( ataCmd );
1858 break;
1859
1860 case kATACommandAbort:
1861 case kATACommandAbortAll:
1862 case kATACommandDeviceReset:
1863 abortCommandDone( ataCmd );
1864 break;
1865
1866 case kATACommandCancel:
1867 cancelCommandDone( ataCmd );
1868 break;
1869
1870 default:
1871 ;
1872 }
1873
1874 checkIdleNotify();
1875
1876 dispatchRequest();
1877}
1878
1879/*
1880 *
1881 *
1882 *
1883 */
1884void IOATAStandardDevice::checkIdleNotify()
1885{
1886 if ( idleNotifyActive == false )
1887 {
1888 return;
1889 }
1890
1891 if ( (queue_empty( &activeList ) == true)
1892 && (queue_empty( &abortList ) == true)
1893 && (queue_empty( &cancelList ) == true) )
1894 {
1895 idleNotifyActive = false;
1896 (idleNotifyCallback)( idleNotifyTarget, idleNotifyRefcon );
1897 }
1898}
1899
1900/*
1901 *
1902 *
1903 *
1904 */
1905void IOATAStandardDevice::flushQueue( UInt32 queueType, IOReturn rc )
1906{
1907 queue_head_t *queue;
1908
1909 queue = (queueType == kATAQTypeBypassQ) ? &bypassList : &deviceList;
1910 purgeAllCommands( queue, rc );
1911}
1912
1913/*
1914 *
1915 *
1916 *
1917 */
1918void IOATAStandardDevice::executeCommandDone( IOATAStandardCommand *ataCmd )
1919{
1920 deleteCommand( ataCmd->list, ataCmd );
1921
1922 commandCount--;
1923 controller->commandCount--;
1924
1925 if ( ataCmd->taskfile.tagType != kATATagTypeNone )
1926 {
1927 freeTag( ataCmd->taskfile.tag );
1928 ataCmd->taskfile.tagType = kATATagTypeNone;
1929 }
1930
1931 if ( deviceType == kATADeviceATAPI
1932 && ataCmd->results.adapterStatus == kATAReturnStatusError
1933 && ataCmd->results.requestSenseDone == false
1934 && ataCmd->senseData != 0 )
1935 {
1936 reqSenseOrigCmd = ataCmd;
1937 reqSenseState = kStateIssue;
1938 return;
1939 }
1940
1941 finishCommand( ataCmd );
1942}
1943
1944/*
1945 *
1946 *
1947 *
1948 */
1949void IOATAStandardDevice::executeReqSenseDone( IOATAStandardCommand *ataCmd )
1950{
1951 IOATAStandardCommand *origCommand;
1952
1953 deleteCommand( ataCmd->list, ataCmd );
1954
1955 commandCount--;
1956 controller->commandCount--;
1957
1958 reqSenseState = kStateIdle;
1959
1960 reqSenseOrigCmd = 0;
1961
1962 origCommand = ataCmd->origCommand;
1963
1964 if ( (ataCmd->results.returnCode == kIOReturnSuccess) || (ataCmd->results.returnCode == kIOReturnUnderrun))
1965 {
1966 origCommand->results.requestSenseDone = true;
1967 origCommand->results.requestSenseLength = ataCmd->results.bytesTransferred;
1968 }
1969 else
1970 {
1971 origCommand->results.requestSenseDone = false;
1972 origCommand->results.requestSenseLength = 0;
1973 }
1974
1975 finishCommand( ataCmd->origCommand );
1976}
1977
1978/*
1979 *
1980 *
1981 *
1982 */
1983void IOATAStandardDevice::abortCommandDone( IOATAStandardCommand *ataCmd )
1984{
1985 IOATAStandardCommand *origATACmd;
1986
1987 deleteCommand( ataCmd->list, ataCmd );
1988
1989 if ( ataCmd->cmdType == kATACommandAbortAll )
1990 {
1991 resetOccurred( (ATAClientMessage) (kATAClientMsgDeviceAbort | kATAClientMsgDone) );
1992 abortCmdPending = kATACommandNone;
1993 }
1994 if ( ataCmd->cmdType == kATACommandDeviceReset )
1995 {
1996 resetOccurred( (ATAClientMessage) (kATAClientMsgDeviceReset | kATAClientMsgDone) );
1997 abortCmdPending = kATACommandNone;
1998 }
1999 else if ( ataCmd->cmdType == kATACommandAbort )
2000 {
2001 origATACmd = ataCmd->origCommand;
2002
2003 if ( findCommand( &abortList, origATACmd ) == true )
2004 {
2005 moveCommand( &abortList, &cancelList, origATACmd, kIOReturnAborted );
2006 }
2007 }
2008
2009 abortState = kStateIdle;
2010
2011 return;
2012}
2013
2014/*
2015 *
2016 *
2017 *
2018 */
2019void IOATAStandardDevice::cancelCommandDone( IOATAStandardCommand *ataCmd )
2020{
2021 IOATAStandardCommand *origATACmd;
2022
2023 cancelState = kStateIdle;
2024
2025 origATACmd = ataCmd->origCommand;
2026
2027 if ( findCommand( &cancelList, origATACmd ) == true )
2028 {
2029 IOLog( "IOATAStandardDevice::cancelCommandDone - Cancelled command not completed - ataCmd = %08x\n\r", (int)origATACmd );
2030 deleteCommand( &cancelList, origATACmd );
2031 }
2032}
2033
2034/*
2035 *
2036 *
2037 *
2038 */
2039void IOATAStandardDevice::finishCommand( IOATAStandardCommand *ataCmd )
2040{
2041 if ( ataCmd->completionInfo.async.callback )
2042 {
2043 (*ataCmd->completionInfo.async.callback)( ataCmd->completionInfo.async.target,
2044 ataCmd->completionInfo.async.refcon );
2045 }
2046 else
2047 {
2048 ataCmd->completionInfo.sync.lock->signal();
2049 }
2050}
2051
2052
2053/*
2054 *
2055 *
2056 */
2057OSDictionary *IOATAStandardDevice::createProperties()
2058{
2059 OSDictionary *propTable = 0;
2060 OSObject *regObj;
2061 char tmpbuf[81];
2062 const char *s;
2063 char *d;
2064
2065
2066 propTable = OSDictionary::withCapacity(kATAMaxProperties);
2067 if ( propTable == NULL )
2068 {
2069 return NULL;
2070 }
2071
2072 s = (deviceType == kATADeviceATA) ? kATAPropertyProtocolATA : kATAPropertyProtocolATAPI;
2073 regObj = (OSObject *)OSString::withCString( s );
2074 if ( addToRegistry( propTable, regObj, kATAPropertyProtocol ) != true )
2075 {
2076 goto createprop_error;
2077 }
2078
2079 regObj = (OSObject *)OSNumber::withNumber(unit,32);
2080 if ( addToRegistry( propTable, regObj, kATAPropertyDeviceNumber ) != true )
2081 {
2082 goto createprop_error;
2083 }
2084
2085 regObj = (OSObject *)OSNumber::withNumber(unit,32);
2086 if ( addToRegistry( propTable, regObj, kATAPropertyLocation ) != true )
2087 {
2088 goto createprop_error;
2089 }
2090
2091 d = tmpbuf;
2092 stripBlanks( d, (char *)identifyData->modelNumber, sizeof(identifyData->modelNumber));
2093 regObj = (OSObject *)OSString::withCString( d );
2094 if ( addToRegistry( propTable, regObj, kATAPropertyModelNumber ) != true )
2095 {
2096 goto createprop_error;
2097 }
2098
2099 d = tmpbuf;
2100 stripBlanks( d, (char *)identifyData->firmwareRevision, sizeof(identifyData->firmwareRevision));
2101 regObj = (OSObject *)OSString::withCString( d );
2102 if ( addToRegistry( propTable, regObj, kATAPropertyFirmwareRev ) != true )
2103 {
2104 goto createprop_error;
2105 }
2106
2107 if ( inquiryData )
2108 {
2109 stripBlanks( d, (char *)inquiryData->vendorName, sizeof(inquiryData->vendorName) );
2110 regObj = (OSObject *)OSString::withCString( d );
2111 if ( addToRegistry( propTable, regObj, kATAPropertyVendorName ) != true )
2112 {
2113 goto createprop_error;
2114 }
2115
2116 stripBlanks( d, (char *)inquiryData->productName, sizeof(inquiryData->productName) );
2117 regObj = (OSObject *)OSString::withCString( d );
2118 if ( addToRegistry( propTable, regObj, kATAPropertyProductName ) != true )
2119 {
2120 goto createprop_error;
2121 }
2122
2123 stripBlanks( d, (char *)inquiryData->productRevision, sizeof(inquiryData->productRevision) );
2124 regObj = (OSObject *)OSString::withCString( d );
2125 if ( addToRegistry( propTable, regObj, kATAPropertyProductRevision ) != true )
2126 {
2127 goto createprop_error;
2128 }
2129 }
2130 return propTable;
2131
2132createprop_error: ;
2133 propTable->release();
2134 return NULL;
2135}
2136
2137
2138/*
2139 *
2140 *
2141 */
2142bool IOATAStandardDevice::addToRegistry( OSDictionary *propTable, OSObject *regObj, char *key,
2143 bool doRelease = true )
2144{
2145 bool rc;
2146
2147 if ( regObj == NULL )
2148 {
2149 return false;
2150 }
2151
2152 rc = propTable->setObject( key, regObj );
2153
2154 if ( doRelease )
2155 {
2156 // If 'doRelease' is true, then a reference count is consumed.
2157 regObj->release();
2158 }
2159
2160 return rc;
2161}
2162
2163
2164/*
2165 *
2166 *
2167 *
2168 */
2169bool IOATAStandardDevice::matchPropertyTable(OSDictionary * table)
2170{
2171 return( controller->matchNubWithPropertyTable( this, table ));
2172}
2173
2174
2175/*
2176 *
2177 *
2178 *
2179 */
2180IOService *IOATAStandardDevice::matchLocation(IOService * client)
2181{
2182 return this;
2183}
2184
2185
2186/*
2187 *
2188 *
2189 *
2190 */
2191void IOATAStandardDevice::stripBlanks( char *d, char *s, UInt32 l )
2192{
2193 char *p, c;
2194
2195 for ( p = d, c = *s; l && c ; l--)
2196 {
2197 c = (*d++ = *s++);
2198 if ( c != ' ' )
2199 {
2200 p = d;
2201 }
2202 }
2203 *p = 0;
2204}
2205
2206/*
2207 *
2208 *
2209 */
2210void IOATAStandardDevice::endianConvertData( void *data, void *endianTable )
2211{
2212 EndianTable *t;
2213
2214 union EndianPtr
2215 {
2216 void *voidPtr;
2217 UInt8 *bytePtr;
2218 UInt16 *shortPtr;
2219 UInt32 *longPtr;
2220 UInt64 *longlongPtr;
2221 } p;
2222
2223 UInt32 i,j;
2224
2225 p.voidPtr = data;
2226
2227 t = (EndianTable *)endianTable;
2228
2229 for ( ; t->type; t++ )
2230 {
2231 i = t->size/t->type;
2232
2233 switch ( t->type )
2234 {
2235
2236 /* Note:
2237 *
2238 * The ATA standard defines identify strings as arrays of short ints,
2239 * with the left-most character of the string as the most significant
2240 * byte of the short int. Strings are not normally affected by the host
2241 * endianess. However, the way ATA defines strings would cause strings
2242 * to appear byte reversed. We do a manditory short int byte-swap here,
2243 * although strictly speaking this is not an endian issue.
2244 *
2245 */
2246 case sizeof(UInt8):
2247 for ( j = 0; j < i/2; j++ )
2248 {
2249 *p.shortPtr++ = OSSwapInt16(*p.shortPtr);
2250 }
2251
2252 break;
2253
2254 case sizeof(UInt16):
2255 for ( j = 0; j < i; j++ )
2256 {
2257 *p.shortPtr++ = OSSwapLittleToHostInt16(*p.shortPtr);
2258 }
2259 break;
2260
2261 case sizeof(UInt32):
2262 for ( j = 0; j < i; j++ )
2263 {
2264 *p.longPtr++ = OSSwapLittleToHostInt32(*p.longPtr);
2265 }
2266 break;
2267
2268 case sizeof(UInt64):
2269 for ( j = 0; j < i; j++ )
2270 {
2271 *p.longlongPtr++ = OSSwapLittleToHostInt64(*p.longlongPtr);
2272 }
2273 break;
2274
2275 default:
2276 ;
2277 }
2278 }
2279}
2280
2281/*
2282 *
2283 *
2284 *
2285 */
2286IOATACommand *IOATAStandardDevice::allocCommand( IOATADevice *, UInt32 clientDataSize )
2287{
2288 return (IOATAStandardCommand *) allocCommand( kIOATAStandardDevice, clientDataSize );
2289}
2290
2291IOCDBCommand *IOATAStandardDevice::allocCommand( IOCDBDevice *, UInt32 clientDataSize )
2292{
2293 return (IOCDBCommand *) allocCommand( kIOATAStandardDevice, clientDataSize );
2294}
2295
2296IOATAStandardCommand *IOATAStandardDevice::allocCommand( IOATAStandardDevice *, UInt32 clientDataSize )
2297{
2298 IOATAStandardCommand *cmd;
2299
2300 if ( (cmd = controller->allocCommand( clientDataSize )) )
2301 {
2302 cmd->device = this;
2303 }
2304 return cmd;
2305}
2306
2307
2308/*
2309 *
2310 *
2311 */
2312IOWorkLoop *IOATAStandardDevice::getWorkLoop() const
2313{
2314 return controller->workLoop;
2315}
2316
2317
2318/*
2319 *
2320 *
2321 *
2322 */
2323bool IOATAStandardDevice::open( IOService *forClient, IOOptionBits options, void *arg )
2324{
2325 if ( client != 0 ) return false;
2326
2327 client = forClient;
2328
2329 return super::open( forClient, options, arg );
2330}
2331
2332/*
2333 *
2334 *
2335 *
2336 */
2337void IOATAStandardDevice::close( IOService *forClient, IOOptionBits options )
2338{
2339 client = 0;
2340
2341 return super::close( forClient, options );
2342}
2343
2344/*
2345 *
2346 *
2347 *
2348 */
2349void IOATAStandardDevice::free()
2350{
2351 if ( deviceGate != 0 )
2352 {
2353 controller->workLoop->removeEventSource( deviceGate );
2354 deviceGate->release();
2355 }
2356
2357 if ( reqSenseCmd != 0 ) reqSenseCmd->release();
2358 if ( abortCmd != 0 ) abortCmd->release();
2359 if ( cancelCmd != 0 ) cancelCmd->release();
2360 if ( probeCmd != 0 ) probeCmd->release();
2361
2362 if ( tagArray != 0 ) IOFree( tagArray, tagArraySize );
2363 if ( inquiryData != 0 ) IOFree( inquiryData, inquiryDataSize );
2364 if ( devicePrivateData != 0 ) IOFreeContiguous( devicePrivateData, controller->controllerInfo.devicePrivateDataSize );
2365 if ( clientSem != 0 ) IORWLockFree( clientSem );
2366
2367 super::free();
2368}
2369
2370