3 Copyright (c) 2002-2014 Alexandr A. Telyatnikov (Alter)
9 This file contains DMA/UltraDMA and IDE BusMastering related definitions,
10 internal structures and useful macros
13 Alexander A. Telyatnikov (Alter)
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.
34 Alter, Copyright (c) 2002-2015
36 Some definitions were taken from FreeBSD 4.3-9.2 ATA driver by
37 Søren Schmidt, Copyright (c) 1998-2014
44 #ifndef __IDE_BUSMASTER_H__
45 #define __IDE_BUSMASTER_H__
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
66 #include "bm_devs_decl.h"
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 */
83 #define PCI_ADDRESS_IOMASK 0xfffffff0
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)
97 #define ATA_DMA_ENTRIES 256 /* PAGESIZE/2/sizeof(BM_DMA_ENTRY)*/
98 #define ATA_DMA_EOT 0x80000000
100 #define DEV_BSIZE 512
102 #define ATAPI_MAGIC_LSB 0x14
103 #define ATAPI_MAGIC_MSB 0xeb
105 #define AHCI_MAX_PORT 32
107 #define SATA_MAX_PM_UNITS 16
109 typedef struct _BUSMASTER_CTX
{
110 PBUSMASTER_CONTROLLER_INFORMATION
* BMListPtr
;
112 } BUSMASTER_CTX
, *PBUSMASTER_CTX
;
114 #define PCI_DEV_CLASS_STORAGE 0x01
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
121 #define PCI_DEV_PROGIF_AHCI_1_0 0x01
123 #pragma pack(push, 1)
125 /* structure for holding DMA address data */
126 typedef struct BM_DMA_ENTRY
{
129 } BM_DMA_ENTRY
, *PBM_DMA_ENTRY
;
131 typedef struct _IDE_BUSMASTER_REGISTERS
{
133 UCHAR DeviceSpecific0
;
135 UCHAR DeviceSpecific1
;
137 } IDE_BUSMASTER_REGISTERS
, *PIDE_BUSMASTER_REGISTERS
;
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
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
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 */
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
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)
170 typedef struct _IDE_AHCI_REGISTERS
{
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
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
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
209 // Global HBA Control
211 ULONG HR
:1; // HBA Reset
212 ULONG IE
:1; // interrupt enable
213 ULONG Reserved2_30
:1;
214 ULONG AE
:1; // AHCI enable
217 #define AHCI_GHC 0x04
218 #define AHCI_GHC_HR 0x00000001
219 #define AHCI_GHC_IE 0x00000002
220 #define AHCI_GHC_AE 0x80000000
222 // Interrupt status (bit mask)
224 // Ports implemented (bit mask)
229 ULONG CCC_CTL
; // 0x14
230 ULONG CCC_PORTS
; // 0x18
231 ULONG EM_LOC
; // 0x1c
232 ULONG EM_CTL
; // 0x20
234 // Extended HBA Capabilities
236 ULONG BOH
:1; // BIOS/OS Handoff
237 ULONG NVMP
:1; // NVMHCI Present
238 ULONG APST
:1; // Automatic Partial to Slumber Transitions
242 #define AHCI_CAP2_BOH 0x00000001
243 #define AHCI_CAP2_NVMP 0x00000002
244 #define AHCI_CAP2_APST 0x00000004
246 // BIOS/OS Handoff Control and Status
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
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
262 UCHAR Reserved2
[0x74];
264 UCHAR VendorSpec
[0x60];
265 } IDE_AHCI_REGISTERS
, *PIDE_AHCI_REGISTERS
;
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))
276 typedef union _SATA_SSTATUS_REG
{
279 ULONG DET
:4; // Device Detection
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
286 ULONG SPD
:4; // Current Interface Speed
288 #define SStatus_SPD_NoDev 0x00
289 #define SStatus_SPD_Gen1 0x01
290 #define SStatus_SPD_Gen2 0x02
291 #define SStatus_SPD_Gen3 0x03
293 ULONG IPM
:4; // Interface Power Management
295 #define SStatus_IPM_NoDev 0x00
296 #define SStatus_IPM_Active 0x01
297 #define SStatus_IPM_Partial 0x02
298 #define SStatus_IPM_Slumber 0x06
304 } SATA_SSTATUS_REG
, *PSATA_SSTATUS_REG
;
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
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
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
323 typedef union _SATA_SCONTROL_REG
{
326 ULONG DET
:4; // Device Detection Init
328 #define SControl_DET_DoNothing 0x00
329 #define SControl_DET_Idle 0x00
330 #define SControl_DET_Init 0x01
331 #define SControl_DET_Disable 0x04
333 ULONG SPD
:4; // Speed Allowed
335 #define SControl_SPD_NoRestrict 0x00
336 #define SControl_SPD_LimGen1 0x01
337 #define SControl_SPD_LimGen2 0x02
338 #define SControl_SPD_LimGen3 0x03
340 ULONG IPM
:4; // Interface Power Management Transitions Allowed
342 #define SControl_IPM_NoRestrict 0x00
343 #define SControl_IPM_NoPartial 0x01
344 #define SControl_IPM_NoSlumber 0x02
345 #define SControl_IPM_NoPartialSlumber 0x03
347 ULONG SPM
:4; // Select Power Management, unused by AHCI
348 ULONG PMP
:4; // Port Multiplier Port, unused by AHCI
353 } SATA_SCONTROL_REG
, *PSATA_SCONTROL_REG
;
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
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
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
371 typedef union _SATA_SERROR_REG
{
375 UCHAR I
:1; // Recovered Data Integrity Error
376 UCHAR M
:1; // Recovered Communications Error
377 UCHAR Reserved_2_7
:6;
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;
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
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;
404 } SATA_SERROR_REG
, *PSATA_SERROR_REG
;
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
423 typedef struct _IDE_SATA_REGISTERS
{
425 SATA_SSTATUS_REG SStatus
;
429 SATA_SERROR_REG SError
;
433 SATA_SCONTROL_REG SControl
;
443 USHORT PMN
; // PM Notify, bitmask
448 } IDE_SATA_REGISTERS
, *PIDE_SATA_REGISTERS
;
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
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)
460 #define IDX_INDEXED_IO (IDX_SATA_IO+IDX_SATA_IO_SZ)
461 #define IDX_INDEXED_IO_SZ 2
463 #define IDX_INDEXED_ADDR (0+IDX_INDEXED_IO)
464 #define IDX_INDEXED_DATA (1+IDX_INDEXED_IO)
466 #define IDX_MAX_REG (IDX_INDEXED_IO+IDX_INDEXED_IO_SZ)
469 typedef union _AHCI_IS_REG
{
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
480 ULONG Reserved_8_21
:14;
481 ULONG PRCS
:1;// PhyRdy Change Status
482 ULONG IPMS
:1;// Incorrect Port Multiplier Status
484 ULONG OFS
:1; // Overflow Status
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
494 } AHCI_IS_REG
, *PAHCI_IS_REG
;
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
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
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))
519 typedef struct _IDE_AHCI_PORT_REGISTERS
{
522 ULONG CLB
; // command list base address, 1K-aligned
523 ULONG CLBU
; // command list base address (upper 32bits)
526 }; // 0x100 + 0x80*c + 0x0000
530 ULONG FB
; // FIS base address
531 ULONG FBU
; // FIS base address (upper 32bits)
534 }; // 0x100 + 0x80*c + 0x0008
537 ULONG IS_Reg
; // interrupt status
539 }; // 0x100 + 0x80*c + 0x0010
542 ULONG Reg
; // interrupt enable
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
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
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
565 } IE
; // 0x100 + 0x80*c + 0x0014
568 ULONG Reg
; // command register
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;
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
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;
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
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
603 } CMD
; // 0x100 + 0x80*c + 0x0018
608 ULONG Reg
; // Task File Data
612 UCHAR cs1
:2;// command-specific
614 UCHAR cs2
:3;// command-specific
617 UCHAR ERR
; // Contains the latest copy of the task file error register.
620 } TFD
; // 0x100 + 0x80*c + 0x0020
623 ULONG Reg
; // signature
626 UCHAR LbaLow
; // IDX_IO1_i_BlockNumber
627 UCHAR LbaMid
; // IDX_IO1_i_CylinderLow
628 UCHAR LbaHigh
; // IDX_IO1_i_CylinderHigh
630 } SIG
; // 0x100 + 0x80*c + 0x0024
632 ULONG SStatus
; // SCR0
633 SATA_SSTATUS_REG SSTS
;
634 }; // 0x100 + 0x80*c + 0x0028
636 ULONG SControl
; // SCR2
637 SATA_SCONTROL_REG SCTL
;
638 }; // 0x100 + 0x80*c + 0x002c
640 ULONG SError
; // SCR1
641 SATA_SERROR_REG SERR
;
642 }; // 0x100 + 0x80*c + 0x0030
645 ULONG SActive
; // bitmask
646 }; // 0x100 + 0x80*c + 0x0034
648 ULONG CI
; // Command issue, bitmask, 0x100 + 0x80*c + 0x0038
654 USHORT PMN
; // PM Notify, bitmask
657 } SNTF
; // 0x100 + 0x80*c + 0x003c
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
672 } FBS
; // 0x100 + 0x80*c + 0x0040
674 ULONG Reserved_44_7f
[11];
675 UCHAR VendorSpec
[16];
677 } IDE_AHCI_PORT_REGISTERS
, *PIDE_AHCI_PORT_REGISTERS
;
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))
692 #define IDX_AHCI_P_SNTF (FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, SNTF))
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
720 typedef struct _IDE_AHCI_PRD_ENTRY
{
743 } IDE_AHCI_PRD_ENTRY
, *PIDE_AHCI_PRD_ENTRY
;
745 #define ATA_AHCI_DMA_ENTRIES (PAGE_SIZE/2/sizeof(IDE_AHCI_PRD_ENTRY)) /* 128 */
746 #define ATA_AHCI_MAX_TAGS 32
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
757 typedef struct _AHCI_ATA_H2D_FIS
{
758 UCHAR FIS_Type
; // = 0x27
760 UCHAR Cmd
:1; // update Command register
761 UCHAR Command
; // [2]
762 UCHAR Feature
; // [3]
764 UCHAR BlockNumber
; // [4]
765 UCHAR CylinderLow
; // [5]
766 UCHAR CylinderHigh
; // [6]
767 UCHAR DriveSelect
; // [7]
769 UCHAR BlockNumberExp
; // [8]
770 UCHAR CylinderLowExp
; // [9]
771 UCHAR CylinderHighExp
; // [10]
772 UCHAR FeatureExp
; // [11]
774 UCHAR BlockCount
; // [12]
775 UCHAR BlockCountExp
; // [13]
776 UCHAR Reserved14
; // [14]
777 UCHAR Control
; // [15]
779 } AHCI_ATA_H2D_FIS
, *PAHCI_ATA_H2D_FIS
;
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))
795 #define AHCI_FIS_COMM_PM (0x80 | AHCI_DEV_SEL_PM)
797 #define AHCI_DEV_SEL_1 0x00
798 #define AHCI_DEV_SEL_2 0x01
799 #define AHCI_DEV_SEL_PM 0x0f
801 /* 128-byte aligned */
802 typedef struct _IDE_AHCI_CMD
{
806 IDE_AHCI_PRD_ENTRY prd_tab
[ATA_AHCI_DMA_ENTRIES
]; // also 128-byte aligned
807 } IDE_AHCI_CMD
, *PIDE_AHCI_CMD
;
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
818 /* 128-byte aligned */
819 typedef struct _IDE_AHCI_CMD_LIST
{
821 USHORT prd_length
; /* PRD entries */
823 ULONGLONG cmd_table_phys
; /* points to IDE_AHCI_CMD */
825 } IDE_AHCI_CMD_LIST
, *PIDE_AHCI_CMD_LIST
;
827 /* 256-byte aligned */
828 typedef struct _IDE_AHCI_RCV_FIS
{
838 } IDE_AHCI_RCV_FIS
, *PIDE_AHCI_RCV_FIS
;
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
;
849 #define IsBusMaster(pciData) \
850 ( ((pciData)->Command & (PCI_ENABLE_BUS_MASTER/* | PCI_ENABLE_IO_SPACE*/)) == \
851 (PCI_ENABLE_BUS_MASTER/* | PCI_ENABLE_IO_SPACE*/))
853 #define PCI_IDE_PROGIF_NATIVE_1 0x01
854 #define PCI_IDE_PROGIF_NATIVE_2 0x04
855 #define PCI_IDE_PROGIF_NATIVE_ALL 0x05
857 #define IsMasterDev(pciData) \
858 ( ((pciData)->ProgIf & 0x80) && \
859 ((pciData)->ProgIf & PCI_IDE_PROGIF_NATIVE_ALL) != PCI_IDE_PROGIF_NATIVE_ALL )
861 //#define INT_Q_SIZE 32
862 #define MIN_REQ_TTL 4
866 typedef union _ATA_REQ
{
867 // ULONG reqId; // serial
873 union _ATA_REQ
* next_req
;
874 union _ATA_REQ
* prev_req
;
876 PSCSI_REQUEST_BLOCK Srb
; // Current request on controller.
878 PUSHORT DataBuffer
; // Data buffer pointer.
879 ULONG WordsLeft
; // Data words left.
880 ULONG TransferLength
; // Originally requested transfer length
882 ULONG WordsTransfered
;// Data words already transfered.
891 PSCSI_REQUEST_BLOCK OriginalSrb
; // Mechanism Status Srb Data
902 ULONGLONG ahci_base64
;
904 PIDE_AHCI_CMD ahci_cmd_ptr
;
908 USHORT io_cmd_flags
; // out
913 //UCHAR padding_128b[128]; // Note: we assume, NT allocates block > 4k as PAGE-aligned
917 BM_DMA_ENTRY dma_tab
[ATA_DMA_ENTRIES
];
918 IDE_AHCI_CMD ahci_cmd0
; // for AHCI, 128-byte aligned
923 UCHAR padding_4kb
[PAGE_SIZE
];
925 } ATA_REQ
, *PATA_REQ
;
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
939 #define REQ_STATE_NONE 0x00
940 #define REQ_STATE_QUEUED 0x10
942 #define REQ_STATE_PREPARE_TO_TRANSFER 0x20
943 #define REQ_STATE_PREPARE_TO_NEXT 0x21
944 #define REQ_STATE_READY_TO_TRANSFER 0x30
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
952 #define REQ_STATE_EARLY_INTR 0x48
954 #define REQ_STATE_PROCESSING_INTR 0x50
956 #define REQ_STATE_DPC_INTR_REQ 0x51
957 #define REQ_STATE_DPC_RESET_REQ 0x52
958 #define REQ_STATE_DPC_COMPLETE_REQ 0x53
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
967 #define REQ_STATE_TRANSFER_COMPLETE 0x7f
970 #define CMD_ACTION_PREPARE 0x01
971 #define CMD_ACTION_EXEC 0x02
972 #define CMD_ACTION_ALL (CMD_ACTION_PREPARE | CMD_ACTION_EXEC)
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)
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)
985 #define REORDER_COST_SWITCH_RW_HDD (0)
986 #define REORDER_MCOST_SWITCH_RW_HDD (4)
987 #define REORDER_MCOST_SEEK_BACK_HDD (2)
989 /*typedef struct _ATA_QUEUE {
990 struct _ATA_REQ* head_req; // index
991 struct _ATA_REQ* tail_req; // index
994 BM_DMA_ENTRY dma_tab[ATA_DMA_ENTRIES];
995 } ATA_QUEUE, *PATA_QUEUE;*/
997 struct _HW_DEVICE_EXTENSION
;
998 struct _HW_LU_EXTENSION
;
1000 typedef struct _IORES
{
1002 ULONG Addr
; /* Base address*/
1003 PVOID pAddr
; /* Base address in pointer form */
1005 ULONG MemIo
:1; /* Memory mapping (1) vs IO ports (0) */
1006 ULONG Proc
:1; /* Need special processing via IO_Proc */
1010 // Channel extension
1011 typedef struct _HW_CHANNEL
{
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;*/
1020 ULONG ChannelSelectWaitCount
;
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
1034 // Placeholder for status register after a GET_MEDIA_STATUS command
1035 UCHAR ReturningMediaStatus
;
1037 BOOLEAN CopyDmaBuffer
;
1044 MECHANICAL_STATUS_INFORMATION_HEADER MechStatusData
;
1045 SENSE_DATA MechStatusSense
;
1046 ULONG MechStatusRetryCount
;
1047 SCSI_REQUEST_BLOCK InternalSrb
;
1049 ULONG MaxTransferMode
; // may differ from Controller's value due to 40-pin cable
1051 ULONG ChannelCtrlFlags
;
1052 ULONG ResetInProgress
; // flag
1058 #define CHECK_INTR_ACTIVE 0x03
1059 #define CHECK_INTR_DETECTED 0x02
1060 #define CHECK_INTR_CHECK 0x01
1061 #define CHECK_INTR_IDLE 0x00
1064 PHW_TIMER HwScsiTimer
;
1067 PHW_TIMER HwScsiTimer1
;
1068 PHW_TIMER HwScsiTimer2
;
1070 // PHW_TIMER CurDpc;
1071 // LARGE_INTEGER ActivationTime;
1075 // PHW_TIMER HwScsiTimer;
1076 // KSPIN_LOCK QueueSpinLock;
1077 // KIRQL QueueOldIrql;
1079 struct _HW_DEVICE_EXTENSION
* DeviceExtension
;
1080 struct _HW_LU_EXTENSION
* lun
[IDE_MAX_LUN_PER_CHAN
];
1085 // Double-buffering support
1087 ULONG DB_PRD_PhAddr
;
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
;
1099 ULONG AhciCompleteCI
;
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
;
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
1117 //ULONG BaseMemAddress;
1118 //ULONG BaseMemAddressOffset;
1119 IORES RegTranslation
[IDX_MAX_REG
];
1121 } HW_CHANNEL
, *PHW_CHANNEL
;
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
1138 #define CTRFLAGS_PERMANENT (CTRFLAGS_DMA_RO | CTRFLAGS_NO_SLAVE)
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
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
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
;
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)
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
;
1182 ULONG LunSelectWaitCount
;
1183 ULONG AtapiReadyWaitDelay
;
1187 ULONG opt_MaxTransferMode
;
1188 ULONG opt_PreferedTransferMode
;
1189 BOOLEAN opt_ReadCacheEnable
;
1190 BOOLEAN opt_WriteCacheEnable
;
1192 UCHAR opt_AdvPowerMode
;
1193 UCHAR opt_AcousticMode
;
1194 UCHAR opt_StandbyTimer
;
1195 UCHAR opt_Padding
[2]; // padding
1197 struct _SBadBlockListItem
* bbListDescr
;
1198 struct _SBadBlockRange
* arrBadBlocks
;
1201 // Controller-specific LUN options
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.
1210 struct _HW_DEVICE_EXTENSION
* DeviceExtension
;
1211 struct _HW_CHANNEL
* chan
;
1214 ULONGLONG errLastLba
;
1217 UCHAR errPadding
[3];
1219 #ifdef IO_STATISTICS
1221 LONGLONG ModeErrorCount
[MAX_RETRIES
];
1222 LONGLONG RecoverCount
[MAX_RETRIES
];
1224 LONGLONG BlockIoCount
;
1226 #endif//IO_STATISTICS
1227 } HW_LU_EXTENSION
, *PHW_LU_EXTENSION
;
1230 typedef struct _HW_DEVICE_EXTENSION
{
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
1241 ULONG NumberChannels
;
1243 ULONG FirstChannelToCheck
;
1245 HW_LU_EXTENSION lun
[IDE_MAX_LUN
];
1246 HW_CHANNEL chan
[AHCI_MAX_PORT
/*IDE_MAX_CHAN*/];
1248 PHW_LU_EXTENSION lun
; // lun array
1249 PHW_CHANNEL chan
; // channel array
1251 UCHAR LastInterruptedChannel
;
1252 // Indicates the number of blocks transferred per int. according to the
1254 BOOLEAN DriverMustPoll
; // Driver is being used by the crash dump utility or ntldr.
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;
1262 ULONG ActiveDpcChan
;
1264 ULONG ExpectingInterrupt
; // Indicates entire controller expecting an interrupt
1266 PHW_TIMER HwScsiTimer1;
1267 PHW_TIMER HwScsiTimer2;
1273 PDEVICE_OBJECT Isr2DevObj
;
1275 //PIDE_BUSMASTER_REGISTERS BaseIoAddressBM_0;
1276 IORES BaseIoAddressBM_0
;
1277 //PIDE_BUSMASTER_REGISTERS BaseIoAddressBM[IDE_MAX_CHAN];
1279 // Device identification
1283 ULONG SystemIoBusNumber
;
1286 ULONG InitMethod
; // vendor specific
1291 BOOLEAN simplexOnly
;
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; */
1305 ULONG MaxTransferMode
; // max transfer mode supported by controller
1307 INTERFACE_TYPE OrigAdapterInterfaceType
;
1308 INTERFACE_TYPE AdapterInterfaceType
;
1309 ULONG MaximumDmaTransferLength
;
1310 ULONG AlignmentMask
;
1311 ULONG DmaSegmentLength
;
1312 ULONG DmaSegmentAlignmentMask
; // must be PAGE-aligned
1314 //ULONG BaseMemAddress;
1316 //PIDE_SATA_REGISTERS BaseIoAddressSATA_0;
1317 IORES BaseIoAddressSATA_0
;
1318 //PIDE_SATA_REGISTERS BaseIoAddressSATA[IDE_MAX_CHAN];
1321 //PIDE_AHCI_PORT_REGISTERS BaseIoAHCIPort[AHCI_MAX_PORT];
1324 ULONG AHCI_PI_mask
; // for port exclusion, usually = AHCI_PI
1325 PATA_REQ AhciInternalAtaReq0
;
1326 PSCSI_REQUEST_BLOCK AhciInternalSrb0
;
1328 BOOLEAN opt_AtapiDmaZeroTransfer
; // default FALSE
1329 BOOLEAN opt_AtapiDmaControlCmd
; // default FALSE
1330 BOOLEAN opt_AtapiDmaRawRead
; // default TRUE
1331 BOOLEAN opt_AtapiDmaReadWrite
; // default TRUE
1335 // Controller specific state/options
1340 } HW_DEVICE_EXTENSION
, *PHW_DEVICE_EXTENSION
;
1342 typedef struct _ISR2_DEVICE_EXTENSION
{
1343 PHW_DEVICE_EXTENSION HwDeviceExtension
;
1345 } ISR2_DEVICE_EXTENSION
, *PISR2_DEVICE_EXTENSION
;
1347 typedef ISR2_DEVICE_EXTENSION PCIIDE_DEVICE_EXTENSION
;
1348 typedef PISR2_DEVICE_EXTENSION PPCIIDE_DEVICE_EXTENSION
;
1350 #define HBAFLAGS_DMA_DISABLED 0x01
1351 #define HBAFLAGS_DMA_DISABLED_LBA48 0x02
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
;
1360 //extern const CHAR retry_Wdma[MAX_RETRIES+1];
1361 //extern const CHAR retry_Udma[MAX_RETRIES+1];
1365 UniataEnumBusMasterController(
1366 IN PVOID DriverObject
,
1371 UniataFindCompatBusMasterController1(
1372 IN PVOID HwDeviceExtension
,
1374 IN PVOID BusInformation
,
1375 IN PCHAR ArgumentString
,
1376 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
1381 UniataFindCompatBusMasterController2(
1382 IN PVOID HwDeviceExtension
,
1384 IN PVOID BusInformation
,
1385 IN PCHAR ArgumentString
,
1386 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
1390 #define UNIATA_ALLOCATE_NEW_LUNS 0x00
1392 extern BOOLEAN NTAPI
1393 UniataAllocateLunExt(
1394 PHW_DEVICE_EXTENSION deviceExtension
,
1395 ULONG NewNumberChannels
1400 PHW_DEVICE_EXTENSION deviceExtension
1404 UniataFindBusMasterController(
1405 IN PVOID HwDeviceExtension
,
1407 IN PVOID BusInformation
,
1408 IN PCHAR ArgumentString
,
1409 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
1415 UniataClaimLegacyPCIIDE(
1422 IN PVOID HwDeviceExtension
1427 UniataDisconnectIntr2(
1428 IN PVOID HwDeviceExtension
1433 ScsiPortGetBusDataByOffset(
1434 IN PVOID HwDeviceExtension
,
1435 IN BUS_DATA_TYPE BusDataType
,
1437 IN ULONG SlotNumber
,
1443 #define PCIBUSNUM_NOT_SPECIFIED (0xffffffffL)
1444 #define PCISLOTNUM_NOT_SPECIFIED (0xffffffffL)
1449 PBUSMASTER_CONTROLLER_INFORMATION_BASE BusMasterAdapters
,
1451 IN PVOID HwDeviceExtension
,
1453 IN ULONG SlotNumber
,
1454 OUT PCI_SLOT_NUMBER
* _slotData
// optional
1460 IN PVOID HwDeviceExtension
,
1461 IN BUS_DATA_TYPE BusDataType
,
1463 IN ULONG SlotNumber
,
1471 IN PVOID HwDeviceExtension
,
1472 IN PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
1473 IN ULONG lChannel
// logical channel,
1479 IN PVOID HwDeviceExtension
,
1480 IN ULONG DeviceNumber
,
1481 IN ULONG lChannel
, // logical channel,
1482 IN PSCSI_REQUEST_BLOCK Srb
,
1490 PVOID HwDeviceExtension
,
1491 PSCSI_REQUEST_BLOCK Srb
,
1500 PSCSI_REQUEST_BLOCK Srb
1506 IN PVOID HwDeviceExtension
,
1508 PSCSI_REQUEST_BLOCK Srb
1514 IN PVOID HwDeviceExtension
,
1515 IN ULONG DeviceNumber
,
1516 IN ULONG lChannel
, // logical channel,
1517 IN PSCSI_REQUEST_BLOCK Srb
1523 IN PVOID HwDeviceExtension
,
1524 IN ULONG DeviceNumber
,
1525 IN ULONG lChannel
, // logical channel,
1526 IN PSCSI_REQUEST_BLOCK Srb
1532 IN PHW_DEVICE_EXTENSION deviceExtension
,
1533 IN PHW_LU_EXTENSION LunExt
,
1540 IN PHW_DEVICE_EXTENSION deviceExtension
,
1541 IN PHW_LU_EXTENSION LunExt
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
1556 extern BOOLEAN NTAPI
1558 IN PKINTERRUPT Interrupt
,
1559 IN PVOID HwDeviceExtension
1562 extern PDRIVER_OBJECT SavedDriverObject
;
1566 UniataChipDetectChannels(
1567 IN PVOID HwDeviceExtension
,
1568 IN PPCI_COMMON_CONFIG pciData
, // optional
1569 IN ULONG DeviceNumber
,
1570 IN PPORT_CONFIGURATION_INFORMATION ConfigInfo
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
1586 IN PVOID HwDeviceExtension
,
1587 IN ULONG DeviceNumber
,
1594 IN PVOID HwDeviceExtension
,
1595 IN PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
1596 IN PPCI_COMMON_CONFIG pciData
,
1597 IN ULONG SystemIoBusNumber
,
1600 IN ULONG length
//range id
1607 IN ULONG slotNumber
,
1608 IN OUT PPCI_COMMON_CONFIG pciData
1611 /****************** 1 *****************/
1612 #define GetPciConfig1(offs, op) { \
1613 ScsiPortGetBusDataByOffset(HwDeviceExtension, \
1615 SystemIoBusNumber, \
1622 #define SetPciConfig1(offs, op) { \
1624 ScsiPortSetBusDataByOffset(HwDeviceExtension, \
1626 SystemIoBusNumber, \
1633 #define ChangePciConfig1(offs, _op) { \
1635 GetPciConfig1(offs, a); \
1637 SetPciConfig1(offs, a); \
1640 /****************** 2 *****************/
1641 #define GetPciConfig2(offs, op) { \
1642 ScsiPortGetBusDataByOffset(HwDeviceExtension, \
1644 SystemIoBusNumber, \
1651 #define SetPciConfig2(offs, op) { \
1653 ScsiPortSetBusDataByOffset(HwDeviceExtension, \
1655 SystemIoBusNumber, \
1662 #define ChangePciConfig2(offs, _op) { \
1664 GetPciConfig2(offs, a); \
1665 a = (USHORT)(_op); \
1666 SetPciConfig2(offs, a); \
1669 /****************** 4 *****************/
1670 #define GetPciConfig4(offs, op) { \
1671 ScsiPortGetBusDataByOffset(HwDeviceExtension, \
1673 SystemIoBusNumber, \
1680 #define SetPciConfig4(offs, op) { \
1682 ScsiPortSetBusDataByOffset(HwDeviceExtension, \
1684 SystemIoBusNumber, \
1691 #define ChangePciConfig4(offs, _op) { \
1693 GetPciConfig4(offs, a); \
1695 SetPciConfig4(offs, a); \
1698 #define DMA_MODE_NONE 0x00
1699 #define DMA_MODE_BM 0x01
1700 #define DMA_MODE_AHCI 0x02
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
1708 #define AtapiVirtToPhysAddr(hwde, srb, phaddr, plen, phaddru) \
1709 AtapiVirtToPhysAddr_(hwde, srb, phaddr, plen, phaddru);
1711 #define AtapiVirtToPhysAddr(hwde, srb, phaddr, plen, phaddru) \
1712 (ScsiPortConvertPhysicalAddressToUlong/*(ULONG)ScsiPortGetVirtualAddress*/(/*hwde,*/ \
1713 ScsiPortGetPhysicalAddress(hwde, srb, phaddr, plen)))
1714 #endif //USE_OWN_DMA
1719 IN PHW_CHANNEL chan
,
1720 IN ULONGIO_PTR port
,
1727 IN PHW_CHANNEL chan
,
1728 IN ULONGIO_PTR port
,
1735 IN PHW_CHANNEL chan
,
1736 IN ULONGIO_PTR port
,
1743 IN PHW_CHANNEL chan
,
1744 IN ULONGIO_PTR port
,
1752 IN PHW_CHANNEL chan
,
1753 IN ULONGIO_PTR port
,
1761 IN PHW_CHANNEL chan
,
1768 IN PHW_CHANNEL chan
,
1775 IN PHW_CHANNEL chan
,
1782 IN PHW_CHANNEL chan
,
1783 IN ULONGIO_PTR port
,
1790 IN PHW_CHANNEL chan
,
1791 IN ULONGIO_PTR port
,
1798 IN PHW_CHANNEL chan
,
1799 IN ULONGIO_PTR _port
,
1808 IN PHW_CHANNEL chan
,
1809 IN ULONGIO_PTR _port
,
1818 IN PHW_CHANNEL chan
,
1819 IN ULONGIO_PTR _port
,
1828 IN PHW_CHANNEL chan
,
1829 IN ULONGIO_PTR _port
,
1835 /*#define GET_CHANNEL(Srb) (Srb->TargetId >> 1)
1836 #define GET_LDEV(Srb) (Srb->TargetId)
1837 #define GET_LDEV2(P, T, L) (T)*/
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)
1847 IN PHW_CHANNEL chan
,
1848 IN PHW_DEVICE_EXTENSION deviceExtension
,
1852 #define AtapiSetupLunPtrs(chan, deviceExtension, c) \
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; \
1866 AtapiReadChipConfig(
1867 IN PVOID HwDeviceExtension
,
1868 IN ULONG DeviceNumber
,
1869 IN ULONG channel
// physical channel
1875 PHW_LU_EXTENSION LunExt
1878 extern ULONG SkipRaids
;
1879 extern ULONG ForceSimplex
;
1880 extern BOOLEAN g_opt_AtapiDmaRawRead
;
1881 extern BOOLEAN hasPCI
;
1883 extern BOOLEAN InDriverEntry
;
1884 extern BOOLEAN g_Dump
;
1886 extern BOOLEAN g_opt_Verbose
;
1887 extern ULONG g_opt_VirtualMachine
;
1889 extern ULONG g_opt_WaitBusyResetCount
;
1891 extern ULONG CPU_num
;
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
1900 #define VM_MAX_KNOWN VM_BOCHS
1902 extern BOOLEAN WinVer_WDM_Model
;
1906 #endif //__IDE_BUSMASTER_H__