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