ReactOS 0.4.15-dev-7961-gdcf9eb0
atapi.h
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Storage Stack
3 * LICENSE: DDK - see license.txt in the root dir
4 * FILE: drivers/storage/atapi/atapi.h
5 * PURPOSE: ATAPI IDE miniport driver
6 * PROGRAMMERS: Based on a source code sample from Microsoft NT4 DDK
7 */
8
9#include <srb.h>
10#include <scsi.h>
11
12//
13// IDE register definition
14//
15
16typedef struct _IDE_REGISTERS_1 {
25
26typedef struct _IDE_REGISTERS_2 {
30
31typedef struct _IDE_REGISTERS_3 {
35
36//
37// Device Extension Device Flags
38//
39
40#define DFLAGS_DEVICE_PRESENT 0x0001 // Indicates that some device is present.
41#define DFLAGS_ATAPI_DEVICE 0x0002 // Indicates whether Atapi commands can be used.
42#define DFLAGS_TAPE_DEVICE 0x0004 // Indicates whether this is a tape device.
43#define DFLAGS_INT_DRQ 0x0008 // Indicates whether device interrupts as DRQ is set after
44 // receiving Atapi Packet Command
45#define DFLAGS_REMOVABLE_DRIVE 0x0010 // Indicates that the drive has the 'removable' bit set in
46 // identify data (offset 128)
47#define DFLAGS_MEDIA_STATUS_ENABLED 0x0020 // Media status notification enabled
48#define DFLAGS_ATAPI_CHANGER 0x0040 // Indicates atapi 2.5 changer present.
49#define DFLAGS_SANYO_ATAPI_CHANGER 0x0080 // Indicates multi-platter device, not conforming to the 2.5 spec.
50#define DFLAGS_CHANGER_INITED 0x0100 // Indicates that the init path for changers has already been done.
51//
52// Used to disable 'advanced' features.
53//
54
55#define MAX_ERRORS 4
56
57//
58// ATAPI command definitions
59//
60
61#define ATAPI_MODE_SENSE 0x5A
62#define ATAPI_MODE_SELECT 0x55
63#define ATAPI_FORMAT_UNIT 0x24
64
65//
66// ATAPI Command Descriptor Block
67//
68
69typedef struct _MODE_SENSE_10 {
73 UCHAR Pc : 2;
79
80typedef struct _MODE_SELECT_10 {
90
97
98//
99// IDE command definitions
100//
101
102#define IDE_COMMAND_ATAPI_RESET 0x08
103#define IDE_COMMAND_RECALIBRATE 0x10
104#define IDE_COMMAND_READ 0x20
105#define IDE_COMMAND_WRITE 0x30
106#define IDE_COMMAND_VERIFY 0x40
107#define IDE_COMMAND_SEEK 0x70
108#define IDE_COMMAND_SET_DRIVE_PARAMETERS 0x91
109#define IDE_COMMAND_ATAPI_PACKET 0xA0
110#define IDE_COMMAND_ATAPI_IDENTIFY 0xA1
111#define IDE_COMMAND_READ_MULTIPLE 0xC4
112#define IDE_COMMAND_WRITE_MULTIPLE 0xC5
113#define IDE_COMMAND_SET_MULTIPLE 0xC6
114#define IDE_COMMAND_READ_DMA 0xC8
115#define IDE_COMMAND_WRITE_DMA 0xCA
116#define IDE_COMMAND_GET_MEDIA_STATUS 0xDA
117#define IDE_COMMAND_ENABLE_MEDIA_STATUS 0xEF
118#define IDE_COMMAND_IDENTIFY 0xEC
119#define IDE_COMMAND_MEDIA_EJECT 0xED
120
121//
122// IDE status definitions
123//
124
125#define IDE_STATUS_ERROR 0x01
126#define IDE_STATUS_INDEX 0x02
127#define IDE_STATUS_CORRECTED_ERROR 0x04
128#define IDE_STATUS_DRQ 0x08
129#define IDE_STATUS_DSC 0x10
130#define IDE_STATUS_DRDY 0x40
131#define IDE_STATUS_IDLE 0x50
132#define IDE_STATUS_BUSY 0x80
133
134//
135// IDE drive select/head definitions
136//
137
138#define IDE_DRIVE_SELECT_1 0xA0
139#define IDE_DRIVE_SELECT_2 0x10
140
141//
142// IDE drive control definitions
143//
144
145#define IDE_DC_DISABLE_INTERRUPTS 0x02
146#define IDE_DC_RESET_CONTROLLER 0x04
147#define IDE_DC_REENABLE_CONTROLLER 0x00
148
149//
150// IDE error definitions
151//
152
153#define IDE_ERROR_BAD_BLOCK 0x80
154#define IDE_ERROR_DATA_ERROR 0x40
155#define IDE_ERROR_MEDIA_CHANGE 0x20
156#define IDE_ERROR_ID_NOT_FOUND 0x10
157#define IDE_ERROR_MEDIA_CHANGE_REQ 0x08
158#define IDE_ERROR_COMMAND_ABORTED 0x04
159#define IDE_ERROR_END_OF_MEDIA 0x02
160#define IDE_ERROR_ILLEGAL_LENGTH 0x01
161
162//
163// ATAPI register definition
164//
165
166typedef struct _ATAPI_REGISTERS_1 {
175
176typedef struct _ATAPI_REGISTERS_2 {
180
181//
182// ATAPI interrupt reasons
183//
184
185#define ATAPI_IR_COD 0x01
186#define ATAPI_IR_IO 0x02
187
188//
189// IDENTIFY data
190//
191
192typedef struct _IDENTIFY_DATA {
195 USHORT Reserved1; // 04 2
196 USHORT NumberOfHeads; // 06 3
199 USHORT SectorsPerTrack; // 0C 6
200 USHORT VendorUnique1[3]; // 0E 7-9
201 USHORT SerialNumber[10]; // 14 10-19
202 USHORT BufferType; // 28 20
203 USHORT BufferSectorSize; // 2A 21
204 USHORT NumberOfEccBytes; // 2C 22
205 USHORT FirmwareRevision[4]; // 2E 23-26
206 USHORT ModelNumber[20]; // 36 27-46
208 UCHAR VendorUnique2; // 5F
209 USHORT DoubleWordIo; // 60 48
211 USHORT Reserved2; // 64 50
212 UCHAR VendorUnique3; // 66 51
214 UCHAR VendorUnique4; // 68 52
217 USHORT Reserved3:15;
221 ULONG CurrentSectorCapacity; // 72 57-58
226 USHORT MultiWordDMASupport : 8; // 63
228 USHORT AdvancedPIOModes : 8; // 64
229 USHORT Reserved4 : 8;
234 USHORT Reserved5[2]; // 69-70
237 USHORT MajorRevision; // 73
238 USHORT MinorRevision; // 74
239 USHORT Reserved6[50]; // 75-126
241 USHORT Reserved7[128]; // 128-255
243
244//
245// Identify data without the Reserved4.
246//
247
248typedef struct _IDENTIFY_DATA2 {
279
280#define IDENTIFY_DATA_SIZE sizeof(IDENTIFY_DATA)
281
282//
283// IDENTIFY capability bit definitions.
284//
285
286#define IDENTIFY_CAPABILITIES_DMA_SUPPORTED 0x0100
287#define IDENTIFY_CAPABILITIES_LBA_SUPPORTED 0x0200
288
289//
290// IDENTIFY DMA timing cycle modes.
291//
292
293#define IDENTIFY_DMA_CYCLES_MODE_0 0x00
294#define IDENTIFY_DMA_CYCLES_MODE_1 0x01
295#define IDENTIFY_DMA_CYCLES_MODE_2 0x02
296
297
304
306 { "1095", 4, "0640", 4},
307 { "1039", 4, "0601", 4}
308};
309
310#define BROKEN_ADAPTERS (sizeof(BrokenAdapters) / sizeof(BROKEN_CONTROLLER_INFORMATION))
311
318
320 { "10ad", 4, "0105", 4}
321};
322#define NUM_NATIVE_MODE_ADAPTERS (sizeof(NativeModeAdapters) / sizeof(NATIVE_MODE_CONTROLLER_INFORMATION))
323
324//
325// Beautification macros
326//
327
328#define GetStatus(BaseIoAddress, Status) \
329 Status = ScsiPortReadPortUchar(&BaseIoAddress->AlternateStatus);
330
331#define GetBaseStatus(BaseIoAddress, Status) \
332 Status = ScsiPortReadPortUchar(&BaseIoAddress->Command);
333
334#define WriteCommand(BaseIoAddress, Command) \
335 ScsiPortWritePortUchar(&BaseIoAddress->Command, Command);
336
337
338
339#define ReadBuffer(BaseIoAddress, Buffer, Count) \
340 ScsiPortReadPortBufferUshort(&BaseIoAddress->Data, \
341 Buffer, \
342 Count);
343
344#define WriteBuffer(BaseIoAddress, Buffer, Count) \
345 ScsiPortWritePortBufferUshort(&BaseIoAddress->Data, \
346 Buffer, \
347 Count);
348
349#define ReadBuffer2(BaseIoAddress, Buffer, Count) \
350 ScsiPortReadPortBufferUlong(&BaseIoAddress->Data, \
351 Buffer, \
352 Count);
353
354#define WriteBuffer2(BaseIoAddress, Buffer, Count) \
355 ScsiPortWritePortBufferUlong(&BaseIoAddress->Data, \
356 Buffer, \
357 Count);
358
359#define WaitOnBusy(BaseIoAddress, Status) \
360{ \
361 ULONG i; \
362 for (i=0; i<20000; i++) { \
363 GetStatus(BaseIoAddress, Status); \
364 if (Status & IDE_STATUS_BUSY) { \
365 ScsiPortStallExecution(150); \
366 continue; \
367 } else { \
368 break; \
369 } \
370 } \
371}
372
373#define WaitOnBaseBusy(BaseIoAddress, Status) \
374{ \
375 ULONG i; \
376 for (i=0; i<20000; i++) { \
377 GetBaseStatus(BaseIoAddress, Status); \
378 if (Status & IDE_STATUS_BUSY) { \
379 ScsiPortStallExecution(150); \
380 continue; \
381 } else { \
382 break; \
383 } \
384 } \
385}
386
387#define WaitForDrq(BaseIoAddress, Status) \
388{ \
389 ULONG i; \
390 for (i=0; i<1000; i++) { \
391 GetStatus(BaseIoAddress, Status); \
392 if (Status & IDE_STATUS_BUSY) { \
393 ScsiPortStallExecution(100); \
394 } else if (Status & IDE_STATUS_DRQ) { \
395 break; \
396 } else { \
397 ScsiPortStallExecution(200); \
398 } \
399 } \
400}
401
402
403#define WaitShortForDrq(BaseIoAddress, Status) \
404{ \
405 ULONG i; \
406 for (i=0; i<2; i++) { \
407 GetStatus(BaseIoAddress, Status); \
408 if (Status & IDE_STATUS_BUSY) { \
409 ScsiPortStallExecution(100); \
410 } else if (Status & IDE_STATUS_DRQ) { \
411 break; \
412 } else { \
413 ScsiPortStallExecution(100); \
414 } \
415 } \
416}
417
418#define AtapiSoftReset(BaseIoAddress,DeviceNumber) \
419{\
420 UCHAR statusByte; \
421 ULONG i = 1000*1000;\
422 ScsiPortWritePortUchar(&BaseIoAddress->DriveSelect,(UCHAR)(((DeviceNumber & 0x1) << 4) | 0xA0)); \
423 ScsiPortStallExecution(500);\
424 ScsiPortWritePortUchar(&BaseIoAddress->Command, IDE_COMMAND_ATAPI_RESET); \
425 while ((ScsiPortReadPortUchar(&BaseIoAddress->Command) & IDE_STATUS_BUSY) && i--)\
426 ScsiPortStallExecution(30);\
427 ScsiPortWritePortUchar(&BaseIoAddress->DriveSelect,(UCHAR)((DeviceNumber << 4) | 0xA0)); \
428 WaitOnBusy( ((PIDE_REGISTERS_2)((PUCHAR)BaseIoAddress + 0x206)), statusByte); \
429 ScsiPortStallExecution(500);\
430}
431
432#define IdeHardReset(BaseIoAddress,result) \
433{\
434 UCHAR statusByte;\
435 ULONG i;\
436 ScsiPortWritePortUchar(&BaseIoAddress->AlternateStatus,IDE_DC_RESET_CONTROLLER );\
437 ScsiPortStallExecution(50 * 1000);\
438 ScsiPortWritePortUchar(&BaseIoAddress->AlternateStatus,IDE_DC_REENABLE_CONTROLLER);\
439 for (i = 0; i < 1000 * 1000; i++) {\
440 statusByte = ScsiPortReadPortUchar(&BaseIoAddress->AlternateStatus);\
441 if (statusByte != IDE_STATUS_IDLE && statusByte != 0x0) {\
442 ScsiPortStallExecution(5);\
443 } else {\
444 break;\
445 }\
446 }\
447 if (i == 1000*1000) {\
448 result = FALSE;\
449 }\
450 result = TRUE;\
451}
452
453#define IS_RDP(OperationCode)\
454 ((OperationCode == SCSIOP_ERASE)||\
455 (OperationCode == SCSIOP_LOAD_UNLOAD)||\
456 (OperationCode == SCSIOP_LOCATE)||\
457 (OperationCode == SCSIOP_REWIND) ||\
458 (OperationCode == SCSIOP_SPACE)||\
459 (OperationCode == SCSIOP_SEEK)||\
460 (OperationCode == SCSIOP_WRITE_FILEMARKS))
461
struct _IDENTIFY_DATA * PIDENTIFY_DATA
struct _IDE_REGISTERS_3 * PIDE_REGISTERS_3
struct _MODE_SENSE_10 MODE_SENSE_10
struct _IDENTIFY_DATA IDENTIFY_DATA
struct _IDE_REGISTERS_2 IDE_REGISTERS_2
struct _ATAPI_REGISTERS_2 ATAPI_REGISTERS_2
struct _ATAPI_REGISTERS_1 ATAPI_REGISTERS_1
struct _IDE_REGISTERS_2 * PIDE_REGISTERS_2
struct _BROKEN_CONTROLLER_INFORMATION * PBROKEN_CONTROLLER_INFORMATION
struct _IDENTIFY_DATA2 IDENTIFY_DATA2
struct _NATIVE_MODE_CONTROLLER_INFORMATION NATIVE_MODE_CONTROLLER_INFORMATION
struct _IDE_REGISTERS_1 IDE_REGISTERS_1
struct _IDE_REGISTERS_3 IDE_REGISTERS_3
struct _MODE_SELECT_10 MODE_SELECT_10
struct _MODE_PARAMETER_HEADER_10 MODE_PARAMETER_HEADER_10
struct _NATIVE_MODE_CONTROLLER_INFORMATION * PNATIVE_MODE_CONTROLLER_INFORMATION
struct _BROKEN_CONTROLLER_INFORMATION BROKEN_CONTROLLER_INFORMATION
struct _MODE_PARAMETER_HEADER_10 * PMODE_PARAMETER_HEADER_10
struct _IDENTIFY_DATA2 * PIDENTIFY_DATA2
struct _IDE_REGISTERS_1 * PIDE_REGISTERS_1
struct _MODE_SENSE_10 * PMODE_SENSE_10
BROKEN_CONTROLLER_INFORMATION const BrokenAdapters[]
Definition: atapi.h:305
struct _ATAPI_REGISTERS_2 * PATAPI_REGISTERS_2
struct _ATAPI_REGISTERS_1 * PATAPI_REGISTERS_1
NATIVE_MODE_CONTROLLER_INFORMATION const NativeModeAdapters[]
Definition: atapi.h:319
struct _MODE_SELECT_10 * PMODE_SELECT_10
unsigned short USHORT
Definition: pedump.c:61
UCHAR ByteCountLow
Definition: atapi.h:170
UCHAR InterruptReason
Definition: atapi.h:168
UCHAR ByteCountHigh
Definition: atapi.h:171
UCHAR DriveSelect
Definition: atapi.h:172
UCHAR AlternateStatus
Definition: atapi.h:177
UCHAR DriveAddress
Definition: atapi.h:178
USHORT Reserved2
Definition: atapi.h:267
USHORT NumberOfHeads
Definition: atapi.h:252
UCHAR VendorUnique3
Definition: atapi.h:268
USHORT VendorUnique1[3]
Definition: atapi.h:256
USHORT NumberOfEccBytes
Definition: atapi.h:260
USHORT SerialNumber[10]
Definition: atapi.h:257
USHORT TranslationFieldsValid
Definition: atapi.h:272
USHORT CurrentSectorsPerTrack
Definition: atapi.h:276
USHORT UnformattedBytesPerSector
Definition: atapi.h:254
UCHAR MaximumBlockTransfer
Definition: atapi.h:263
USHORT NumberOfCylinders
Definition: atapi.h:250
USHORT NumberOfCurrentHeads
Definition: atapi.h:275
USHORT FirmwareRevision[4]
Definition: atapi.h:261
UCHAR VendorUnique4
Definition: atapi.h:270
USHORT Reserved3
Definition: atapi.h:273
USHORT GeneralConfiguration
Definition: atapi.h:249
USHORT Capabilities
Definition: atapi.h:266
USHORT DoubleWordIo
Definition: atapi.h:265
USHORT SectorsPerTrack
Definition: atapi.h:255
USHORT ModelNumber[20]
Definition: atapi.h:262
USHORT UnformattedBytesPerTrack
Definition: atapi.h:253
UCHAR VendorUnique2
Definition: atapi.h:264
USHORT BufferSectorSize
Definition: atapi.h:259
ULONG CurrentSectorCapacity
Definition: atapi.h:277
USHORT NumberOfCurrentCylinders
Definition: atapi.h:274
USHORT BufferType
Definition: atapi.h:258
USHORT Reserved1
Definition: atapi.h:251
UCHAR DmaCycleTimingMode
Definition: atapi.h:271
UCHAR PioCycleTimingMode
Definition: atapi.h:269
USHORT NumberOfCurrentCylinders
Definition: hwide.h:208
USHORT BufferType
Definition: hwide.h:184
USHORT Capabilities
Definition: atapi.h:210
USHORT Reserved4
Definition: hwide.h:219
USHORT UnformattedBytesPerSector
Definition: hwide.h:180
USHORT SingleWordDMASupport
Definition: hwide.h:214
USHORT NumberOfCurrentHeads
Definition: hwide.h:209
USHORT Reserved5[2]
Definition: hwide.h:224
ULONG UserAddressableSectors
Definition: hwide.h:213
USHORT MultiWordDMASupport
Definition: hwide.h:216
USHORT NumberOfHeads
Definition: hwide.h:178
USHORT GeneralConfiguration
Definition: atapi.h:193
UCHAR PioCycleTimingMode
Definition: hwide.h:203
USHORT SerialNumber[10]
Definition: hwide.h:183
USHORT Reserved7[151]
Definition: hwide.h:281
USHORT NumberOfCylinders
Definition: hwide.h:176
USHORT BufferSectorSize
Definition: hwide.h:185
USHORT MinorRevision
Definition: hwide.h:235
UCHAR VendorUnique4
Definition: hwide.h:204
USHORT Reserved3
Definition: hwide.h:207
USHORT CurrentSectorsPerTrack
Definition: hwide.h:210
UCHAR VendorUnique2
Definition: hwide.h:190
USHORT DoubleWordIo
Definition: hwide.h:191
USHORT CurrentMultiSectorSetting
Definition: hwide.h:212
USHORT MajorRevision
Definition: hwide.h:234
USHORT NumberOfEccBytes
Definition: hwide.h:186
USHORT TranslationFieldsValid
Definition: hwide.h:206
USHORT Reserved6[13]
Definition: hwide.h:279
UCHAR VendorUnique3
Definition: hwide.h:202
USHORT ReleaseTimeServiceCommand
Definition: hwide.h:226
USHORT UnformattedBytesPerTrack
Definition: hwide.h:179
UCHAR DmaCycleTimingMode
Definition: hwide.h:205
USHORT SingleWordDMAActive
Definition: hwide.h:215
USHORT AdvancedPIOModes
Definition: hwide.h:218
USHORT Reserved2
Definition: hwide.h:201
USHORT FirmwareRevision[4]
Definition: hwide.h:187
USHORT SectorsPerTrack
Definition: hwide.h:181
UCHAR MaximumBlockTransfer
Definition: atapi.h:207
USHORT VendorUnique1[3]
Definition: hwide.h:182
USHORT MultiWordDMAActive
Definition: hwide.h:217
USHORT SpecialFunctionsEnabled
Definition: atapi.h:240
USHORT RecommendedMWXferCycleTime
Definition: hwide.h:221
USHORT MinimumPIOCycleTimeIORDY
Definition: hwide.h:223
USHORT ModelNumber[20]
Definition: hwide.h:188
USHORT Reserved1
Definition: hwide.h:177
USHORT MinimumMWXferCycleTime
Definition: hwide.h:220
USHORT ReleaseTimeOverlapped
Definition: hwide.h:225
ULONG CurrentSectorCapacity
Definition: hwide.h:211
USHORT MinimumPIOCycleTime
Definition: hwide.h:222
UCHAR CylinderHigh
Definition: atapi.h:21
UCHAR BlockCount
Definition: atapi.h:18
UCHAR Command
Definition: atapi.h:23
UCHAR CylinderLow
Definition: atapi.h:20
UCHAR BlockNumber
Definition: atapi.h:19
UCHAR DriveSelect
Definition: atapi.h:22
USHORT Data
Definition: atapi.h:17
UCHAR DriveAddress
Definition: atapi.h:28
UCHAR AlternateStatus
Definition: atapi.h:27
UCHAR Others[4]
Definition: atapi.h:33
ULONG Data
Definition: atapi.h:32
UCHAR Reserved4[3]
Definition: atapi.h:88
UCHAR Reserved3[5]
Definition: atapi.h:85
UCHAR OperationCode
Definition: atapi.h:81
UCHAR Reserved2
Definition: atapi.h:84
UCHAR Reserved1
Definition: atapi.h:82
UCHAR ParameterListLengthLsb
Definition: atapi.h:87
UCHAR PFBit
Definition: atapi.h:83
UCHAR ParameterListLengthMsb
Definition: atapi.h:86
UCHAR Pc
Definition: atapi.h:73
UCHAR PageCode
Definition: atapi.h:72
UCHAR Reserved2[4]
Definition: atapi.h:74
UCHAR Reserved1
Definition: atapi.h:71
UCHAR Reserved3[3]
Definition: atapi.h:77
UCHAR OperationCode
Definition: atapi.h:70
UCHAR ParameterListLengthMsb
Definition: atapi.h:75
UCHAR ParameterListLengthLsb
Definition: atapi.h:76
uint32_t ULONG
Definition: typedefs.h:59
char * PCHAR
Definition: typedefs.h:51
_Reserved_ PVOID Reserved
Definition: winddi.h:3974
unsigned char UCHAR
Definition: xmlstorage.h:181