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