1/*
2 * Copyright (c) 2000-2008 Apple 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/*
24 *
25 *	IOATACommand.cpp
26 *
27 */
28
29
30#include<IOKit/IOTypes.h>
31#include <IOKit/IOLib.h>
32
33#include"IOATATypes.h"
34#include"IOATACommand.h"
35
36#ifdef DLOG
37#undef DLOG
38#endif
39
40#ifdef  ATA_DEBUG
41#define DLOG(fmt, args...)  IOLog(fmt, ## args)
42#else
43#define DLOG(fmt, args...)
44#endif
45
46//---------------------------------------------------------------------------
47
48#define super IOCommand
49
50OSDefineMetaClass( IOATACommand, IOCommand )
51OSDefineAbstractStructors( IOATACommand, IOCommand )
52
53    OSMetaClassDefineReservedUsed(IOATACommand, 0)  //setendResult()
54    OSMetaClassDefineReservedUsed(IOATACommand, 1) // getExtendedLBAPtr()
55    OSMetaClassDefineReservedUnused(IOATACommand, 2);
56    OSMetaClassDefineReservedUnused(IOATACommand, 3);
57    OSMetaClassDefineReservedUnused(IOATACommand, 4);
58    OSMetaClassDefineReservedUnused(IOATACommand, 5);
59    OSMetaClassDefineReservedUnused(IOATACommand, 6);
60    OSMetaClassDefineReservedUnused(IOATACommand, 7);
61    OSMetaClassDefineReservedUnused(IOATACommand, 8);
62    OSMetaClassDefineReservedUnused(IOATACommand, 9);
63    OSMetaClassDefineReservedUnused(IOATACommand, 10);
64    OSMetaClassDefineReservedUnused(IOATACommand, 11);
65    OSMetaClassDefineReservedUnused(IOATACommand, 12);
66    OSMetaClassDefineReservedUnused(IOATACommand, 13);
67    OSMetaClassDefineReservedUnused(IOATACommand, 14);
68    OSMetaClassDefineReservedUnused(IOATACommand, 15);
69    OSMetaClassDefineReservedUnused(IOATACommand, 16);
70    OSMetaClassDefineReservedUnused(IOATACommand, 17);
71    OSMetaClassDefineReservedUnused(IOATACommand, 18);
72    OSMetaClassDefineReservedUnused(IOATACommand, 19);
73    OSMetaClassDefineReservedUnused(IOATACommand, 20);
74
75
76
77/*-----------------------------------------------------------------------------
78 *
79 *
80 *-----------------------------------------------------------------------------*/
81bool
82IOATACommand::init()
83{
84	fExpansionData = (ExpansionData*) IOMalloc( sizeof( ExpansionData) );
85	fExpansionData->extLBA = IOExtendedLBA::createIOExtendedLBA( this );
86
87	if( ! super::init() || fExpansionData == NULL || fExpansionData->extLBA == NULL )
88		return false;
89
90	zeroCommand();
91
92	return true;
93
94}
95
96/*---------------------------------------------------------------------------
97 *	free() - the pseudo destructor. Let go of what we don't need anymore.
98 *
99 *
100 ---------------------------------------------------------------------------*/
101void
102IOATACommand::free()
103{
104
105	getExtendedLBA()->release();
106	IOFree( fExpansionData, sizeof( ExpansionData) );
107	super::free();
108
109}
110/*-----------------------------------------------------------------------------
111 *
112 *
113 *-----------------------------------------------------------------------------*/
114void
115IOATACommand::zeroCommand(void)
116{
117
118	_opCode	= kATANoOp;
119	_flags = 0;
120	_unit = kATAInvalidDeviceID;
121	_timeoutMS = 0;
122	_desc = 0L;
123	_position = 0;
124	_byteCount = 0;
125	_regMask = (ataRegMask) 0;
126	_callback = 0L ;
127 	_result = 0;
128	_actualByteCount = 0;
129 	_status = 0;
130 	_errReg = 0;
131	_logicalChunkSize = kATADefaultSectorSize;
132 	_inUse = false;
133
134	_taskFile.ataDataRegister = 0x0000;
135	_taskFile.ataAltSDevCReg = 0x00;
136	_taskFile.taskFile.ataTFFeatures = 0;
137	_taskFile.taskFile.ataTFCount  = 0;
138	_taskFile.taskFile.ataTFSector  = 0;
139	_taskFile.taskFile.ataTFCylLo  = 0;
140	_taskFile.taskFile.ataTFCylHigh  = 0;
141	_taskFile.taskFile.ataTFSDH  = 0;
142	_taskFile.taskFile.ataTFCommand  = 0;
143
144
145	for( int i = 0; i < 16 ; i += 2 )
146	{
147		_packet.atapiCommandByte[ i ] = 0x000;
148	}
149
150	_packet.atapiPacketSize = 0;
151
152	getExtendedLBA()->zeroData();
153
154}
155
156
157/*-----------------------------------------------------------------------------
158 *
159 *
160 *-----------------------------------------------------------------------------*/
161void
162IOATACommand::setOpcode( ataOpcode inCode)
163{
164
165	_opCode = inCode;
166
167}
168
169
170/*-----------------------------------------------------------------------------
171 *
172 *
173 *-----------------------------------------------------------------------------*/
174
175void
176IOATACommand::setFlags( UInt32 inFlags)
177{
178
179	_flags = inFlags;
180
181}
182
183
184/*-----------------------------------------------------------------------------
185 *
186 *
187 *-----------------------------------------------------------------------------*/
188
189void
190IOATACommand::setUnit( ataUnitID inUnit)
191{
192
193	_unit = inUnit;
194
195}
196
197
198/*-----------------------------------------------------------------------------
199 *
200 *
201 *-----------------------------------------------------------------------------*/
202
203void
204IOATACommand::setTimeoutMS( UInt32 inMS)
205{
206
207	_timeoutMS = inMS;
208
209}
210
211
212/*-----------------------------------------------------------------------------
213 *
214 *
215 *-----------------------------------------------------------------------------*/
216
217void
218IOATACommand::setCallbackPtr (IOATACompletionFunction* inCompletion)
219{
220
221	_callback = inCompletion;
222
223}
224
225
226/*-----------------------------------------------------------------------------
227 *
228 *
229 *-----------------------------------------------------------------------------*/
230void
231IOATACommand::setRegMask( ataRegMask mask)
232{
233
234	_regMask = mask;
235
236}
237
238/*-----------------------------------------------------------------------------
239 *
240 *
241 *-----------------------------------------------------------------------------*/
242
243void
244IOATACommand::setBuffer ( IOMemoryDescriptor* inDesc)
245{
246
247	_desc = inDesc;
248
249}
250
251
252
253/*-----------------------------------------------------------------------------
254 *
255 *
256 *-----------------------------------------------------------------------------*/
257
258void
259IOATACommand::setPosition (IOByteCount fromPosition)
260{
261
262	_position = fromPosition;
263
264}
265
266
267/*-----------------------------------------------------------------------------
268 *
269 *
270 *-----------------------------------------------------------------------------*/
271
272void
273IOATACommand::setByteCount (IOByteCount numBytes)
274{
275
276	_byteCount = numBytes;
277
278}
279
280/*-----------------------------------------------------------------------------
281 *
282 *
283 *-----------------------------------------------------------------------------*/
284
285void
286IOATACommand::setTransferChunkSize (IOByteCount numBytes)
287{
288
289	_logicalChunkSize = numBytes;
290
291}
292
293
294
295/*-----------------------------------------------------------------------------
296 *
297 *
298 *-----------------------------------------------------------------------------*/
299
300void
301IOATACommand::setFeatures( UInt8 in)
302{
303
304	_taskFile.taskFile.ataTFFeatures = in;
305
306}
307
308
309/*-----------------------------------------------------------------------------
310 *
311 *
312 *-----------------------------------------------------------------------------*/
313
314UInt8
315IOATACommand::getErrorReg (void )
316{
317
318	return _taskFile.taskFile.ataTFFeatures;
319
320}
321
322
323/*-----------------------------------------------------------------------------
324 *
325 *
326 *-----------------------------------------------------------------------------*/
327
328void
329IOATACommand::setSectorCount( UInt8 in)
330{
331
332	_taskFile.taskFile.ataTFCount = in;
333
334}
335
336
337/*-----------------------------------------------------------------------------
338 *
339 *
340 *-----------------------------------------------------------------------------*/
341
342UInt8
343IOATACommand::getSectorCount (void )
344{
345
346	return  _taskFile.taskFile.ataTFCount;
347
348}
349
350
351/*-----------------------------------------------------------------------------
352 *
353 *
354 *-----------------------------------------------------------------------------*/
355
356void
357IOATACommand::setSectorNumber( UInt8 in)
358{
359
360	_taskFile.taskFile.ataTFSector = in;
361
362}
363
364
365/*-----------------------------------------------------------------------------
366 *
367 *
368 *-----------------------------------------------------------------------------*/
369
370UInt8
371IOATACommand::getSectorNumber (void )
372{
373
374	return _taskFile.taskFile.ataTFSector;
375
376}
377
378
379/*-----------------------------------------------------------------------------
380 *
381 *
382 *-----------------------------------------------------------------------------*/
383
384void
385IOATACommand::setCylLo ( UInt8 in)
386{
387
388	_taskFile.taskFile.ataTFCylLo = in;
389
390}
391
392
393/*-----------------------------------------------------------------------------
394 *
395 *
396 *-----------------------------------------------------------------------------*/
397
398
399UInt8
400IOATACommand::getCylLo (void )
401{
402
403	return _taskFile.taskFile.ataTFCylLo;
404
405}
406
407/*-----------------------------------------------------------------------------
408 *
409 *
410 *-----------------------------------------------------------------------------*/
411void
412IOATACommand::setCylHi( UInt8 in)
413{
414
415	_taskFile.taskFile.ataTFCylHigh = in;
416
417}
418
419
420/*-----------------------------------------------------------------------------
421 *
422 *
423 *-----------------------------------------------------------------------------*/
424
425UInt8
426IOATACommand::getCylHi (void )
427{
428
429	return _taskFile.taskFile.ataTFCylHigh;
430
431}
432
433
434/*-----------------------------------------------------------------------------
435 *
436 *
437 *-----------------------------------------------------------------------------*/
438
439void
440IOATACommand::setDevice_Head( UInt8 in)
441{
442
443	_taskFile.taskFile.ataTFSDH = in;
444
445}
446
447
448/*-----------------------------------------------------------------------------
449 *
450 *
451 *-----------------------------------------------------------------------------*/
452
453UInt8
454IOATACommand::getDevice_Head (void )
455{
456
457	return _taskFile.taskFile.ataTFSDH;
458
459}
460
461
462/*-----------------------------------------------------------------------------
463 *
464 *
465 *-----------------------------------------------------------------------------*/
466
467void
468IOATACommand::setCommand ( UInt8 in)
469{
470
471	_taskFile.taskFile.ataTFCommand = in;
472
473}
474
475
476/*-----------------------------------------------------------------------------
477 *
478 *
479 *-----------------------------------------------------------------------------*/
480
481UInt8
482IOATACommand::getStatus (void )
483{
484
485	return _taskFile.taskFile.ataTFCommand;
486
487}
488
489
490/*-----------------------------------------------------------------------------
491 *
492 *
493 *-----------------------------------------------------------------------------*/
494
495
496
497IOReturn
498IOATACommand::setPacketCommand( UInt16 packetSizeBytes, UInt8* packetBytes)
499{
500//	IOLog("ATACommand::setPacket size %d  bytePtr = %lx\n", packetSizeBytes, packetBytes);
501
502	if( ( packetSizeBytes > 16 ) || (packetBytes == 0L))
503		return -1;
504
505	UInt8* cmdBytes = (UInt8*) _packet.atapiCommandByte;
506
507	for( int i = 0; i < packetSizeBytes; i++ )
508	{
509		cmdBytes[ i ] = packetBytes[ i ];
510	}
511
512	_packet.atapiPacketSize = packetSizeBytes;
513
514	return kATANoErr;
515
516}
517
518
519
520/*-----------------------------------------------------------------------------
521 *
522 *
523 *-----------------------------------------------------------------------------*/
524
525void
526IOATACommand::setDataReg ( UInt16 in)
527{
528
529	_taskFile.ataDataRegister = in;
530
531}
532
533
534/*-----------------------------------------------------------------------------
535 *
536 *
537 *-----------------------------------------------------------------------------*/
538
539
540UInt16
541IOATACommand::getDataReg (void )
542{
543
544	return _taskFile.ataDataRegister;
545
546}
547
548
549/*-----------------------------------------------------------------------------
550 *
551 *
552 *-----------------------------------------------------------------------------*/
553
554
555
556void
557IOATACommand::setControl ( UInt8 in)
558{
559
560	_taskFile.ataAltSDevCReg = in;
561
562}
563
564
565/*-----------------------------------------------------------------------------
566 *
567 *
568 *-----------------------------------------------------------------------------*/
569
570
571UInt8
572IOATACommand::getAltStatus (void )
573{
574
575	return _taskFile.ataAltSDevCReg;
576
577}
578
579
580/*-----------------------------------------------------------------------------
581 *
582 *
583 *-----------------------------------------------------------------------------*/
584
585
586
587
588IOReturn
589IOATACommand::getResult (void)
590{
591
592	return _result;
593
594}
595
596
597/*-----------------------------------------------------------------------------
598 *
599 *
600 *-----------------------------------------------------------------------------*/
601
602
603IOMemoryDescriptor*
604IOATACommand::getBuffer ( void )
605{
606
607	return _desc;
608
609}
610
611
612/*-----------------------------------------------------------------------------
613 *
614 *
615 *-----------------------------------------------------------------------------*/
616
617
618IOByteCount
619IOATACommand::getActualTransfer ( void )
620{
621
622	return _actualByteCount;
623
624}
625
626
627/*-----------------------------------------------------------------------------
628 *
629 *
630 *-----------------------------------------------------------------------------*/
631
632
633UInt8
634IOATACommand::getEndStatusReg (void)
635{
636
637	return _status;
638
639}
640
641
642/*-----------------------------------------------------------------------------
643 *
644 *
645 *-----------------------------------------------------------------------------*/
646
647
648
649UInt8
650IOATACommand::getEndErrorReg( void )
651{
652
653	return _errReg;
654
655}
656
657
658/*-----------------------------------------------------------------------------
659 * returns true if IOATAController is using the command.
660 *
661 *-----------------------------------------------------------------------------*/
662
663bool
664IOATACommand::getCommandInUse( void )
665{
666
667
668	return _inUse;
669
670
671}
672
673/*-----------------------------------------------------------------------------
674 *
675 *
676 *-----------------------------------------------------------------------------*/
677
678IOReturn
679IOATACommand::setLBA28( UInt32 lba, ataUnitID inUnit)
680{
681	// param check the inputs
682
683	if( (lba & 0xF0000000) != 0x00000000
684		|| !(inUnit == kATADevice0DeviceID || inUnit == kATADevice1DeviceID) )
685	{
686		//param out of range
687		return -1;
688	}
689
690
691	setSectorNumber( (lba &      0xFF) );  //LBA 7:0
692	setCylLo( ((lba &          0xFF00) >> 8) );	// LBA 15:8
693	setCylHi( ((lba &      0x00FF0000) >> 16) );  // LBA 23:16
694	setDevice_Head(((lba & 0x0F000000) >> 24 ) |  mATALBASelect |( ((UInt8) inUnit) << 4));  //LBA 27:24
695
696	return kATANoErr;
697
698}
699
700void
701IOATACommand::setEndResult(UInt8 inStatus, UInt8 endError  )
702{
703	_status = inStatus;
704	_errReg = endError;
705}
706
707
708
709IOExtendedLBA*
710IOATACommand::getExtendedLBA(void)
711{
712
713	return fExpansionData->extLBA;
714
715}
716
717
718
719////////////////////////////////////////////////////////////////////////
720#pragma mark IOExtendedLBA
721#undef super
722
723#define super OSObject
724OSDefineMetaClassAndStructors( IOExtendedLBA, OSObject )
725
726OSMetaClassDefineReservedUnused(IOExtendedLBA, 0)
727OSMetaClassDefineReservedUnused(IOExtendedLBA, 1)
728OSMetaClassDefineReservedUnused(IOExtendedLBA, 2);
729OSMetaClassDefineReservedUnused(IOExtendedLBA, 3);
730OSMetaClassDefineReservedUnused(IOExtendedLBA, 4);
731OSMetaClassDefineReservedUnused(IOExtendedLBA, 5);
732OSMetaClassDefineReservedUnused(IOExtendedLBA, 6);
733OSMetaClassDefineReservedUnused(IOExtendedLBA, 7);
734OSMetaClassDefineReservedUnused(IOExtendedLBA, 8);
735OSMetaClassDefineReservedUnused(IOExtendedLBA, 9);
736OSMetaClassDefineReservedUnused(IOExtendedLBA, 10);
737
738
739
740
741
742IOExtendedLBA*
743IOExtendedLBA::createIOExtendedLBA(IOATACommand* inOwner)
744{
745
746	IOExtendedLBA* me = new IOExtendedLBA;
747	if( me == NULL)
748	{
749		return NULL;
750	}
751
752	me->owner = inOwner;
753	me->zeroData();
754
755	return me;
756
757}
758
759
760
761void
762IOExtendedLBA::setLBALow16( UInt16 inLBALow)
763{
764	lbaLow =  inLBALow ;
765
766}
767
768
769UInt16
770IOExtendedLBA::getLBALow16 (void)
771{
772
773	return lbaLow ;
774
775}
776
777void
778IOExtendedLBA::setLBAMid16 (UInt16 inLBAMid)
779{
780
781	lbaMid =  inLBAMid ;
782}
783
784
785UInt16
786IOExtendedLBA::getLBAMid16( void )
787{
788
789	return lbaMid;
790
791
792}
793
794void
795IOExtendedLBA::setLBAHigh16( UInt16 inLBAHigh )
796{
797	lbaHigh =  inLBAHigh ;
798}
799
800
801UInt16
802IOExtendedLBA::getLBAHigh16( void )
803{
804
805	return lbaHigh;
806
807}
808
809void
810IOExtendedLBA::setSectorCount16( UInt16 inSectorCount )
811{
812
813	sectorCount =  inSectorCount ;
814
815}
816
817UInt16
818IOExtendedLBA::getSectorCount16( void )
819{
820	return sectorCount;
821}
822
823void
824IOExtendedLBA::setFeatures16( UInt16 inFeatures )
825{
826	features =  inFeatures;
827}
828
829UInt16
830IOExtendedLBA::getFeatures16( void )
831{
832
833	return features;
834
835}
836
837void
838IOExtendedLBA::setDevice( UInt8 inDevice )
839{
840
841	device = inDevice;
842
843}
844
845
846UInt8
847IOExtendedLBA::getDevice( void )
848{
849
850
851	return device;
852
853}
854
855void
856IOExtendedLBA::setCommand( UInt8 inCommand )
857{
858
859
860	command = inCommand;
861
862}
863
864
865UInt8
866IOExtendedLBA::getCommand( void )
867{
868
869	return command;
870}
871
872
873
874void
875IOExtendedLBA::setExtendedLBA( UInt32 inLBAHi, UInt32 inLBALo, ataUnitID inUnit, UInt16 extendedCount, UInt8 extendedCommand )
876{
877
878	UInt8 lba7, lba15, lba23, lba31, lba39, lba47;
879	lba7 = (inLBALo & 0xff);
880	lba15 = (inLBALo & 0xff00) >> 8;
881	lba23 = (inLBALo & 0xff0000) >> 16;
882	lba31 = (inLBALo & 0xff000000) >> 24;
883	lba39 = (inLBAHi & 0xff);
884	lba47 = (inLBAHi & 0xff00) >> 8;
885
886	setLBALow16(  lba7 | (lba31 << 8) );
887	setLBAMid16(  lba15 | (lba39 << 8));
888	setLBAHigh16(  lba23 | (lba47 << 8));
889
890	setSectorCount16( extendedCount );
891	setCommand( extendedCommand );
892	setDevice(   mATALBASelect |( ((UInt8) inUnit) << 4)); // set the LBA bit and device select bits. The rest are reserved in extended addressing.
893
894}
895
896void
897IOExtendedLBA::getExtendedLBA( UInt32* outLBAHi, UInt32* outLBALo )
898{
899
900
901
902	*outLBALo = (getLBALow16() & 0xff) | ( (getLBAMid16() & 0xff) << 8) | ((getLBAHigh16() & 0xff) << 16) | ((getLBALow16() & 0xff00) << 16) ;
903
904	*outLBAHi = (getLBAHigh16() & 0xff00) | ((getLBAMid16() & 0xff00) >> 8) ;
905
906}
907
908void
909IOExtendedLBA::zeroData(void)
910{
911	lbaLow = lbaMid = lbaHigh = sectorCount = features = device = command = 0;
912}
913
914
915