xref: /reactos/drivers/storage/ide/uniata/bsmaster.h (revision 02e84521)
1 /*++
2 
3 Copyright (c) 2002-2014 Alexandr A. Telyatnikov (Alter)
4 
5 Module Name:
6     bsmaster.h
7 
8 Abstract:
9     This file contains DMA/UltraDMA and IDE BusMastering related definitions,
10     internal structures and useful macros
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     Code was created by
34          Alter, Copyright (c) 2002-2015
35 
36     Some definitions were taken from FreeBSD 4.3-9.2 ATA driver by
37          S�ren Schmidt, Copyright (c) 1998-2014
38 
39 Licence:
40     GPLv2
41 
42 --*/
43 
44 #ifndef __IDE_BUSMASTER_H__
45 #define __IDE_BUSMASTER_H__
46 
47 #include "config.h"
48 
49 #include "tools.h"
50 
51 //
52 //
53 //
54 #define         ATA_IDLE                0x0
55 #define         ATA_IMMEDIATE           0x1
56 #define         ATA_WAIT_INTR           0x2
57 #define         ATA_WAIT_READY          0x3
58 #define         ATA_ACTIVE              0x4
59 #define         ATA_ACTIVE_ATA          0x5
60 #define         ATA_ACTIVE_ATAPI        0x6
61 #define         ATA_REINITING           0x7
62 #define         ATA_WAIT_BASE_READY     0x8
63 #define         ATA_WAIT_IDLE           0x9
64 
65 
66 #include "bm_devs_decl.h"
67 
68 #include "uata_ctl.h"
69 
70 #pragma pack(push, 8)
71 
72 #define MAX_RETRIES                     6
73 #define RETRY_UDMA2                     1
74 #define RETRY_WDMA                      2
75 #define RETRY_PIO                       3
76 
77 
78 #define	IO_WD1	        0x1F0		/* Primary Fixed Disk Controller */
79 #define	IO_WD2	        0x170		/* Secondary Fixed Disk Controller */
80 #define IP_PC98_BANK    0x432
81 #define	IO_FLOPPY_INT	0x3F6		/* AltStatus inside Floppy I/O range */
82 
83 #define PCI_ADDRESS_IOMASK              0xfffffff0
84 
85 #define ATA_BM_OFFSET1			0x08
86 #define ATA_IOSIZE			0x08
87 #define ATA_ALTOFFSET			0x206	/* alternate registers offset */
88 #define ATA_PCCARD_ALTOFFSET		0x0e	/* do for PCCARD devices */
89 #define ATA_ALTIOSIZE			0x01	/* alternate registers size */
90 #define ATA_BMIOSIZE			0x20
91 #define ATA_PC98_BANKIOSIZE             0x01
92 //#define ATA_MAX_LBA28                   DEF_U64(0x0fffffff)
93 // Hitachi 1 Tb HDD didn't allow LBA28 with BCount > 1 beyond this LBA
94 #define ATA_MAX_IOLBA28                 DEF_U64(0x0fffff80)
95 #define ATA_MAX_LBA28                   DEF_U64(0x0fffffff)
96 
97 #define ATA_DMA_ENTRIES			256     /* PAGESIZE/2/sizeof(BM_DMA_ENTRY)*/
98 #define ATA_DMA_EOT			0x80000000
99 
100 #define DEV_BSIZE                       512
101 
102 #define ATAPI_MAGIC_LSB			0x14
103 #define ATAPI_MAGIC_MSB			0xeb
104 
105 #define AHCI_MAX_PORT                   32
106 
107 #define SATA_MAX_PM_UNITS               16
108 
109 typedef struct _BUSMASTER_CTX {
110     PBUSMASTER_CONTROLLER_INFORMATION* BMListPtr;
111     ULONG* BMListLen;
112 } BUSMASTER_CTX, *PBUSMASTER_CTX;
113 
114 #define PCI_DEV_CLASS_STORAGE           0x01
115 
116 #define PCI_DEV_SUBCLASS_IDE            0x01
117 #define PCI_DEV_SUBCLASS_RAID           0x04
118 #define PCI_DEV_SUBCLASS_ATA            0x05
119 #define PCI_DEV_SUBCLASS_SATA           0x06
120 
121 #define PCI_DEV_PROGIF_AHCI_1_0         0x01
122 
123 #pragma pack(push, 1)
124 
125 /* structure for holding DMA address data */
126 typedef struct BM_DMA_ENTRY {
127     ULONG base;
128     ULONG count;
129 } BM_DMA_ENTRY, *PBM_DMA_ENTRY;
130 
131 typedef struct _IDE_BUSMASTER_REGISTERS {
132     UCHAR Command;
133     UCHAR DeviceSpecific0;
134     UCHAR Status;
135     UCHAR DeviceSpecific1;
136     ULONG PRD_Table;
137 } IDE_BUSMASTER_REGISTERS, *PIDE_BUSMASTER_REGISTERS;
138 
139 #define BM_STATUS_ACTIVE                0x01
140 #define BM_STATUS_ERR                   0x02
141 #define BM_STATUS_INTR                  0x04
142 #define BM_STATUS_MASK                  0x07
143 #define BM_STATUS_DRIVE_0_DMA           0x20
144 #define BM_STATUS_DRIVE_1_DMA           0x40
145 #define BM_STATUS_SIMPLEX_ONLY          0x80
146 
147 #define BM_COMMAND_START_STOP		0x01
148 /*#define BM_COMMAND_WRITE		0x08
149 #define BM_COMMAND_READ		        0x00*/
150 #define BM_COMMAND_WRITE		0x00
151 #define BM_COMMAND_READ		        0x08
152 
153 #define BM_DS0_SII_DMA_ENABLE           (1 << 0)  /* DMA run switch */
154 #define BM_DS0_SII_IRQ	                (1 << 3)  /* ??? */
155 #define BM_DS0_SII_DMA_SATA_IRQ	        (1 << 4)  /* OR of all SATA IRQs */
156 #define BM_DS0_SII_DMA_ERROR	        (1 << 17) /* PCI bus error */
157 #define BM_DS0_SII_DMA_COMPLETE	        (1 << 18) /* cmd complete / IRQ pending */
158 
159 
160 #define IDX_BM_IO                       (IDX_IO2_o+IDX_IO2_o_SZ)
161 //#define IDX_BM_IO_SZ                    sizeof(IDE_BUSMASTER_REGISTERS)
162 #define IDX_BM_IO_SZ                    5
163 
164 #define IDX_BM_Command                  (FIELD_OFFSET(IDE_BUSMASTER_REGISTERS, Command        )+IDX_BM_IO)
165 #define IDX_BM_DeviceSpecific0          (FIELD_OFFSET(IDE_BUSMASTER_REGISTERS, DeviceSpecific0)+IDX_BM_IO)
166 #define IDX_BM_Status                   (FIELD_OFFSET(IDE_BUSMASTER_REGISTERS, Status         )+IDX_BM_IO)
167 #define IDX_BM_DeviceSpecific1          (FIELD_OFFSET(IDE_BUSMASTER_REGISTERS, DeviceSpecific1)+IDX_BM_IO)
168 #define IDX_BM_PRD_Table                (FIELD_OFFSET(IDE_BUSMASTER_REGISTERS, PRD_Table      )+IDX_BM_IO)
169 
170 typedef struct _IDE_AHCI_REGISTERS {
171     // HBA Capabilities
172     struct {
173         ULONG NOP:5;   // number of ports
174         ULONG SXS:1;   // Supports External SATA
175         ULONG EMS:1;   // Enclosure Management Supported
176         ULONG CCCS:1;  // Command Completion Coalescing Supported
177         ULONG NCS:5;   // number of command slots
178         ULONG PSC:1;   // partial state capable
179         ULONG SSC:1;   // slumber state capable
180         ULONG PMD:1;   // PIO multiple DRQ block
181         ULONG FBSS:1;  // FIS-based Switching Supported
182 
183         ULONG SPM:1;   // port multiplier
184         ULONG SAM:1;   // AHCI mode only
185         ULONG SNZO:1;  // non-zero DMA offset
186         ULONG ISS:4;   // interface speed
187         ULONG SCLO:1;  // command list override
188         ULONG SAL:1;   // activity LED
189         ULONG SALP:1;  // aggressive link power management
190         ULONG SSS:1;   // staggered spin-up
191         ULONG SIS:1;   // interlock switch
192         ULONG SSNTF:1; // Supports SNotification Register
193         ULONG SNCQ:1;  // native command queue
194         ULONG S64A:1;  // 64bit addr
195     } CAP;
196 
197 #define AHCI_CAP_NOP_MASK    0x0000001f
198 #define AHCI_CAP_CCC         0x00000080
199 #define AHCI_CAP_NCS_MASK    0x00001f00
200 #define AHCI_CAP_PMD         0x00008000
201 #define AHCI_CAP_SPM         0x00020000
202 #define AHCI_CAP_SAM         0x00040000
203 #define	AHCI_CAP_ISS_MASK    0x00f00000
204 #define	AHCI_CAP_SCLO	     0x01000000
205 #define AHCI_CAP_SNTF        0x20000000
206 #define	AHCI_CAP_NCQ	     0x40000000
207 #define AHCI_CAP_S64A        0x80000000
208 
209     // Global HBA Control
210     struct {
211         ULONG HR:1;    // HBA Reset
212         ULONG IE:1;    // interrupt enable
213         ULONG Reserved2_30:1;
214         ULONG AE:1;    // AHCI enable
215     } GHC;
216 
217 #define AHCI_GHC   0x04
218 #define AHCI_GHC_HR    0x00000001
219 #define AHCI_GHC_IE    0x00000002
220 #define AHCI_GHC_AE    0x80000000
221 
222     // Interrupt status (bit mask)
223     ULONG IS; //  0x08
224     // Ports implemented (bit mask)
225     ULONG PI; //  0x0c
226     // AHCI Version
227     ULONG VS; //  0x10
228 
229     ULONG CCC_CTL; //  0x14
230     ULONG CCC_PORTS; //  0x18
231     ULONG EM_LOC; //  0x1c
232     ULONG EM_CTL; //  0x20
233 
234     // Extended HBA Capabilities
235     struct { //  0x24
236         ULONG BOH:1;   // BIOS/OS Handoff
237         ULONG NVMP:1;  // NVMHCI Present
238         ULONG APST:1;  // Automatic Partial to Slumber Transitions
239         ULONG Reserved:29;
240     } CAP2;
241 
242 #define AHCI_CAP2_BOH       0x00000001
243 #define AHCI_CAP2_NVMP      0x00000002
244 #define AHCI_CAP2_APST      0x00000004
245 
246     // BIOS/OS Handoff Control and Status
247     struct { //  0x28
248         ULONG BB:1;    // BIOS Busy
249         ULONG OOC:1;   // OS Ownership Change
250         ULONG SOOE:1;  // SMI on OS Ownership Change Enable
251         ULONG OOS:1;   // OS Owned Semaphore
252         ULONG BOS:1;   // BIOS Owned Semaphore
253         ULONG Reserved:27;
254     } BOHC;
255 
256 #define AHCI_BOHC_BB      0x00000001
257 #define AHCI_BOHC_OOC     0x00000002
258 #define AHCI_BOHC_SOOE    0x00000004
259 #define AHCI_BOHC_OOS     0x00000008
260 #define AHCI_BOHC_BOS     0x00000010
261 
262     UCHAR Reserved2[0x74];
263 
264     UCHAR VendorSpec[0x60];
265 } IDE_AHCI_REGISTERS, *PIDE_AHCI_REGISTERS;
266 
267 #define IDX_AHCI_CAP                    (FIELD_OFFSET(IDE_AHCI_REGISTERS, CAP))
268 #define IDX_AHCI_GHC                    (FIELD_OFFSET(IDE_AHCI_REGISTERS, GHC))
269 #define IDX_AHCI_IS                     (FIELD_OFFSET(IDE_AHCI_REGISTERS, IS))
270 #define IDX_AHCI_VS                     (FIELD_OFFSET(IDE_AHCI_REGISTERS, VS))
271 #define IDX_AHCI_PI                     (FIELD_OFFSET(IDE_AHCI_REGISTERS, PI))
272 #define IDX_AHCI_CAP2                   (FIELD_OFFSET(IDE_AHCI_REGISTERS, CAP2))
273 #define IDX_AHCI_BOHC                   (FIELD_OFFSET(IDE_AHCI_REGISTERS, BOHC))
274 
275 
276 typedef union _SATA_SSTATUS_REG {
277 
278     struct {
279         ULONG DET:4; // Device Detection
280 
281 #define SStatus_DET_NoDev        0x00
282 #define SStatus_DET_Dev_NoPhy    0x01
283 #define SStatus_DET_Dev_Ok       0x03
284 #define SStatus_DET_Offline      0x04
285 
286         ULONG SPD:4; // Current Interface Speed
287 
288 #define SStatus_SPD_NoDev        0x00
289 #define SStatus_SPD_Gen1         0x01
290 #define SStatus_SPD_Gen2         0x02
291 #define SStatus_SPD_Gen3         0x03
292 
293         ULONG IPM:4; // Interface Power Management
294 
295 #define SStatus_IPM_NoDev        0x00
296 #define SStatus_IPM_Active       0x01
297 #define SStatus_IPM_Partial      0x02
298 #define SStatus_IPM_Slumber      0x06
299 
300         ULONG Reserved:20;
301     };
302     ULONG Reg;
303 
304 } SATA_SSTATUS_REG, *PSATA_SSTATUS_REG;
305 
306 #define         ATA_SS_DET_MASK         0x0000000f
307 #define         ATA_SS_DET_NO_DEVICE    0x00000000
308 #define         ATA_SS_DET_DEV_PRESENT  0x00000001
309 #define         ATA_SS_DET_PHY_ONLINE   0x00000003
310 #define         ATA_SS_DET_PHY_OFFLINE  0x00000004
311 
312 #define         ATA_SS_SPD_MASK         0x000000f0
313 #define         ATA_SS_SPD_NO_SPEED     0x00000000
314 #define         ATA_SS_SPD_GEN1         0x00000010
315 #define         ATA_SS_SPD_GEN2         0x00000020
316 
317 #define         ATA_SS_IPM_MASK         0x00000f00
318 #define         ATA_SS_IPM_NO_DEVICE    0x00000000
319 #define         ATA_SS_IPM_ACTIVE       0x00000100
320 #define         ATA_SS_IPM_PARTIAL      0x00000200
321 #define         ATA_SS_IPM_SLUMBER      0x00000600
322 
323 typedef union _SATA_SCONTROL_REG {
324 
325     struct {
326         ULONG DET:4; // Device Detection Init
327 
328 #define SControl_DET_DoNothing   0x00
329 #define SControl_DET_Idle        0x00
330 #define SControl_DET_Init        0x01
331 #define SControl_DET_Disable     0x04
332 
333         ULONG SPD:4; // Speed Allowed
334 
335 #define SControl_SPD_NoRestrict  0x00
336 #define SControl_SPD_LimGen1     0x01
337 #define SControl_SPD_LimGen2     0x02
338 #define SControl_SPD_LimGen3     0x03
339 
340         ULONG IPM:4; // Interface Power Management Transitions Allowed
341 
342 #define SControl_IPM_NoRestrict  0x00
343 #define SControl_IPM_NoPartial   0x01
344 #define SControl_IPM_NoSlumber   0x02
345 #define SControl_IPM_NoPartialSlumber 0x03
346 
347         ULONG SPM:4; // Select Power Management, unused by AHCI
348         ULONG PMP:4; // Port Multiplier Port, unused by AHCI
349         ULONG Reserved:12;
350     };
351     ULONG Reg;
352 
353 } SATA_SCONTROL_REG, *PSATA_SCONTROL_REG;
354 
355 #define         ATA_SC_DET_MASK         0x0000000f
356 #define         ATA_SC_DET_IDLE         0x00000000
357 #define         ATA_SC_DET_RESET        0x00000001
358 #define         ATA_SC_DET_DISABLE      0x00000004
359 
360 #define         ATA_SC_SPD_MASK         0x000000f0
361 #define         ATA_SC_SPD_NO_SPEED     0x00000000
362 #define         ATA_SC_SPD_SPEED_GEN1   0x00000010
363 #define         ATA_SC_SPD_SPEED_GEN2   0x00000020
364 #define         ATA_SC_SPD_SPEED_GEN3   0x00000040
365 
366 #define         ATA_SC_IPM_MASK         0x00000f00
367 #define         ATA_SC_IPM_NONE         0x00000000
368 #define         ATA_SC_IPM_DIS_PARTIAL  0x00000100
369 #define         ATA_SC_IPM_DIS_SLUMBER  0x00000200
370 
371 typedef union _SATA_SERROR_REG {
372 
373     struct {
374         struct {
375             UCHAR I:1; // Recovered Data Integrity Error
376             UCHAR M:1; // Recovered Communications Error
377             UCHAR Reserved_2_7:6;
378 
379             UCHAR T:1; // Transient Data Integrity Error
380             UCHAR C:1; // Persistent Communication or Data Integrity Error
381             UCHAR P:1; // Protocol Error
382             UCHAR E:1; // Internal Error
383             UCHAR Reserved_12_15:4;
384         } ERR;
385 
386         struct {
387             UCHAR N:1; // PhyRdy Change, PIS.PRCS
388             UCHAR I:1; // Phy Internal Error
389             UCHAR W:1; // Comm Wake
390             UCHAR B:1; // 10B to 8B Decode Error
391             UCHAR D:1; // Disparity Error, not used by AHCI
392             UCHAR C:1; // CRC Error
393             UCHAR H:1; // Handshake Error
394             UCHAR S:1; // Link Sequence Error
395 
396             UCHAR T:1; // Transport state transition error
397             UCHAR F:1; // Unknown FIS Type
398             UCHAR X:1; // Exchanged
399             UCHAR Reserved_27_31:5;
400         } DIAG;
401     };
402     ULONG Reg;
403 
404 } SATA_SERROR_REG, *PSATA_SERROR_REG;
405 
406 #define         ATA_SE_DATA_CORRECTED   0x00000001
407 #define         ATA_SE_COMM_CORRECTED   0x00000002
408 #define         ATA_SE_DATA_ERR         0x00000100
409 #define         ATA_SE_COMM_ERR         0x00000200
410 #define         ATA_SE_PROT_ERR         0x00000400
411 #define         ATA_SE_HOST_ERR         0x00000800
412 #define         ATA_SE_PHY_CHANGED      0x00010000
413 #define         ATA_SE_PHY_IERROR       0x00020000
414 #define         ATA_SE_COMM_WAKE        0x00040000
415 #define         ATA_SE_DECODE_ERR       0x00080000
416 #define         ATA_SE_PARITY_ERR       0x00100000
417 #define         ATA_SE_CRC_ERR          0x00200000
418 #define         ATA_SE_HANDSHAKE_ERR    0x00400000
419 #define         ATA_SE_LINKSEQ_ERR      0x00800000
420 #define         ATA_SE_TRANSPORT_ERR    0x01000000
421 #define         ATA_SE_UNKNOWN_FIS      0x02000000
422 
423 typedef struct _IDE_SATA_REGISTERS {
424     union {
425         SATA_SSTATUS_REG   SStatus;
426         ULONG              SStatus_Reg;
427     };
428     union {
429         SATA_SERROR_REG    SError;
430         ULONG              SError_Reg;
431     };
432     union {
433         SATA_SCONTROL_REG  SControl;
434         ULONG              SControl_Reg;
435     };
436 
437     // SATA 1.2
438 
439     ULONG                  SActive;
440     union {
441         ULONG Reg;
442         struct {
443             USHORT PMN;     // PM Notify, bitmask
444             USHORT Reserved;
445         };
446     } SNTF;
447     ULONG                  SReserved[11];
448 } IDE_SATA_REGISTERS, *PIDE_SATA_REGISTERS;
449 
450 #define IDX_SATA_IO                     (IDX_BM_IO+IDX_BM_IO_SZ)
451 //#define IDX_SATA_IO_SZ                  sizeof(IDE_SATA_REGISTERS)
452 #define IDX_SATA_IO_SZ                  5
453 
454 #define IDX_SATA_SStatus                (0+IDX_SATA_IO)
455 #define IDX_SATA_SError                 (1+IDX_SATA_IO)
456 #define IDX_SATA_SControl               (2+IDX_SATA_IO)
457 #define IDX_SATA_SActive                (3+IDX_SATA_IO)
458 #define IDX_SATA_SNTF_PMN               (4+IDX_SATA_IO)
459 
460 #define IDX_INDEXED_IO                  (IDX_SATA_IO+IDX_SATA_IO_SZ)
461 #define IDX_INDEXED_IO_SZ               2
462 
463 #define IDX_INDEXED_ADDR                (0+IDX_INDEXED_IO)
464 #define IDX_INDEXED_DATA                (1+IDX_INDEXED_IO)
465 
466 #define IDX_MAX_REG                     (IDX_INDEXED_IO+IDX_INDEXED_IO_SZ)
467 
468 
469 typedef union _AHCI_IS_REG {
470     struct {
471         ULONG DHRS:1;// Device to Host Register FIS Interrupt
472         ULONG PSS:1; // PIO Setup FIS Interrupt
473         ULONG DSS:1; // DMA Setup FIS Interrupt
474         ULONG SDBS:1;// Set Device Bits Interrupt
475         ULONG UFS:1; // Unknown FIS Interrupt
476         ULONG DPS:1; // Descriptor Processed
477         ULONG PCS:1; // Port Connect Change Status
478         ULONG DMPS:1;// Device Mechanical Presence Status
479 
480         ULONG Reserved_8_21:14;
481         ULONG PRCS:1;// PhyRdy Change Status
482         ULONG IPMS:1;// Incorrect Port Multiplier Status
483 
484         ULONG OFS:1; // Overflow Status
485         ULONG Reserved_25:1;
486         ULONG INFS:1;// Interface Non-fatal Error Status
487         ULONG IFS:1; // Interface Fatal Error Status
488         ULONG HBDS:1;// Host Bus Data Error Status
489         ULONG HBFS:1;// Host Bus Fatal Error Status
490         ULONG TFES:1;// Task File Error Status
491         ULONG CPDS:1;// Cold Port Detect Status
492     };
493     ULONG Reg;
494 } AHCI_IS_REG, *PAHCI_IS_REG;
495 
496 #define         ATA_AHCI_P_IX_DHR       0x00000001
497 #define         ATA_AHCI_P_IX_PS        0x00000002
498 #define         ATA_AHCI_P_IX_DS        0x00000004
499 #define         ATA_AHCI_P_IX_SDB       0x00000008
500 #define         ATA_AHCI_P_IX_UF        0x00000010
501 #define         ATA_AHCI_P_IX_DP        0x00000020
502 #define         ATA_AHCI_P_IX_PC        0x00000040
503 #define         ATA_AHCI_P_IX_DI        0x00000080
504 
505 #define         ATA_AHCI_P_IX_PRC       0x00400000
506 #define         ATA_AHCI_P_IX_IPM       0x00800000
507 #define         ATA_AHCI_P_IX_OF        0x01000000
508 #define         ATA_AHCI_P_IX_INF       0x04000000
509 #define         ATA_AHCI_P_IX_IF        0x08000000
510 #define         ATA_AHCI_P_IX_HBD       0x10000000
511 #define         ATA_AHCI_P_IX_HBF       0x20000000
512 #define         ATA_AHCI_P_IX_TFE       0x40000000
513 #define         ATA_AHCI_P_IX_CPD       0x80000000
514 
515 #define AHCI_CLB_ALIGNEMENT_MASK    ((ULONGLONG)(1024-1))
516 #define AHCI_FIS_ALIGNEMENT_MASK    ((ULONGLONG)(256-1))
517 #define AHCI_CMD_ALIGNEMENT_MASK    ((ULONGLONG)(128-1))
518 
519 typedef struct _IDE_AHCI_PORT_REGISTERS {
520     union {
521         struct {
522             ULONG  CLB;   // command list base address, 1K-aligned
523             ULONG  CLBU;  // command list base address (upper 32bits)
524         };
525         ULONGLONG CLB64;
526     };  // 0x100 + 0x80*c + 0x0000
527 
528     union {
529         struct {
530             ULONG  FB;   // FIS base address
531             ULONG  FBU;  // FIS base address (upper 32bits)
532         };
533         ULONGLONG FB64;
534     };  // 0x100 + 0x80*c + 0x0008
535 
536     union {
537         ULONG       IS_Reg;            // interrupt status
538         AHCI_IS_REG IS;
539     };  // 0x100 + 0x80*c + 0x0010
540 
541     union {
542         ULONG Reg;            // interrupt enable
543         struct {
544             ULONG DHRE:1;// Device to Host Register FIS Interrupt Enable
545             ULONG PSE:1; // PIO Setup FIS Interrupt Enable
546             ULONG DSE:1; // DMA Setup FIS Interrupt Enable
547             ULONG SDBE:1;// Set Device Bits FIS Interrupt Enable
548             ULONG UFE:1; // Unknown FIS Interrupt Enable
549             ULONG DPE:1; // Descriptor Processed Interrupt Enable
550             ULONG PCE:1; // Port Change Interrupt Enable
551             ULONG DPME:1;// Device Mechanical Presence Enable
552 
553             ULONG Reserved_8_21:14;
554             ULONG PRCE:1;// PhyRdy Change Interrupt Enable
555             ULONG IPME:1;// Incorrect Port Multiplier Enable
556             ULONG OFE:1; // Overflow Enable
557             ULONG Reserved_25:1;
558             ULONG INFE:1;// Interface Non-fatal Error Enable
559             ULONG IFE:1; // Interface Fatal Error Enable
560             ULONG HBDE:1;// Host Bus Data Error Enable
561             ULONG HBFE:1;// Host Bus Fatal Error Enable
562             ULONG TFEE:1;// Task File Error Enable
563             ULONG CPDE:1;// Cold Port Detect Enable
564         };
565     } IE;  // 0x100 + 0x80*c + 0x0014
566 
567     union {
568         ULONG Reg;           // command register
569         struct {
570 
571             ULONG ST:1;  // Start
572             ULONG SUD:1; // Spin-Up Device
573             ULONG POD:1; // Power On Device
574             ULONG CLO:1; // Command List Override
575             ULONG FRE:1; // FIS Receive Enable
576             ULONG Reserved_5_7:3;
577 
578             ULONG CCS:5; // Current Command Slot
579             ULONG MPSS:1;// Mechanical Presence Switch State
580             ULONG FR:1;  // FIS Receive Running
581             ULONG CR:1;  // Command List Running
582 
583             ULONG CPS:1; // Cold Presence State
584             ULONG PMA:1; // Port Multiplier Attached
585             ULONG HPCP:1;// Hot Plug Capable Port
586             ULONG MPSP:1;// Mechanical Presence Switch Attached to Port
587             ULONG CPD:1; // Cold Presence Detection
588             ULONG ESP:1; // External SATA Port
589             ULONG Reserved_22_23:2;
590 
591             ULONG ATAPI:1; // Device is ATAPI
592             ULONG DLAE:1;// Drive LED on ATAPI Enable
593             ULONG ALPE:1;// Aggressive Link Power Management Enable
594             ULONG ASP:1; // Aggressive Slumber / Partial
595             ULONG ICC:4; // Interface Communication Control
596 
597 #define SATA_CMD_ICC_Idle    0x00
598 #define SATA_CMD_ICC_NoOp    0x00
599 #define SATA_CMD_ICC_Active  0x01
600 #define SATA_CMD_ICC_Partial 0x02
601 #define SATA_CMD_ICC_Slumber 0x06
602         };
603     } CMD;  // 0x100 + 0x80*c + 0x0018
604 
605     ULONG Reserved;
606 
607     union {
608         ULONG Reg;           // Task File Data
609         struct {
610             struct {
611                 UCHAR ERR:1;
612                 UCHAR cs1:2;// command-specific
613                 UCHAR DRQ:1;
614                 UCHAR cs2:3;// command-specific
615                 UCHAR BSY:1;
616             } STS;
617             UCHAR ERR; // Contains the latest copy of the task file error register.
618             UCHAR Reserved[2];
619         };
620     } TFD;  // 0x100 + 0x80*c + 0x0020
621 
622     union {
623         ULONG Reg;           // signature
624         struct {
625             UCHAR SectorCount;
626             UCHAR LbaLow;       // IDX_IO1_i_BlockNumber
627             UCHAR LbaMid;       // IDX_IO1_i_CylinderLow
628             UCHAR LbaHigh;      // IDX_IO1_i_CylinderHigh
629         };
630     } SIG;  // 0x100 + 0x80*c + 0x0024
631     union {
632         ULONG             SStatus;      // SCR0
633         SATA_SSTATUS_REG  SSTS;
634     };  // 0x100 + 0x80*c + 0x0028
635     union {
636         ULONG             SControl;     // SCR2
637         SATA_SCONTROL_REG SCTL;
638     };  // 0x100 + 0x80*c + 0x002c
639     union {
640         ULONG             SError;       // SCR1
641         SATA_SERROR_REG   SERR;
642     };  // 0x100 + 0x80*c + 0x0030
643     union {
644         ULONG SACT;      // SCR3
645         ULONG SActive;   // bitmask
646     };  // 0x100 + 0x80*c + 0x0034
647 
648     ULONG CI;            // Command issue, bitmask,   0x100 + 0x80*c + 0x0038
649 
650     // AHCI 1.1
651     union {
652         ULONG Reg;
653         struct {
654             USHORT PMN;     // PM Notify, bitmask
655             USHORT Reserved;
656         };
657     } SNTF;  // 0x100 + 0x80*c + 0x003c
658 
659     // AHCI 1.2
660     union {
661         ULONG Reg;
662         struct {
663             ULONG EN:1;     // Enable
664             ULONG DEC:1;    // Device Error Clear
665             ULONG SDE:1;    // Single Device Error
666             ULONG Reserved_3_7:5;  // Reserved
667             ULONG DEV:4;    // Device To Issue
668             ULONG ADO:4;    // Active Device Optimization (recommended parallelism)
669             ULONG DWE:4;    // Device With Error
670             ULONG Reserved_20_31:12;  // Reserved
671         };
672     } FBS;  // 0x100 + 0x80*c + 0x0040
673 
674     ULONG Reserved_44_7f[11];
675     UCHAR VendorSpec[16];
676 
677 } IDE_AHCI_PORT_REGISTERS, *PIDE_AHCI_PORT_REGISTERS;
678 
679 #define IDX_AHCI_P_CLB                    (FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, CLB))
680 #define IDX_AHCI_P_FB                     (FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, FB))
681 #define IDX_AHCI_P_IS                     (FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, IS))
682 #define IDX_AHCI_P_IE                     (FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, IE))
683 #define IDX_AHCI_P_CI                     (FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, CI))
684 #define IDX_AHCI_P_TFD                    (FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, TFD))
685 #define IDX_AHCI_P_SIG                    (FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, SIG))
686 #define IDX_AHCI_P_CMD                    (FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, CMD))
687 #define IDX_AHCI_P_SStatus                (FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, SStatus))
688 #define IDX_AHCI_P_SControl               (FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, SControl))
689 #define IDX_AHCI_P_SError                 (FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, SError))
690 #define IDX_AHCI_P_ACT                    (FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, SACT))
691 
692 #define IDX_AHCI_P_SNTF                   (FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, SNTF))
693 
694 // AHCI commands ( -> IDX_AHCI_P_CMD)
695 #define         ATA_AHCI_P_CMD_ST       0x00000001
696 #define         ATA_AHCI_P_CMD_SUD      0x00000002
697 #define         ATA_AHCI_P_CMD_POD      0x00000004
698 #define         ATA_AHCI_P_CMD_CLO      0x00000008
699 #define         ATA_AHCI_P_CMD_FRE      0x00000010
700 #define         ATA_AHCI_P_CMD_CCS_MASK 0x00001f00
701 #define         ATA_AHCI_P_CMD_ISS      0x00002000
702 #define         ATA_AHCI_P_CMD_FR       0x00004000
703 #define         ATA_AHCI_P_CMD_CR       0x00008000
704 #define         ATA_AHCI_P_CMD_CPS      0x00010000
705 #define         ATA_AHCI_P_CMD_PMA      0x00020000
706 #define         ATA_AHCI_P_CMD_HPCP     0x00040000
707 #define         ATA_AHCI_P_CMD_ISP      0x00080000
708 #define         ATA_AHCI_P_CMD_CPD      0x00100000
709 #define         ATA_AHCI_P_CMD_ATAPI    0x01000000
710 #define         ATA_AHCI_P_CMD_DLAE     0x02000000
711 #define         ATA_AHCI_P_CMD_ALPE     0x04000000
712 #define         ATA_AHCI_P_CMD_ASP      0x08000000
713 #define         ATA_AHCI_P_CMD_ICC_MASK 0xf0000000
714 #define         ATA_AHCI_P_CMD_NOOP     0x00000000
715 #define         ATA_AHCI_P_CMD_ACTIVE   0x10000000
716 #define         ATA_AHCI_P_CMD_PARTIAL  0x20000000
717 #define         ATA_AHCI_P_CMD_SLUMBER  0x60000000
718 
719 
720 typedef struct _IDE_AHCI_PRD_ENTRY {
721     union {
722         ULONG base;
723         ULONGLONG base64;
724         struct {
725             ULONG DBA;
726             union {
727                 ULONG DBAU;
728                 ULONG baseu;
729             };
730         };
731     };
732     ULONG Reserved1;
733 
734     union {
735         struct {
736             ULONG DBC:22;
737             ULONG Reserved2:9;
738             ULONG I:1;
739         };
740         ULONG DBC_ULONG;
741     };
742 
743 } IDE_AHCI_PRD_ENTRY, *PIDE_AHCI_PRD_ENTRY;
744 
745 #define ATA_AHCI_DMA_ENTRIES		(PAGE_SIZE/2/sizeof(IDE_AHCI_PRD_ENTRY))   /* 128 */
746 #define ATA_AHCI_MAX_TAGS		32
747 
748 #define AHCI_FIS_TYPE_ATA_H2D           0x27
749 #define AHCI_FIS_TYPE_ATA_D2H           0x34
750 #define AHCI_FIS_TYPE_DMA_D2H           0x39
751 #define AHCI_FIS_TYPE_DMA_BiDi          0x41
752 #define AHCI_FIS_TYPE_DATA_BiDi         0x46
753 #define AHCI_FIS_TYPE_BIST_BiDi         0x58
754 #define AHCI_FIS_TYPE_PIO_D2H           0x5f
755 #define AHCI_FIS_TYPE_DEV_BITS_D2H      0xA1
756 
757 typedef struct _AHCI_ATA_H2D_FIS {
758     UCHAR    FIS_Type; // = 0x27
759     UCHAR    Reserved1:7;
760     UCHAR    Cmd:1;    // update Command register
761     UCHAR    Command;                  // [2]
762     UCHAR    Feature;                  // [3]
763 
764     UCHAR    BlockNumber;              // [4]
765     UCHAR    CylinderLow;              // [5]
766     UCHAR    CylinderHigh;             // [6]
767     UCHAR    DriveSelect;              // [7]
768 
769     UCHAR    BlockNumberExp;           // [8]
770     UCHAR    CylinderLowExp;           // [9]
771     UCHAR    CylinderHighExp;          // [10]
772     UCHAR    FeatureExp;               // [11]
773 
774     UCHAR    BlockCount;               // [12]
775     UCHAR    BlockCountExp;            // [13]
776     UCHAR    Reserved14;               // [14]
777     UCHAR    Control;                  // [15]
778 
779 } AHCI_ATA_H2D_FIS, *PAHCI_ATA_H2D_FIS;
780 
781 #define IDX_AHCI_o_Command              (FIELD_OFFSET(AHCI_ATA_H2D_FIS, Command))
782 #define IDX_AHCI_o_Feature              (FIELD_OFFSET(AHCI_ATA_H2D_FIS, Feature))
783 #define IDX_AHCI_o_BlockNumber          (FIELD_OFFSET(AHCI_ATA_H2D_FIS, BlockNumber ))
784 #define IDX_AHCI_o_CylinderLow          (FIELD_OFFSET(AHCI_ATA_H2D_FIS, CylinderLow ))
785 #define IDX_AHCI_o_CylinderHigh         (FIELD_OFFSET(AHCI_ATA_H2D_FIS, CylinderHigh))
786 #define IDX_AHCI_o_DriveSelect          (FIELD_OFFSET(AHCI_ATA_H2D_FIS, DriveSelect ))
787 #define IDX_AHCI_o_BlockCount           (FIELD_OFFSET(AHCI_ATA_H2D_FIS, BlockCount))
788 #define IDX_AHCI_o_Control              (FIELD_OFFSET(AHCI_ATA_H2D_FIS, Control))
789 #define IDX_AHCI_o_FeatureExp           (FIELD_OFFSET(AHCI_ATA_H2D_FIS, FeatureExp))
790 #define IDX_AHCI_o_BlockNumberExp       (FIELD_OFFSET(AHCI_ATA_H2D_FIS, BlockNumberExp ))
791 #define IDX_AHCI_o_CylinderLowExp       (FIELD_OFFSET(AHCI_ATA_H2D_FIS, CylinderLowExp ))
792 #define IDX_AHCI_o_CylinderHighExp      (FIELD_OFFSET(AHCI_ATA_H2D_FIS, CylinderHighExp))
793 #define IDX_AHCI_o_BlockCountExp        (FIELD_OFFSET(AHCI_ATA_H2D_FIS, BlockCountExp))
794 
795 #define AHCI_FIS_COMM_PM                (0x80 | AHCI_DEV_SEL_PM)
796 
797 #define AHCI_DEV_SEL_1                  0x00
798 #define AHCI_DEV_SEL_2                  0x01
799 #define AHCI_DEV_SEL_PM                 0x0f
800 
801 /* 128-byte aligned */
802 typedef struct _IDE_AHCI_CMD {
803     UCHAR              cfis[64];
804     UCHAR              acmd[16];
805     UCHAR              Reserved[48];
806     IDE_AHCI_PRD_ENTRY prd_tab[ATA_AHCI_DMA_ENTRIES]; // also 128-byte aligned
807 } IDE_AHCI_CMD, *PIDE_AHCI_CMD;
808 
809 
810 /* cmd_flags */
811 #define ATA_AHCI_CMD_ATAPI		0x0020
812 #define ATA_AHCI_CMD_WRITE		0x0040
813 #define ATA_AHCI_CMD_PREFETCH		0x0080
814 #define ATA_AHCI_CMD_RESET		0x0100
815 #define ATA_AHCI_CMD_BIST		0x0200
816 #define ATA_AHCI_CMD_CLR_BUSY		0x0400
817 
818 /* 128-byte aligned */
819 typedef struct _IDE_AHCI_CMD_LIST {
820     USHORT             cmd_flags;
821     USHORT             prd_length;     /* PRD entries */
822     ULONG              bytecount;
823     ULONGLONG          cmd_table_phys; /* points to IDE_AHCI_CMD */
824     ULONG              Reserved[4];
825 } IDE_AHCI_CMD_LIST, *PIDE_AHCI_CMD_LIST;
826 
827 /* 256-byte aligned */
828 typedef struct _IDE_AHCI_RCV_FIS {
829     UCHAR              dsfis[28];
830     UCHAR              Reserved1[4];
831     UCHAR              psfis[20];
832     UCHAR              Reserved2[12];
833     UCHAR              rfis[20];
834     UCHAR              Reserved3[4];
835     UCHAR              SDBFIS[8];
836     UCHAR              ufis[64];
837     UCHAR              Reserved4[96];
838 } IDE_AHCI_RCV_FIS, *PIDE_AHCI_RCV_FIS;
839 
840 /* 1K-byte aligned */
841 typedef struct _IDE_AHCI_CHANNEL_CTL_BLOCK {
842     IDE_AHCI_CMD_LIST  cmd_list[ATA_AHCI_MAX_TAGS]; // 1K-size (32*32)
843     IDE_AHCI_RCV_FIS   rcv_fis;
844     IDE_AHCI_CMD       cmd; // for single internal commands w/o associated AtaReq
845 } IDE_AHCI_CHANNEL_CTL_BLOCK, *PIDE_AHCI_CHANNEL_CTL_BLOCK;
846 
847 #pragma pack(pop)
848 
849 #define IsBusMaster(pciData) \
850     ( ((pciData)->Command & (PCI_ENABLE_BUS_MASTER/* | PCI_ENABLE_IO_SPACE*/)) == \
851           (PCI_ENABLE_BUS_MASTER/* | PCI_ENABLE_IO_SPACE*/))
852 
853 #define PCI_IDE_PROGIF_NATIVE_1         0x01
854 #define PCI_IDE_PROGIF_NATIVE_2         0x04
855 #define PCI_IDE_PROGIF_NATIVE_ALL       0x05
856 
857 #define IsMasterDev(pciData) \
858     ( ((pciData)->ProgIf & 0x80) && \
859       ((pciData)->ProgIf & PCI_IDE_PROGIF_NATIVE_ALL) != PCI_IDE_PROGIF_NATIVE_ALL )
860 
861 //#define INT_Q_SIZE 32
862 #define MIN_REQ_TTL 4
863 
864 union _ATA_REQ;
865 
866 typedef union _ATA_REQ {
867 //    ULONG               reqId;          // serial
868     struct {
869 
870         //union {
871 
872         struct {
873             union _ATA_REQ*     next_req;
874             union _ATA_REQ*     prev_req;
875 
876             PSCSI_REQUEST_BLOCK Srb;            // Current request on controller.
877 
878             PUSHORT             DataBuffer;     // Data buffer pointer.
879             ULONG               WordsLeft;      // Data words left.
880             ULONG               TransferLength; // Originally requested transfer length
881             LONGLONG            lba;
882             ULONG               WordsTransfered;// Data words already transfered.
883             ULONG               bcount;
884 
885             UCHAR               retry;
886             UCHAR               ttl;
887         //    UCHAR               tag;
888             UCHAR               Flags;
889             UCHAR               ReqState;
890 
891             PSCSI_REQUEST_BLOCK OriginalSrb;    // Mechanism Status Srb Data
892 
893             ULONG               dma_entries;
894             union {
895                 // for ATA
896                 struct {
897                     ULONG           dma_base;
898                     ULONG           dma_baseu;
899                 } ata;
900                 // for AHCI
901                 struct {
902                     ULONGLONG       ahci_base64;
903                     ULONGLONG       in_lba;
904                     PIDE_AHCI_CMD   ahci_cmd_ptr;
905                     ULONG           in_bcount;
906                     ULONG           in_status;
907                     ULONG           in_serror;
908                     USHORT          io_cmd_flags; // out
909                     UCHAR           in_error;
910                 } ahci;
911             };
912         };
913             //UCHAR padding_128b[128];  // Note: we assume, NT allocates block > 4k as PAGE-aligned
914         //};
915         struct {
916             union {
917                 BM_DMA_ENTRY    dma_tab[ATA_DMA_ENTRIES];
918                 IDE_AHCI_CMD    ahci_cmd0;       // for AHCI, 128-byte aligned
919             };
920         };
921     };
922 
923     UCHAR padding_4kb[PAGE_SIZE];
924 
925 } ATA_REQ, *PATA_REQ;
926 
927 #define REQ_FLAG_FORCE_DOWNRATE         0x01
928 #define REQ_FLAG_DMA_OPERATION          0x02
929 #define REQ_FLAG_REORDERABLE_CMD        0x04
930 #define REQ_FLAG_RW_MASK                0x08
931 #define     REQ_FLAG_READ                   0x08
932 #define     REQ_FLAG_WRITE                  0x00
933 #define REQ_FLAG_FORCE_DOWNRATE_LBA48   0x10
934 #define REQ_FLAG_DMA_DBUF               0x20
935 #define REQ_FLAG_DMA_DBUF_PRD           0x40
936 #define REQ_FLAG_LBA48                  0x80
937 
938 // Request states
939 #define REQ_STATE_NONE                  0x00
940 #define REQ_STATE_QUEUED                0x10
941 
942 #define REQ_STATE_PREPARE_TO_TRANSFER   0x20
943 #define REQ_STATE_PREPARE_TO_NEXT       0x21
944 #define REQ_STATE_READY_TO_TRANSFER     0x30
945 
946 #define REQ_STATE_EXPECTING_INTR        0x40
947 #define REQ_STATE_ATAPI_EXPECTING_CMD_INTR     0x41
948 #define REQ_STATE_ATAPI_EXPECTING_DATA_INTR    0x42
949 #define REQ_STATE_ATAPI_EXPECTING_DATA_INTR2   0x43
950 #define REQ_STATE_ATAPI_DO_NOTHING_INTR        0x44
951 
952 #define REQ_STATE_EARLY_INTR            0x48
953 
954 #define REQ_STATE_PROCESSING_INTR       0x50
955 
956 #define REQ_STATE_DPC_INTR_REQ          0x51
957 #define REQ_STATE_DPC_RESET_REQ         0x52
958 #define REQ_STATE_DPC_COMPLETE_REQ      0x53
959 
960 #define REQ_STATE_DPC_WAIT_BUSY0        0x57
961 #define REQ_STATE_DPC_WAIT_BUSY1        0x58
962 #define REQ_STATE_DPC_WAIT_BUSY         0x59
963 #define REQ_STATE_DPC_WAIT_DRQ          0x5a
964 #define REQ_STATE_DPC_WAIT_DRQ0         0x5b
965 #define REQ_STATE_DPC_WAIT_DRQ_ERR      0x5c
966 
967 #define REQ_STATE_TRANSFER_COMPLETE     0x7f
968 
969 // Command actions:
970 #define CMD_ACTION_PREPARE              0x01
971 #define CMD_ACTION_EXEC                 0x02
972 #define CMD_ACTION_ALL                  (CMD_ACTION_PREPARE | CMD_ACTION_EXEC)
973 
974 // predefined Reorder costs
975 #define REORDER_COST_MAX               ((DEF_I64(0x1) << 60) - 1)
976 #define REORDER_COST_TTL               (REORDER_COST_MAX - 1)
977 #define REORDER_COST_INTERSECT         (REORDER_COST_MAX - 2)
978 #define REORDER_COST_DENIED            (REORDER_COST_MAX - 3)
979 #define REORDER_COST_RESELECT          (REORDER_COST_MAX/4)
980 
981 #define REORDER_COST_SWITCH_RW_CD      (REORDER_COST_MAX/8)
982 #define REORDER_MCOST_SWITCH_RW_CD     (0)
983 #define REORDER_MCOST_SEEK_BACK_CD     (16)
984 
985 #define REORDER_COST_SWITCH_RW_HDD     (0)
986 #define REORDER_MCOST_SWITCH_RW_HDD    (4)
987 #define REORDER_MCOST_SEEK_BACK_HDD    (2)
988 
989 /*typedef struct _ATA_QUEUE {
990     struct _ATA_REQ*    head_req; // index
991     struct _ATA_REQ*    tail_req; // index
992     ULONG               req_count;
993     ULONG               dma_base;
994     BM_DMA_ENTRY        dma_tab[ATA_DMA_ENTRIES];
995 } ATA_QUEUE, *PATA_QUEUE;*/
996 
997 struct _HW_DEVICE_EXTENSION;
998 struct _HW_LU_EXTENSION;
999 
1000 typedef struct _IORES {
1001     union {
1002         ULONG Addr;          /* Base address*/
1003         PVOID pAddr;         /* Base address in pointer form */
1004     };
1005     ULONG MemIo:1;       /* Memory mapping (1) vs IO ports (0) */
1006     ULONG Proc:1;        /* Need special processing via IO_Proc */
1007     ULONG Reserved:30;
1008 } IORES, *PIORES;
1009 
1010 // Channel extension
1011 typedef struct _HW_CHANNEL {
1012 
1013     PATA_REQ            cur_req;
1014     ULONG               cur_cdev;
1015     ULONG               last_cdev; /* device for which we have configured timings last time */
1016     ULONG               last_devsel; /* device selected during last call to SelectDrive() */
1017 /*    PATA_REQ            first_req;
1018     PATA_REQ            last_req;*/
1019     ULONG               queue_depth;
1020     ULONG               ChannelSelectWaitCount;
1021 
1022     UCHAR               DpcState;
1023 
1024     BOOLEAN             ExpectingInterrupt;    // Indicates expecting an interrupt
1025     BOOLEAN             RDP;    // Indicate last tape command was DSC Restrictive.
1026     // Indicates whether '0x1f0' is the base address. Used
1027     // in SMART Ioctl calls.
1028     BOOLEAN             PrimaryAddress;
1029     // Placeholder for the sub-command value of the last
1030     // SMART command.
1031     UCHAR               SmartCommand;
1032     // Reorder anabled
1033     BOOLEAN             UseReorder;
1034     // Placeholder for status register after a GET_MEDIA_STATUS command
1035     UCHAR               ReturningMediaStatus;
1036 
1037     BOOLEAN             CopyDmaBuffer;
1038     //BOOLEAN             MemIo;
1039     BOOLEAN             AltRegMap;
1040     BOOLEAN             Force80pin;
1041 
1042     UCHAR               Reserved[2];
1043 
1044     MECHANICAL_STATUS_INFORMATION_HEADER MechStatusData;
1045     SENSE_DATA          MechStatusSense;
1046     ULONG               MechStatusRetryCount;
1047     SCSI_REQUEST_BLOCK  InternalSrb;
1048 
1049     ULONG               MaxTransferMode; // may differ from Controller's value due to 40-pin cable
1050 
1051     ULONG               ChannelCtrlFlags;
1052     ULONG               ResetInProgress; // flag
1053     LONG                DisableIntr;
1054     LONG                CheckIntr;
1055 
1056     ULONG               lChannel;
1057 
1058 #define CHECK_INTR_ACTIVE               0x03
1059 #define CHECK_INTR_DETECTED             0x02
1060 #define CHECK_INTR_CHECK                0x01
1061 #define CHECK_INTR_IDLE                 0x00
1062 
1063     ULONG       NextDpcChan;
1064     PHW_TIMER   HwScsiTimer;
1065     LONGLONG    DpcTime;
1066 #if 0
1067     PHW_TIMER   HwScsiTimer1;
1068     PHW_TIMER   HwScsiTimer2;
1069     LONGLONG    DpcTime1;
1070 //    PHW_TIMER           CurDpc;
1071 //    LARGE_INTEGER       ActivationTime;
1072 
1073 //    KDPC                Dpc;
1074 //    KTIMER              Timer;
1075 //    PHW_TIMER           HwScsiTimer;
1076 //    KSPIN_LOCK          QueueSpinLock;
1077 //    KIRQL               QueueOldIrql;
1078 #endif
1079     struct _HW_DEVICE_EXTENSION* DeviceExtension;
1080     struct _HW_LU_EXTENSION* lun[IDE_MAX_LUN_PER_CHAN];
1081 
1082     ULONG   NumberLuns;
1083     ULONG   PmLunMap;
1084 
1085     // Double-buffering support
1086     PVOID   DB_PRD;
1087     ULONG   DB_PRD_PhAddr;
1088     PVOID   DB_IO;
1089     ULONG   DB_IO_PhAddr;
1090 
1091     PUCHAR  DmaBuffer;
1092 
1093     //
1094     PIDE_AHCI_CHANNEL_CTL_BLOCK       AhciCtlBlock0; // unaligned
1095     PIDE_AHCI_CHANNEL_CTL_BLOCK       AhciCtlBlock;  // 128-byte aligned
1096     ULONGLONG                         AHCI_CTL_PhAddr;
1097     IORES                             BaseIoAHCI_Port;
1098     ULONG                             AhciPrevCI;
1099     ULONG                             AhciCompleteCI;
1100     ULONG                             AhciLastIS;
1101     ULONG                             AhciLastSError;
1102     //PVOID                    AHCI_FIS;  // is not actually used by UniATA now, but is required by AHCI controller
1103     //ULONGLONG                AHCI_FIS_PhAddr;
1104     // Note: in contrast to FBSD, we keep PRD and CMD item in AtaReq structure
1105     PATA_REQ                          AhciInternalAtaReq;
1106     PSCSI_REQUEST_BLOCK               AhciInternalSrb;
1107 
1108 #ifdef QUEUE_STATISTICS
1109     LONGLONG QueueStat[MAX_QUEUE_STAT];
1110     LONGLONG ReorderCount;
1111     LONGLONG IntersectCount;
1112     LONGLONG TryReorderCount;
1113     LONGLONG TryReorderHeadCount;
1114     LONGLONG TryReorderTailCount; /* in-order requests */
1115 #endif //QUEUE_STATISTICS
1116 
1117     //ULONG BaseMemAddress;
1118     //ULONG BaseMemAddressOffset;
1119     IORES RegTranslation[IDX_MAX_REG];
1120 
1121 } HW_CHANNEL, *PHW_CHANNEL;
1122 
1123 #define CTRFLAGS_DMA_ACTIVE             0x0001
1124 #define CTRFLAGS_DMA_RO                 0x0002
1125 #define CTRFLAGS_DMA_OPERATION          0x0004
1126 #define CTRFLAGS_INTR_DISABLED          0x0008
1127 #define CTRFLAGS_DPC_REQ                0x0010
1128 #define CTRFLAGS_ENABLE_INTR_REQ        0x0020
1129 #define CTRFLAGS_LBA48                  0x0040
1130 #define CTRFLAGS_DSC_BSY                0x0080
1131 #define CTRFLAGS_NO_SLAVE               0x0100
1132 //#define CTRFLAGS_DMA_BEFORE_R           0x0200
1133 //#define CTRFLAGS_PATA                   0x0200
1134 //#define CTRFLAGS_NOT_PRESENT            0x0200
1135 #define CTRFLAGS_AHCI_PM                0x0400
1136 #define CTRFLAGS_AHCI_PM2               0x0800
1137 
1138 #define CTRFLAGS_PERMANENT  (CTRFLAGS_DMA_RO | CTRFLAGS_NO_SLAVE)
1139 
1140 #define GEOM_AUTO                       0xffffffff
1141 #define GEOM_STD                        0x0000
1142 #define GEOM_UNIATA                     0x0001
1143 #define GEOM_ORIG                       0x0002
1144 #define GEOM_MANUAL                     0x0003
1145 
1146 #define DPC_STATE_NONE                  0x00
1147 #define DPC_STATE_ISR                   0x10
1148 #define DPC_STATE_DPC                   0x20
1149 #define DPC_STATE_TIMER                 0x30
1150 #define DPC_STATE_COMPLETE              0x40
1151 
1152 // Logical unit extension
1153 typedef struct _HW_LU_EXTENSION {
1154     IDENTIFY_DATA2 IdentifyData;
1155     ULONGLONG      NumOfSectors;
1156     ULONG          DeviceFlags;    // Flags word for each possible device. DFLAGS_XXX
1157     ULONG          DiscsPresent;   // Indicates number of platters on changer-ish devices.
1158     BOOLEAN        DWordIO;        // Indicates use of 32-bit PIO
1159     UCHAR          ReturningMediaStatus;
1160     UCHAR          MaximumBlockXfer;
1161     UCHAR          PowerState;
1162 
1163     UCHAR          TransferMode;          // current transfer mode
1164     UCHAR          LimitedTransferMode;   // user-defined or IDE cable limitation
1165     UCHAR          OrigTransferMode;      // transfer mode, returned by device IDENTIFY (can be changed via IOCTL)
1166     UCHAR          PhyTransferMode;       // phy transfer mode (actual bus transfer mode for PATA DMA and SATA)
1167 
1168     ULONG          ErrorCount;     // Count of errors. Used to turn off features.
1169  //   ATA_QUEUE      cmd_queue;
1170     LONGLONG       ReadCmdCost;
1171     LONGLONG       WriteCmdCost;
1172     LONGLONG       OtherCmdCost;
1173     LONGLONG       RwSwitchCost;
1174     LONGLONG       RwSwitchMCost;
1175     LONGLONG       SeekBackMCost;
1176     //
1177     PATA_REQ       first_req;
1178     PATA_REQ       last_req;
1179     ULONG          queue_depth;
1180     ULONG          last_write;
1181 
1182     ULONG          LunSelectWaitCount;
1183     ULONG          AtapiReadyWaitDelay;
1184 
1185     // tuning options
1186     ULONG          opt_GeomType;
1187     ULONG          opt_MaxTransferMode;
1188     ULONG          opt_PreferedTransferMode;
1189     BOOLEAN        opt_ReadCacheEnable;
1190     BOOLEAN        opt_WriteCacheEnable;
1191     UCHAR          opt_ReadOnly;
1192     UCHAR          opt_AdvPowerMode;
1193     UCHAR          opt_AcousticMode;
1194     UCHAR          opt_StandbyTimer;
1195     UCHAR          opt_Padding[2]; // padding
1196 
1197     struct _SBadBlockListItem* bbListDescr;
1198     struct _SBadBlockRange* arrBadBlocks;
1199     ULONG           nBadBlocks;
1200 
1201     // Controller-specific LUN options
1202     union {
1203         /* for tricky controllers, those can change Logical-to-Physical LUN mapping.
1204            mainly for mapping SATA ports to compatible PATA registers
1205            Treated as PHYSICAL port number, regardless of logical mapping.
1206          */
1207         ULONG          SATA_lun_map;
1208     };
1209 
1210     struct _HW_DEVICE_EXTENSION* DeviceExtension;
1211     struct _HW_CHANNEL* chan;
1212     ULONG  Lun;
1213 
1214     ULONGLONG errLastLba;
1215     ULONG    errBCount;
1216     UCHAR    errRetry;
1217     UCHAR    errPadding[3];
1218 
1219 #ifdef IO_STATISTICS
1220 
1221     LONGLONG ModeErrorCount[MAX_RETRIES];
1222     LONGLONG RecoverCount[MAX_RETRIES];
1223     LONGLONG IoCount;
1224     LONGLONG BlockIoCount;
1225 
1226 #endif//IO_STATISTICS
1227 } HW_LU_EXTENSION, *PHW_LU_EXTENSION;
1228 
1229 // Device extension
1230 typedef struct _HW_DEVICE_EXTENSION {
1231     CHAR Signature[32];
1232     //PIDE_REGISTERS_1 BaseIoAddress1[IDE_MAX_CHAN];    // Base register locations
1233     //PIDE_REGISTERS_2 BaseIoAddress2[IDE_MAX_CHAN];
1234     ULONG BusInterruptLevel;    // Interrupt level
1235     ULONG InterruptMode;        // Interrupt Mode (Level or Edge)
1236     ULONG BusInterruptVector;
1237     // Number of channels being supported by one instantiation
1238     // of the device extension. Normally (and correctly) one, but
1239     // with so many broken PCI IDE controllers being sold, we have
1240     // to support them.
1241     ULONG NumberChannels;
1242     ULONG NumberLuns;
1243     ULONG FirstChannelToCheck;
1244 #if 0
1245     HW_LU_EXTENSION lun[IDE_MAX_LUN];
1246     HW_CHANNEL chan[AHCI_MAX_PORT/*IDE_MAX_CHAN*/];
1247 #else
1248     PHW_LU_EXTENSION lun; // lun array
1249     PHW_CHANNEL chan; // channel array
1250 #endif
1251     UCHAR LastInterruptedChannel;
1252     // Indicates the number of blocks transferred per int. according to the
1253     // identify data.
1254     BOOLEAN DriverMustPoll;    // Driver is being used by the crash dump utility or ntldr.
1255     BOOLEAN BusMaster;
1256     BOOLEAN UseDpc;            // Indicates use of DPC on long waits
1257     IDENTIFY_DATA FullIdentifyData;    // Identify data for device
1258     // BusMaster specific data
1259 //    PBM_DMA_ENTRY dma_tab_0;
1260     //KSPIN_LOCK  DpcSpinLock;
1261 
1262     ULONG       ActiveDpcChan;
1263     ULONG       FirstDpcChan;
1264     ULONG       ExpectingInterrupt;    // Indicates entire controller expecting an interrupt
1265 /*
1266     PHW_TIMER   HwScsiTimer1;
1267     PHW_TIMER   HwScsiTimer2;
1268     LONGLONG    DpcTime1;
1269     LONGLONG    DpcTime2;
1270 */
1271     ULONG          queue_depth;
1272 
1273     PDEVICE_OBJECT Isr2DevObj;
1274 
1275     //PIDE_BUSMASTER_REGISTERS  BaseIoAddressBM_0;
1276     IORES                     BaseIoAddressBM_0;
1277     //PIDE_BUSMASTER_REGISTERS  BaseIoAddressBM[IDE_MAX_CHAN];
1278 
1279     // Device identification
1280     ULONG DevID;
1281     ULONG RevID;
1282     ULONG slotNumber;
1283     ULONG SystemIoBusNumber;
1284     ULONG DevIndex;
1285 
1286     ULONG InitMethod; // vendor specific
1287 
1288     ULONG Channel;
1289 
1290     ULONG HbaCtrlFlags;
1291     BOOLEAN simplexOnly;
1292     //BOOLEAN MemIo;
1293     BOOLEAN AltRegMap;
1294     BOOLEAN UnknownDev;
1295     BOOLEAN MasterDev;
1296     BOOLEAN Host64;
1297     BOOLEAN DWordIO;         // Indicates use of 32-bit PIO
1298 /*    // Indicates, that HW Initialized is already called for this controller
1299     // 0 bit for Primary, 1 - for Secondary. Is used to manage AltInit under w2k+
1300     UCHAR   Initialized;     */
1301     UCHAR   Reserved1[2];
1302 
1303     LONG  ReCheckIntr;
1304 
1305     ULONG MaxTransferMode;  // max transfer mode supported by controller
1306     ULONG HwFlags;
1307     INTERFACE_TYPE OrigAdapterInterfaceType;
1308     INTERFACE_TYPE AdapterInterfaceType;
1309     ULONG MaximumDmaTransferLength;
1310     ULONG AlignmentMask;
1311     ULONG DmaSegmentLength;
1312     ULONG DmaSegmentAlignmentMask; // must be PAGE-aligned
1313 
1314     //ULONG BaseMemAddress;
1315 
1316     //PIDE_SATA_REGISTERS       BaseIoAddressSATA_0;
1317     IORES          BaseIoAddressSATA_0;
1318     //PIDE_SATA_REGISTERS       BaseIoAddressSATA[IDE_MAX_CHAN];
1319 
1320     IORES          BaseIoAHCI_0;
1321     //PIDE_AHCI_PORT_REGISTERS  BaseIoAHCIPort[AHCI_MAX_PORT];
1322     ULONG          AHCI_CAP;
1323     ULONG          AHCI_PI;
1324     ULONG          AHCI_PI_mask; // for port exclusion, usually = AHCI_PI
1325     PATA_REQ       AhciInternalAtaReq0;
1326     PSCSI_REQUEST_BLOCK AhciInternalSrb0;
1327 
1328     BOOLEAN        opt_AtapiDmaZeroTransfer; // default FALSE
1329     BOOLEAN        opt_AtapiDmaControlCmd;   // default FALSE
1330     BOOLEAN        opt_AtapiDmaRawRead;      // default TRUE
1331     BOOLEAN        opt_AtapiDmaReadWrite;    // default TRUE
1332 
1333     PCCH           FullDevName;
1334 
1335     // Controller specific state/options
1336     union {
1337         ULONG      HwCfg;
1338     };
1339 
1340 } HW_DEVICE_EXTENSION, *PHW_DEVICE_EXTENSION;
1341 
1342 typedef struct _ISR2_DEVICE_EXTENSION {
1343     PHW_DEVICE_EXTENSION HwDeviceExtension;
1344     ULONG DevIndex;
1345 } ISR2_DEVICE_EXTENSION, *PISR2_DEVICE_EXTENSION;
1346 
1347 typedef ISR2_DEVICE_EXTENSION   PCIIDE_DEVICE_EXTENSION;
1348 typedef PISR2_DEVICE_EXTENSION  PPCIIDE_DEVICE_EXTENSION;
1349 
1350 #define HBAFLAGS_DMA_DISABLED           0x01
1351 #define HBAFLAGS_DMA_DISABLED_LBA48     0x02
1352 
1353 extern UCHAR         pciBuffer[256];
1354 extern PBUSMASTER_CONTROLLER_INFORMATION BMList;
1355 extern ULONG         BMListLen;
1356 extern ULONG         IsaCount;
1357 extern ULONG         MCACount;
1358 extern UNICODE_STRING SavedRegPath;
1359 
1360 //extern const CHAR retry_Wdma[MAX_RETRIES+1];
1361 //extern const CHAR retry_Udma[MAX_RETRIES+1];
1362 
1363 extern VOID
1364 NTAPI
1365 UniataEnumBusMasterController(
1366     IN PVOID DriverObject,
1367     PVOID Argument2
1368     );
1369 
1370 extern ULONG NTAPI
1371 UniataFindCompatBusMasterController1(
1372     IN PVOID HwDeviceExtension,
1373     IN PVOID Context,
1374     IN PVOID BusInformation,
1375     IN PCHAR ArgumentString,
1376     IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo,
1377     OUT PBOOLEAN Again
1378     );
1379 
1380 extern ULONG NTAPI
1381 UniataFindCompatBusMasterController2(
1382     IN PVOID HwDeviceExtension,
1383     IN PVOID Context,
1384     IN PVOID BusInformation,
1385     IN PCHAR ArgumentString,
1386     IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo,
1387     OUT PBOOLEAN Again
1388     );
1389 
1390 #define UNIATA_ALLOCATE_NEW_LUNS  0x00
1391 
1392 extern BOOLEAN NTAPI
1393 UniataAllocateLunExt(
1394     PHW_DEVICE_EXTENSION  deviceExtension,
1395     ULONG NewNumberChannels
1396     );
1397 
1398 extern VOID NTAPI
1399 UniataFreeLunExt(
1400     PHW_DEVICE_EXTENSION  deviceExtension
1401     );
1402 
1403 extern ULONG NTAPI
1404 UniataFindBusMasterController(
1405     IN PVOID HwDeviceExtension,
1406     IN PVOID Context,
1407     IN PVOID BusInformation,
1408     IN PCHAR ArgumentString,
1409     IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo,
1410     OUT PBOOLEAN Again
1411     );
1412 
1413 extern NTSTATUS
1414 NTAPI
1415 UniataClaimLegacyPCIIDE(
1416     ULONG i
1417     );
1418 
1419 extern NTSTATUS
1420 NTAPI
1421 UniataConnectIntr2(
1422     IN PVOID HwDeviceExtension
1423     );
1424 
1425 extern NTSTATUS
1426 NTAPI
1427 UniataDisconnectIntr2(
1428     IN PVOID HwDeviceExtension
1429     );
1430 
1431 extern ULONG
1432 NTAPI
1433 ScsiPortGetBusDataByOffset(
1434     IN PVOID  HwDeviceExtension,
1435     IN BUS_DATA_TYPE  BusDataType,
1436     IN ULONG  BusNumber,
1437     IN ULONG  SlotNumber,
1438     IN PVOID  Buffer,
1439     IN ULONG  Offset,
1440     IN ULONG  Length
1441     );
1442 
1443 #define PCIBUSNUM_NOT_SPECIFIED    (0xffffffffL)
1444 #define PCISLOTNUM_NOT_SPECIFIED   (0xffffffffL)
1445 
1446 extern ULONG
1447 NTAPI
1448 AtapiFindListedDev(
1449     PBUSMASTER_CONTROLLER_INFORMATION_BASE BusMasterAdapters,
1450     ULONG     lim,
1451     IN PVOID  HwDeviceExtension,
1452     IN ULONG  BusNumber,
1453     IN ULONG  SlotNumber,
1454     OUT PCI_SLOT_NUMBER* _slotData // optional
1455     );
1456 
1457 extern ULONG
1458 NTAPI
1459 AtapiFindDev(
1460     IN PVOID  HwDeviceExtension,
1461     IN BUS_DATA_TYPE  BusDataType,
1462     IN ULONG  BusNumber,
1463     IN ULONG  SlotNumber,
1464     IN ULONG  dev_id,
1465     IN ULONG  RevID
1466     );
1467 
1468 extern VOID
1469 NTAPI
1470 AtapiDmaAlloc(
1471     IN PVOID HwDeviceExtension,
1472     IN PPORT_CONFIGURATION_INFORMATION ConfigInfo,
1473     IN ULONG lChannel          // logical channel,
1474     );
1475 
1476 extern BOOLEAN
1477 NTAPI
1478 AtapiDmaSetup(
1479     IN PVOID HwDeviceExtension,
1480     IN ULONG DeviceNumber,
1481     IN ULONG lChannel,          // logical channel,
1482     IN PSCSI_REQUEST_BLOCK Srb,
1483     IN PUCHAR data,
1484     IN ULONG count
1485     );
1486 
1487 extern BOOLEAN
1488 NTAPI
1489 AtapiDmaPioSync(
1490     PVOID  HwDeviceExtension,
1491     PSCSI_REQUEST_BLOCK Srb,
1492     PUCHAR data,
1493     ULONG  count
1494     );
1495 
1496 extern BOOLEAN
1497 NTAPI
1498 AtapiDmaDBSync(
1499     PHW_CHANNEL chan,
1500     PSCSI_REQUEST_BLOCK Srb
1501     );
1502 
1503 extern BOOLEAN
1504 NTAPI
1505 AtapiDmaDBPreSync(
1506     IN PVOID HwDeviceExtension,
1507     PHW_CHANNEL chan,
1508     PSCSI_REQUEST_BLOCK Srb
1509     );
1510 
1511 extern VOID
1512 NTAPI
1513 AtapiDmaStart(
1514     IN PVOID HwDeviceExtension,
1515     IN ULONG DeviceNumber,
1516     IN ULONG lChannel,          // logical channel,
1517     IN PSCSI_REQUEST_BLOCK Srb
1518     );
1519 
1520 extern UCHAR
1521 NTAPI
1522 AtapiDmaDone(
1523     IN PVOID HwDeviceExtension,
1524     IN ULONG DeviceNumber,
1525     IN ULONG lChannel,          // logical channel,
1526     IN PSCSI_REQUEST_BLOCK Srb
1527     );
1528 
1529 extern VOID
1530 NTAPI
1531 AtapiDmaReinit(
1532     IN PHW_DEVICE_EXTENSION deviceExtension,
1533     IN PHW_LU_EXTENSION LunExt,
1534     IN PATA_REQ AtaReq
1535     );
1536 
1537 extern VOID
1538 NTAPI
1539 AtapiDmaInit__(
1540     IN PHW_DEVICE_EXTENSION deviceExtension,
1541     IN PHW_LU_EXTENSION LunExt
1542     );
1543 
1544 extern VOID
1545 NTAPI
1546 AtapiDmaInit(
1547     IN PVOID HwDeviceExtension,
1548     IN ULONG DeviceNumber,
1549     IN ULONG lChannel,          // logical channel,
1550                                // is always 0 except simplex-only and multi-channel controllers
1551     IN SCHAR apiomode,
1552     IN SCHAR wdmamode,
1553     IN SCHAR udmamode
1554     );
1555 
1556 extern BOOLEAN NTAPI
1557 AtapiInterrupt2(
1558     IN PKINTERRUPT Interrupt,
1559     IN PVOID HwDeviceExtension
1560     );
1561 
1562 extern PDRIVER_OBJECT SavedDriverObject;
1563 
1564 extern BOOLEAN
1565 NTAPI
1566 UniataChipDetectChannels(
1567     IN PVOID HwDeviceExtension,
1568     IN PPCI_COMMON_CONFIG pciData, // optional
1569     IN ULONG DeviceNumber,
1570     IN PPORT_CONFIGURATION_INFORMATION ConfigInfo
1571     );
1572 
1573 extern NTSTATUS
1574 NTAPI
1575 UniataChipDetect(
1576     IN PVOID HwDeviceExtension,
1577     IN PPCI_COMMON_CONFIG pciData, // optional
1578     IN ULONG DeviceNumber,
1579     IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo,
1580     IN BOOLEAN* simplexOnly
1581     );
1582 
1583 extern BOOLEAN
1584 NTAPI
1585 AtapiChipInit(
1586     IN PVOID HwDeviceExtension,
1587     IN ULONG DeviceNumber,
1588     IN ULONG c
1589     );
1590 
1591 #ifdef __REACTOS__
1592 extern ULONG_PTR
1593 #else
1594 extern ULONG
1595 #endif
1596 NTAPI
1597 AtapiGetIoRange(
1598     IN PVOID HwDeviceExtension,
1599     IN PPORT_CONFIGURATION_INFORMATION ConfigInfo,
1600     IN PPCI_COMMON_CONFIG pciData,
1601     IN ULONG SystemIoBusNumber,
1602     IN ULONG rid,
1603     IN ULONG offset,
1604     IN ULONG length //range id
1605     );
1606 
1607 extern USHORT
1608 NTAPI
1609 UniataEnableIoPCI(
1610     IN  ULONG                  busNumber,
1611     IN  ULONG                  slotNumber,
1612  IN OUT PPCI_COMMON_CONFIG     pciData
1613     );
1614 
1615 /****************** 1 *****************/
1616 #define GetPciConfig1(offs, op) {                                \
1617     ScsiPortGetBusDataByOffset(HwDeviceExtension,                \
1618                                PCIConfiguration,                 \
1619                                SystemIoBusNumber,                \
1620                                slotNumber,                       \
1621                                &op,                              \
1622                                offs,                             \
1623                                1);                               \
1624 }
1625 
1626 #define SetPciConfig1(offs, op) {                                \
1627     UCHAR _a = op;                                              \
1628     ScsiPortSetBusDataByOffset(HwDeviceExtension,                \
1629                                PCIConfiguration,                 \
1630                                SystemIoBusNumber,                \
1631                                slotNumber,                       \
1632                                &_a,                              \
1633                                offs,                             \
1634                                1);                               \
1635 }
1636 
1637 #define ChangePciConfig1(offs, _op) {                            \
1638     UCHAR a = 0;                                                 \
1639     GetPciConfig1(offs, a);                                      \
1640     a = (UCHAR)(_op);                                            \
1641     SetPciConfig1(offs, a);                                      \
1642 }
1643 
1644 /****************** 2 *****************/
1645 #define GetPciConfig2(offs, op) {                                \
1646     ScsiPortGetBusDataByOffset(HwDeviceExtension,                \
1647                                PCIConfiguration,                 \
1648                                SystemIoBusNumber,                \
1649                                slotNumber,                       \
1650                                &op,                              \
1651                                offs,                             \
1652                                2);                               \
1653 }
1654 
1655 #define SetPciConfig2(offs, op) {                                \
1656     USHORT _a = op;                                              \
1657     ScsiPortSetBusDataByOffset(HwDeviceExtension,                \
1658                                PCIConfiguration,                 \
1659                                SystemIoBusNumber,                \
1660                                slotNumber,                       \
1661                                &_a,                              \
1662                                offs,                             \
1663                                2);                               \
1664 }
1665 
1666 #define ChangePciConfig2(offs, _op) {                            \
1667     USHORT a = 0;                                                \
1668     GetPciConfig2(offs, a);                                      \
1669     a = (USHORT)(_op);                                           \
1670     SetPciConfig2(offs, a);                                      \
1671 }
1672 
1673 /****************** 4 *****************/
1674 #define GetPciConfig4(offs, op) {                                \
1675     ScsiPortGetBusDataByOffset(HwDeviceExtension,                \
1676                                PCIConfiguration,                 \
1677                                SystemIoBusNumber,                \
1678                                slotNumber,                       \
1679                                &op,                              \
1680                                offs,                             \
1681                                4);                               \
1682 }
1683 
1684 #define SetPciConfig4(offs, op) {                                \
1685     ULONG _a = op;                                               \
1686     ScsiPortSetBusDataByOffset(HwDeviceExtension,                \
1687                                PCIConfiguration,                 \
1688                                SystemIoBusNumber,                \
1689                                slotNumber,                       \
1690                                &_a,                              \
1691                                offs,                             \
1692                                4);                               \
1693 }
1694 
1695 #define ChangePciConfig4(offs, _op) {                            \
1696     ULONG a = 0;                                                 \
1697     GetPciConfig4(offs, a);                                      \
1698     a = _op;                                                     \
1699     SetPciConfig4(offs, a);                                      \
1700 }
1701 
1702 #define DMA_MODE_NONE  0x00
1703 #define DMA_MODE_BM    0x01
1704 #define DMA_MODE_AHCI  0x02
1705 
1706 #ifndef GetDmaStatus
1707 #define GetDmaStatus(de, c) \
1708     (((de)->BusMaster == DMA_MODE_BM) ? AtapiReadPort1(&((de)->chan[c]), IDX_BM_Status) : 0)
1709 #endif //GetDmaStatus
1710 
1711 #ifdef USE_OWN_DMA
1712 #define AtapiVirtToPhysAddr(hwde, srb, phaddr, plen, phaddru) \
1713     AtapiVirtToPhysAddr_(hwde, srb, phaddr, plen, phaddru);
1714 #else
1715 #define AtapiVirtToPhysAddr(hwde, srb, phaddr, plen, phaddru) \
1716     (ScsiPortConvertPhysicalAddressToUlong/*(ULONG)ScsiPortGetVirtualAddress*/(/*hwde,*/  \
1717                     ScsiPortGetPhysicalAddress(hwde, srb, phaddr, plen)))
1718 #endif //USE_OWN_DMA
1719 
1720 VOID
1721 DDKFASTAPI
1722 AtapiWritePort4(
1723     IN PHW_CHANNEL chan,
1724     IN ULONGIO_PTR port,
1725     IN ULONG data
1726     );
1727 
1728 VOID
1729 DDKFASTAPI
1730 AtapiWritePort2(
1731     IN PHW_CHANNEL chan,
1732     IN ULONGIO_PTR port,
1733     IN USHORT data
1734     );
1735 
1736 VOID
1737 DDKFASTAPI
1738 AtapiWritePort1(
1739     IN PHW_CHANNEL chan,
1740     IN ULONGIO_PTR port,
1741     IN UCHAR data
1742     );
1743 
1744 VOID
1745 DDKFASTAPI
1746 AtapiWritePortEx4(
1747     IN PHW_CHANNEL chan,
1748     IN ULONGIO_PTR port,
1749     IN ULONG offs,
1750     IN ULONG data
1751     );
1752 
1753 VOID
1754 DDKFASTAPI
1755 AtapiWritePortEx1(
1756     IN PHW_CHANNEL chan,
1757     IN ULONGIO_PTR port,
1758     IN ULONG offs,
1759     IN UCHAR data
1760     );
1761 
1762 ULONG
1763 DDKFASTAPI
1764 AtapiReadPort4(
1765     IN PHW_CHANNEL chan,
1766     IN ULONGIO_PTR port
1767     );
1768 
1769 USHORT
1770 DDKFASTAPI
1771 AtapiReadPort2(
1772     IN PHW_CHANNEL chan,
1773     IN ULONGIO_PTR port
1774     );
1775 
1776 UCHAR
1777 DDKFASTAPI
1778 AtapiReadPort1(
1779     IN PHW_CHANNEL chan,
1780     IN ULONGIO_PTR port
1781     );
1782 
1783 ULONG
1784 DDKFASTAPI
1785 AtapiReadPortEx4(
1786     IN PHW_CHANNEL chan,
1787     IN ULONGIO_PTR port,
1788     IN ULONG offs
1789     );
1790 
1791 UCHAR
1792 DDKFASTAPI
1793 AtapiReadPortEx1(
1794     IN PHW_CHANNEL chan,
1795     IN ULONGIO_PTR port,
1796     IN ULONG offs
1797     );
1798 
1799 VOID
1800 DDKFASTAPI
1801 AtapiWriteBuffer4(
1802     IN PHW_CHANNEL chan,
1803     IN ULONGIO_PTR _port,
1804     IN PVOID Buffer,
1805     IN ULONG Count,
1806     IN ULONG Timing
1807     );
1808 
1809 VOID
1810 DDKFASTAPI
1811 AtapiWriteBuffer2(
1812     IN PHW_CHANNEL chan,
1813     IN ULONGIO_PTR _port,
1814     IN PVOID Buffer,
1815     IN ULONG Count,
1816     IN ULONG Timing
1817     );
1818 
1819 VOID
1820 DDKFASTAPI
1821 AtapiReadBuffer4(
1822     IN PHW_CHANNEL chan,
1823     IN ULONGIO_PTR _port,
1824     IN PVOID Buffer,
1825     IN ULONG Count,
1826     IN ULONG Timing
1827     );
1828 
1829 VOID
1830 DDKFASTAPI
1831 AtapiReadBuffer2(
1832     IN PHW_CHANNEL chan,
1833     IN ULONGIO_PTR _port,
1834     IN PVOID Buffer,
1835     IN ULONG Count,
1836     IN ULONG Timing
1837     );
1838 
1839 /*#define GET_CHANNEL(Srb)  (Srb->TargetId >> 1)
1840 #define GET_LDEV(Srb)  (Srb->TargetId)
1841 #define GET_LDEV2(P, T, L)  (T)*/
1842 
1843 #define GET_CHANNEL(Srb)  (Srb->PathId)
1844 //#define GET_LDEV(Srb)  (Srb->TargetId | (Srb->PathId << 1))
1845 //#define GET_LDEV2(P, T, L)  (T | ((P)<<1))
1846 #define GET_CDEV(Srb)  (Srb->TargetId)
1847 
1848 VOID
1849 NTAPI
1850 AtapiSetupLunPtrs(
1851     IN PHW_CHANNEL chan,
1852     IN PHW_DEVICE_EXTENSION deviceExtension,
1853     IN ULONG c
1854     );
1855 /*
1856 #define AtapiSetupLunPtrs(chan, deviceExtension, c) \
1857 { \
1858         chan->DeviceExtension = deviceExtension; \
1859         chan->lChannel        = c; \
1860         chan->lun[0] = &(deviceExtension->lun[c*2+0]); \
1861         chan->lun[1] = &(deviceExtension->lun[c*2+1]); \
1862         chan->AltRegMap       = deviceExtension->AltRegMap; \
1863         chan->NextDpcChan     = -1; \
1864         chan->lun[0]->DeviceExtension = deviceExtension; \
1865         chan->lun[1]->DeviceExtension = deviceExtension; \
1866 }
1867 */
1868 BOOLEAN
1869 NTAPI
1870 AtapiReadChipConfig(
1871     IN PVOID HwDeviceExtension,
1872     IN ULONG DeviceNumber,
1873     IN ULONG channel // physical channel
1874     );
1875 
1876 VOID
1877 NTAPI
1878 UniataForgetDevice(
1879     PHW_LU_EXTENSION   LunExt
1880     );
1881 
1882 extern ULONG SkipRaids;
1883 extern ULONG ForceSimplex;
1884 extern BOOLEAN g_opt_AtapiDmaRawRead;
1885 extern BOOLEAN hasPCI;
1886 
1887 extern BOOLEAN InDriverEntry;
1888 extern BOOLEAN g_Dump;
1889 
1890 extern BOOLEAN g_opt_Verbose;
1891 extern ULONG   g_opt_VirtualMachine;
1892 
1893 extern ULONG   g_opt_WaitBusyResetCount;
1894 
1895 extern ULONG CPU_num;
1896 
1897 #define VM_AUTO      0x00
1898 #define VM_NONE      0x01
1899 #define VM_VBOX      0x02
1900 #define VM_VMWARE    0x03
1901 #define VM_QEMU      0x04
1902 #define VM_BOCHS     0x05
1903 #define VM_PCEM      0x06
1904 
1905 #define VM_MAX_KNOWN VM_PCEM
1906 
1907 extern BOOLEAN WinVer_WDM_Model;
1908 
1909 #pragma pack(pop)
1910 
1911 #endif //__IDE_BUSMASTER_H__
1912