This repository has been archived by the owner on Jul 21, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathIOATACommand.h
478 lines (383 loc) · 16.3 KB
/
IOATACommand.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
/*
* Copyright (c) 1998-2008 Apple Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* The contents of this file constitute Original Code as defined in and
* are subject to the Apple Public Source License Version 1.1 (the
* "License"). You may not use this file except in compliance with the
* License. Please obtain a copy of the License at
* http://www.apple.com/publicsource and read it before using this file.
*
* This Original Code and all software distributed under the License are
* distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
* License for the specific language governing rights and limitations
* under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
*
* IOATACommand.h
*
*/
#ifndef _IOATACOMMAND_H
#define _IOATACOMMAND_H
#include <libkern/c++/OSObject.h>
#include <IOKit/IOTypes.h>
#include <IOKit/IOMemoryDescriptor.h>
#include <IOKit/IOCommand.h>
#include "IOATATypes.h"
class IOExtendedLBA;
class IOATACommand;
/*! @typedef IOATACompletionFunction callback function for ATA disk devices.
*/
typedef void (IOATACompletionFunction)(IOATACommand* command );
/*!
@class IOATACommand
@discussion
Command structure superclass, created and freed only by IOATADevice objects
populated by disk device drivers with command parameters
then submitted for operation to their IOATADevice provider for execution.
IOATACommand is a virtual class, a concrete subclass contains the methods and fields needed
by IOATAControllers. Subclasses may be specific to particular controller hardware.
Disk device drivers will only have visibility to this interface and may not subclass this object.
Disk device drivers should instead make use of the void* refcon field which the controllers will not
touch
*/
class IOATACommand : public IOCommand {
OSDeclareAbstractStructors( IOATACommand );
public:
/*!@function zeroCommand
@abstract set to blank state, MUST call prior to re-use of this object
*/
virtual void zeroCommand(void);
/*!@function setOpcode
@abstract command opcode as defined in IOATATypes.
*/
virtual void setOpcode( ataOpcode inCode);
/*!@function setFlags
@abstract set the flags for this command, as defined in IOATATypes.
*/
virtual void setFlags( UInt32 inFlags);
/*!@function setUnit
@abstract set the unit number for this command.
*/
virtual void setUnit( ataUnitID inUnit);
/*!@function setTimeoutMS
@abstract how long to allow this command to complete, in milliseconds, once issued to
the hardware. if the time period expires, this command will return with a timeout error.
*/
virtual void setTimeoutMS( UInt32 inMs);
/*!@function setCallbackPtr
@abstract set the function pointer to call when this command completes.
*/
virtual void setCallbackPtr (IOATACompletionFunction* inCompletion);
/*!@function setRegMask
@abstract used when accessing registers or reading registers on an error result. Mask is defined
in IOATATypes.h
*/
virtual void setRegMask( ataRegMask mask);
// memory information
// Since ATA hardware is limited in the amount of bytes
// that can be transfered in a command, the disk driver shall supply
// a seperate offset and byte count per transfer.
// the offset may be any amount. The byte count must be a multiple of the
// sector size of the device, ie, N * 512 bytes for ata hard drives.
/*!@function setBuffer
@abstract set the IIOMemoryDescriptor for this transaction.
*/
virtual void setBuffer ( IOMemoryDescriptor* inDesc);
/*!@function setPosition
@abstract used to set an offset into the memory descriptor for this transfer.
*/
virtual void setPosition (IOByteCount fromPosition);
/*!@function setByteCount
@abstract set the byte count for this transaction. Should agree with the device command and the
memory descriptor in use.
*/
virtual void setByteCount (IOByteCount numBytes);
/*!@function setTransferChunkSize
@abstract set the size of transfer between intervening interrupts. necessary when doing PIO Read/Write Multiple, etc. so the controller knows when to expect an interrupt during multi-sector data transfers.
*/
virtual void setTransferChunkSize( IOByteCount chunk = kATADefaultSectorSize);
/*!@function setFeatures
@abstract Taskfile access. Registers are named in accordance with ATA Standards conventions
*/
virtual void setFeatures( UInt8 in);
/*!@function getErrorReg
@abstract Taskfile access. Registers are named in accordance with ATA Standards conventions
*/
virtual UInt8 getErrorReg (void );
/*!@function setSectorCount
@abstract Taskfile access. Registers are named in accordance with ATA Standards conventions
*/
virtual void setSectorCount( UInt8 in);
/*!@function getSectorCount
@abstract Taskfile access. Registers are named in accordance with ATA Standards conventions
*/
virtual UInt8 getSectorCount (void );
/*!@function setSectorNumber
@abstract Taskfile access. Registers are named in accordance with ATA Standards conventions
*/
virtual void setSectorNumber( UInt8 in);
/*!@function getSectorNumber
@abstract Taskfile access. Registers are named in accordance with ATA Standards conventions
*/
virtual UInt8 getSectorNumber (void );
/*!@function setCylLo
@abstract Taskfile access. Registers are named in accordance with ATA Standards conventions
*/
virtual void setCylLo ( UInt8 in);
/*!@function getCylLo
@abstract Taskfile access. Registers are named in accordance with ATA Standards conventions
*/
virtual UInt8 getCylLo (void );
/*!@function setCylHi
@abstract Taskfile access. Registers are named in accordance with ATA Standards conventions
*/
virtual void setCylHi( UInt8 in);
/*!@function getCylHi
@abstract Taskfile access. Registers are named in accordance with ATA Standards conventions
*/
virtual UInt8 getCylHi (void );
/*!@function setDevice_Head
@abstract Taskfile access. Registers are named in accordance with ATA Standards conventions
*/
virtual void setDevice_Head( UInt8 in);
/*!@function getDevice_Head
@abstract Taskfile access. Registers are named in accordance with ATA Standards conventions
*/
virtual UInt8 getDevice_Head (void );
/*!@function setCommand
@abstract Taskfile access. Registers are named in accordance with ATA Standards conventions
*/
virtual void setCommand ( UInt8 in);
/*!@function getStatus
@abstract Taskfile access. Registers are named in accordance with ATA Standards conventions
*/
virtual UInt8 getStatus (void );
/*!@function setLBA28
@abstract convenience method that sets the taskfile registers into a 28-bit LBA address, with unit selected and LBA bit set. return err if param out of range, return kIOSuccess (kATANoErr) = 0 on return if successful
*/
virtual IOReturn setLBA28( UInt32 lba, ataUnitID inUnit);
/*!@function setPacketCommand
@abstract ATAPI command packet max size is 16 bytes. Makes deep copy of data.
*/
virtual IOReturn setPacketCommand( UInt16 packetSizeBytes, UInt8* command);
// the following registers are only accessed by register access
// commands. Not by normal command dispatch where they are handled
// by the controller.
// not part of task file params. not written to device when sending commands.
virtual void setDataReg ( UInt16 in);
virtual UInt16 getDataReg (void );
// not part of taskfile. Not usually used except by controller.
virtual void setControl ( UInt8 in);
virtual UInt8 getAltStatus (void );
// return values
/*!@function getResult
@abstract IOReturn value of the result of this command. ATA family errors are defined in IOATATypes.h
*/
virtual IOReturn getResult (void);
/*!@function getBuffer
@abstract the IOMemoryDescriptor used in this transaction.
*/
virtual IOMemoryDescriptor* getBuffer ( void );
/*!@function getActualTransfer
@abstract The byte count on the ending result, as best as can be determined by the controller. May be zero, but partial transfer may have occurred on error in some cases.
*/
virtual IOByteCount getActualTransfer ( void );
/*!@function getEndStatusReg
@abstract the value of the status register on the end of the command.
*/
virtual UInt8 getEndStatusReg (void); // always returned
/*!@function getEndErrorReg
@abstract If the error bit was set in the status register, the value of the error register is returned at the end of a command.
*/
virtual UInt8 getEndErrorReg( void );
/*!@function getCommandInUse
@abstract returns true if IOATAController is still in control of the command.
*/
virtual bool getCommandInUse( void ); // returns true if IOATAController is using the command.
// for use by disk drivers, clients of IOATADevice only.
// IOATADevice and IOATAControllers shall not use this field in any manner
/*!@var refCon
@abstract for use by disk drivers, clients of IOATADevice only. IOATADevice and IOATAControllers shall not use this field in any manner.
*/
void* refCon;
/*!@var refCon2
@abstract for use by disk drivers, clients of IOATADevice only. IOATADevice and IOATAControllers shall not use this field in any manner.
*/
void* refCon2;
protected:
// < return from ATA controllers to disk drivers
// > sent to ATA controllers from disk drivers
ataOpcode _opCode; // > Command code for the controller.
UInt32 _flags; // > Flags for this command
ataRegisterImage _taskFile; // <> Taskfile + data and control registers.
ATAPICmdPacket _packet; // > ATAPI packet
ataUnitID _unit; // > Unit number
UInt32 _timeoutMS; // > timeout command in ms.
IOMemoryDescriptor* _desc; // > Buffer for data may be nil if command transfer no data
IOByteCount _position; // > Position within the descriptor for this command
IOByteCount _byteCount; // > How many bytes to transfer.
IOByteCount _logicalChunkSize; // > How many bytes between intervening interrupts (R/W Multiple)
ataRegMask _regMask; // > Which registers to write or read for reg access commands
IOATACompletionFunction* _callback; // > if nil, command is synchronous
IOReturn _result; // < result
IOByteCount _actualByteCount; // < actual bytes transfered.
UInt8 _status; // < Status register at end of command
UInt8 _errReg; // < Error register at end of command if error bit set.
bool _inUse; // < true while IOATAController has possesion of the command
virtual bool init();
protected:
/*! @struct ExpansionData
@discussion This structure will be used to expand the capablilties of the IOWorkLoop in the future.
*/
struct ExpansionData {IOExtendedLBA* extLBA; };
/*! @var reserved
Reserved for future use. (Internal use only) */
ExpansionData *fExpansionData;
// overrides
virtual void free();
private:
OSMetaClassDeclareReservedUsed(IOATACommand, 0); // set end result
OSMetaClassDeclareReservedUsed(IOATACommand, 1); // get extendedLBAPtr
OSMetaClassDeclareReservedUnused(IOATACommand, 2);
OSMetaClassDeclareReservedUnused(IOATACommand, 3);
OSMetaClassDeclareReservedUnused(IOATACommand, 4);
OSMetaClassDeclareReservedUnused(IOATACommand, 5);
OSMetaClassDeclareReservedUnused(IOATACommand, 6);
OSMetaClassDeclareReservedUnused(IOATACommand, 7);
OSMetaClassDeclareReservedUnused(IOATACommand, 8);
OSMetaClassDeclareReservedUnused(IOATACommand, 9);
OSMetaClassDeclareReservedUnused(IOATACommand, 10);
OSMetaClassDeclareReservedUnused(IOATACommand, 11);
OSMetaClassDeclareReservedUnused(IOATACommand, 12);
OSMetaClassDeclareReservedUnused(IOATACommand, 13);
OSMetaClassDeclareReservedUnused(IOATACommand, 14);
OSMetaClassDeclareReservedUnused(IOATACommand, 15);
OSMetaClassDeclareReservedUnused(IOATACommand, 16);
OSMetaClassDeclareReservedUnused(IOATACommand, 17);
OSMetaClassDeclareReservedUnused(IOATACommand, 18);
OSMetaClassDeclareReservedUnused(IOATACommand, 19);
OSMetaClassDeclareReservedUnused(IOATACommand, 20);
public:
virtual void setEndResult(UInt8 inStatus, UInt8 endError );
virtual IOExtendedLBA* getExtendedLBA(void);
};
/*!
@class IOExtendedLBA
@discussion
If 48-bit LBAs are supported, IOExtendedLBA is used to represent a 48-bit LBA.
The driver examines the ATA identify data to determine if 48-bit addressing is
supported.
*/
class IOExtendedLBA : public OSObject
{
OSDeclareDefaultStructors( IOExtendedLBA );
public:
static IOExtendedLBA* createIOExtendedLBA(IOATACommand* owner);
// terminology as established in ATA/ATAPI-6.
// for the extended LBA address
/*!@function setLBALow16
@abstract convenience method that sets the lower 16 bits of a 48-bit LBA
*/
virtual void setLBALow16( UInt16 lbaLow);
/*!@function getLBALow16
@abstract convenience method that gets the lower 16 bits of a 48-bit LBA
*/
virtual UInt16 getLBALow16 (void);
/*!@function setLBAMid16
@abstract convenience method that sets the middle 16 bits of a 48-bit LBA
*/
virtual void setLBAMid16 (UInt16 lbaMid);
/*!@function getLBAMid16
@abstract convenience method that gets the middle 16 bits of a 48-bit LBA
*/
virtual UInt16 getLBAMid16( void );
/*!@function setLBAHigh16
@abstract convenience method that sets the high 16 bits of a 48-bit LBA
*/
virtual void setLBAHigh16( UInt16 lbaHigh );
/*!@function getLBAHigh16
@abstract convenience method that gets the high 16 bits of a 48-bit LBA
*/
virtual UInt16 getLBAHigh16( void );
/*!@function setSectorCount16
@abstract Taskfile access. Registers are named in accordance with ATA Standards conventions
*/
virtual void setSectorCount16( UInt16 sectorCount );
/*!@function getSectorCount16
@abstract Taskfile access. Registers are named in accordance with ATA Standards conventions
*/
virtual UInt16 getSectorCount16( void );
/*!@function setFeatures16
@abstract Taskfile access. Registers are named in accordance with ATA Standards conventions
*/
virtual void setFeatures16( UInt16 features );
/*!@function getFeatures16
@abstract Taskfile access. Registers are named in accordance with ATA Standards conventions
*/
virtual UInt16 getFeatures16( void );
/*!@function setDevice
@abstract Taskfile access. Registers are named in accordance with ATA Standards conventions
*/
virtual void setDevice( UInt8 inDevice );
/*!@function getDevice
@abstract Taskfile access. Registers are named in accordance with ATA Standards conventions
*/
virtual UInt8 getDevice( void );
/*!@function setCommand
@abstract Taskfile access. Registers are named in accordance with ATA Standards conventions
*/
virtual void setCommand( UInt8 inCommand );
/*!@function getCommand
@abstract Taskfile access. Registers are named in accordance with ATA Standards conventions
*/
virtual UInt8 getCommand( void );
/*!@function setExtendedLBA
@abstract convenience method that sets the taskfile registers into a 48-bit LBA address, along with sector count, and unit selected and LBA bit set
*/
virtual void setExtendedLBA( UInt32 inLBAHi, UInt32 inLBALo, ataUnitID inUnit, UInt16 extendedCount, UInt8 extendedCommand);
/*!@function getExtendedLBA
@abstract convenience method that gets a 48-bit LBA
*/
virtual void getExtendedLBA( UInt32* outLBAHi, UInt32* outLBALo );
/*!@function zeroData
@abstract convenience method that zeros out the lba, sector count, features, device, and command member variables
*/
virtual void zeroData(void);
/*! @struct ExpansionData
@discussion This structure will be used to expand the capablilties in the future.
*/
struct ExpansionData { };
/*! @var reserved
Reserved for future use. (Internal use only) */
ExpansionData *reserved;
protected:
IOATACommand* owner;
UInt16 lbaLow;
UInt16 lbaMid;
UInt16 lbaHigh;
UInt16 sectorCount;
UInt16 features;
UInt16 device;
UInt16 command;
private:
OSMetaClassDeclareReservedUnused(IOExtendedLBA, 0);
OSMetaClassDeclareReservedUnused(IOExtendedLBA, 1);
OSMetaClassDeclareReservedUnused(IOExtendedLBA, 2);
OSMetaClassDeclareReservedUnused(IOExtendedLBA, 3);
OSMetaClassDeclareReservedUnused(IOExtendedLBA, 4);
OSMetaClassDeclareReservedUnused(IOExtendedLBA, 5);
OSMetaClassDeclareReservedUnused(IOExtendedLBA, 6);
OSMetaClassDeclareReservedUnused(IOExtendedLBA, 7);
OSMetaClassDeclareReservedUnused(IOExtendedLBA, 8);
OSMetaClassDeclareReservedUnused(IOExtendedLBA, 9);
OSMetaClassDeclareReservedUnused(IOExtendedLBA, 10);
};
#endif