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 *	IOATABusCommand.cpp
26 *
27 */
28
29
30#include <IOKit/IOTypes.h>
31#include <IOKit/IOSyncer.h>
32#include "IOATATypes.h"
33#include "IOATABusCommand.h"
34
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
49#define super IOATACommand
50
51OSDefineMetaClassAndStructors( IOATABusCommand, IOATACommand )
52    OSMetaClassDefineReservedUnused(IOATABusCommand, 0);
53    OSMetaClassDefineReservedUnused(IOATABusCommand, 1);
54    OSMetaClassDefineReservedUnused(IOATABusCommand, 2);
55    OSMetaClassDefineReservedUnused(IOATABusCommand, 3);
56    OSMetaClassDefineReservedUnused(IOATABusCommand, 4);
57    OSMetaClassDefineReservedUnused(IOATABusCommand, 5);
58    OSMetaClassDefineReservedUnused(IOATABusCommand, 6);
59    OSMetaClassDefineReservedUnused(IOATABusCommand, 7);
60    OSMetaClassDefineReservedUnused(IOATABusCommand, 8);
61    OSMetaClassDefineReservedUnused(IOATABusCommand, 9);
62    OSMetaClassDefineReservedUnused(IOATABusCommand, 10);
63    OSMetaClassDefineReservedUnused(IOATABusCommand, 11);
64    OSMetaClassDefineReservedUnused(IOATABusCommand, 12);
65    OSMetaClassDefineReservedUnused(IOATABusCommand, 13);
66    OSMetaClassDefineReservedUnused(IOATABusCommand, 14);
67    OSMetaClassDefineReservedUnused(IOATABusCommand, 15);
68    OSMetaClassDefineReservedUnused(IOATABusCommand, 16);
69    OSMetaClassDefineReservedUnused(IOATABusCommand, 17);
70    OSMetaClassDefineReservedUnused(IOATABusCommand, 18);
71    OSMetaClassDefineReservedUnused(IOATABusCommand, 19);
72    OSMetaClassDefineReservedUnused(IOATABusCommand, 20);
73
74
75/*-----------------------------------------------------------------------------
76 *  Static allocator.
77 *
78 *-----------------------------------------------------------------------------*/
79IOATABusCommand*
80IOATABusCommand::allocateCmd(void)
81{
82	IOATABusCommand* cmd = new IOATABusCommand;
83
84	if( cmd == 0L)
85		return 0L;
86
87
88	if( ! cmd->init() )
89	{
90		cmd->free();
91		return 0L;
92	}
93
94	return cmd;
95
96}
97
98
99/*-----------------------------------------------------------------------------
100 *
101 *
102 *-----------------------------------------------------------------------------*/
103bool
104IOATABusCommand::init()
105{
106	if( ! super::init() )
107		return false;
108
109	zeroCommand();
110
111	return true;
112
113}
114
115/*-----------------------------------------------------------------------------
116 *
117 *
118 *-----------------------------------------------------------------------------*/
119void
120IOATABusCommand::zeroCommand(void)
121{
122	queue_init( &queueChain );
123	state = 0;
124	syncer = 0L;
125
126	super::zeroCommand();
127
128}
129
130
131
132/*-----------------------------------------------------------------------------
133 *
134 *
135 *-----------------------------------------------------------------------------*/
136 // return the command opcode
137ataOpcode
138IOATABusCommand::getOpcode( void )
139{
140
141	return _opCode;
142
143}
144
145
146/*-----------------------------------------------------------------------------
147 *
148 *
149 *-----------------------------------------------------------------------------*/
150	// get the command flags
151ataFlags
152IOATABusCommand::getFlags ( void )
153{
154
155	return (ataFlags) _flags;
156
157}
158
159/*-----------------------------------------------------------------------------
160 *
161 *
162 *-----------------------------------------------------------------------------*/
163ataRegMask
164IOATABusCommand::getRegMask( void )
165{
166	return _regMask;
167
168}
169
170
171
172/*-----------------------------------------------------------------------------
173 *
174 *
175 *-----------------------------------------------------------------------------*/
176	// return the unit id (0 master, 1 slave)
177ataUnitID
178IOATABusCommand::getUnit( void )
179{
180
181	return _unit;
182
183}
184
185
186/*-----------------------------------------------------------------------------
187 *
188 *
189 *-----------------------------------------------------------------------------*/
190	// return the timeout value for this command
191UInt32
192IOATABusCommand::getTimeoutMS (void )
193{
194
195	return _timeoutMS;
196
197}
198
199
200/*-----------------------------------------------------------------------------
201 *
202 *
203 *-----------------------------------------------------------------------------*/
204	// return the callback pointer
205IOATACompletionFunction*
206IOATABusCommand::getCallbackPtr (void )
207{
208
209	return _callback;
210
211}
212
213
214/*-----------------------------------------------------------------------------
215 *
216 *
217 *-----------------------------------------------------------------------------*/
218	// call the completion callback function
219void
220IOATABusCommand::executeCallback(void)
221{
222	_inUse = false;
223
224	if(_callback != 0L)
225	{
226		 (*_callback)(this);
227
228	} else if( syncer != 0L ) {
229
230		syncer->signal();
231		syncer = 0L;
232
233	}
234
235
236}
237
238/*-----------------------------------------------------------------------------
239 * get the number of bytes between intervening interrupts for this transfer.
240 *
241 *-----------------------------------------------------------------------------*/
242IOByteCount
243IOATABusCommand::getTransferChunkSize(void)
244{
245
246	return _logicalChunkSize;
247
248}
249
250ataTaskFile*
251IOATABusCommand::getTaskFilePtr(void)
252{
253	return &(_taskFile.taskFile) ;
254}
255
256UInt16
257IOATABusCommand::getPacketSize(void)
258{
259	return _packet.atapiPacketSize;
260}
261
262
263UInt16*
264IOATABusCommand::getPacketData(void)
265{
266	return _packet.atapiCommandByte;
267}
268
269IOByteCount
270IOATABusCommand::getByteCount (void)
271{
272
273	return _byteCount;
274}
275
276
277IOByteCount
278IOATABusCommand::getPosition (void)
279{
280
281	return _position;
282
283}
284
285
286
287IOMemoryDescriptor*
288IOATABusCommand::getBuffer ( void)
289{
290	return _desc;
291}
292
293
294void
295IOATABusCommand::setActualTransfer ( IOByteCount bytesTransferred )
296{
297	_actualByteCount = bytesTransferred;
298}
299
300void
301IOATABusCommand::setResult( IOReturn inResult)
302{
303
304	_result = inResult;
305}
306
307
308void
309IOATABusCommand::setCommandInUse( bool inUse /* = true */)
310{
311
312	_inUse = inUse;
313
314}
315
316#pragma mark -- IOATABusCommand64 --
317
318#undef super
319
320#define super IOATABusCommand
321
322OSDefineMetaClassAndStructors( IOATABusCommand64, super )
323
324/*-----------------------------------------------------------------------------
325 *  Static allocator.
326 *
327 *-----------------------------------------------------------------------------*/
328IOATABusCommand64*
329IOATABusCommand64::allocateCmd32(void)
330{
331	IOATABusCommand64* cmd = new IOATABusCommand64;
332
333	if( cmd == 0L)
334		return 0L;
335
336
337	if( ! cmd->init() )
338	{
339		cmd->free();
340		return 0L;
341	}
342
343
344	return cmd;
345
346}
347
348/*-----------------------------------------------------------------------------
349 *
350 *
351 *-----------------------------------------------------------------------------*/
352bool
353IOATABusCommand64::init()
354{
355	if( ! super::init() )
356		return false;
357
358	zeroCommand();
359
360	_dmaCmd = IODMACommand::withSpecification(IODMACommand::OutputHost32,
361								32,
362								0x10000,
363								IODMACommand::kMapped,
364								512 * 2048,
365								2);
366
367
368	if( ! _dmaCmd )
369	{
370		return false;
371	}
372
373
374	return true;
375
376}
377
378/*-----------------------------------------------------------------------------
379 *
380 *
381 *-----------------------------------------------------------------------------*/
382void
383IOATABusCommand64::zeroCommand(void)
384{
385	if(_dmaCmd != NULL)
386	{
387		if( _dmaCmd->getMemoryDescriptor() != NULL)
388		{
389			_dmaCmd->clearMemoryDescriptor();
390		}
391	}
392
393	super::zeroCommand();
394
395}
396
397/*-----------------------------------------------------------------------------
398 *
399 *
400 *-----------------------------------------------------------------------------*/
401
402void
403IOATABusCommand64::free()
404{
405
406	if( _dmaCmd != NULL )
407	{
408		_dmaCmd->clearMemoryDescriptor();
409		_dmaCmd->release();
410		_dmaCmd = NULL;
411	}
412
413	super::free();
414
415}
416
417void
418IOATABusCommand64::setBuffer ( IOMemoryDescriptor* inDesc)
419{
420
421	super::setBuffer( inDesc );
422
423}
424
425void
426IOATABusCommand64::executeCallback(void)
427{
428	if( _dmaCmd != NULL
429		&& _desc != NULL
430		&& ( _flags & mATAFlagUseDMA ) )
431	{
432		_dmaCmd->complete();
433	}
434
435	_dmaCmd->clearMemoryDescriptor();
436
437	super::executeCallback();
438
439}
440
441
442IODMACommand*
443IOATABusCommand64::GetDMACommand( void )
444{
445
446	return _dmaCmd;
447
448}
449
450void
451IOATABusCommand64::setCommandInUse( bool inUse /* = true */)
452{
453
454	if( inUse )
455	{
456
457		if( _dmaCmd != NULL
458			&& _desc != NULL
459			&& ( _flags & mATAFlagUseDMA ) )
460		{
461			_dmaCmd->setMemoryDescriptor( _desc, true );
462
463
464		}
465
466
467	}
468
469	super::setCommandInUse( inUse);
470
471}
472