3 Copyright (c) 2002-2018 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_MAX_IOLBA32 DEF_U64(0xffffff80)
98 #define ATA_MAX_LBA32 DEF_U64(0xffffffff)
100 #define ATA_DMA_ENTRIES 256 /* PAGESIZE/2/sizeof(BM_DMA_ENTRY)*/
101 #define ATA_DMA_EOT 0x80000000
103 #define DEV_BSIZE 512
105 #define ATAPI_MAGIC_LSB 0x14
106 #define ATAPI_MAGIC_MSB 0xeb
108 #define AHCI_MAX_PORT 32
110 #define SATA_MAX_PM_UNITS 16
112 typedef struct _BUSMASTER_CTX
{
113 PBUSMASTER_CONTROLLER_INFORMATION
* BMListPtr
;
115 } BUSMASTER_CTX
, *PBUSMASTER_CTX
;
117 #define PCI_DEV_CLASS_STORAGE 0x01
119 #define PCI_DEV_SUBCLASS_IDE 0x01
120 #define PCI_DEV_SUBCLASS_RAID 0x04
121 #define PCI_DEV_SUBCLASS_ATA 0x05
122 #define PCI_DEV_SUBCLASS_SATA 0x06
124 #define PCI_DEV_PROGIF_AHCI_1_0 0x01
126 #pragma pack(push, 1)
128 /* structure for holding DMA address data */
129 typedef struct BM_DMA_ENTRY
{
132 } BM_DMA_ENTRY
, *PBM_DMA_ENTRY
;
134 typedef struct _IDE_BUSMASTER_REGISTERS
{
136 UCHAR DeviceSpecific0
;
138 UCHAR DeviceSpecific1
;
140 } IDE_BUSMASTER_REGISTERS
, *PIDE_BUSMASTER_REGISTERS
;
142 #define BM_STATUS_ACTIVE 0x01
143 #define BM_STATUS_ERR 0x02
144 #define BM_STATUS_INTR 0x04
145 #define BM_STATUS_MASK 0x07
146 #define BM_STATUS_DRIVE_0_DMA 0x20
147 #define BM_STATUS_DRIVE_1_DMA 0x40
148 #define BM_STATUS_SIMPLEX_ONLY 0x80
150 #define BM_COMMAND_START_STOP 0x01
151 /*#define BM_COMMAND_WRITE 0x08
152 #define BM_COMMAND_READ 0x00*/
153 #define BM_COMMAND_WRITE 0x00
154 #define BM_COMMAND_READ 0x08
156 #define BM_DS0_SII_DMA_ENABLE (1 << 0) /* DMA run switch */
157 #define BM_DS0_SII_IRQ (1 << 3) /* ??? */
158 #define BM_DS0_SII_DMA_SATA_IRQ (1 << 4) /* OR of all SATA IRQs */
159 #define BM_DS0_SII_DMA_ERROR (1 << 17) /* PCI bus error */
160 #define BM_DS0_SII_DMA_COMPLETE (1 << 18) /* cmd complete / IRQ pending */
163 #define IDX_BM_IO (IDX_IO2_o+IDX_IO2_o_SZ)
164 //#define IDX_BM_IO_SZ sizeof(IDE_BUSMASTER_REGISTERS)
165 #define IDX_BM_IO_SZ 5
167 #define IDX_BM_Command (FIELD_OFFSET(IDE_BUSMASTER_REGISTERS, Command )+IDX_BM_IO)
168 #define IDX_BM_DeviceSpecific0 (FIELD_OFFSET(IDE_BUSMASTER_REGISTERS, DeviceSpecific0)+IDX_BM_IO)
169 #define IDX_BM_Status (FIELD_OFFSET(IDE_BUSMASTER_REGISTERS, Status )+IDX_BM_IO)
170 #define IDX_BM_DeviceSpecific1 (FIELD_OFFSET(IDE_BUSMASTER_REGISTERS, DeviceSpecific1)+IDX_BM_IO)
171 #define IDX_BM_PRD_Table (FIELD_OFFSET(IDE_BUSMASTER_REGISTERS, PRD_Table )+IDX_BM_IO)
173 typedef struct _IDE_AHCI_REGISTERS
{
176 ULONG NOP
:5; // number of ports
177 ULONG SXS
:1; // Supports External SATA
178 ULONG EMS
:1; // Enclosure Management Supported
179 ULONG CCCS
:1; // Command Completion Coalescing Supported
180 ULONG NCS
:5; // number of command slots
181 ULONG PSC
:1; // partial state capable
182 ULONG SSC
:1; // slumber state capable
183 ULONG PMD
:1; // PIO multiple DRQ block
184 ULONG FBSS
:1; // FIS-based Switching Supported
186 ULONG SPM
:1; // port multiplier
187 ULONG SAM
:1; // AHCI mode only
188 ULONG SNZO
:1; // non-zero DMA offset
189 ULONG ISS
:4; // interface speed
190 ULONG SCLO
:1; // command list override
191 ULONG SAL
:1; // activity LED
192 ULONG SALP
:1; // aggressive link power management
193 ULONG SSS
:1; // staggered spin-up
194 ULONG SIS
:1; // interlock switch
195 ULONG SSNTF
:1; // Supports SNotification Register
196 ULONG SNCQ
:1; // native command queue
197 ULONG S64A
:1; // 64bit addr
200 #define AHCI_CAP_NOP_MASK 0x0000001f
201 #define AHCI_CAP_CCC 0x00000080
202 #define AHCI_CAP_NCS_MASK 0x00001f00
203 #define AHCI_CAP_PMD 0x00008000
204 #define AHCI_CAP_SPM 0x00020000
205 #define AHCI_CAP_SAM 0x00040000
206 #define AHCI_CAP_ISS_MASK 0x00f00000
207 #define AHCI_CAP_SCLO 0x01000000
208 #define AHCI_CAP_SNTF 0x20000000
209 #define AHCI_CAP_NCQ 0x40000000
210 #define AHCI_CAP_S64A 0x80000000
212 // Global HBA Control
214 ULONG HR
:1; // HBA Reset
215 ULONG IE
:1; // interrupt enable
216 ULONG Reserved2_30
:1;
217 ULONG AE
:1; // AHCI enable
220 #define AHCI_GHC 0x04
221 #define AHCI_GHC_HR 0x00000001
222 #define AHCI_GHC_IE 0x00000002
223 #define AHCI_GHC_AE 0x80000000
225 // Interrupt status (bit mask)
227 // Ports implemented (bit mask)
232 ULONG CCC_CTL
; // 0x14
233 ULONG CCC_PORTS
; // 0x18
234 ULONG EM_LOC
; // 0x1c
235 ULONG EM_CTL
; // 0x20
237 // Extended HBA Capabilities
239 ULONG BOH
:1; // BIOS/OS Handoff
240 ULONG NVMP
:1; // NVMHCI Present
241 ULONG APST
:1; // Automatic Partial to Slumber Transitions
245 #define AHCI_CAP2_BOH 0x00000001
246 #define AHCI_CAP2_NVMP 0x00000002
247 #define AHCI_CAP2_APST 0x00000004
249 // BIOS/OS Handoff Control and Status
251 ULONG BB
:1; // BIOS Busy
252 ULONG OOC
:1; // OS Ownership Change
253 ULONG SOOE
:1; // SMI on OS Ownership Change Enable
254 ULONG OOS
:1; // OS Owned Semaphore
255 ULONG BOS
:1; // BIOS Owned Semaphore
259 #define AHCI_BOHC_BB 0x00000001
260 #define AHCI_BOHC_OOC 0x00000002
261 #define AHCI_BOHC_SOOE 0x00000004
262 #define AHCI_BOHC_OOS 0x00000008
263 #define AHCI_BOHC_BOS 0x00000010
265 UCHAR Reserved2
[0x74];
267 UCHAR VendorSpec
[0x60];
268 } IDE_AHCI_REGISTERS
, *PIDE_AHCI_REGISTERS
;
270 #define IDX_AHCI_CAP (FIELD_OFFSET(IDE_AHCI_REGISTERS, CAP))
271 #define IDX_AHCI_GHC (FIELD_OFFSET(IDE_AHCI_REGISTERS, GHC))
272 #define IDX_AHCI_IS (FIELD_OFFSET(IDE_AHCI_REGISTERS, IS))
273 #define IDX_AHCI_VS (FIELD_OFFSET(IDE_AHCI_REGISTERS, VS))
274 #define IDX_AHCI_PI (FIELD_OFFSET(IDE_AHCI_REGISTERS, PI))
275 #define IDX_AHCI_CAP2 (FIELD_OFFSET(IDE_AHCI_REGISTERS, CAP2))
276 #define IDX_AHCI_BOHC (FIELD_OFFSET(IDE_AHCI_REGISTERS, BOHC))
279 typedef union _SATA_SSTATUS_REG
{
282 ULONG DET
:4; // Device Detection
284 #define SStatus_DET_NoDev 0x00
285 #define SStatus_DET_Dev_NoPhy 0x01
286 #define SStatus_DET_Dev_Ok 0x03
287 #define SStatus_DET_Offline 0x04
289 ULONG SPD
:4; // Current Interface Speed
291 #define SStatus_SPD_NoDev 0x00
292 #define SStatus_SPD_Gen1 0x01
293 #define SStatus_SPD_Gen2 0x02
294 #define SStatus_SPD_Gen3 0x03
296 ULONG IPM
:4; // Interface Power Management
298 #define SStatus_IPM_NoDev 0x00
299 #define SStatus_IPM_Active 0x01
300 #define SStatus_IPM_Partial 0x02
301 #define SStatus_IPM_Slumber 0x06
307 } SATA_SSTATUS_REG
, *PSATA_SSTATUS_REG
;
309 #define ATA_SS_DET_MASK 0x0000000f
310 #define ATA_SS_DET_NO_DEVICE 0x00000000
311 #define ATA_SS_DET_DEV_PRESENT 0x00000001
312 #define ATA_SS_DET_PHY_ONLINE 0x00000003
313 #define ATA_SS_DET_PHY_OFFLINE 0x00000004
315 #define ATA_SS_SPD_MASK 0x000000f0
316 #define ATA_SS_SPD_NO_SPEED 0x00000000
317 #define ATA_SS_SPD_GEN1 0x00000010
318 #define ATA_SS_SPD_GEN2 0x00000020
320 #define ATA_SS_IPM_MASK 0x00000f00
321 #define ATA_SS_IPM_NO_DEVICE 0x00000000
322 #define ATA_SS_IPM_ACTIVE 0x00000100
323 #define ATA_SS_IPM_PARTIAL 0x00000200
324 #define ATA_SS_IPM_SLUMBER 0x00000600
326 typedef union _SATA_SCONTROL_REG
{
329 ULONG DET
:4; // Device Detection Init
331 #define SControl_DET_DoNothing 0x00
332 #define SControl_DET_Idle 0x00
333 #define SControl_DET_Init 0x01
334 #define SControl_DET_Disable 0x04
336 ULONG SPD
:4; // Speed Allowed
338 #define SControl_SPD_NoRestrict 0x00
339 #define SControl_SPD_LimGen1 0x01
340 #define SControl_SPD_LimGen2 0x02
341 #define SControl_SPD_LimGen3 0x03
343 ULONG IPM
:4; // Interface Power Management Transitions Allowed
345 #define SControl_IPM_NoRestrict 0x00
346 #define SControl_IPM_NoPartial 0x01
347 #define SControl_IPM_NoSlumber 0x02
348 #define SControl_IPM_NoPartialSlumber 0x03
350 ULONG SPM
:4; // Select Power Management, unused by AHCI
351 ULONG PMP
:4; // Port Multiplier Port, unused by AHCI
356 } SATA_SCONTROL_REG
, *PSATA_SCONTROL_REG
;
358 #define ATA_SC_DET_MASK 0x0000000f
359 #define ATA_SC_DET_IDLE 0x00000000
360 #define ATA_SC_DET_RESET 0x00000001
361 #define ATA_SC_DET_DISABLE 0x00000004
363 #define ATA_SC_SPD_MASK 0x000000f0
364 #define ATA_SC_SPD_NO_SPEED 0x00000000
365 #define ATA_SC_SPD_SPEED_GEN1 0x00000010
366 #define ATA_SC_SPD_SPEED_GEN2 0x00000020
367 #define ATA_SC_SPD_SPEED_GEN3 0x00000040
369 #define ATA_SC_IPM_MASK 0x00000f00
370 #define ATA_SC_IPM_NONE 0x00000000
371 #define ATA_SC_IPM_DIS_PARTIAL 0x00000100
372 #define ATA_SC_IPM_DIS_SLUMBER 0x00000200
374 typedef union _SATA_SERROR_REG
{
378 UCHAR I
:1; // Recovered Data Integrity Error
379 UCHAR M
:1; // Recovered Communications Error
380 UCHAR Reserved_2_7
:6;
382 UCHAR T
:1; // Transient Data Integrity Error
383 UCHAR C
:1; // Persistent Communication or Data Integrity Error
384 UCHAR P
:1; // Protocol Error
385 UCHAR E
:1; // Internal Error
386 UCHAR Reserved_12_15
:4;
390 UCHAR N
:1; // PhyRdy Change, PIS.PRCS
391 UCHAR I
:1; // Phy Internal Error
392 UCHAR W
:1; // Comm Wake
393 UCHAR B
:1; // 10B to 8B Decode Error
394 UCHAR D
:1; // Disparity Error, not used by AHCI
395 UCHAR C
:1; // CRC Error
396 UCHAR H
:1; // Handshake Error
397 UCHAR S
:1; // Link Sequence Error
399 UCHAR T
:1; // Transport state transition error
400 UCHAR F
:1; // Unknown FIS Type
401 UCHAR X
:1; // Exchanged
402 UCHAR Reserved_27_31
:5;
407 } SATA_SERROR_REG
, *PSATA_SERROR_REG
;
409 #define ATA_SE_DATA_CORRECTED 0x00000001
410 #define ATA_SE_COMM_CORRECTED 0x00000002
411 #define ATA_SE_DATA_ERR 0x00000100
412 #define ATA_SE_COMM_ERR 0x00000200
413 #define ATA_SE_PROT_ERR 0x00000400
414 #define ATA_SE_HOST_ERR 0x00000800
415 #define ATA_SE_PHY_CHANGED 0x00010000
416 #define ATA_SE_PHY_IERROR 0x00020000
417 #define ATA_SE_COMM_WAKE 0x00040000
418 #define ATA_SE_DECODE_ERR 0x00080000
419 #define ATA_SE_PARITY_ERR 0x00100000
420 #define ATA_SE_CRC_ERR 0x00200000
421 #define ATA_SE_HANDSHAKE_ERR 0x00400000
422 #define ATA_SE_LINKSEQ_ERR 0x00800000
423 #define ATA_SE_TRANSPORT_ERR 0x01000000
424 #define ATA_SE_UNKNOWN_FIS 0x02000000
426 typedef struct _IDE_SATA_REGISTERS
{
428 SATA_SSTATUS_REG SStatus
;
432 SATA_SERROR_REG SError
;
436 SATA_SCONTROL_REG SControl
;
446 USHORT PMN
; // PM Notify, bitmask
451 } IDE_SATA_REGISTERS
, *PIDE_SATA_REGISTERS
;
453 #define IDX_SATA_IO (IDX_BM_IO+IDX_BM_IO_SZ)
454 //#define IDX_SATA_IO_SZ sizeof(IDE_SATA_REGISTERS)
455 #define IDX_SATA_IO_SZ 5
457 #define IDX_SATA_SStatus (0+IDX_SATA_IO)
458 #define IDX_SATA_SError (1+IDX_SATA_IO)
459 #define IDX_SATA_SControl (2+IDX_SATA_IO)
460 #define IDX_SATA_SActive (3+IDX_SATA_IO)
461 #define IDX_SATA_SNTF_PMN (4+IDX_SATA_IO)
463 #define IDX_INDEXED_IO (IDX_SATA_IO+IDX_SATA_IO_SZ)
464 #define IDX_INDEXED_IO_SZ 2
466 #define IDX_INDEXED_ADDR (0+IDX_INDEXED_IO)
467 #define IDX_INDEXED_DATA (1+IDX_INDEXED_IO)
469 #define IDX_MAX_REG (IDX_INDEXED_IO+IDX_INDEXED_IO_SZ)
472 typedef union _AHCI_IS_REG
{
474 ULONG DHRS
:1;// Device to Host Register FIS Interrupt
475 ULONG PSS
:1; // PIO Setup FIS Interrupt
476 ULONG DSS
:1; // DMA Setup FIS Interrupt
477 ULONG SDBS
:1;// Set Device Bits Interrupt
478 ULONG UFS
:1; // Unknown FIS Interrupt
479 ULONG DPS
:1; // Descriptor Processed
480 ULONG PCS
:1; // Port Connect Change Status
481 ULONG DMPS
:1;// Device Mechanical Presence Status
483 ULONG Reserved_8_21
:14;
484 ULONG PRCS
:1;// PhyRdy Change Status
485 ULONG IPMS
:1;// Incorrect Port Multiplier Status
487 ULONG OFS
:1; // Overflow Status
489 ULONG INFS
:1;// Interface Non-fatal Error Status
490 ULONG IFS
:1; // Interface Fatal Error Status
491 ULONG HBDS
:1;// Host Bus Data Error Status
492 ULONG HBFS
:1;// Host Bus Fatal Error Status
493 ULONG TFES
:1;// Task File Error Status
494 ULONG CPDS
:1;// Cold Port Detect Status
497 } AHCI_IS_REG
, *PAHCI_IS_REG
;
499 #define ATA_AHCI_P_IX_DHR 0x00000001
500 #define ATA_AHCI_P_IX_PS 0x00000002
501 #define ATA_AHCI_P_IX_DS 0x00000004
502 #define ATA_AHCI_P_IX_SDB 0x00000008
503 #define ATA_AHCI_P_IX_UF 0x00000010
504 #define ATA_AHCI_P_IX_DP 0x00000020
505 #define ATA_AHCI_P_IX_PC 0x00000040
506 #define ATA_AHCI_P_IX_DI 0x00000080
508 #define ATA_AHCI_P_IX_PRC 0x00400000
509 #define ATA_AHCI_P_IX_IPM 0x00800000
510 #define ATA_AHCI_P_IX_OF 0x01000000
511 #define ATA_AHCI_P_IX_INF 0x04000000
512 #define ATA_AHCI_P_IX_IF 0x08000000
513 #define ATA_AHCI_P_IX_HBD 0x10000000
514 #define ATA_AHCI_P_IX_HBF 0x20000000
515 #define ATA_AHCI_P_IX_TFE 0x40000000
516 #define ATA_AHCI_P_IX_CPD 0x80000000
518 #define AHCI_CLB_ALIGNEMENT_MASK ((ULONGLONG)(1024-1))
519 #define AHCI_FIS_ALIGNEMENT_MASK ((ULONGLONG)(256-1))
520 #define AHCI_CMD_ALIGNEMENT_MASK ((ULONGLONG)(128-1))
522 typedef struct _IDE_AHCI_PORT_REGISTERS
{
525 ULONG CLB
; // command list base address, 1K-aligned
526 ULONG CLBU
; // command list base address (upper 32bits)
529 }; // 0x100 + 0x80*c + 0x0000
533 ULONG FB
; // FIS base address
534 ULONG FBU
; // FIS base address (upper 32bits)
537 }; // 0x100 + 0x80*c + 0x0008
540 ULONG IS_Reg
; // interrupt status
542 }; // 0x100 + 0x80*c + 0x0010
545 ULONG Reg
; // interrupt enable
547 ULONG DHRE
:1;// Device to Host Register FIS Interrupt Enable
548 ULONG PSE
:1; // PIO Setup FIS Interrupt Enable
549 ULONG DSE
:1; // DMA Setup FIS Interrupt Enable
550 ULONG SDBE
:1;// Set Device Bits FIS Interrupt Enable
551 ULONG UFE
:1; // Unknown FIS Interrupt Enable
552 ULONG DPE
:1; // Descriptor Processed Interrupt Enable
553 ULONG PCE
:1; // Port Change Interrupt Enable
554 ULONG DPME
:1;// Device Mechanical Presence Enable
556 ULONG Reserved_8_21
:14;
557 ULONG PRCE
:1;// PhyRdy Change Interrupt Enable
558 ULONG IPME
:1;// Incorrect Port Multiplier Enable
559 ULONG OFE
:1; // Overflow Enable
561 ULONG INFE
:1;// Interface Non-fatal Error Enable
562 ULONG IFE
:1; // Interface Fatal Error Enable
563 ULONG HBDE
:1;// Host Bus Data Error Enable
564 ULONG HBFE
:1;// Host Bus Fatal Error Enable
565 ULONG TFEE
:1;// Task File Error Enable
566 ULONG CPDE
:1;// Cold Port Detect Enable
568 } IE
; // 0x100 + 0x80*c + 0x0014
571 ULONG Reg
; // command register
575 ULONG SUD
:1; // Spin-Up Device
576 ULONG POD
:1; // Power On Device
577 ULONG CLO
:1; // Command List Override
578 ULONG FRE
:1; // FIS Receive Enable
579 ULONG Reserved_5_7
:3;
581 ULONG CCS
:5; // Current Command Slot
582 ULONG MPSS
:1;// Mechanical Presence Switch State
583 ULONG FR
:1; // FIS Receive Running
584 ULONG CR
:1; // Command List Running
586 ULONG CPS
:1; // Cold Presence State
587 ULONG PMA
:1; // Port Multiplier Attached
588 ULONG HPCP
:1;// Hot Plug Capable Port
589 ULONG MPSP
:1;// Mechanical Presence Switch Attached to Port
590 ULONG CPD
:1; // Cold Presence Detection
591 ULONG ESP
:1; // External SATA Port
592 ULONG Reserved_22_23
:2;
594 ULONG ATAPI
:1; // Device is ATAPI
595 ULONG DLAE
:1;// Drive LED on ATAPI Enable
596 ULONG ALPE
:1;// Aggressive Link Power Management Enable
597 ULONG ASP
:1; // Aggressive Slumber / Partial
598 ULONG ICC
:4; // Interface Communication Control
600 #define SATA_CMD_ICC_Idle 0x00
601 #define SATA_CMD_ICC_NoOp 0x00
602 #define SATA_CMD_ICC_Active 0x01
603 #define SATA_CMD_ICC_Partial 0x02
604 #define SATA_CMD_ICC_Slumber 0x06
606 } CMD
; // 0x100 + 0x80*c + 0x0018
611 ULONG Reg
; // Task File Data
615 UCHAR cs1
:2;// command-specific
617 UCHAR cs2
:3;// command-specific
620 UCHAR ERR
; // Contains the latest copy of the task file error register.
623 } TFD
; // 0x100 + 0x80*c + 0x0020
626 ULONG Reg
; // signature
629 UCHAR LbaLow
; // IDX_IO1_i_BlockNumber
630 UCHAR LbaMid
; // IDX_IO1_i_CylinderLow
631 UCHAR LbaHigh
; // IDX_IO1_i_CylinderHigh
633 } SIG
; // 0x100 + 0x80*c + 0x0024
635 ULONG SStatus
; // SCR0
636 SATA_SSTATUS_REG SSTS
;
637 }; // 0x100 + 0x80*c + 0x0028
639 ULONG SControl
; // SCR2
640 SATA_SCONTROL_REG SCTL
;
641 }; // 0x100 + 0x80*c + 0x002c
643 ULONG SError
; // SCR1
644 SATA_SERROR_REG SERR
;
645 }; // 0x100 + 0x80*c + 0x0030
648 ULONG SActive
; // bitmask
649 }; // 0x100 + 0x80*c + 0x0034
651 ULONG CI
; // Command issue, bitmask, 0x100 + 0x80*c + 0x0038
657 USHORT PMN
; // PM Notify, bitmask
660 } SNTF
; // 0x100 + 0x80*c + 0x003c
666 ULONG EN
:1; // Enable
667 ULONG DEC
:1; // Device Error Clear
668 ULONG SDE
:1; // Single Device Error
669 ULONG Reserved_3_7
:5; // Reserved
670 ULONG DEV
:4; // Device To Issue
671 ULONG ADO
:4; // Active Device Optimization (recommended parallelism)
672 ULONG DWE
:4; // Device With Error
673 ULONG Reserved_20_31
:12; // Reserved
675 } FBS
; // 0x100 + 0x80*c + 0x0040
677 ULONG Reserved_44_7f
[11];
678 UCHAR VendorSpec
[16];
680 } IDE_AHCI_PORT_REGISTERS
, *PIDE_AHCI_PORT_REGISTERS
;
682 #define IDX_AHCI_P_CLB (FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, CLB))
683 #define IDX_AHCI_P_FB (FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, FB))
684 #define IDX_AHCI_P_IS (FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, IS))
685 #define IDX_AHCI_P_IE (FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, IE))
686 #define IDX_AHCI_P_CI (FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, CI))
687 #define IDX_AHCI_P_TFD (FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, TFD))
688 #define IDX_AHCI_P_SIG (FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, SIG))
689 #define IDX_AHCI_P_CMD (FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, CMD))
690 #define IDX_AHCI_P_SStatus (FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, SStatus))
691 #define IDX_AHCI_P_SControl (FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, SControl))
692 #define IDX_AHCI_P_SError (FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, SError))
693 #define IDX_AHCI_P_ACT (FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, SACT))
695 #define IDX_AHCI_P_SNTF (FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, SNTF))
697 // AHCI commands ( -> IDX_AHCI_P_CMD)
698 #define ATA_AHCI_P_CMD_ST 0x00000001
699 #define ATA_AHCI_P_CMD_SUD 0x00000002
700 #define ATA_AHCI_P_CMD_POD 0x00000004
701 #define ATA_AHCI_P_CMD_CLO 0x00000008
702 #define ATA_AHCI_P_CMD_FRE 0x00000010
703 #define ATA_AHCI_P_CMD_CCS_MASK 0x00001f00
704 #define ATA_AHCI_P_CMD_ISS 0x00002000
705 #define ATA_AHCI_P_CMD_FR 0x00004000
706 #define ATA_AHCI_P_CMD_CR 0x00008000
707 #define ATA_AHCI_P_CMD_CPS 0x00010000
708 #define ATA_AHCI_P_CMD_PMA 0x00020000
709 #define ATA_AHCI_P_CMD_HPCP 0x00040000
710 #define ATA_AHCI_P_CMD_ISP 0x00080000
711 #define ATA_AHCI_P_CMD_CPD 0x00100000
712 #define ATA_AHCI_P_CMD_ATAPI 0x01000000
713 #define ATA_AHCI_P_CMD_DLAE 0x02000000
714 #define ATA_AHCI_P_CMD_ALPE 0x04000000
715 #define ATA_AHCI_P_CMD_ASP 0x08000000
716 #define ATA_AHCI_P_CMD_ICC_MASK 0xf0000000
717 #define ATA_AHCI_P_CMD_NOOP 0x00000000
718 #define ATA_AHCI_P_CMD_ACTIVE 0x10000000
719 #define ATA_AHCI_P_CMD_PARTIAL 0x20000000
720 #define ATA_AHCI_P_CMD_SLUMBER 0x60000000
723 typedef struct _IDE_AHCI_PRD_ENTRY
{
746 } IDE_AHCI_PRD_ENTRY
, *PIDE_AHCI_PRD_ENTRY
;
748 #define ATA_AHCI_DMA_ENTRIES (PAGE_SIZE/2/sizeof(IDE_AHCI_PRD_ENTRY)) /* 128 */
749 #define ATA_AHCI_MAX_TAGS 32
751 #define AHCI_FIS_TYPE_ATA_H2D 0x27
752 #define AHCI_FIS_TYPE_ATA_D2H 0x34
753 #define AHCI_FIS_TYPE_DMA_D2H 0x39
754 #define AHCI_FIS_TYPE_DMA_BiDi 0x41
755 #define AHCI_FIS_TYPE_DATA_BiDi 0x46
756 #define AHCI_FIS_TYPE_BIST_BiDi 0x58
757 #define AHCI_FIS_TYPE_PIO_D2H 0x5f
758 #define AHCI_FIS_TYPE_DEV_BITS_D2H 0xA1
760 typedef struct _AHCI_ATA_H2D_FIS
{
761 UCHAR FIS_Type
; // = 0x27
763 UCHAR Cmd
:1; // update Command register
764 UCHAR Command
; // [2]
765 UCHAR Feature
; // [3]
767 UCHAR BlockNumber
; // [4]
768 UCHAR CylinderLow
; // [5]
769 UCHAR CylinderHigh
; // [6]
770 UCHAR DriveSelect
; // [7]
772 UCHAR BlockNumberExp
; // [8]
773 UCHAR CylinderLowExp
; // [9]
774 UCHAR CylinderHighExp
; // [10]
775 UCHAR FeatureExp
; // [11]
777 UCHAR BlockCount
; // [12]
778 UCHAR BlockCountExp
; // [13]
779 UCHAR Reserved14
; // [14]
780 UCHAR Control
; // [15]
782 } AHCI_ATA_H2D_FIS
, *PAHCI_ATA_H2D_FIS
;
784 #define IDX_AHCI_o_Command (FIELD_OFFSET(AHCI_ATA_H2D_FIS, Command))
785 #define IDX_AHCI_o_Feature (FIELD_OFFSET(AHCI_ATA_H2D_FIS, Feature))
786 #define IDX_AHCI_o_BlockNumber (FIELD_OFFSET(AHCI_ATA_H2D_FIS, BlockNumber ))
787 #define IDX_AHCI_o_CylinderLow (FIELD_OFFSET(AHCI_ATA_H2D_FIS, CylinderLow ))
788 #define IDX_AHCI_o_CylinderHigh (FIELD_OFFSET(AHCI_ATA_H2D_FIS, CylinderHigh))
789 #define IDX_AHCI_o_DriveSelect (FIELD_OFFSET(AHCI_ATA_H2D_FIS, DriveSelect ))
790 #define IDX_AHCI_o_BlockCount (FIELD_OFFSET(AHCI_ATA_H2D_FIS, BlockCount))
791 #define IDX_AHCI_o_Control (FIELD_OFFSET(AHCI_ATA_H2D_FIS, Control))
792 #define IDX_AHCI_o_FeatureExp (FIELD_OFFSET(AHCI_ATA_H2D_FIS, FeatureExp))
793 #define IDX_AHCI_o_BlockNumberExp (FIELD_OFFSET(AHCI_ATA_H2D_FIS, BlockNumberExp ))
794 #define IDX_AHCI_o_CylinderLowExp (FIELD_OFFSET(AHCI_ATA_H2D_FIS, CylinderLowExp ))
795 #define IDX_AHCI_o_CylinderHighExp (FIELD_OFFSET(AHCI_ATA_H2D_FIS, CylinderHighExp))
796 #define IDX_AHCI_o_BlockCountExp (FIELD_OFFSET(AHCI_ATA_H2D_FIS, BlockCountExp))
798 #define AHCI_FIS_COMM_PM (0x80 | AHCI_DEV_SEL_PM)
800 #define AHCI_DEV_SEL_1 0x00
801 #define AHCI_DEV_SEL_2 0x01
802 #define AHCI_DEV_SEL_PM 0x0f
804 /* 128-byte aligned */
805 typedef struct _IDE_AHCI_CMD
{
809 IDE_AHCI_PRD_ENTRY prd_tab
[ATA_AHCI_DMA_ENTRIES
]; // also 128-byte aligned
810 } IDE_AHCI_CMD
, *PIDE_AHCI_CMD
;
814 #define ATA_AHCI_CMD_ATAPI 0x0020
815 #define ATA_AHCI_CMD_WRITE 0x0040
816 #define ATA_AHCI_CMD_PREFETCH 0x0080
817 #define ATA_AHCI_CMD_RESET 0x0100
818 #define ATA_AHCI_CMD_BIST 0x0200
819 #define ATA_AHCI_CMD_CLR_BUSY 0x0400
821 /* 128-byte aligned */
822 typedef struct _IDE_AHCI_CMD_LIST
{
824 USHORT prd_length
; /* PRD entries */
826 ULONGLONG cmd_table_phys
; /* points to IDE_AHCI_CMD */
828 } IDE_AHCI_CMD_LIST
, *PIDE_AHCI_CMD_LIST
;
830 /* 256-byte aligned */
831 typedef struct _IDE_AHCI_RCV_FIS
{
841 } IDE_AHCI_RCV_FIS
, *PIDE_AHCI_RCV_FIS
;
843 /* 1K-byte aligned */
844 typedef struct _IDE_AHCI_CHANNEL_CTL_BLOCK
{
845 IDE_AHCI_CMD_LIST cmd_list
[ATA_AHCI_MAX_TAGS
]; // 1K-size (32*32)
846 IDE_AHCI_RCV_FIS rcv_fis
;
847 IDE_AHCI_CMD cmd
; // for single internal commands w/o associated AtaReq
848 } IDE_AHCI_CHANNEL_CTL_BLOCK
, *PIDE_AHCI_CHANNEL_CTL_BLOCK
;
852 #define IsBusMaster(pciData) \
853 ( ((pciData)->Command & (PCI_ENABLE_BUS_MASTER/* | PCI_ENABLE_IO_SPACE*/)) == \
854 (PCI_ENABLE_BUS_MASTER/* | PCI_ENABLE_IO_SPACE*/))
856 #define PCI_IDE_PROGIF_NATIVE_1 0x01
857 #define PCI_IDE_PROGIF_NATIVE_2 0x04
858 #define PCI_IDE_PROGIF_NATIVE_ALL 0x05
860 #define IsMasterDev(pciData) \
861 ( ((pciData)->ProgIf & 0x80) && \
862 ((pciData)->ProgIf & PCI_IDE_PROGIF_NATIVE_ALL) != PCI_IDE_PROGIF_NATIVE_ALL )
864 //#define INT_Q_SIZE 32
865 #define MIN_REQ_TTL 4
869 typedef union _ATA_REQ
{
870 // ULONG reqId; // serial
876 union _ATA_REQ
* next_req
;
877 union _ATA_REQ
* prev_req
;
879 PSCSI_REQUEST_BLOCK Srb
; // Current request on controller.
881 PUSHORT DataBuffer
; // Data buffer pointer.
882 ULONG WordsLeft
; // Data words left.
883 ULONG TransferLength
; // Originally requested transfer length
885 ULONG WordsTransfered
;// Data words already transfered.
894 PSCSI_REQUEST_BLOCK OriginalSrb
; // Mechanism Status Srb Data
905 ULONGLONG ahci_base64
;
907 PIDE_AHCI_CMD ahci_cmd_ptr
;
911 USHORT io_cmd_flags
; // out
916 //UCHAR padding_128b[128]; // Note: we assume, NT allocates block > 4k as PAGE-aligned
920 BM_DMA_ENTRY dma_tab
[ATA_DMA_ENTRIES
];
921 IDE_AHCI_CMD ahci_cmd0
; // for AHCI, 128-byte aligned
926 UCHAR padding_4kb
[PAGE_SIZE
];
928 } ATA_REQ
, *PATA_REQ
;
930 #define REQ_FLAG_FORCE_DOWNRATE 0x01
931 #define REQ_FLAG_DMA_OPERATION 0x02
932 #define REQ_FLAG_REORDERABLE_CMD 0x04
933 #define REQ_FLAG_RW_MASK 0x08
934 #define REQ_FLAG_READ 0x08
935 #define REQ_FLAG_WRITE 0x00
936 #define REQ_FLAG_FORCE_DOWNRATE_LBA48 0x10
937 #define REQ_FLAG_DMA_DBUF 0x20
938 #define REQ_FLAG_DMA_DBUF_PRD 0x40
939 #define REQ_FLAG_LBA48 0x80
942 #define REQ_STATE_NONE 0x00
943 #define REQ_STATE_QUEUED 0x10
945 #define REQ_STATE_PREPARE_TO_TRANSFER 0x20
946 #define REQ_STATE_PREPARE_TO_NEXT 0x21
947 #define REQ_STATE_READY_TO_TRANSFER 0x30
949 #define REQ_STATE_EXPECTING_INTR 0x40
950 #define REQ_STATE_ATAPI_EXPECTING_CMD_INTR 0x41
951 #define REQ_STATE_ATAPI_EXPECTING_DATA_INTR 0x42
952 #define REQ_STATE_ATAPI_EXPECTING_DATA_INTR2 0x43
953 #define REQ_STATE_ATAPI_DO_NOTHING_INTR 0x44
955 #define REQ_STATE_EARLY_INTR 0x48
957 #define REQ_STATE_PROCESSING_INTR 0x50
959 #define REQ_STATE_DPC_INTR_REQ 0x51
960 #define REQ_STATE_DPC_RESET_REQ 0x52
961 #define REQ_STATE_DPC_COMPLETE_REQ 0x53
963 #define REQ_STATE_DPC_WAIT_BUSY0 0x57
964 #define REQ_STATE_DPC_WAIT_BUSY1 0x58
965 #define REQ_STATE_DPC_WAIT_BUSY 0x59
966 #define REQ_STATE_DPC_WAIT_DRQ 0x5a
967 #define REQ_STATE_DPC_WAIT_DRQ0 0x5b
968 #define REQ_STATE_DPC_WAIT_DRQ_ERR 0x5c
970 #define REQ_STATE_TRANSFER_COMPLETE 0x7f
973 #define CMD_ACTION_PREPARE 0x01
974 #define CMD_ACTION_EXEC 0x02
975 #define CMD_ACTION_ALL (CMD_ACTION_PREPARE | CMD_ACTION_EXEC)
977 // predefined Reorder costs
978 #define REORDER_COST_MAX ((DEF_I64(0x1) << 60) - 1)
979 #define REORDER_COST_TTL (REORDER_COST_MAX - 1)
980 #define REORDER_COST_INTERSECT (REORDER_COST_MAX - 2)
981 #define REORDER_COST_DENIED (REORDER_COST_MAX - 3)
982 #define REORDER_COST_RESELECT (REORDER_COST_MAX/4)
984 #define REORDER_COST_SWITCH_RW_CD (REORDER_COST_MAX/8)
985 #define REORDER_MCOST_SWITCH_RW_CD (0)
986 #define REORDER_MCOST_SEEK_BACK_CD (16)
988 #define REORDER_COST_SWITCH_RW_HDD (0)
989 #define REORDER_MCOST_SWITCH_RW_HDD (4)
990 #define REORDER_MCOST_SEEK_BACK_HDD (2)
992 /*typedef struct _ATA_QUEUE {
993 struct _ATA_REQ* head_req; // index
994 struct _ATA_REQ* tail_req; // index
997 BM_DMA_ENTRY dma_tab[ATA_DMA_ENTRIES];
998 } ATA_QUEUE, *PATA_QUEUE;*/
1000 struct _HW_DEVICE_EXTENSION
;
1001 struct _HW_LU_EXTENSION
;
1003 typedef struct _IORES
{
1005 ULONG Addr
; /* Base address*/
1006 PVOID pAddr
; /* Base address in pointer form */
1008 ULONG MemIo
:1; /* Memory mapping (1) vs IO ports (0) */
1009 ULONG Proc
:1; /* Need special processing via IO_Proc */
1013 // Channel extension
1014 typedef struct _HW_CHANNEL
{
1018 ULONG last_cdev
; /* device for which we have configured timings last time */
1019 ULONG last_devsel
; /* device selected during last call to SelectDrive() */
1020 /* PATA_REQ first_req;
1021 PATA_REQ last_req;*/
1023 ULONG ChannelSelectWaitCount
;
1027 BOOLEAN ExpectingInterrupt
; // Indicates expecting an interrupt
1028 BOOLEAN RDP
; // Indicate last tape command was DSC Restrictive.
1029 // Indicates whether '0x1f0' is the base address. Used
1030 // in SMART Ioctl calls.
1031 BOOLEAN PrimaryAddress
;
1032 // Placeholder for the sub-command value of the last
1037 // Placeholder for status register after a GET_MEDIA_STATUS command
1038 UCHAR ReturningMediaStatus
;
1040 BOOLEAN CopyDmaBuffer
;
1047 MECHANICAL_STATUS_INFORMATION_HEADER MechStatusData
;
1048 SENSE_DATA MechStatusSense
;
1049 ULONG MechStatusRetryCount
;
1050 SCSI_REQUEST_BLOCK InternalSrb
;
1052 ULONG MaxTransferMode
; // may differ from Controller's value due to 40-pin cable
1054 ULONG ChannelCtrlFlags
;
1055 ULONG ResetInProgress
; // flag
1061 #define CHECK_INTR_ACTIVE 0x03
1062 #define CHECK_INTR_DETECTED 0x02
1063 #define CHECK_INTR_CHECK 0x01
1064 #define CHECK_INTR_IDLE 0x00
1067 PHW_TIMER HwScsiTimer
;
1070 PHW_TIMER HwScsiTimer1
;
1071 PHW_TIMER HwScsiTimer2
;
1073 // PHW_TIMER CurDpc;
1074 // LARGE_INTEGER ActivationTime;
1078 // PHW_TIMER HwScsiTimer;
1079 // KSPIN_LOCK QueueSpinLock;
1080 // KIRQL QueueOldIrql;
1082 struct _HW_DEVICE_EXTENSION
* DeviceExtension
;
1083 struct _HW_LU_EXTENSION
* lun
[IDE_MAX_LUN_PER_CHAN
];
1088 // Double-buffering support
1090 ULONG DB_PRD_PhAddr
;
1097 PIDE_AHCI_CHANNEL_CTL_BLOCK AhciCtlBlock0
; // unaligned
1098 PIDE_AHCI_CHANNEL_CTL_BLOCK AhciCtlBlock
; // 128-byte aligned
1099 ULONGLONG AHCI_CTL_PhAddr
;
1100 IORES BaseIoAHCI_Port
;
1102 ULONG AhciCompleteCI
;
1104 ULONG AhciLastSError
;
1105 //PVOID AHCI_FIS; // is not actually used by UniATA now, but is required by AHCI controller
1106 //ULONGLONG AHCI_FIS_PhAddr;
1107 // Note: in contrast to FBSD, we keep PRD and CMD item in AtaReq structure
1108 PATA_REQ AhciInternalAtaReq
;
1109 PSCSI_REQUEST_BLOCK AhciInternalSrb
;
1111 #ifdef QUEUE_STATISTICS
1112 LONGLONG QueueStat
[MAX_QUEUE_STAT
];
1113 LONGLONG ReorderCount
;
1114 LONGLONG IntersectCount
;
1115 LONGLONG TryReorderCount
;
1116 LONGLONG TryReorderHeadCount
;
1117 LONGLONG TryReorderTailCount
; /* in-order requests */
1118 #endif //QUEUE_STATISTICS
1120 //ULONG BaseMemAddress;
1121 //ULONG BaseMemAddressOffset;
1122 IORES RegTranslation
[IDX_MAX_REG
];
1124 } HW_CHANNEL
, *PHW_CHANNEL
;
1126 #define CTRFLAGS_DMA_ACTIVE 0x0001
1127 #define CTRFLAGS_DMA_RO 0x0002
1128 #define CTRFLAGS_DMA_OPERATION 0x0004
1129 #define CTRFLAGS_INTR_DISABLED 0x0008
1130 #define CTRFLAGS_DPC_REQ 0x0010
1131 #define CTRFLAGS_ENABLE_INTR_REQ 0x0020
1132 #define CTRFLAGS_LBA48 0x0040
1133 #define CTRFLAGS_DSC_BSY 0x0080
1134 #define CTRFLAGS_NO_SLAVE 0x0100
1135 //#define CTRFLAGS_DMA_BEFORE_R 0x0200
1136 //#define CTRFLAGS_PATA 0x0200
1137 //#define CTRFLAGS_NOT_PRESENT 0x0200
1138 #define CTRFLAGS_AHCI_PM 0x0400
1139 #define CTRFLAGS_AHCI_PM2 0x0800
1141 #define CTRFLAGS_PERMANENT (CTRFLAGS_DMA_RO | CTRFLAGS_NO_SLAVE)
1143 #define GEOM_AUTO 0xffffffff
1144 #define GEOM_STD 0x0000
1145 #define GEOM_UNIATA 0x0001
1146 #define GEOM_ORIG 0x0002
1147 #define GEOM_MANUAL 0x0003
1149 #define DPC_STATE_NONE 0x00
1150 #define DPC_STATE_ISR 0x10
1151 #define DPC_STATE_DPC 0x20
1152 #define DPC_STATE_TIMER 0x30
1153 #define DPC_STATE_COMPLETE 0x40
1155 // Logical unit extension
1156 typedef struct _HW_LU_EXTENSION
{
1157 IDENTIFY_DATA2 IdentifyData
;
1158 ULONGLONG NumOfSectors
;
1159 ULONG DeviceFlags
; // Flags word for each possible device. DFLAGS_XXX
1160 ULONG DiscsPresent
; // Indicates number of platters on changer-ish devices.
1161 BOOLEAN DWordIO
; // Indicates use of 32-bit PIO
1162 UCHAR ReturningMediaStatus
;
1163 UCHAR MaximumBlockXfer
;
1166 UCHAR TransferMode
; // current transfer mode
1167 UCHAR LimitedTransferMode
; // user-defined or IDE cable limitation
1168 UCHAR OrigTransferMode
; // transfer mode, returned by device IDENTIFY (can be changed via IOCTL)
1169 UCHAR PhyTransferMode
; // phy transfer mode (actual bus transfer mode for PATA DMA and SATA)
1171 ULONG ErrorCount
; // Count of errors. Used to turn off features.
1172 // ATA_QUEUE cmd_queue;
1173 LONGLONG ReadCmdCost
;
1174 LONGLONG WriteCmdCost
;
1175 LONGLONG OtherCmdCost
;
1176 LONGLONG RwSwitchCost
;
1177 LONGLONG RwSwitchMCost
;
1178 LONGLONG SeekBackMCost
;
1185 ULONG LunSelectWaitCount
;
1186 ULONG AtapiReadyWaitDelay
;
1190 ULONG opt_MaxTransferMode
;
1191 ULONG opt_PreferedTransferMode
;
1192 BOOLEAN opt_ReadCacheEnable
;
1193 BOOLEAN opt_WriteCacheEnable
;
1195 UCHAR opt_AdvPowerMode
;
1196 UCHAR opt_AcousticMode
;
1197 UCHAR opt_StandbyTimer
;
1198 UCHAR opt_Padding
[2]; // padding
1200 struct _SBadBlockListItem
* bbListDescr
;
1201 struct _SBadBlockRange
* arrBadBlocks
;
1204 // Controller-specific LUN options
1206 /* for tricky controllers, those can change Logical-to-Physical LUN mapping.
1207 mainly for mapping SATA ports to compatible PATA registers
1208 Treated as PHYSICAL port number, regardless of logical mapping.
1213 struct _HW_DEVICE_EXTENSION
* DeviceExtension
;
1214 struct _HW_CHANNEL
* chan
;
1217 ULONGLONG errLastLba
;
1220 UCHAR errPadding
[3];
1222 #ifdef IO_STATISTICS
1224 LONGLONG ModeErrorCount
[MAX_RETRIES
];
1225 LONGLONG RecoverCount
[MAX_RETRIES
];
1227 LONGLONG BlockIoCount
;
1229 #endif//IO_STATISTICS
1230 } HW_LU_EXTENSION
, *PHW_LU_EXTENSION
;
1233 typedef struct _HW_DEVICE_EXTENSION
{
1235 //PIDE_REGISTERS_1 BaseIoAddress1[IDE_MAX_CHAN]; // Base register locations
1236 //PIDE_REGISTERS_2 BaseIoAddress2[IDE_MAX_CHAN];
1237 ULONG BusInterruptLevel
; // Interrupt level
1238 ULONG InterruptMode
; // Interrupt Mode (Level or Edge)
1239 ULONG BusInterruptVector
;
1240 // Number of channels being supported by one instantiation
1241 // of the device extension. Normally (and correctly) one, but
1242 // with so many broken PCI IDE controllers being sold, we have
1244 ULONG NumberChannels
;
1246 ULONG FirstChannelToCheck
;
1248 HW_LU_EXTENSION lun
[IDE_MAX_LUN
];
1249 HW_CHANNEL chan
[AHCI_MAX_PORT
/*IDE_MAX_CHAN*/];
1251 PHW_LU_EXTENSION lun
; // lun array
1252 PHW_CHANNEL chan
; // channel array
1254 UCHAR LastInterruptedChannel
;
1255 // Indicates the number of blocks transferred per int. according to the
1257 BOOLEAN DriverMustPoll
; // Driver is being used by the crash dump utility or ntldr.
1259 BOOLEAN UseDpc
; // Indicates use of DPC on long waits
1260 IDENTIFY_DATA FullIdentifyData
; // Identify data for device
1261 // BusMaster specific data
1262 // PBM_DMA_ENTRY dma_tab_0;
1263 //KSPIN_LOCK DpcSpinLock;
1265 ULONG ActiveDpcChan
;
1267 ULONG ExpectingInterrupt
; // Indicates entire controller expecting an interrupt
1269 PHW_TIMER HwScsiTimer1;
1270 PHW_TIMER HwScsiTimer2;
1276 PDEVICE_OBJECT Isr2DevObj
;
1278 //PIDE_BUSMASTER_REGISTERS BaseIoAddressBM_0;
1279 IORES BaseIoAddressBM_0
;
1280 //PIDE_BUSMASTER_REGISTERS BaseIoAddressBM[IDE_MAX_CHAN];
1282 // Device identification
1286 ULONG SystemIoBusNumber
;
1289 ULONG InitMethod
; // vendor specific
1294 BOOLEAN simplexOnly
;
1300 BOOLEAN DWordIO
; // Indicates use of 32-bit PIO
1301 /* // Indicates, that HW Initialized is already called for this controller
1302 // 0 bit for Primary, 1 - for Secondary. Is used to manage AltInit under w2k+
1303 UCHAR Initialized; */
1308 ULONG MaxTransferMode
; // max transfer mode supported by controller
1310 INTERFACE_TYPE OrigAdapterInterfaceType
;
1311 INTERFACE_TYPE AdapterInterfaceType
;
1312 ULONG MaximumDmaTransferLength
;
1313 ULONG AlignmentMask
;
1314 ULONG DmaSegmentLength
;
1315 ULONG DmaSegmentAlignmentMask
; // must be PAGE-aligned
1317 //ULONG BaseMemAddress;
1319 //PIDE_SATA_REGISTERS BaseIoAddressSATA_0;
1320 IORES BaseIoAddressSATA_0
;
1321 //PIDE_SATA_REGISTERS BaseIoAddressSATA[IDE_MAX_CHAN];
1324 //PIDE_AHCI_PORT_REGISTERS BaseIoAHCIPort[AHCI_MAX_PORT];
1327 ULONG AHCI_PI_mask
; // for port exclusion, usually = AHCI_PI
1328 PATA_REQ AhciInternalAtaReq0
;
1329 PSCSI_REQUEST_BLOCK AhciInternalSrb0
;
1331 BOOLEAN opt_AtapiDmaZeroTransfer
; // default FALSE
1332 BOOLEAN opt_AtapiDmaControlCmd
; // default FALSE
1333 BOOLEAN opt_AtapiDmaRawRead
; // default TRUE
1334 BOOLEAN opt_AtapiDmaReadWrite
; // default TRUE
1338 // Controller specific state/options
1343 } HW_DEVICE_EXTENSION
, *PHW_DEVICE_EXTENSION
;
1345 typedef struct _ISR2_DEVICE_EXTENSION
{
1346 PHW_DEVICE_EXTENSION HwDeviceExtension
;
1348 } ISR2_DEVICE_EXTENSION
, *PISR2_DEVICE_EXTENSION
;
1350 typedef ISR2_DEVICE_EXTENSION PCIIDE_DEVICE_EXTENSION
;
1351 typedef PISR2_DEVICE_EXTENSION PPCIIDE_DEVICE_EXTENSION
;
1353 #define HBAFLAGS_DMA_DISABLED 0x01
1354 #define HBAFLAGS_DMA_DISABLED_LBA48 0x02
1356 extern UCHAR pciBuffer
[256];
1357 extern PBUSMASTER_CONTROLLER_INFORMATION BMList
;
1358 extern ULONG BMListLen
;
1359 extern ULONG IsaCount
;
1360 extern ULONG MCACount
;
1361 extern UNICODE_STRING SavedRegPath
;
1363 //extern const CHAR retry_Wdma[MAX_RETRIES+1];
1364 //extern const CHAR retry_Udma[MAX_RETRIES+1];
1368 UniataEnumBusMasterController(
1369 IN PVOID DriverObject
,
1374 UniataFindCompatBusMasterController1(
1375 IN PVOID HwDeviceExtension
,
1377 IN PVOID BusInformation
,
1378 IN PCHAR ArgumentString
,
1379 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
1384 UniataFindCompatBusMasterController2(
1385 IN PVOID HwDeviceExtension
,
1387 IN PVOID BusInformation
,
1388 IN PCHAR ArgumentString
,
1389 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
1393 #define UNIATA_ALLOCATE_NEW_LUNS 0x00
1395 extern BOOLEAN NTAPI
1396 UniataAllocateLunExt(
1397 PHW_DEVICE_EXTENSION deviceExtension
,
1398 ULONG NewNumberChannels
1403 PHW_DEVICE_EXTENSION deviceExtension
1407 UniataFindBusMasterController(
1408 IN PVOID HwDeviceExtension
,
1410 IN PVOID BusInformation
,
1411 IN PCHAR ArgumentString
,
1412 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
1418 UniataClaimLegacyPCIIDE(
1425 IN PVOID HwDeviceExtension
1430 UniataDisconnectIntr2(
1431 IN PVOID HwDeviceExtension
1436 ScsiPortGetBusDataByOffset(
1437 IN PVOID HwDeviceExtension
,
1438 IN BUS_DATA_TYPE BusDataType
,
1440 IN ULONG SlotNumber
,
1446 #define PCIBUSNUM_NOT_SPECIFIED (0xffffffffL)
1447 #define PCISLOTNUM_NOT_SPECIFIED (0xffffffffL)
1452 PBUSMASTER_CONTROLLER_INFORMATION_BASE BusMasterAdapters
,
1454 IN PVOID HwDeviceExtension
,
1456 IN ULONG SlotNumber
,
1457 OUT PCI_SLOT_NUMBER
* _slotData
// optional
1463 IN PVOID HwDeviceExtension
,
1464 IN BUS_DATA_TYPE BusDataType
,
1466 IN ULONG SlotNumber
,
1474 IN PVOID HwDeviceExtension
,
1475 IN PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
1476 IN ULONG lChannel
// logical channel,
1482 IN PVOID HwDeviceExtension
,
1483 IN ULONG DeviceNumber
,
1484 IN ULONG lChannel
, // logical channel,
1485 IN PSCSI_REQUEST_BLOCK Srb
,
1493 PVOID HwDeviceExtension
,
1494 PSCSI_REQUEST_BLOCK Srb
,
1503 PSCSI_REQUEST_BLOCK Srb
1509 IN PVOID HwDeviceExtension
,
1511 PSCSI_REQUEST_BLOCK Srb
1517 IN PVOID HwDeviceExtension
,
1518 IN ULONG DeviceNumber
,
1519 IN ULONG lChannel
, // logical channel,
1520 IN PSCSI_REQUEST_BLOCK Srb
1526 IN PVOID HwDeviceExtension
,
1527 IN ULONG DeviceNumber
,
1528 IN ULONG lChannel
, // logical channel,
1529 IN PSCSI_REQUEST_BLOCK Srb
1535 IN PHW_DEVICE_EXTENSION deviceExtension
,
1536 IN PHW_LU_EXTENSION LunExt
,
1543 IN PHW_DEVICE_EXTENSION deviceExtension
,
1544 IN PHW_LU_EXTENSION LunExt
1550 IN PVOID HwDeviceExtension
,
1551 IN ULONG DeviceNumber
,
1552 IN ULONG lChannel
, // logical channel,
1553 // is always 0 except simplex-only and multi-channel controllers
1559 extern BOOLEAN NTAPI
1561 IN PKINTERRUPT Interrupt
,
1562 IN PVOID HwDeviceExtension
1565 extern PDRIVER_OBJECT SavedDriverObject
;
1569 UniataChipDetectChannels(
1570 IN PVOID HwDeviceExtension
,
1571 IN PPCI_COMMON_CONFIG pciData
, // optional
1572 IN ULONG DeviceNumber
,
1573 IN PPORT_CONFIGURATION_INFORMATION ConfigInfo
1579 IN PVOID HwDeviceExtension
,
1580 IN PPCI_COMMON_CONFIG pciData
, // optional
1581 IN ULONG DeviceNumber
,
1582 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
1583 IN BOOLEAN
* simplexOnly
1589 IN PVOID HwDeviceExtension
,
1590 IN ULONG DeviceNumber
,
1597 IN PVOID HwDeviceExtension
,
1598 IN PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
1599 IN PPCI_COMMON_CONFIG pciData
,
1600 IN ULONG SystemIoBusNumber
,
1603 IN ULONG length
//range id
1610 IN ULONG slotNumber
,
1611 IN OUT PPCI_COMMON_CONFIG pciData
1614 /****************** 1 *****************/
1615 #define GetPciConfig1(offs, op) { \
1616 ScsiPortGetBusDataByOffset(HwDeviceExtension, \
1618 SystemIoBusNumber, \
1625 #define SetPciConfig1(offs, op) { \
1627 ScsiPortSetBusDataByOffset(HwDeviceExtension, \
1629 SystemIoBusNumber, \
1636 #define ChangePciConfig1(offs, _op) { \
1638 GetPciConfig1(offs, a); \
1640 SetPciConfig1(offs, a); \
1643 /****************** 2 *****************/
1644 #define GetPciConfig2(offs, op) { \
1645 ScsiPortGetBusDataByOffset(HwDeviceExtension, \
1647 SystemIoBusNumber, \
1654 #define SetPciConfig2(offs, op) { \
1656 ScsiPortSetBusDataByOffset(HwDeviceExtension, \
1658 SystemIoBusNumber, \
1665 #define ChangePciConfig2(offs, _op) { \
1667 GetPciConfig2(offs, a); \
1668 a = (USHORT)(_op); \
1669 SetPciConfig2(offs, a); \
1672 /****************** 4 *****************/
1673 #define GetPciConfig4(offs, op) { \
1674 ScsiPortGetBusDataByOffset(HwDeviceExtension, \
1676 SystemIoBusNumber, \
1683 #define SetPciConfig4(offs, op) { \
1685 ScsiPortSetBusDataByOffset(HwDeviceExtension, \
1687 SystemIoBusNumber, \
1694 #define ChangePciConfig4(offs, _op) { \
1696 GetPciConfig4(offs, a); \
1698 SetPciConfig4(offs, a); \
1701 #define DMA_MODE_NONE 0x00
1702 #define DMA_MODE_BM 0x01
1703 #define DMA_MODE_AHCI 0x02
1705 #ifndef GetDmaStatus
1706 #define GetDmaStatus(de, c) \
1707 (((de)->BusMaster == DMA_MODE_BM) ? AtapiReadPort1(&((de)->chan[c]), IDX_BM_Status) : 0)
1708 #endif //GetDmaStatus
1711 #define AtapiVirtToPhysAddr(hwde, srb, phaddr, plen, phaddru) \
1712 AtapiVirtToPhysAddr_(hwde, srb, phaddr, plen, phaddru);
1714 #define AtapiVirtToPhysAddr(hwde, srb, phaddr, plen, phaddru) \
1715 (ScsiPortConvertPhysicalAddressToUlong/*(ULONG)ScsiPortGetVirtualAddress*/(/*hwde,*/ \
1716 ScsiPortGetPhysicalAddress(hwde, srb, phaddr, plen)))
1717 #endif //USE_OWN_DMA
1722 IN PHW_CHANNEL chan
,
1723 IN ULONGIO_PTR port
,
1730 IN PHW_CHANNEL chan
,
1731 IN ULONGIO_PTR port
,
1738 IN PHW_CHANNEL chan
,
1739 IN ULONGIO_PTR port
,
1746 IN PHW_CHANNEL chan
,
1747 IN ULONGIO_PTR port
,
1755 IN PHW_CHANNEL chan
,
1756 IN ULONGIO_PTR port
,
1764 IN PHW_CHANNEL chan
,
1771 IN PHW_CHANNEL chan
,
1778 IN PHW_CHANNEL chan
,
1785 IN PHW_CHANNEL chan
,
1786 IN ULONGIO_PTR port
,
1793 IN PHW_CHANNEL chan
,
1794 IN ULONGIO_PTR port
,
1801 IN PHW_CHANNEL chan
,
1802 IN ULONGIO_PTR _port
,
1811 IN PHW_CHANNEL chan
,
1812 IN ULONGIO_PTR _port
,
1821 IN PHW_CHANNEL chan
,
1822 IN ULONGIO_PTR _port
,
1831 IN PHW_CHANNEL chan
,
1832 IN ULONGIO_PTR _port
,
1838 /*#define GET_CHANNEL(Srb) (Srb->TargetId >> 1)
1839 #define GET_LDEV(Srb) (Srb->TargetId)
1840 #define GET_LDEV2(P, T, L) (T)*/
1842 #define GET_CHANNEL(Srb) (Srb->PathId)
1843 //#define GET_LDEV(Srb) (Srb->TargetId | (Srb->PathId << 1))
1844 //#define GET_LDEV2(P, T, L) (T | ((P)<<1))
1845 #define GET_CDEV(Srb) (Srb->TargetId)
1850 IN PHW_CHANNEL chan
,
1851 IN PHW_DEVICE_EXTENSION deviceExtension
,
1855 #define AtapiSetupLunPtrs(chan, deviceExtension, c) \
1857 chan->DeviceExtension = deviceExtension; \
1858 chan->lChannel = c; \
1859 chan->lun[0] = &(deviceExtension->lun[c*2+0]); \
1860 chan->lun[1] = &(deviceExtension->lun[c*2+1]); \
1861 chan->AltRegMap = deviceExtension->AltRegMap; \
1862 chan->NextDpcChan = -1; \
1863 chan->lun[0]->DeviceExtension = deviceExtension; \
1864 chan->lun[1]->DeviceExtension = deviceExtension; \
1869 AtapiReadChipConfig(
1870 IN PVOID HwDeviceExtension
,
1871 IN ULONG DeviceNumber
,
1872 IN ULONG channel
// physical channel
1878 PHW_LU_EXTENSION LunExt
1881 extern ULONG SkipRaids
;
1882 extern ULONG ForceSimplex
;
1883 extern BOOLEAN g_opt_AtapiDmaRawRead
;
1884 extern BOOLEAN hasPCI
;
1886 extern BOOLEAN InDriverEntry
;
1887 extern BOOLEAN g_Dump
;
1889 extern BOOLEAN g_opt_Verbose
;
1890 extern ULONG g_opt_VirtualMachine
;
1892 extern ULONG g_opt_WaitBusyResetCount
;
1894 extern ULONG CPU_num
;
1896 #define VM_AUTO 0x00
1897 #define VM_NONE 0x01
1898 #define VM_VBOX 0x02
1899 #define VM_VMWARE 0x03
1900 #define VM_QEMU 0x04
1901 #define VM_BOCHS 0x05
1902 #define VM_PCEM 0x06
1904 #define VM_MAX_KNOWN VM_PCEM
1906 extern BOOLEAN WinVer_WDM_Model
;
1910 #endif //__IDE_BUSMASTER_H__