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