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