xref: /reactos/drivers/storage/ide/uniata/atapi.h (revision 845faec4)
1 /*++
2 
3 Copyright (c) 2002-2016 Alexandr A. Telyatnikov (Alter)
4 
5 Module Name:
6     atapi.h
7 
8 Abstract:
9     This file contains IDE, ATA, ATAPI and SCSI Miniport definitions
10     and function prototypes.
11 
12 Author:
13     Alexander A. Telyatnikov (Alter)
14 
15 Environment:
16     kernel mode only
17 
18 Notes:
19 
20     THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21     IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22     OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23     IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26     DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27     THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28     (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29     THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 
31 Revision History:
32 
33     Some definitions were taken from standard ATAPI.SYS sources from NT4 DDK by
34          Mike Glass (MGlass)
35 
36     Some definitions were taken from FreeBSD 4.3-4.6 ATA driver by
37          S�ren Schmidt, Copyright (c) 1998,1999,2000,2001
38 
39     Code was changed/updated by
40          Alter, Copyright (c) 2002-20016
41 
42 Licence:
43     GPLv2
44 
45 
46 --*/
47 #ifndef __GLOBAL_H__
48 #define __GLOBAL_H__
49 
50 #ifdef __cplusplus
51 extern "C" {
52 #endif //__cplusplus
53 
54 #ifndef USER_MODE
55 #include "config.h"
56 #endif //USER_MODE
57 
58 #include "scsi.h"
59 #include "stdio.h"
60 #include "string.h"
61 
62 #ifdef _DEBUG
63 
64 
65 #ifndef _DBGNT_
66 
67 #ifdef KdPrint
68 #undef KdPrint
69 #endif
70 
71 #ifdef USE_DBGPRINT_LOGGER
72 #include "inc/PostDbgMesg.h"
73 #define DbgPrint             DbgDump_Printf
74 #define Connect_DbgPrint()   {DbgDump_SetAutoReconnect(TRUE); DbgDump_Reconnect();}
75 #else // USE_DBGPRINT_LOGGER
76 #define Connect_DbgPrint()   {;}
77 #endif // USE_DBGPRINT_LOGGER
78 
79 #ifdef SCSI_PORT_DBG_PRINT
80 
81 SCSIPORT_API
82 VOID
83 __cdecl
84 ScsiDebugPrint(
85     ULONG DebugPrintLevel,
86     PCCHAR DebugMessage,
87     ...
88     );
89 
90 #define PRINT_PREFIX                0,
91 
92 #define KdPrint3(_x_) ScsiDebugPrint _x_    {;}
93 #define KdPrint2(_x_) {ScsiDebugPrint("%x: ", PsGetCurrentThread()) ; ScsiDebugPrint _x_ ; }
94 #define KdPrint(_x_) ScsiDebugPrint _x_ {;}
95 
96 #else // SCSI_PORT_DBG_PRINT
97 
98 #ifndef USE_DBGPRINT_LOGGER
99 /*
100 ULONG
101 _cdecl
102 DbgPrint(
103     PCH Format,
104     ...
105     );
106 */
107 #endif // USE_DBGPRINT_LOGGER
108 
109 #define PRINT_PREFIX
110 
111 // Note, that using DbgPrint on raised IRQL will crash w2k
112 // ttis will not happen immediately, so we shall see some logs
113 //#define LOG_ON_RAISED_IRQL_W2K    TRUE
114 //#define LOG_ON_RAISED_IRQL_W2K    FALSE
115 
116 #define KdPrint3(_x_) {if(LOG_ON_RAISED_IRQL_W2K || MajorVersion < 0x05 || KeGetCurrentIrql() <= 2){/*DbgPrint("%x: ", PsGetCurrentThread()) ;*/ DbgPrint _x_ ; if(g_LogToDisplay){ PrintNtConsole _x_ ;} }}
117 #define KdPrint2(_x_) {if(LOG_ON_RAISED_IRQL_W2K || MajorVersion < 0x05 || KeGetCurrentIrql() <= 2){/*DbgPrint("%x: ", PsGetCurrentThread()) ;*/ DbgPrint _x_ ; if(g_LogToDisplay){ PrintNtConsole _x_ ;} }}
118 #define KdPrint(_x_)  {if(LOG_ON_RAISED_IRQL_W2K || MajorVersion < 0x05 || KeGetCurrentIrql() <= 2){/*DbgPrint("%x: ", PsGetCurrentThread()) ;*/ DbgPrint _x_ ; if(g_LogToDisplay){ PrintNtConsole _x_ ;} }}
119 /*
120 #define PRINT_PREFIX_PTR ((PCHAR)&__tmp__kdprint__buff__)
121 #define PRINT_UPREFIX_PTR ((PWCHAR)&__tmp__kdprint__ubuff__)
122 #define PRINT_PREFIX     PRINT_PREFIX_PTR,
123 #define KdPrint2(_x_) \
124 { \
125     WCHAR __tmp__kdprint__ubuff__[256]; \
126     CHAR __tmp__kdprint__buff__[256]; \
127     UNICODE_STRING __tmp__usrt__buff__; \
128     sprintf _x_; \
129     swprintf (PRINT_UPREFIX_PTR, L"%hs", PRINT_PREFIX_PTR); \
130     __tmp__usrt__buff__.Buffer = PRINT_UPREFIX_PTR; \
131     __tmp__usrt__buff__.Length = \
132     __tmp__usrt__buff__.MaximumLength = strlen(PRINT_PREFIX_PTR); \
133     NtDisplayString(&__tmp__usrt__buff__); \
134 };
135 #define KdPrint(_x_)  DbgPrint _x_
136 */
137 #endif // SCSI_PORT_DBG_PRINT
138 
139 //#define AtapiStallExecution(dt)  { KdPrint2(("  AtapiStallExecution(%d)\n", dt)); ScsiPortStallExecution(dt); }
140 #define AtapiStallExecution(dt)  { ScsiPortStallExecution(dt); }
141 
142 #endif // _DBGNT_
143 
144 #else // _DEBUG
145 
146 #ifdef KdPrint
147 #undef KdPrint
148 #endif
149 
150 #define PRINT_PREFIX "UniATA: "
151 
152 //#define KdPrint3(_x_) {if(LOG_ON_RAISED_IRQL_W2K || MajorVersion < 0x05 || KeGetCurrentIrql() <= 2){/*DbgPrint("%x: ", PsGetCurrentThread()) ;*/ DbgPrint _x_ ; if(g_LogToDisplay){ PrintNtConsole _x_ ;} }}
153 #define KdPrint3(_x_)  {;}
154 #define KdPrint2(_x_)  {;}
155 #define KdPrint(_x_)   {;}
156 #define Connect_DbgPrint()   {;}
157 
158 #define AtapiStallExecution(dt)  ScsiPortStallExecution(dt)
159 
160 #endif // _DEBUG
161 
162 // IDE register definition
163 
164 #pragma pack(push, 1)
165 
166 typedef union _IDE_REGISTERS_1 {
167     struct _o {
168         UCHAR Data;
169         UCHAR Feature;
170         UCHAR BlockCount;
171         UCHAR BlockNumber;
172         UCHAR CylinderLow;
173         UCHAR CylinderHigh;
174         UCHAR DriveSelect;
175         UCHAR Command;
176     } o;
177 
178     struct _i {
179         UCHAR Data;
180         UCHAR Error;
181         UCHAR BlockCount;
182         UCHAR BlockNumber;
183         UCHAR CylinderLow;
184         UCHAR CylinderHigh;
185         UCHAR DriveSelect;
186         UCHAR Status;
187     } i;
188 
189 } IDE_REGISTERS_1, *PIDE_REGISTERS_1;
190 
191 #define IDX_IO1                     0
192 #define IDX_IO1_SZ                  sizeof(IDE_REGISTERS_1)
193 
194 #define IDX_IO1                     0
195 #define IDX_IO1_SZ                  sizeof(IDE_REGISTERS_1)
196 #define IDX_IO1_i_Data              (FIELD_OFFSET(IDE_REGISTERS_1, i.Data        )+IDX_IO1)
197 #define IDX_IO1_i_Error             (FIELD_OFFSET(IDE_REGISTERS_1, i.Error       )+IDX_IO1)
198 #define IDX_IO1_i_BlockCount        (FIELD_OFFSET(IDE_REGISTERS_1, i.BlockCount  )+IDX_IO1)
199 #define IDX_IO1_i_BlockNumber       (FIELD_OFFSET(IDE_REGISTERS_1, i.BlockNumber )+IDX_IO1)
200 #define IDX_IO1_i_CylinderLow       (FIELD_OFFSET(IDE_REGISTERS_1, i.CylinderLow )+IDX_IO1)
201 #define IDX_IO1_i_CylinderHigh      (FIELD_OFFSET(IDE_REGISTERS_1, i.CylinderHigh)+IDX_IO1)
202 #define IDX_IO1_i_DriveSelect       (FIELD_OFFSET(IDE_REGISTERS_1, i.DriveSelect )+IDX_IO1)
203 #define IDX_IO1_i_Status            (FIELD_OFFSET(IDE_REGISTERS_1, i.Status      )+IDX_IO1)
204 
205 #define IDX_IO1_o                   IDX_IO1_SZ
206 #define IDX_IO1_o_SZ                sizeof(IDE_REGISTERS_1)
207 
208 #define IDX_IO1_o_Data              (FIELD_OFFSET(IDE_REGISTERS_1, o.Data        )+IDX_IO1_o)
209 #define IDX_IO1_o_Feature           (FIELD_OFFSET(IDE_REGISTERS_1, o.Feature     )+IDX_IO1_o)
210 #define IDX_IO1_o_BlockCount        (FIELD_OFFSET(IDE_REGISTERS_1, o.BlockCount  )+IDX_IO1_o)
211 #define IDX_IO1_o_BlockNumber       (FIELD_OFFSET(IDE_REGISTERS_1, o.BlockNumber )+IDX_IO1_o)
212 #define IDX_IO1_o_CylinderLow       (FIELD_OFFSET(IDE_REGISTERS_1, o.CylinderLow )+IDX_IO1_o)
213 #define IDX_IO1_o_CylinderHigh      (FIELD_OFFSET(IDE_REGISTERS_1, o.CylinderHigh)+IDX_IO1_o)
214 #define IDX_IO1_o_DriveSelect       (FIELD_OFFSET(IDE_REGISTERS_1, o.DriveSelect )+IDX_IO1_o)
215 #define IDX_IO1_o_Command           (FIELD_OFFSET(IDE_REGISTERS_1, o.Command     )+IDX_IO1_o)
216 
217 typedef union _IDE_REGISTERS_2 {
218     UCHAR AltStatus;
219     UCHAR Control;
220 } IDE_REGISTERS_2, *PIDE_REGISTERS_2;
221 
222 #define IDX_IO2                     (IDX_IO1_o+IDX_IO1_o_SZ)
223 #define IDX_IO2_SZ                  sizeof(IDE_REGISTERS_2)
224 
225 #define IDX_IO2_AltStatus           (FIELD_OFFSET(IDE_REGISTERS_2, AltStatus   )+IDX_IO2)
226 //#define IDX_IO2_DriveAddress        (FIELD_OFFSET(IDE_REGISTERS_2, DriveAddress)+IDX_IO2)
227 
228 #define IDX_IO2_o                   (IDX_IO2+IDX_IO2_SZ)
229 #define IDX_IO2_o_SZ                sizeof(IDE_REGISTERS_2)
230 
231 #define IDX_IO2_o_Control           (FIELD_OFFSET(IDE_REGISTERS_2, Control)+IDX_IO2_o)
232 //
233 // Device Extension Device Flags
234 //
235 
236 #define DFLAGS_DEVICE_PRESENT        0x0001    // Indicates that some device is present.
237 #define DFLAGS_ATAPI_DEVICE          0x0002    // Indicates whether ATAPI commands can be used.
238 #define DFLAGS_TAPE_DEVICE           0x0004    // Indicates whether this is a tape device.
239 #define DFLAGS_INT_DRQ               0x0008    // Indicates whether device interrupts as DRQ is set after
240                                                // receiving ATAPI Packet Command
241 #define DFLAGS_REMOVABLE_DRIVE       0x0010    // Indicates that the drive has the 'removable' bit set in
242                                                // identify data (offset 128)
243 #define DFLAGS_MEDIA_STATUS_ENABLED  0x0020    // Media status notification enabled
244 #define DFLAGS_ATAPI_CHANGER         0x0040    // Indicates atapi 2.5 changer present.
245 #define DFLAGS_SANYO_ATAPI_CHANGER   0x0080    // Indicates multi-platter device, not conforming to the 2.5 spec.
246 #define DFLAGS_CHANGER_INITED        0x0100    // Indicates that the init path for changers has already been done.
247 #define DFLAGS_LBA_ENABLED           0x0200    // Indicates that we should use LBA addressing rather than CHS
248 #define DFLAGS_DWORDIO_ENABLED       0x0400    // Indicates that we should use 32-bit IO
249 #define DFLAGS_WCACHE_ENABLED        0x0800    // Indicates that we use write cache
250 #define DFLAGS_RCACHE_ENABLED        0x1000    // Indicates that we use read cache
251 #define DFLAGS_ORIG_GEOMETRY         0x2000    //
252 #define DFLAGS_REINIT_DMA            0x4000    //
253 #define DFLAGS_HIDDEN                0x8000    // Hidden device, available only with special IOCTLs
254                                                // via communication virtual device
255 #define DFLAGS_MANUAL_CHS            0x10000   // For devices those have no IDENTIFY commands
256 //#define DFLAGS_            0x10000    //
257 //
258 // Used to disable 'advanced' features.
259 //
260 
261 #define MAX_ERRORS                     4
262 
263 //
264 // ATAPI command definitions
265 //
266 
267 #define ATAPI_MODE_SENSE   0x5A
268 #define ATAPI_MODE_SELECT  0x55
269 #define ATAPI_FORMAT_UNIT  0x24
270 
271 // ATAPI Command Descriptor Block
272 
273 typedef struct _MODE_SENSE_10 {
274         UCHAR OperationCode;
275         UCHAR Reserved1;
276         UCHAR PageCode : 6;
277         UCHAR Pc : 2;
278         UCHAR Reserved2[4];
279         UCHAR ParameterListLengthMsb;
280         UCHAR ParameterListLengthLsb;
281         UCHAR Reserved3[3];
282 } MODE_SENSE_10, *PMODE_SENSE_10;
283 
284 typedef struct _MODE_SELECT_10 {
285         UCHAR OperationCode;
286         UCHAR Reserved1 : 4;
287         UCHAR PFBit : 1;
288         UCHAR Reserved2 : 3;
289         UCHAR Reserved3[5];
290         UCHAR ParameterListLengthMsb;
291         UCHAR ParameterListLengthLsb;
292         UCHAR Reserved4[3];
293 } MODE_SELECT_10, *PMODE_SELECT_10;
294 
295 typedef struct _MODE_PARAMETER_HEADER_10 {
296     UCHAR ModeDataLengthMsb;
297     UCHAR ModeDataLengthLsb;
298     UCHAR MediumType;
299     UCHAR Reserved[5];
300 }MODE_PARAMETER_HEADER_10, *PMODE_PARAMETER_HEADER_10;
301 
302 //
303 // values for TransferMode
304 //
305 #define         ATA_PIO                 0x00
306 #define 	ATA_PIO_NRDY            0x01
307 
308 #define         ATA_PIO0                0x08
309 #define         ATA_PIO1                0x09
310 #define         ATA_PIO2                0x0a
311 #define         ATA_PIO3                0x0b
312 #define         ATA_PIO4                0x0c
313 #define         ATA_PIO5                0x0d
314 
315 #define         ATA_DMA                 0x10
316 #define         ATA_SDMA                0x10
317 #define         ATA_SDMA0               0x10
318 #define         ATA_SDMA1               0x11
319 #define         ATA_SDMA2               0x12
320 
321 #define         ATA_WDMA                0x20
322 #define         ATA_WDMA0               0x20
323 #define         ATA_WDMA1               0x21
324 #define         ATA_WDMA2               0x22
325 
326 #define         ATA_UDMA                0x40
327 #define         ATA_UDMA0               0x40 // ATA-16
328 #define         ATA_UDMA1               0x41 // ATA-25
329 #define         ATA_UDMA2               0x42 // ATA-33
330 #define         ATA_UDMA3               0x43 // ATA-44
331 #define         ATA_UDMA4               0x44 // ATA-66
332 #define         ATA_UDMA5               0x45 // ATA-100
333 #define         ATA_UDMA6               0x46 // ATA-133
334 //#define         ATA_UDMA7               0x47 // ATA-166
335 
336 #define         ATA_SA150               0x47 /*0x80*/
337 #define         ATA_SA300               0x48 /*0x81*/
338 #define         ATA_SA600               0x49 /*0x82*/
339 
340 #define         ATA_MODE_NOT_SPEC       ((ULONG)(-1)) /*0x82*/
341 
342 //
343 // IDE command definitions
344 //
345 
346 #define IDE_COMMAND_DATA_SET_MGMT    0x06 // TRIM
347 #define IDE_COMMAND_ATAPI_RESET      0x08
348 #define IDE_COMMAND_RECALIBRATE      0x10
349 #define IDE_COMMAND_READ             0x20
350 #define IDE_COMMAND_READ_NO_RETR     0x21
351 #define IDE_COMMAND_READ48           0x24
352 #define IDE_COMMAND_READ_DMA48       0x25
353 #define IDE_COMMAND_READ_DMA_Q48     0x26
354 #define IDE_COMMAND_READ_NATIVE_SIZE48   0x27
355 #define IDE_COMMAND_READ_MUL48           0x29
356 #define IDE_COMMAND_READ_STREAM_DMA48    0x2A
357 #define IDE_COMMAND_READ_STREAM48        0x2B
358 #define IDE_COMMAND_READ_LOG48           0x2f
359 #define IDE_COMMAND_WRITE                0x30
360 #define IDE_COMMAND_WRITE_NO_RETR        0x31
361 #define IDE_COMMAND_WRITE48              0x34
362 #define IDE_COMMAND_WRITE_DMA48          0x35
363 #define IDE_COMMAND_WRITE_DMA_Q48        0x36
364 #define IDE_COMMAND_SET_NATIVE_SIZE48    0x37
365 #define IDE_COMMAND_WRITE_MUL48          0x39
366 #define IDE_COMMAND_WRITE_STREAM_DMA48   0x3a
367 #define IDE_COMMAND_WRITE_STREAM48       0x3b
368 #define IDE_COMMAND_WRITE_FUA_DMA48      0x3d
369 #define IDE_COMMAND_WRITE_FUA_DMA_Q48    0x3e
370 #define IDE_COMMAND_WRITE_LOG48          0x3f
371 #define IDE_COMMAND_VERIFY               0x40
372 #define IDE_COMMAND_VERIFY48             0x42
373 #define IDE_COMMAND_READ_LOG_DMA48       0x47
374 #define IDE_COMMAND_WRITE_LOG_DMA48      0x57
375 #define IDE_COMMAND_TRUSTED_RCV          0x5c
376 #define IDE_COMMAND_TRUSTED_RCV_DMA      0x5d
377 #define IDE_COMMAND_TRUSTED_SEND         0x5e
378 #define IDE_COMMAND_TRUSTED_SEND_DMA     0x5f
379 #define IDE_COMMAND_SEEK                 0x70
380 #define IDE_COMMAND_SET_DRIVE_PARAMETERS 0x91
381 #define IDE_COMMAND_ATAPI_PACKET     0xA0
382 #define IDE_COMMAND_ATAPI_IDENTIFY   0xA1
383 #define IDE_COMMAND_READ_MULTIPLE    0xC4
384 #define IDE_COMMAND_WRITE_MULTIPLE   0xC5
385 #define IDE_COMMAND_SET_MULTIPLE     0xC6
386 #define IDE_COMMAND_READ_DMA_Q       0xC7
387 #define IDE_COMMAND_READ_DMA         0xC8
388 #define IDE_COMMAND_WRITE_DMA        0xCA
389 #define IDE_COMMAND_WRITE_DMA_Q      0xCC
390 #define IDE_COMMAND_WRITE_MUL_FUA48  0xCE
391 #define IDE_COMMAND_GET_MEDIA_STATUS 0xDA
392 #define IDE_COMMAND_DOOR_LOCK        0xDE
393 #define IDE_COMMAND_DOOR_UNLOCK      0xDF
394 #define IDE_COMMAND_STANDBY_IMMED    0xE0 // flush and spin down
395 #define IDE_COMMAND_IDLE_IMMED       0xE1
396 #define IDE_COMMAND_STANDBY          0xE2 // flush and spin down and enable autopowerdown timer
397 #define IDE_COMMAND_IDLE             0xE3
398 #define IDE_COMMAND_READ_PM          0xE4 // SATA PM
399 #define IDE_COMMAND_SLEEP            0xE6 // flush, spin down and deactivate interface
400 #define IDE_COMMAND_FLUSH_CACHE      0xE7
401 #define IDE_COMMAND_WRITE_PM         0xE8 // SATA PM
402 #define IDE_COMMAND_IDENTIFY         0xEC
403 #define IDE_COMMAND_MEDIA_EJECT      0xED
404 #define IDE_COMMAND_FLUSH_CACHE48    0xEA
405 #define IDE_COMMAND_ENABLE_MEDIA_STATUS  0xEF
406 #define	IDE_COMMAND_SET_FEATURES     0xEF      /* features command,
407                                                  IDE_COMMAND_ENABLE_MEDIA_STATUS */
408 #define IDE_COMMAND_READ_NATIVE_SIZE 0xF8
409 #define IDE_COMMAND_SET_NATIVE_SIZE  0xF9
410 
411 #define SCSIOP_ATA_PASSTHROUGH       0xCC //
412 
413 //
414 // IDE status definitions
415 //
416 
417 #define IDE_STATUS_SUCCESS           0x00
418 #define IDE_STATUS_ERROR             0x01
419 #define IDE_STATUS_INDEX             0x02
420 #define IDE_STATUS_CORRECTED_ERROR   0x04
421 #define IDE_STATUS_DRQ               0x08
422 #define IDE_STATUS_DSC               0x10
423 //#define IDE_STATUS_DWF               0x10      /* drive write fault */
424 #define IDE_STATUS_DMA               0x20      /* DMA ready */
425 #define IDE_STATUS_DWF               0x20      /* drive write fault */
426 #define IDE_STATUS_DRDY              0x40
427 #define IDE_STATUS_IDLE              0x50
428 #define IDE_STATUS_BUSY              0x80
429 
430 #define IDE_STATUS_WRONG             0xff
431 #define IDE_STATUS_MASK              0xff
432 
433 
434 //
435 // IDE drive select/head definitions
436 //
437 
438 #define IDE_DRIVE_SELECT             0xA0
439 #define IDE_DRIVE_1                  0x00
440 #define IDE_DRIVE_2                  0x10
441 #define IDE_DRIVE_SELECT_1           (IDE_DRIVE_SELECT | IDE_DRIVE_1)
442 #define IDE_DRIVE_SELECT_2           (IDE_DRIVE_SELECT | IDE_DRIVE_2)
443 #define IDE_DRIVE_MASK               (IDE_DRIVE_SELECT_1 | IDE_DRIVE_SELECT_2)
444 
445 #define IDE_USE_LBA                  0x40
446 
447 //
448 // IDE drive control definitions
449 //
450 
451 #define IDE_DC_DISABLE_INTERRUPTS    0x02
452 #define IDE_DC_RESET_CONTROLLER      0x04
453 #define IDE_DC_A_4BIT                0x80
454 #define IDE_DC_USE_HOB               0x80 // use high-order byte(s)
455 #define IDE_DC_REENABLE_CONTROLLER   0x00
456 
457 // IDE error definitions
458 //
459 
460 #define IDE_ERROR_ICRC               0x80
461 #define IDE_ERROR_BAD_BLOCK          0x80
462 #define IDE_ERROR_DATA_ERROR         0x40
463 #define IDE_ERROR_MEDIA_CHANGE       0x20
464 #define IDE_ERROR_ID_NOT_FOUND       0x10
465 #define IDE_ERROR_MEDIA_CHANGE_REQ   0x08
466 #define IDE_ERROR_COMMAND_ABORTED    0x04
467 #define IDE_ERROR_END_OF_MEDIA       0x02
468 #define IDE_ERROR_NO_MEDIA           0x02
469 #define IDE_ERROR_ILLEGAL_LENGTH     0x01
470 
471 //
472 // ATAPI register definition
473 //
474 
475 typedef union _ATAPI_REGISTERS_1 {
476     struct _o {
477         UCHAR Data;
478         UCHAR Feature;
479         UCHAR Unused0;
480         UCHAR Unused1;
481         UCHAR ByteCountLow;
482         UCHAR ByteCountHigh;
483         UCHAR DriveSelect;
484         UCHAR Command;
485     } o;
486 
487     struct _i {
488         UCHAR Data;
489         UCHAR Error;
490         UCHAR InterruptReason;
491         UCHAR Unused1;
492         UCHAR ByteCountLow;
493         UCHAR ByteCountHigh;
494         UCHAR DriveSelect;
495         UCHAR Status;
496     } i;
497 
498     //IDE_REGISTERS_1 ide;
499 
500 } ATAPI_REGISTERS_1, *PATAPI_REGISTERS_1;
501 
502 #define IDX_ATAPI_IO1                     IDX_IO1
503 #define IDX_ATAPI_IO1_SZ                  sizeof(ATAPI_REGISTERS_1)
504 
505 #define IDX_ATAPI_IO1_i_Data              (FIELD_OFFSET(ATAPI_REGISTERS_1, i.Data           )+IDX_ATAPI_IO1)
506 #define IDX_ATAPI_IO1_i_Error             (FIELD_OFFSET(ATAPI_REGISTERS_1, i.Error          )+IDX_ATAPI_IO1)
507 #define IDX_ATAPI_IO1_i_InterruptReason   (FIELD_OFFSET(ATAPI_REGISTERS_1, i.InterruptReason)+IDX_ATAPI_IO1)
508 #define IDX_ATAPI_IO1_i_Unused1           (FIELD_OFFSET(ATAPI_REGISTERS_1, i.Unused1        )+IDX_ATAPI_IO1)
509 #define IDX_ATAPI_IO1_i_ByteCountLow      (FIELD_OFFSET(ATAPI_REGISTERS_1, i.ByteCountLow   )+IDX_ATAPI_IO1)
510 #define IDX_ATAPI_IO1_i_ByteCountHigh     (FIELD_OFFSET(ATAPI_REGISTERS_1, i.ByteCountHigh  )+IDX_ATAPI_IO1)
511 #define IDX_ATAPI_IO1_i_DriveSelect       (FIELD_OFFSET(ATAPI_REGISTERS_1, i.DriveSelect    )+IDX_ATAPI_IO1)
512 #define IDX_ATAPI_IO1_i_Status            (FIELD_OFFSET(ATAPI_REGISTERS_1, i.Status         )+IDX_ATAPI_IO1)
513 
514 #define IDX_ATAPI_IO1_o_Data              (FIELD_OFFSET(ATAPI_REGISTERS_1, o.Data         )+IDX_ATAPI_IO1)
515 #define IDX_ATAPI_IO1_o_Feature           (FIELD_OFFSET(ATAPI_REGISTERS_1, o.Feature      )+IDX_ATAPI_IO1)
516 #define IDX_ATAPI_IO1_o_Unused0           (FIELD_OFFSET(ATAPI_REGISTERS_1, o.Unused0      )+IDX_ATAPI_IO1)
517 #define IDX_ATAPI_IO1_o_Unused1           (FIELD_OFFSET(ATAPI_REGISTERS_1, o.Unused1      )+IDX_ATAPI_IO1)
518 #define IDX_ATAPI_IO1_o_ByteCountLow      (FIELD_OFFSET(ATAPI_REGISTERS_1, o.ByteCountLow )+IDX_ATAPI_IO1)
519 #define IDX_ATAPI_IO1_o_ByteCountHigh     (FIELD_OFFSET(ATAPI_REGISTERS_1, o.ByteCountHigh)+IDX_ATAPI_IO1)
520 #define IDX_ATAPI_IO1_o_DriveSelect       (FIELD_OFFSET(ATAPI_REGISTERS_1, o.DriveSelect  )+IDX_ATAPI_IO1)
521 #define IDX_ATAPI_IO1_o_Command           (FIELD_OFFSET(ATAPI_REGISTERS_1, o.Command      )+IDX_ATAPI_IO1)
522 
523 /*
524 typedef union _ATAPI_REGISTERS_2 {
525     struct {
526         UCHAR AltStatus;
527         UCHAR DriveAddress;
528     };
529 
530     //IDE_REGISTERS_2 ide;
531 
532 } ATAPI_REGISTERS_2, *PATAPI_REGISTERS_2;
533 
534 #define IDX_ATAPI_IO2               IDX_ATAPI_IO2_SZ
535 #define IDX_ATAPI_IO2_SZ            sizeof(ATAPI_REGISTERS_2)
536 */
537 
538 //
539 // ATAPI interrupt reasons
540 //
541 
542 // for IDX_ATAPI_IO1_i_InterruptReason
543 #define ATAPI_IR_COD 0x01
544 #define ATAPI_IR_COD_Data   0x0
545 #define ATAPI_IR_COD_Cmd    0x1
546 
547 #define ATAPI_IR_IO        0x02
548 #define ATAPI_IR_IO_toDev  0x00
549 #define ATAPI_IR_IO_toHost 0x02
550 
551 #define ATAPI_IR_Mask      0x03
552 
553 //
554 // ATA Features
555 //
556 
557 #define         ATA_F_DMA               0x01    /* enable DMA */
558 #define         ATA_F_OVL               0x02    /* enable overlap */
559 #define         ATA_F_DMAREAD           0x04    /* DMA Packet (ATAPI) read */
560 
561 #define		ATA_C_F_SETXFER	        0x03	/* set transfer mode */
562 
563 #define         ATA_C_F_ENAB_WCACHE     0x02    /* enable write cache */
564 #define         ATA_C_F_DIS_WCACHE      0x82    /* disable write cache */
565 
566 #define         ATA_C_F_ENAB_RCACHE     0xaa    /* enable readahead cache */
567 #define         ATA_C_F_DIS_RCACHE      0x55    /* disable readahead cache */
568 
569 #define         ATA_C_F_ENAB_RELIRQ     0x5d    /* enable release interrupt */
570 #define         ATA_C_F_DIS_RELIRQ      0xdd    /* disable release interrupt */
571 
572 #define         ATA_C_F_ENAB_SRVIRQ     0x5e    /* enable service interrupt */
573 #define         ATA_C_F_DIS_SRVIRQ      0xde    /* disable service interrupt */
574 
575 #define         ATA_C_F_ENAB_MEDIASTAT  0x95    /* enable media status */
576 #define         ATA_C_F_DIS_MEDIASTAT   0x31    /* disable media status */
577 
578 #define         ATA_C_F_ENAB_APM        0x05    /* enable advanced power management */
579 #define         ATA_C_F_DIS_APM         0x85    /* disable advanced power management */
580 #define           ATA_C_F_APM_CNT_MAX_PERF        0xfe    /* maximum performance */
581 #define           ATA_C_F_APM_CNT_MIN_NO_STANDBY  0x80    /* min. power w/o standby */
582 #define           ATA_C_F_APM_CNT_MIN_STANDBY     0x01    /* min. power with standby */
583 
584 #define         ATA_C_F_ENAB_ACOUSTIC   0x42    /* enable acoustic management */
585 #define         ATA_C_F_DIS_ACOUSTIC    0xc2    /* disable acoustic management */
586 #define           ATA_C_F_AAM_CNT_MAX_PERF        0xfe    /* maximum performance */
587 #define           ATA_C_F_AAM_CNT_MAX_POWER_SAVE  0x80    /* min. power */
588 
589 // New SMART Feature definitions
590 #ifndef READ_LOG_SECTOR
591 #define READ_LOG_SECTOR     0xD5
592 #define WRITE_LOG_SECTOR    0xD6
593 #define WRITE_THRESHOLDS    0xD7
594 #define AUTO_OFFLINE        0xDB
595 #endif // READ_LOG_SECTOR
596 
597 //
598 // ATAPI interrupt reasons
599 //
600 
601 #define		ATA_I_CMD		0x01	/* cmd (1) | data (0) */
602 #define		ATA_I_IN		0x02	/* read (1) | write (0) */
603 #define		ATA_I_RELEASE		0x04	/* released bus (1) */
604 #define		ATA_I_TAGMASK		0xf8	/* tag mask */
605 
606 // IDENTIFY data
607 //
608 
609 typedef struct _IDENTIFY_DATA {
610     UCHAR  AtapiCmdSize:2;                 // 00 00
611 #define         ATAPI_PSIZE_12          0       /* 12 bytes */
612 #define         ATAPI_PSIZE_16          1       /* 16 bytes */
613     UCHAR  :3;
614     UCHAR  DrqType:2;                      // 00 00
615 #define         ATAPI_DRQT_MPROC        0       /* cpu    3 ms delay */
616 #define         ATAPI_DRQT_INTR         1       /* intr  10 ms delay */
617 #define         ATAPI_DRQT_ACCEL        2       /* accel 50 us delay */
618     UCHAR  Removable:1;
619 
620     UCHAR  DeviceType:5;
621 #define         ATAPI_TYPE_DIRECT       0       /* disk/floppy */
622 #define         ATAPI_TYPE_TAPE         1       /* streaming tape */
623 #define         ATAPI_TYPE_CDROM        5       /* CD-ROM device */
624 #define         ATAPI_TYPE_OPTICAL      7       /* optical disk */
625     UCHAR  :1;
626     UCHAR  CmdProtocol:2;                      // 00 00
627 #define         ATAPI_PROTO_ATAPI       2
628 //    USHORT GeneralConfiguration;            // 00 00
629 
630     USHORT NumberOfCylinders;               // 02  1
631     USHORT Reserved1;                       // 04  2
632     USHORT NumberOfHeads;                   // 06  3
633     USHORT UnformattedBytesPerTrack;        // 08  4  // Now obsolete
634     USHORT UnformattedBytesPerSector;       // 0A  5  // Now obsolete
635     USHORT SectorsPerTrack;                 // 0C  6
636 
637     USHORT VendorUnique1[3];                // 0E  7-9
638     UCHAR  SerialNumber[20];                // 14  10-19
639 
640     USHORT BufferType;                      // 28  20
641 #define ATA_BT_SINGLEPORTSECTOR		1	/* 1 port, 1 sector buffer */
642 #define ATA_BT_DUALPORTMULTI		2	/* 2 port, mult sector buffer */
643 #define ATA_BT_DUALPORTMULTICACHE	3	/* above plus track cache */
644 
645     USHORT BufferSectorSize;                // 2A  21
646     USHORT NumberOfEccBytes;                // 2C  22
647     USHORT FirmwareRevision[4];             // 2E  23-26
648     USHORT ModelNumber[20];                 // 36  27-46
649     UCHAR  MaximumBlockTransfer;            // 5E  47
650     UCHAR  VendorUnique2;                   // 5F
651 
652     USHORT DoubleWordIo;                    // 60  48
653 
654     USHORT Reserved62_0:8;                  // 62  49
655     USHORT SupportDma:1;
656     USHORT SupportLba:1;
657     USHORT DisableIordy:1;
658     USHORT SupportIordy:1;
659     USHORT SoftReset:1;
660     USHORT StandbyOverlap:1;
661     USHORT SupportQTag:1;                                 /* supports queuing overlap */
662     USHORT SupportIDma:1;                                 /* interleaved DMA supported */
663 
664 /*    USHORT Capabilities;                    // 62  49
665 #define IDENTIFY_CAPABILITIES_SUPPORT_DMA   0x0100
666 #define IDENTIFY_CAPABILITIES_SUPPORT_LBA   0x0200
667 #define IDENTIFY_CAPABILITIES_DISABLE_IORDY 0x0400
668 #define IDENTIFY_CAPABILITIES_SUPPORT_IORDY 0x0800
669 #define IDENTIFY_CAPABILITIES_SOFT_RESET    0x1000
670 #define IDENTIFY_CAPABILITIES_STDBY_OVLP    0x2000
671 #define IDENTIFY_CAPABILITIES_SUPPORT_QTAG  0x4000
672 #define IDENTIFY_CAPABILITIES_SUPPORT_IDMA  0x8000*/
673 
674     USHORT DeviceStandbyMin:1;              // 64  50
675     USHORT Reserved50_1:13;
676     USHORT DeviceCapability1:1;
677     USHORT DeviceCapability0:1;
678 //    USHORT Reserved2;
679 
680     UCHAR  Vendor51;                        // 66  51
681     UCHAR  PioCycleTimingMode;              // 67
682 
683     UCHAR  Vendor52;                        // 68  52
684     UCHAR  DmaCycleTimingMode;              // 69
685 
686     USHORT TranslationFieldsValid:1;        // 6A  53    /* 54-58 */
687     USHORT PioTimingsValid:1;                            /* 64-70 */
688     USHORT UdmaModesValid:1;                             /* 88 */
689     USHORT Reserved3:13;
690 
691     USHORT NumberOfCurrentCylinders;        // 6C  54    \-
692     USHORT NumberOfCurrentHeads;            // 6E  55     \-
693     USHORT CurrentSectorsPerTrack;          // 70  56     /- obsolete USHORT[5]
694     ULONG  CurrentSectorCapacity;           // 72  57-58 /-
695 
696     USHORT CurrentMultiSector:8;            //     59
697     USHORT CurrentMultiSectorValid:1;
698     USHORT Reserved59_9_11:3;
699     USHORT SanitizeSupported:1;
700     USHORT CryptoScrambleExtSupported:1;
701     USHORT OverwriteExtSupported:1;
702     USHORT BlockEraseExtSupported:1;
703 
704     ULONG  UserAddressableSectors;          //     60-61
705 
706     union {
707         struct {
708             USHORT SingleWordDMASupport : 8;        //     62 ATA, obsolete
709             USHORT SingleWordDMAActive : 8;         //
710         };
711         struct {
712             USHORT UDMASupport : 7;        //     62  ATAPI
713             USHORT MultiWordDMASupport : 3;
714             USHORT DMASupport : 1;
715             USHORT Reseved62_11_14 : 4;
716             USHORT DMADirRequired : 1;
717         } AtapiDMA;
718     };
719 
720     USHORT MultiWordDMASupport : 8;         //     63
721     USHORT MultiWordDMAActive : 8;
722 
723     USHORT AdvancedPIOModes : 8;            //     64
724     USHORT Reserved4 : 8;
725 
726 #define AdvancedPIOModes_3                  1
727 #define AdvancedPIOModes_4                  2
728 #define AdvancedPIOModes_5                  4      // non-standard
729 
730     USHORT MinimumMWXferCycleTime;          //     65
731     USHORT RecommendedMWXferCycleTime;      //     66
732     USHORT MinimumPIOCycleTime;             //     67
733     USHORT MinimumPIOCycleTimeIORDY;        //     68
734 
735     USHORT Reserved69_0_4:5;                //     69
736     USHORT ReadZeroAfterTrim:1;
737     USHORT Lba28Support:1;
738     USHORT Reserved69_7_IEEE1667:1;
739     USHORT MicrocodeDownloadDMA:1;
740     USHORT MaxPwdDMA:1;
741     USHORT WriteBufferDMA:1;
742     USHORT ReadBufferDMA:1;
743     USHORT DevConfigDMA:1;
744     USHORT LongSectorErrorReporting:1;
745     USHORT DeterministicReadAfterTrim:1;
746     USHORT CFastSupport:1;
747 
748     USHORT Reserved70;                      //     70
749     USHORT ReleaseTimeOverlapped;           //     71
750     USHORT ReleaseTimeServiceCommand;       //     72
751     USHORT Reserved73_74[2];                //     73-74
752 
753     USHORT QueueLength : 5;                 //     75
754     USHORT Reserved75_6 : 11;
755 
756     USHORT SataCapabilities;                //     76
757 #define ATA_SATA_GEN1			0x0002
758 #define ATA_SATA_GEN2			0x0004
759 #define ATA_SATA_GEN3			0x0008
760 #define ATA_SUPPORT_NCQ			0x0100
761 #define ATA_SUPPORT_IFPWRMNGTRCV	0x0200
762 #define ATA_SUPPORT_PHY_EVENT_COUNTER	0x0400
763 #define ATA_SUPPORT_NCQ_UNLOAD    	0x0800
764 #define ATA_SUPPORT_NCQ_PRI_INFO    	0x1000
765 
766     USHORT Reserved77;                      //     77
767 
768     USHORT SataSupport;                     //     78
769 #define ATA_SUPPORT_NONZERO		0x0002
770 #define ATA_SUPPORT_AUTOACTIVATE	0x0004
771 #define ATA_SUPPORT_IFPWRMNGT		0x0008
772 #define ATA_SUPPORT_INORDERDATA		0x0010
773 
774     USHORT SataEnable;                      //     79
775     USHORT MajorRevision;                   //     80
776     USHORT MinorRevision;                   //     81
777 
778 #define ATA_VER_MJ_ATA4 		0x0010
779 #define ATA_VER_MJ_ATA5 		0x0020
780 #define ATA_VER_MJ_ATA6 		0x0040
781 #define ATA_VER_MJ_ATA7 		0x0080
782 #define ATA_VER_MJ_ATA8_ASC 		0x0100
783 
784     struct {
785         USHORT Smart:1;                     //     82/85
786         USHORT Security:1;
787         USHORT Removable:1;
788         USHORT PowerMngt:1;
789         USHORT Packet:1;
790         USHORT WriteCache:1;
791         USHORT LookAhead:1;
792         USHORT ReleaseDRQ:1;
793         USHORT ServiceDRQ:1;
794         USHORT Reset:1;
795         USHORT Protected:1;
796         USHORT Reserved_82_11:1;
797         USHORT WriteBuffer:1;
798         USHORT ReadBuffer:1;
799         USHORT Nop:1;
800         USHORT Reserved_82_15:1;
801 
802         USHORT Microcode:1;                  //     83/86
803         USHORT Queued:1;                     //
804         USHORT CFA:1;                        //
805         USHORT APM:1;                        //
806         USHORT Notify:1;                     //
807         USHORT Standby:1;                    //
808         USHORT Spinup:1;                     //
809         USHORT Reserver_83_7:1;
810         USHORT MaxSecurity:1;                //
811         USHORT AutoAcoustic:1;               //
812         USHORT Address48:1;                  //
813         USHORT ConfigOverlay:1;              //
814         USHORT FlushCache:1;                 //
815         USHORT FlushCache48:1;               //
816         USHORT SupportOne:1;                 //
817         USHORT SupportZero:1;                //
818 
819         USHORT SmartErrorLog:1;              //     84/87
820         USHORT SmartSelfTest:1;
821         USHORT MediaSerialNo:1;
822         USHORT MediaCardPass:1;
823         USHORT Streaming:1;
824         USHORT Logging:1;
825         USHORT Reserver_84_6:8;
826         USHORT ExtendedOne:1;                 //
827         USHORT ExtendedZero:1;                //
828     } FeaturesSupport, FeaturesEnabled;
829 
830     USHORT UltraDMASupport : 8;             //     88
831     USHORT UltraDMAActive : 8;
832 
833     USHORT EraseTime;                       //     89
834     USHORT EnhancedEraseTime;               //     90
835     USHORT CurentAPMLevel;                  //     91
836 
837     USHORT MasterPasswdRevision;            //     92
838 
839     USHORT HwResMaster : 8;                 //     93
840     USHORT HwResSlave : 5;
841     USHORT HwResCableId : 1;
842     USHORT HwResValid : 2;
843 
844 #define IDENTIFY_CABLE_ID_VALID    0x01
845 
846     USHORT CurrentAcoustic : 8;             //     94
847     USHORT VendorAcoustic : 8;
848 
849     USHORT StreamMinReqSize;                //     95
850     USHORT StreamTransferTime;              //     96
851     USHORT StreamAccessLatency;             //     97
852     ULONG  StreamGranularity;               //     98-99
853 
854     ULONGLONG UserAddressableSectors48;     //     100-103
855 
856     USHORT StreamingTransferTimePIO;        //     104
857     USHORT MaxLBARangeDescBlockCount;       //     105  // in 512b blocks
858     union {
859         USHORT PhysLogSectorSize;               //     106
860         struct {
861             USHORT PLSS_Size:4;
862             USHORT PLSS_Reserved:8;
863             USHORT PLSS_LargeL:1;  // =1 if 117-118 are valid
864             USHORT PLSS_LargeP:1;
865             USHORT PLSS_Signature:2; // = 0x01 = 01b
866         };
867     };
868     USHORT InterSeekDelay;                 //     107
869     USHORT WorldWideName[4];               //     108-111
870     USHORT Reserved112[5];                 //     112-116
871 
872     ULONG  LargeSectorSize;                 //     117-118
873 
874     struct {
875         USHORT Reserved;
876     } CommandFeatureSetSupport, CommandFeatureSetEnabled; // 119-120
877     USHORT Reserved121[4];                  //     121-124
878     USHORT AtapiByteCount0;                 //     125
879     USHORT Reserved126;                     //     126
880 
881     USHORT RemovableStatus;                 //     127
882     union {
883         USHORT SecurityStatus;                  //     128
884         struct {
885             USHORT Support:1;
886             USHORT Enabled:1;
887             USHORT Locked:1;
888             USHORT Frozen:1;
889             USHORT CountExpired:1;
890             USHORT EnhancedEraseSupport:1;
891             USHORT Reserved7_8:2;
892             USHORT MasterPasswdCap:1; // 0 - high, 1 - max
893             USHORT Reserved9_15:7;
894         } SecurityStatusOpt;
895     };
896 
897     USHORT Reserved129[31];                 //     129-159
898     USHORT CfAdvPowerMode;                  //     160
899     USHORT Reserved161[7];                 //     161-167
900     USHORT DeviceNominalFormFactor:4;      //     168
901     USHORT Reserved168_4_15:12;
902     USHORT DataSetManagementSupported:1;   //     169
903     USHORT Reserved169_1_15:15;
904     USHORT AdditionalProdNum[4];           //     170-173
905     USHORT Reserved174[2];                 //     174-175
906     USHORT MediaSerial[30];                 //     176-205
907     union {
908         USHORT SCT;                 //     206
909         struct {
910             USHORT SCT_Supported:1;
911             USHORT Reserved:1;
912             USHORT SCT_WriteSame:1;
913             USHORT SCT_ErrorRecovery:1;
914             USHORT SCT_Feature:1;
915             USHORT SCT_DataTables:1;
916             USHORT Reserved_6_15:10;
917         };
918     };
919     USHORT Reserved_CE_ATA[2];              //     207-208
920     USHORT LogicalSectorOffset:14;          //     209
921     USHORT Reserved209_14_One:1;
922     USHORT Reserved209_15_Zero:1;
923 
924     USHORT WriteReadVerify_CountMode2[2];   //     210-211
925     USHORT WriteReadVerify_CountMode3[2];   //     212-213
926 
927     USHORT NVCache_PM_Supported:1;                  //     214
928     USHORT NVCache_PM_Enabled:1;
929     USHORT NVCache_Reserved_2_3:2;
930     USHORT NVCache_Enabled:1;
931     USHORT NVCache_Reserved_5_7:3;
932     USHORT NVCache_PM_Version:4;
933     USHORT NVCache_Version:4;
934 
935     USHORT NVCache_Size_LogicalBlocks[2];   //     215-216
936     USHORT NominalMediaRotationRate;        //     217
937     USHORT Reserved218;                     //     218
938     USHORT NVCache_DeviceSpinUpTime:8;      //     219
939     USHORT NVCache_Reserved219_8_15:8;
940 
941     USHORT WriteReadVerify_CurrentMode:8;      //     220
942     USHORT WriteReadVerify_Reserved220_8_15:8;
943 
944     USHORT Reserved221;                     //     221
945     union {
946         struct {
947             USHORT VersionFlags:12;
948             USHORT TransportType:4;
949         };
950         struct {
951             USHORT ATA8_APT:1;
952             USHORT ATA_ATAPI7:1;
953             USHORT Reserved:14;
954         } PATA;
955         struct {
956             USHORT ATA8_AST:1;
957             USHORT v10a:1;
958             USHORT II_Ext:1;
959             USHORT v25:1;
960             USHORT v26:1;
961             USHORT v30:1;
962             USHORT Reserved:10;
963         } SATA;
964         USHORT Flags;
965     } TransportMajor;
966     USHORT TransportMinor;                   //     223
967 
968     USHORT Reserved224[10];                 //     224-233
969 
970     USHORT MinBlocks_MicrocodeDownload_Mode3; //     234
971     USHORT MaxBlocks_MicrocodeDownload_Mode3; //     235
972 
973     USHORT Reserved236[19];                 //     236-254
974 
975     union {
976         USHORT Integrity;                       // 255
977         struct {
978 #define ATA_ChecksumValid    0xA5
979             USHORT ChecksumValid:8;
980             USHORT Checksum:8;
981         };
982     };
983 } IDENTIFY_DATA, *PIDENTIFY_DATA;
984 
985 //
986 // Identify data without the Reserved4.
987 //
988 
989 #define IDENTIFY_DATA2      IDENTIFY_DATA
990 #define PIDENTIFY_DATA2     PIDENTIFY_DATA
991 
992 /*typedef struct _IDENTIFY_DATA2 {
993     UCHAR  AtapiCmdSize:2;                 // 00 00
994     UCHAR  :3;
995     UCHAR  DrqType:2;                      // 00 00
996     UCHAR  Removable:1;
997 
998     UCHAR  DeviceType:5;
999     UCHAR  :1;
1000     UCHAR  CmdProtocol:2;                      // 00 00
1001 //    USHORT GeneralConfiguration;            // 00
1002 
1003     USHORT NumberOfCylinders;               // 02
1004     USHORT Reserved1;                       // 04
1005     USHORT NumberOfHeads;                   // 06
1006     USHORT UnformattedBytesPerTrack;        // 08
1007     USHORT UnformattedBytesPerSector;       // 0A
1008     USHORT SectorsPerTrack;                 // 0C
1009     USHORT VendorUnique1[3];                // 0E
1010     UCHAR  SerialNumber[20];                // 14
1011     USHORT BufferType;                      // 28
1012     USHORT BufferSectorSize;                // 2A
1013     USHORT NumberOfEccBytes;                // 2C
1014     USHORT FirmwareRevision[4];             // 2E
1015     USHORT ModelNumber[20];                 // 36
1016     UCHAR  MaximumBlockTransfer;            // 5E
1017     UCHAR  VendorUnique2;                   // 5F
1018     USHORT DoubleWordIo;                    // 60
1019     USHORT Capabilities;                    // 62
1020     USHORT Reserved2;                       // 64
1021     UCHAR  VendorUnique3;                   // 66
1022     UCHAR  PioCycleTimingMode;              // 67
1023     UCHAR  VendorUnique4;                   // 68
1024     UCHAR  DmaCycleTimingMode;              // 69
1025     USHORT TranslationFieldsValid:1;        // 6A
1026     USHORT Reserved3:15;
1027     USHORT NumberOfCurrentCylinders;        // 6C
1028     USHORT NumberOfCurrentHeads;            // 6E
1029     USHORT CurrentSectorsPerTrack;          // 70
1030     ULONG  CurrentSectorCapacity;           // 72
1031 } IDENTIFY_DATA2, *PIDENTIFY_DATA2;*/
1032 
1033 #define IDENTIFY_DATA_SIZE sizeof(IDENTIFY_DATA)
1034 
1035 
1036 // IDENTIFY DMA timing cycle modes.
1037 #define IDENTIFY_DMA_CYCLES_MODE_0 0x00
1038 #define IDENTIFY_DMA_CYCLES_MODE_1 0x01
1039 #define IDENTIFY_DMA_CYCLES_MODE_2 0x02
1040 
1041 // for IDE_COMMAND_DATA_SET_MGMT
1042 typedef struct _TRIM_DATA {
1043     ULONGLONG Lba:48;
1044     ULONGLONG BlockCount:16;
1045 } TRIM_DATA, *PTRIM_DATA;
1046 
1047 /*
1048 #define PCI_DEV_HW_SPEC(idhi, idlo) \
1049     { #idlo, 4, #idhi, 4}
1050 
1051 typedef struct _BROKEN_CONTROLLER_INFORMATION {
1052     PCHAR   VendorId;
1053     ULONG   VendorIdLength;
1054     PCHAR   DeviceId;
1055     ULONG   DeviceIdLength;
1056 }BROKEN_CONTROLLER_INFORMATION, *PBROKEN_CONTROLLER_INFORMATION;
1057 
1058 BROKEN_CONTROLLER_INFORMATION const BrokenAdapters[] = {
1059     // CMD 640 ATA controller !WARNING! buggy chip data loss possible
1060     PCI_DEV_HW_SPEC( 0640, 1095 ), //{ "1095", 4, "0640", 4},
1061     // ??
1062     PCI_DEV_HW_SPEC( 0601, 1039 ), //{ "1039", 4, "0601", 4}
1063     // RZ 100? ATA controller !WARNING! buggy chip data loss possible
1064     PCI_DEV_HW_SPEC( 1000, 1042 ),
1065     PCI_DEV_HW_SPEC( 1001, 1042 )
1066 };
1067 
1068 #define BROKEN_ADAPTERS (sizeof(BrokenAdapters) / sizeof(BROKEN_CONTROLLER_INFORMATION))
1069 
1070 typedef struct _NATIVE_MODE_CONTROLLER_INFORMATION {
1071     PCHAR   VendorId;
1072     ULONG   VendorIdLength;
1073     PCHAR   DeviceId;
1074     ULONG   DeviceIdLength;
1075 }NATIVE_MODE_CONTROLLER_INFORMATION, *PNATIVE_MODE_CONTROLLER_INFORMATION;
1076 
1077 NATIVE_MODE_CONTROLLER_INFORMATION const NativeModeAdapters[] = {
1078     PCI_DEV_HW_SPEC( 0105, 10ad ) //{ "10ad", 4, "0105", 4}
1079 };
1080 
1081 #define NUM_NATIVE_MODE_ADAPTERS (sizeof(NativeModeAdapters) / sizeof(NATIVE_MODE_CONTROLLER_INFORMATION))
1082 */
1083 //
1084 // Beautification macros
1085 //
1086 
1087 #ifndef USER_MODE
1088 
1089 #define GetStatus(chan, Status) \
1090     Status = AtapiReadPort1(chan, IDX_IO2_AltStatus);
1091 
1092 #define GetBaseStatus(chan, pStatus) \
1093     pStatus = AtapiReadPort1(chan, IDX_IO1_i_Status);
1094 
1095 #define WriteCommand(chan, _Command) \
1096     AtapiWritePort1(chan, IDX_IO1_o_Command, _Command);
1097 
1098 /*
1099 #define SelectDrive(chan, unit) { \
1100     if(chan && chan->lun[unit] && chan->lun[unit]->DeviceFlags & DFLAGS_ATAPI_CHANGER) KdPrint3(("  Select %d\n", unit)); \
1101     AtapiWritePort1(chan, IDX_IO1_o_DriveSelect, (unit) ? IDE_DRIVE_SELECT_2 : IDE_DRIVE_SELECT_1); \
1102 }
1103 */
1104 
1105 #define ReadBuffer(chan, Buffer, Count, timing) \
1106     AtapiReadBuffer2(chan, IDX_IO1_i_Data, \
1107                                  Buffer, \
1108                                  Count, \
1109                                  timing);
1110 
1111 #define WriteBuffer(chan, Buffer, Count, timing) \
1112     AtapiWriteBuffer2(chan, IDX_IO1_o_Data, \
1113                                   Buffer, \
1114                                  Count, \
1115                                  timing);
1116 
1117 #define ReadBuffer2(chan, Buffer, Count, timing) \
1118     AtapiReadBuffer4(chan, IDX_IO1_i_Data, \
1119                              Buffer, \
1120                                  Count, \
1121                                  timing);
1122 
1123 #define WriteBuffer2(chan, Buffer, Count, timing) \
1124     AtapiWriteBuffer4(chan, IDX_IO1_o_Data, \
1125                               Buffer, \
1126                                  Count, \
1127                                  timing);
1128 
1129 UCHAR
1130 DDKFASTAPI
1131 SelectDrive(
1132     IN struct _HW_CHANNEL*   chan,
1133     IN ULONG                 DeviceNumber
1134     );
1135 
1136 UCHAR
1137 DDKFASTAPI
1138 WaitOnBusy(
1139     IN struct _HW_CHANNEL*   chan/*,
1140     PIDE_REGISTERS_2 BaseIoAddress*/
1141     );
1142 
1143 UCHAR
1144 DDKFASTAPI
1145 WaitOnBusyLong(
1146     IN struct _HW_CHANNEL*   chan/*,
1147     PIDE_REGISTERS_2 BaseIoAddress*/
1148     );
1149 
1150 UCHAR
1151 DDKFASTAPI
1152 WaitOnBaseBusy(
1153     IN struct _HW_CHANNEL*   chan/*,
1154     PIDE_REGISTERS_1 BaseIoAddress*/
1155     );
1156 
1157 UCHAR
1158 DDKFASTAPI
1159 WaitOnBaseBusyLong(
1160     IN struct _HW_CHANNEL*   chan/*,
1161     PIDE_REGISTERS_1 BaseIoAddress*/
1162     );
1163 
1164 UCHAR
1165 DDKFASTAPI
1166 WaitForDrq(
1167     IN struct _HW_CHANNEL*   chan/*,
1168     PIDE_REGISTERS_2 BaseIoAddress*/
1169     );
1170 
1171 UCHAR
1172 DDKFASTAPI
1173 WaitShortForDrq(
1174     IN struct _HW_CHANNEL*   chan/*,
1175     PIDE_REGISTERS_2 BaseIoAddress*/
1176     );
1177 
1178 VOID
1179 DDKFASTAPI
1180 AtapiSoftReset(
1181     IN struct _HW_CHANNEL*   chan,/*
1182     PIDE_REGISTERS_1 BaseIoAddress*/
1183     IN ULONG            DeviceNumber
1184     );
1185 
1186 VOID
1187 DDKFASTAPI
1188 AtapiHardReset(
1189     IN struct _HW_CHANNEL*   chan,
1190     IN BOOLEAN               DisableInterrupts,
1191     IN ULONG                 Delay
1192     );
1193 
1194 
1195 #endif //USER_MODE
1196 
1197 #define IS_RDP(OperationCode)\
1198     ((OperationCode == SCSIOP_ERASE)||\
1199     (OperationCode == SCSIOP_LOAD_UNLOAD)||\
1200     (OperationCode == SCSIOP_LOCATE)||\
1201     (OperationCode == SCSIOP_REWIND) ||\
1202     (OperationCode == SCSIOP_SPACE)||\
1203     (OperationCode == SCSIOP_SEEK)||\
1204 /*    (OperationCode == SCSIOP_FORMAT_UNIT)||\
1205     (OperationCode == SCSIOP_BLANK)||*/ \
1206     (OperationCode == SCSIOP_WRITE_FILEMARKS))
1207 
1208 #ifndef USER_MODE
1209 
1210 PSCSI_REQUEST_BLOCK
1211 NTAPI
1212 BuildMechanismStatusSrb (
1213     IN PVOID HwDeviceExtension,
1214     IN PSCSI_REQUEST_BLOCK Srb
1215     );
1216 
1217 PSCSI_REQUEST_BLOCK
1218 NTAPI
1219 BuildRequestSenseSrb (
1220     IN PVOID HwDeviceExtension,
1221     IN PSCSI_REQUEST_BLOCK Srb
1222     );
1223 
1224 VOID
1225 NTAPI
1226 AtapiHwInitializeChanger (
1227     IN PVOID HwDeviceExtension,
1228     IN ULONG TargetId,
1229     IN PMECHANICAL_STATUS_INFORMATION_HEADER MechanismStatus
1230     );
1231 
1232 ULONG
1233 NTAPI
1234 AtapiSendCommand(
1235     IN PVOID HwDeviceExtension,
1236     IN PSCSI_REQUEST_BLOCK Srb,
1237     IN ULONG CmdAction
1238     );
1239 
1240 ULONG
1241 NTAPI
1242 IdeSendCommand(
1243     IN PVOID HwDeviceExtension,
1244     IN PSCSI_REQUEST_BLOCK Srb,
1245     IN ULONG CmdAction
1246     );
1247 
1248 #define AtapiCopyMemory RtlCopyMemory
1249 
1250 VOID
1251 NTAPI
1252 AtapiHexToString (
1253     ULONG Value,
1254     PCHAR *Buffer
1255     );
1256 
1257 #define AtapiStringCmp(s1, s2, n)  _strnicmp(s1, s2, n)
1258 
1259 BOOLEAN
1260 NTAPI
1261 AtapiInterrupt(
1262     IN PVOID HwDeviceExtension
1263     );
1264 
1265 BOOLEAN
1266 NTAPI
1267 AtapiInterrupt__(
1268     IN PVOID HwDeviceExtension,
1269     IN UCHAR c
1270     );
1271 
1272 UCHAR
1273 NTAPI
1274 AtapiCheckInterrupt__(
1275     IN PVOID HwDeviceExtension,
1276     IN UCHAR c
1277     );
1278 
1279 #define INTERRUPT_REASON_IGNORE          0
1280 #define INTERRUPT_REASON_OUR             1
1281 #define INTERRUPT_REASON_UNEXPECTED      2
1282 
1283 BOOLEAN
1284 NTAPI
1285 AtapiHwInitialize(
1286     IN PVOID HwDeviceExtension
1287         );
1288 
1289 ULONG
1290 NTAPI
1291 IdeBuildSenseBuffer(
1292     IN PVOID HwDeviceExtension,
1293     IN PSCSI_REQUEST_BLOCK Srb
1294     );
1295 
1296 VOID
1297 NTAPI
1298 IdeMediaStatus(
1299     BOOLEAN EnableMSN,
1300     IN PVOID HwDeviceExtension,
1301     IN ULONG lChannel,
1302     IN ULONG DeviceNumber
1303     );
1304 
1305 ULONG
1306 NTAPI
1307 AtapiFindIsaController(
1308     IN PVOID HwDeviceExtension,
1309     IN PVOID Context,
1310     IN PVOID BusInformation,
1311     IN PCHAR ArgumentString,
1312     IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo,
1313     OUT PBOOLEAN Again
1314     );
1315 
1316 ULONG
1317 NTAPI
1318 AtapiReadArgumentString(
1319     IN PVOID HwDeviceExtension,
1320     IN PVOID Context,
1321     IN PVOID BusInformation,
1322     IN PCHAR ArgumentString,
1323     IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo,
1324     OUT PBOOLEAN Again
1325     );
1326 
1327 ULONG
1328 NTAPI
1329 AtapiParseArgumentString(
1330     IN PCCH String,
1331     IN PCCH KeyWord
1332     );
1333 
1334 BOOLEAN
1335 NTAPI
1336 IssueIdentify(
1337     IN PVOID HwDeviceExtension,
1338     IN ULONG DeviceNumber,
1339     IN ULONG Channel,
1340     IN UCHAR Command,
1341     IN BOOLEAN NoSetup
1342     );
1343 
1344 BOOLEAN
1345 NTAPI
1346 SetDriveParameters(
1347     IN PVOID HwDeviceExtension,
1348     IN ULONG DeviceNumber,
1349     IN ULONG Channel
1350     );
1351 
1352 ULONG
1353 NTAPI
1354 CheckDevice(
1355     IN PVOID   HwDeviceExtension,
1356     IN ULONG   Channel,
1357     IN ULONG   deviceNumber,
1358     IN BOOLEAN ResetBus
1359     );
1360 
1361 #define UNIATA_FIND_DEV_UNHIDE    0x01
1362 
1363 BOOLEAN
1364 NTAPI
1365 FindDevices(
1366     IN PVOID HwDeviceExtension,
1367     IN ULONG   Flags,
1368     IN ULONG   Channel
1369     );
1370 
1371 #endif //USER_MODE
1372 
1373 #ifdef __cplusplus
1374 };
1375 #endif //__cplusplus
1376 
1377 #ifndef USER_MODE
1378 
1379 BOOLEAN
1380 NTAPI
1381 AtapiResetController(
1382     IN PVOID HwDeviceExtension,
1383     IN ULONG PathId
1384     );
1385 
1386 BOOLEAN
1387 NTAPI
1388 AtapiStartIo(
1389     IN PVOID HwDeviceExtension,
1390     IN PSCSI_REQUEST_BLOCK Srb
1391     );
1392 
1393 BOOLEAN
1394 NTAPI
1395 AtapiStartIo__(
1396     IN PVOID HwDeviceExtension,
1397     IN PSCSI_REQUEST_BLOCK Srb,
1398     IN BOOLEAN TopLevel
1399     );
1400 
1401 extern UCHAR
1402 NTAPI
1403 AtaCommand48(
1404 //    IN PVOID HwDeviceExtension,
1405     IN struct _HW_DEVICE_EXTENSION* deviceExtension,
1406     IN ULONG DeviceNumber,
1407     IN ULONG Channel,
1408     IN UCHAR command,
1409     IN ULONGLONG lba,
1410     IN USHORT count,
1411     IN USHORT feature,
1412     IN ULONG flags
1413     );
1414 
1415 extern UCHAR
1416 NTAPI
1417 AtaCommand(
1418 //    IN PVOID HwDeviceExtension,
1419     IN struct _HW_DEVICE_EXTENSION* deviceExtension,
1420     IN ULONG DeviceNumber,
1421     IN ULONG Channel,
1422     IN UCHAR command,
1423     IN USHORT cylinder,
1424     IN UCHAR head,
1425     IN UCHAR sector,
1426     IN UCHAR count,
1427     IN UCHAR feature,
1428     IN ULONG flags
1429     );
1430 
1431 extern LONG
1432 NTAPI
1433 AtaPioMode(PIDENTIFY_DATA2 ident);
1434 
1435 extern LONG
1436 NTAPI
1437 AtaWmode(PIDENTIFY_DATA2 ident);
1438 
1439 extern LONG
1440 NTAPI
1441 AtaUmode(PIDENTIFY_DATA2 ident);
1442 
1443 extern VOID
1444 NTAPI
1445 AtapiDpcDispatch(
1446     IN PKDPC Dpc,
1447     IN PVOID DeferredContext,
1448     IN PVOID SystemArgument1,
1449     IN PVOID SystemArgument2
1450     );
1451 
1452 //#define AtaCommand(de, devn, chan, cmd, cyl, hd, sec, cnt, feat, flg)
1453 
1454 extern LONG
1455 NTAPI
1456 AtaPio2Mode(LONG pio);
1457 
1458 extern LONG
1459 NTAPI
1460 AtaPioMode(PIDENTIFY_DATA2 ident);
1461 
1462 extern VOID
1463 NTAPI
1464 AtapiEnableInterrupts(
1465     IN PVOID HwDeviceExtension,
1466     IN ULONG c
1467     );
1468 
1469 extern VOID
1470 NTAPI
1471 AtapiDisableInterrupts(
1472     IN PVOID HwDeviceExtension,
1473     IN ULONG c
1474     );
1475 
1476 extern VOID
1477 UniataExpectChannelInterrupt(
1478     IN struct _HW_CHANNEL* chan,
1479     IN BOOLEAN Expecting
1480     );
1481 
1482 #define CHAN_NOT_SPECIFIED                  (0xffffffffL)
1483 #define CHAN_NOT_SPECIFIED_CHECK_CABLE      (0xfffffffeL)
1484 #define DEVNUM_NOT_SPECIFIED                (0xffffffffL)
1485 #define IOMODE_NOT_SPECIFIED                (0xffffffffL)
1486 
1487 extern ULONG
1488 NTAPI
1489 AtapiRegCheckDevValue(
1490     IN PVOID HwDeviceExtension,
1491     IN ULONG chan,
1492     IN ULONG dev,
1493     IN PCWSTR Name,
1494     IN ULONG Default
1495     );
1496 
1497 extern ULONG
1498 NTAPI
1499 AtapiRegCheckParameterValue(
1500     IN PVOID HwDeviceExtension,
1501     IN PCWSTR PathSuffix,
1502     IN PCWSTR Name,
1503     IN ULONG Default
1504     );
1505 
1506 extern ULONG g_LogToDisplay;
1507 
1508 extern "C"
1509 VOID
1510 _cdecl
1511 _PrintNtConsole(
1512     PCCH DebugMessage,
1513     ...
1514     );
1515 
1516 VOID
1517 NTAPI
1518 UniataInitMapBM(
1519     IN struct _HW_DEVICE_EXTENSION* deviceExtension,
1520     IN struct _IDE_BUSMASTER_REGISTERS* BaseIoAddressBM_0,
1521     IN BOOLEAN MemIo
1522     );
1523 
1524 VOID
1525 NTAPI
1526 UniataInitMapBase(
1527     IN struct _HW_CHANNEL* chan,
1528     IN PIDE_REGISTERS_1 BaseIoAddress1,
1529     IN PIDE_REGISTERS_2 BaseIoAddress2
1530     );
1531 
1532 VOID
1533 NTAPI
1534 UniataInitSyncBaseIO(
1535     IN struct _HW_CHANNEL* chan
1536     );
1537 
1538 VOID
1539 UniataInitIoRes(
1540     IN struct _HW_CHANNEL* chan,
1541     IN ULONG idx,
1542     IN ULONG addr,
1543     IN BOOLEAN MemIo,
1544     IN BOOLEAN Proc
1545     );
1546 
1547 VOID
1548 UniataInitIoResEx(
1549     IN struct _IORES* IoRes,
1550     IN ULONG addr,
1551     IN BOOLEAN MemIo,
1552     IN BOOLEAN Proc
1553     );
1554 
1555 UCHAR
1556 DDKFASTAPI
1557 UniataIsIdle(
1558     IN struct _HW_DEVICE_EXTENSION* deviceExtension,
1559     IN UCHAR Status
1560     );
1561 
1562 VOID
1563 NTAPI
1564 UniataDumpATARegs(
1565     IN struct _HW_CHANNEL* chan
1566     );
1567 
1568 ULONG
1569 NTAPI
1570 EncodeVendorStr(
1571    OUT PWCHAR Buffer,
1572     IN PUCHAR Str,
1573     IN ULONG  Length
1574     );
1575 
1576 ULONGLONG
1577 NTAPI
1578 UniAtaCalculateLBARegsBack(
1579     struct _HW_LU_EXTENSION* LunExt,
1580     ULONGLONG            lba
1581     );
1582 
1583 ULONG
1584 NTAPI
1585 UniataAnybodyHome(
1586     IN PVOID   HwDeviceExtension,
1587     IN ULONG   Channel,
1588     IN ULONG   deviceNumber
1589     );
1590 
1591 #endif //USER_MODE
1592 
1593 #define ATA_AT_HOME_HDD        0x01
1594 #define ATA_AT_HOME_ATAPI      0x02
1595 #define ATA_AT_HOME_XXX        0x04
1596 #define ATA_AT_HOME_NOBODY     0x00
1597 
1598 #define ATA_CMD_FLAG_LBAIOsupp 0x01
1599 #define ATA_CMD_FLAG_48supp    0x02
1600 #define ATA_CMD_FLAG_48        0x04
1601 #define ATA_CMD_FLAG_DMA       0x08
1602 #define ATA_CMD_FLAG_FUA       0x10
1603 #define ATA_CMD_FLAG_In        0x40
1604 #define ATA_CMD_FLAG_Out       0x80
1605 
1606 /*
1607  We need LBA48 when requested LBA or BlockCount are too large.
1608  But for LBA-based commands we have *special* limitation
1609 */
1610 #define UniAta_need_lba48(command, lba, count, supp48) \
1611     (  ((AtaCommandFlags[command] & ATA_CMD_FLAG_LBAIOsupp) && (supp48) && (((lba+count) >= ATA_MAX_IOLBA28) || (count > 256)) ) || \
1612        (lba > ATA_MAX_LBA28) || (count > 255) )
1613 
1614 #ifndef USER_MODE
1615 
1616 #define UniAtaClearAtaReq(AtaReq) \
1617 {  \
1618         RtlZeroMemory((PCHAR)(AtaReq), FIELD_OFFSET(ATA_REQ, ata)); \
1619 }
1620 
1621 extern UCHAR const AtaCommands48[256];
1622 extern UCHAR const AtaCommandFlags[256];
1623 
1624 //#define ATAPI_DEVICE(de, ldev)    (de->lun[ldev].DeviceFlags & DFLAGS_ATAPI_DEVICE)
1625 #define ATAPI_DEVICE(chan, dev)    ((chan->lun[dev]->DeviceFlags & DFLAGS_ATAPI_DEVICE) ? TRUE : FALSE)
1626 
1627 #ifdef _DEBUG
1628 #define PrintNtConsole  _PrintNtConsole
1629 #else //_DEBUG
1630 #define PrintNtConsole(x)  {;}
1631 #endif //_DEBUG
1632 
1633 #endif //USER_MODE
1634 
1635 __inline
1636 BOOLEAN
1637 ata_is_sata(
1638     PIDENTIFY_DATA ident
1639     )
1640 {
1641     return (ident->SataCapabilities && ident->SataCapabilities != 0xffff);
1642 } // end ata_is_sata()
1643 
1644 #define IDENT_MODE_MAX     FALSE
1645 #define IDENT_MODE_ACTIVE  TRUE
1646 
1647 __inline
1648 LONG
1649 ata_cur_mode_from_ident(
1650     PIDENTIFY_DATA ident,
1651     BOOLEAN Active
1652     )
1653 {
1654     USHORT mode;
1655     if(ata_is_sata(ident)) {
1656         if(ident->SataCapabilities & ATA_SATA_GEN3) {
1657             return ATA_SA600;
1658         } else
1659         if(ident->SataCapabilities & ATA_SATA_GEN2) {
1660             return ATA_SA300;
1661         } else
1662         if(ident->SataCapabilities & ATA_SATA_GEN1) {
1663             return ATA_SA150;
1664         }
1665         return ATA_SA150;
1666     }
1667 
1668     if (ident->UdmaModesValid) {
1669         mode = Active ? ident->UltraDMAActive : ident->UltraDMASupport;
1670         if (mode & 0x40)
1671             return ATA_UDMA0+6;
1672         if (mode & 0x20)
1673             return ATA_UDMA0+5;
1674         if (mode & 0x10)
1675             return ATA_UDMA0+4;
1676         if (mode & 0x08)
1677             return ATA_UDMA0+3;
1678         if (mode & 0x04)
1679             return ATA_UDMA0+2;
1680         if (mode & 0x02)
1681             return ATA_UDMA0+1;
1682         if (mode & 0x01)
1683             return ATA_UDMA0+0;
1684     }
1685 
1686     mode = Active ? ident->MultiWordDMAActive : ident->MultiWordDMASupport;
1687     if (ident->MultiWordDMAActive & 0x04)
1688         return ATA_WDMA0+2;
1689     if (ident->MultiWordDMAActive & 0x02)
1690         return ATA_WDMA0+1;
1691     if (ident->MultiWordDMAActive & 0x01)
1692         return ATA_WDMA0+0;
1693 
1694     mode = Active ? ident->SingleWordDMAActive : ident->SingleWordDMASupport;
1695     if (ident->SingleWordDMAActive & 0x04)
1696         return ATA_SDMA0+2;
1697     if (ident->SingleWordDMAActive & 0x02)
1698         return ATA_SDMA0+1;
1699     if (ident->SingleWordDMAActive & 0x01)
1700         return ATA_SDMA0+0;
1701 
1702     if (ident->PioTimingsValid) {
1703         mode = ident->AdvancedPIOModes;
1704         if (mode & AdvancedPIOModes_5)
1705             return ATA_PIO0+5;
1706         if (mode & AdvancedPIOModes_4)
1707             return ATA_PIO0+4;
1708         if (mode & AdvancedPIOModes_3)
1709             return ATA_PIO0+3;
1710     }
1711     mode = ident->PioCycleTimingMode;
1712     if (ident->PioCycleTimingMode == 2)
1713         return ATA_PIO0+2;
1714     if (ident->PioCycleTimingMode == 1)
1715         return ATA_PIO0+1;
1716     if (ident->PioCycleTimingMode == 0)
1717         return ATA_PIO0+0;
1718 
1719     return ATA_PIO;
1720 } // end ata_cur_mode_from_ident()
1721 
1722 #pragma pack(pop)
1723 
1724 #endif // __GLOBAL_H__
1725