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