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_ESP 0x00200000
713 #define ATA_AHCI_P_CMD_ATAPI 0x01000000
714 #define ATA_AHCI_P_CMD_DLAE 0x02000000
715 #define ATA_AHCI_P_CMD_ALPE 0x04000000
716 #define ATA_AHCI_P_CMD_ASP 0x08000000
717 #define ATA_AHCI_P_CMD_ICC_MASK 0xf0000000
718 #define ATA_AHCI_P_CMD_NOOP 0x00000000
719 #define ATA_AHCI_P_CMD_ACTIVE 0x10000000
720 #define ATA_AHCI_P_CMD_PARTIAL 0x20000000
721 #define ATA_AHCI_P_CMD_SLUMBER 0x60000000
724 typedef struct _IDE_AHCI_PRD_ENTRY
{
747 } IDE_AHCI_PRD_ENTRY
, *PIDE_AHCI_PRD_ENTRY
;
749 #define ATA_AHCI_DMA_ENTRIES (PAGE_SIZE/2/sizeof(IDE_AHCI_PRD_ENTRY)) /* 128 */
750 #define ATA_AHCI_MAX_TAGS 32
752 #define AHCI_FIS_TYPE_ATA_H2D 0x27
753 #define AHCI_FIS_TYPE_ATA_D2H 0x34
754 #define AHCI_FIS_TYPE_DMA_D2H 0x39
755 #define AHCI_FIS_TYPE_DMA_BiDi 0x41
756 #define AHCI_FIS_TYPE_DATA_BiDi 0x46
757 #define AHCI_FIS_TYPE_BIST_BiDi 0x58
758 #define AHCI_FIS_TYPE_PIO_D2H 0x5f
759 #define AHCI_FIS_TYPE_DEV_BITS_D2H 0xA1
761 typedef struct _AHCI_ATA_H2D_FIS
{
762 UCHAR FIS_Type
; // = 0x27
764 UCHAR Cmd
:1; // update Command register
765 UCHAR Command
; // [2]
766 UCHAR Feature
; // [3]
768 UCHAR BlockNumber
; // [4]
769 UCHAR CylinderLow
; // [5]
770 UCHAR CylinderHigh
; // [6]
771 UCHAR DriveSelect
; // [7]
773 UCHAR BlockNumberExp
; // [8]
774 UCHAR CylinderLowExp
; // [9]
775 UCHAR CylinderHighExp
; // [10]
776 UCHAR FeatureExp
; // [11]
778 UCHAR BlockCount
; // [12]
779 UCHAR BlockCountExp
; // [13]
780 UCHAR Reserved14
; // [14]
781 UCHAR Control
; // [15]
783 } AHCI_ATA_H2D_FIS
, *PAHCI_ATA_H2D_FIS
;
785 #define IDX_AHCI_o_Command (FIELD_OFFSET(AHCI_ATA_H2D_FIS, Command))
786 #define IDX_AHCI_o_Feature (FIELD_OFFSET(AHCI_ATA_H2D_FIS, Feature))
787 #define IDX_AHCI_o_BlockNumber (FIELD_OFFSET(AHCI_ATA_H2D_FIS, BlockNumber ))
788 #define IDX_AHCI_o_CylinderLow (FIELD_OFFSET(AHCI_ATA_H2D_FIS, CylinderLow ))
789 #define IDX_AHCI_o_CylinderHigh (FIELD_OFFSET(AHCI_ATA_H2D_FIS, CylinderHigh))
790 #define IDX_AHCI_o_DriveSelect (FIELD_OFFSET(AHCI_ATA_H2D_FIS, DriveSelect ))
791 #define IDX_AHCI_o_BlockCount (FIELD_OFFSET(AHCI_ATA_H2D_FIS, BlockCount))
792 #define IDX_AHCI_o_Control (FIELD_OFFSET(AHCI_ATA_H2D_FIS, Control))
793 #define IDX_AHCI_o_FeatureExp (FIELD_OFFSET(AHCI_ATA_H2D_FIS, FeatureExp))
794 #define IDX_AHCI_o_BlockNumberExp (FIELD_OFFSET(AHCI_ATA_H2D_FIS, BlockNumberExp ))
795 #define IDX_AHCI_o_CylinderLowExp (FIELD_OFFSET(AHCI_ATA_H2D_FIS, CylinderLowExp ))
796 #define IDX_AHCI_o_CylinderHighExp (FIELD_OFFSET(AHCI_ATA_H2D_FIS, CylinderHighExp))
797 #define IDX_AHCI_o_BlockCountExp (FIELD_OFFSET(AHCI_ATA_H2D_FIS, BlockCountExp))
799 #define AHCI_FIS_COMM_PM (0x80 | AHCI_DEV_SEL_PM)
801 #define AHCI_DEV_SEL_1 0x00
802 #define AHCI_DEV_SEL_2 0x01
803 #define AHCI_DEV_SEL_PM 0x0f
805 /* 128-byte aligned */
806 typedef struct _IDE_AHCI_CMD
{
810 IDE_AHCI_PRD_ENTRY prd_tab
[ATA_AHCI_DMA_ENTRIES
]; // also 128-byte aligned
811 } IDE_AHCI_CMD
, *PIDE_AHCI_CMD
;
815 #define ATA_AHCI_CMD_ATAPI 0x0020
816 #define ATA_AHCI_CMD_WRITE 0x0040
817 #define ATA_AHCI_CMD_PREFETCH 0x0080
818 #define ATA_AHCI_CMD_RESET 0x0100
819 #define ATA_AHCI_CMD_BIST 0x0200
820 #define ATA_AHCI_CMD_CLR_BUSY 0x0400
822 /* 128-byte aligned */
823 typedef struct _IDE_AHCI_CMD_LIST
{
825 USHORT prd_length
; /* PRD entries */
827 ULONGLONG cmd_table_phys
; /* points to IDE_AHCI_CMD */
829 } IDE_AHCI_CMD_LIST
, *PIDE_AHCI_CMD_LIST
;
831 /* 256-byte aligned */
832 typedef struct _IDE_AHCI_RCV_FIS
{
842 } IDE_AHCI_RCV_FIS
, *PIDE_AHCI_RCV_FIS
;
844 /* 1K-byte aligned */
845 typedef struct _IDE_AHCI_CHANNEL_CTL_BLOCK
{
846 IDE_AHCI_CMD_LIST cmd_list
[ATA_AHCI_MAX_TAGS
]; // 1K-size (32*32)
847 IDE_AHCI_RCV_FIS rcv_fis
;
848 IDE_AHCI_CMD cmd
; // for single internal commands w/o associated AtaReq
849 } IDE_AHCI_CHANNEL_CTL_BLOCK
, *PIDE_AHCI_CHANNEL_CTL_BLOCK
;
853 #define IsBusMaster(pciData) \
854 ( ((pciData)->Command & (PCI_ENABLE_BUS_MASTER/* | PCI_ENABLE_IO_SPACE*/)) == \
855 (PCI_ENABLE_BUS_MASTER/* | PCI_ENABLE_IO_SPACE*/))
857 #define PCI_IDE_PROGIF_NATIVE_1 0x01
858 #define PCI_IDE_PROGIF_NATIVE_2 0x04
859 #define PCI_IDE_PROGIF_NATIVE_ALL 0x05
861 #define IsMasterDev(pciData) \
862 ( ((pciData)->ProgIf & 0x80) && \
863 ((pciData)->ProgIf & PCI_IDE_PROGIF_NATIVE_ALL) != PCI_IDE_PROGIF_NATIVE_ALL )
865 //#define INT_Q_SIZE 32
866 #define MIN_REQ_TTL 4
870 typedef union _ATA_REQ
{
871 // ULONG reqId; // serial
877 union _ATA_REQ
* next_req
;
878 union _ATA_REQ
* prev_req
;
880 PSCSI_REQUEST_BLOCK Srb
; // Current request on controller.
882 PUSHORT DataBuffer
; // Data buffer pointer.
883 ULONG WordsLeft
; // Data words left.
884 ULONG TransferLength
; // Originally requested transfer length
886 ULONG WordsTransfered
;// Data words already transfered.
895 PSCSI_REQUEST_BLOCK OriginalSrb
; // Mechanism Status Srb Data
906 ULONGLONG ahci_base64
;
908 PIDE_AHCI_CMD ahci_cmd_ptr
;
912 USHORT io_cmd_flags
; // out
917 //UCHAR padding_128b[128]; // Note: we assume, NT allocates block > 4k as PAGE-aligned
921 BM_DMA_ENTRY dma_tab
[ATA_DMA_ENTRIES
];
922 IDE_AHCI_CMD ahci_cmd0
; // for AHCI, 128-byte aligned
927 UCHAR padding_4kb
[PAGE_SIZE
];
929 } ATA_REQ
, *PATA_REQ
;
931 #define REQ_FLAG_FORCE_DOWNRATE 0x01
932 #define REQ_FLAG_DMA_OPERATION 0x02
933 #define REQ_FLAG_REORDERABLE_CMD 0x04
934 #define REQ_FLAG_RW_MASK 0x08
935 #define REQ_FLAG_READ 0x08
936 #define REQ_FLAG_WRITE 0x00
937 #define REQ_FLAG_FORCE_DOWNRATE_LBA48 0x10
938 #define REQ_FLAG_DMA_DBUF 0x20
939 #define REQ_FLAG_DMA_DBUF_PRD 0x40
940 #define REQ_FLAG_LBA48 0x80
943 #define REQ_STATE_NONE 0x00
944 #define REQ_STATE_QUEUED 0x10
946 #define REQ_STATE_PREPARE_TO_TRANSFER 0x20
947 #define REQ_STATE_PREPARE_TO_NEXT 0x21
948 #define REQ_STATE_READY_TO_TRANSFER 0x30
950 #define REQ_STATE_EXPECTING_INTR 0x40
951 #define REQ_STATE_ATAPI_EXPECTING_CMD_INTR 0x41
952 #define REQ_STATE_ATAPI_EXPECTING_DATA_INTR 0x42
953 #define REQ_STATE_ATAPI_EXPECTING_DATA_INTR2 0x43
954 #define REQ_STATE_ATAPI_DO_NOTHING_INTR 0x44
956 #define REQ_STATE_EARLY_INTR 0x48
958 #define REQ_STATE_PROCESSING_INTR 0x50
960 #define REQ_STATE_DPC_INTR_REQ 0x51
961 #define REQ_STATE_DPC_RESET_REQ 0x52
962 #define REQ_STATE_DPC_COMPLETE_REQ 0x53
964 #define REQ_STATE_DPC_WAIT_BUSY0 0x57
965 #define REQ_STATE_DPC_WAIT_BUSY1 0x58
966 #define REQ_STATE_DPC_WAIT_BUSY 0x59
967 #define REQ_STATE_DPC_WAIT_DRQ 0x5a
968 #define REQ_STATE_DPC_WAIT_DRQ0 0x5b
969 #define REQ_STATE_DPC_WAIT_DRQ_ERR 0x5c
971 #define REQ_STATE_TRANSFER_COMPLETE 0x7f
974 #define CMD_ACTION_PREPARE 0x01
975 #define CMD_ACTION_EXEC 0x02
976 #define CMD_ACTION_ALL (CMD_ACTION_PREPARE | CMD_ACTION_EXEC)
978 // predefined Reorder costs
979 #define REORDER_COST_MAX ((DEF_I64(0x1) << 60) - 1)
980 #define REORDER_COST_TTL (REORDER_COST_MAX - 1)
981 #define REORDER_COST_INTERSECT (REORDER_COST_MAX - 2)
982 #define REORDER_COST_DENIED (REORDER_COST_MAX - 3)
983 #define REORDER_COST_RESELECT (REORDER_COST_MAX/4)
985 #define REORDER_COST_SWITCH_RW_CD (REORDER_COST_MAX/8)
986 #define REORDER_MCOST_SWITCH_RW_CD (0)
987 #define REORDER_MCOST_SEEK_BACK_CD (16)
989 #define REORDER_COST_SWITCH_RW_HDD (0)
990 #define REORDER_MCOST_SWITCH_RW_HDD (4)
991 #define REORDER_MCOST_SEEK_BACK_HDD (2)
993 /*typedef struct _ATA_QUEUE {
994 struct _ATA_REQ* head_req; // index
995 struct _ATA_REQ* tail_req; // index
998 BM_DMA_ENTRY dma_tab[ATA_DMA_ENTRIES];
999 } ATA_QUEUE, *PATA_QUEUE;*/
1001 struct _HW_DEVICE_EXTENSION
;
1002 struct _HW_LU_EXTENSION
;
1004 typedef struct _IORES
{
1006 ULONG Addr
; /* Base address*/
1007 PVOID pAddr
; /* Base address in pointer form */
1009 ULONG MemIo
:1; /* Memory mapping (1) vs IO ports (0) */
1010 ULONG Proc
:1; /* Need special processing via IO_Proc */
1014 // Channel extension
1015 typedef struct _HW_CHANNEL
{
1019 ULONG last_cdev
; /* device for which we have configured timings last time */
1020 ULONG last_devsel
; /* device selected during last call to SelectDrive() */
1021 /* PATA_REQ first_req;
1022 PATA_REQ last_req;*/
1024 ULONG ChannelSelectWaitCount
;
1028 BOOLEAN ExpectingInterrupt
; // Indicates expecting an interrupt
1029 BOOLEAN RDP
; // Indicate last tape command was DSC Restrictive.
1030 // Indicates whether '0x1f0' is the base address. Used
1031 // in SMART Ioctl calls.
1032 BOOLEAN PrimaryAddress
;
1033 // Placeholder for the sub-command value of the last
1038 // Placeholder for status register after a GET_MEDIA_STATUS command
1039 UCHAR ReturningMediaStatus
;
1041 BOOLEAN CopyDmaBuffer
;
1048 MECHANICAL_STATUS_INFORMATION_HEADER MechStatusData
;
1049 SENSE_DATA MechStatusSense
;
1050 ULONG MechStatusRetryCount
;
1051 SCSI_REQUEST_BLOCK InternalSrb
;
1053 ULONG MaxTransferMode
; // may differ from Controller's value due to 40-pin cable
1055 ULONG ChannelCtrlFlags
;
1056 ULONG ResetInProgress
; // flag
1062 #define CHECK_INTR_ACTIVE 0x03
1063 #define CHECK_INTR_DETECTED 0x02
1064 #define CHECK_INTR_CHECK 0x01
1065 #define CHECK_INTR_IDLE 0x00
1068 PHW_TIMER HwScsiTimer
;
1071 PHW_TIMER HwScsiTimer1
;
1072 PHW_TIMER HwScsiTimer2
;
1074 // PHW_TIMER CurDpc;
1075 // LARGE_INTEGER ActivationTime;
1079 // PHW_TIMER HwScsiTimer;
1080 // KSPIN_LOCK QueueSpinLock;
1081 // KIRQL QueueOldIrql;
1083 struct _HW_DEVICE_EXTENSION
* DeviceExtension
;
1084 struct _HW_LU_EXTENSION
* lun
[IDE_MAX_LUN_PER_CHAN
];
1089 // Double-buffering support
1091 ULONG DB_PRD_PhAddr
;
1098 PIDE_AHCI_CHANNEL_CTL_BLOCK AhciCtlBlock0
; // unaligned
1099 PIDE_AHCI_CHANNEL_CTL_BLOCK AhciCtlBlock
; // 128-byte aligned
1100 ULONGLONG AHCI_CTL_PhAddr
;
1101 IORES BaseIoAHCI_Port
;
1103 ULONG AhciCompleteCI
;
1105 ULONG AhciLastSError
;
1106 //PVOID AHCI_FIS; // is not actually used by UniATA now, but is required by AHCI controller
1107 //ULONGLONG AHCI_FIS_PhAddr;
1108 // Note: in contrast to FBSD, we keep PRD and CMD item in AtaReq structure
1109 PATA_REQ AhciInternalAtaReq
;
1110 PSCSI_REQUEST_BLOCK AhciInternalSrb
;
1112 #ifdef QUEUE_STATISTICS
1113 LONGLONG QueueStat
[MAX_QUEUE_STAT
];
1114 LONGLONG ReorderCount
;
1115 LONGLONG IntersectCount
;
1116 LONGLONG TryReorderCount
;
1117 LONGLONG TryReorderHeadCount
;
1118 LONGLONG TryReorderTailCount
; /* in-order requests */
1119 #endif //QUEUE_STATISTICS
1121 //ULONG BaseMemAddress;
1122 //ULONG BaseMemAddressOffset;
1123 IORES RegTranslation
[IDX_MAX_REG
];
1125 } HW_CHANNEL
, *PHW_CHANNEL
;
1127 #define CTRFLAGS_DMA_ACTIVE 0x0001
1128 #define CTRFLAGS_DMA_RO 0x0002
1129 #define CTRFLAGS_DMA_OPERATION 0x0004
1130 #define CTRFLAGS_INTR_DISABLED 0x0008
1131 #define CTRFLAGS_DPC_REQ 0x0010
1132 #define CTRFLAGS_ENABLE_INTR_REQ 0x0020
1133 #define CTRFLAGS_LBA48 0x0040
1134 #define CTRFLAGS_DSC_BSY 0x0080
1135 #define CTRFLAGS_NO_SLAVE 0x0100
1136 //#define CTRFLAGS_DMA_BEFORE_R 0x0200
1137 //#define CTRFLAGS_PATA 0x0200
1138 //#define CTRFLAGS_NOT_PRESENT 0x0200
1139 #define CTRFLAGS_AHCI_PM 0x0400
1140 #define CTRFLAGS_AHCI_PM2 0x0800
1142 #define CTRFLAGS_PERMANENT (CTRFLAGS_DMA_RO | CTRFLAGS_NO_SLAVE)
1144 #define GEOM_AUTO 0xffffffff
1145 #define GEOM_STD 0x0000
1146 #define GEOM_UNIATA 0x0001
1147 #define GEOM_ORIG 0x0002
1148 #define GEOM_MANUAL 0x0003
1150 #define DPC_STATE_NONE 0x00
1151 #define DPC_STATE_ISR 0x10
1152 #define DPC_STATE_DPC 0x20
1153 #define DPC_STATE_TIMER 0x30
1154 #define DPC_STATE_COMPLETE 0x40
1156 // Logical unit extension
1157 typedef struct _HW_LU_EXTENSION
{
1158 IDENTIFY_DATA2 IdentifyData
;
1159 ULONGLONG NumOfSectors
;
1160 ULONG DeviceFlags
; // Flags word for each possible device. DFLAGS_XXX
1161 ULONG DiscsPresent
; // Indicates number of platters on changer-ish devices.
1162 BOOLEAN DWordIO
; // Indicates use of 32-bit PIO
1163 UCHAR ReturningMediaStatus
;
1164 UCHAR MaximumBlockXfer
;
1167 UCHAR TransferMode
; // current transfer mode
1168 UCHAR LimitedTransferMode
; // user-defined or IDE cable limitation
1169 UCHAR OrigTransferMode
; // transfer mode, returned by device IDENTIFY (can be changed via IOCTL)
1170 UCHAR PhyTransferMode
; // phy transfer mode (actual bus transfer mode for PATA DMA and SATA)
1172 ULONG ErrorCount
; // Count of errors. Used to turn off features.
1173 // ATA_QUEUE cmd_queue;
1174 LONGLONG ReadCmdCost
;
1175 LONGLONG WriteCmdCost
;
1176 LONGLONG OtherCmdCost
;
1177 LONGLONG RwSwitchCost
;
1178 LONGLONG RwSwitchMCost
;
1179 LONGLONG SeekBackMCost
;
1186 ULONG LunSelectWaitCount
;
1187 ULONG AtapiReadyWaitDelay
;
1191 ULONG opt_MaxTransferMode
;
1192 ULONG opt_PreferedTransferMode
;
1193 BOOLEAN opt_ReadCacheEnable
;
1194 BOOLEAN opt_WriteCacheEnable
;
1196 UCHAR opt_AdvPowerMode
;
1197 UCHAR opt_AcousticMode
;
1198 UCHAR opt_StandbyTimer
;
1199 UCHAR opt_Padding
[2]; // padding
1201 struct _SBadBlockListItem
* bbListDescr
;
1202 struct _SBadBlockRange
* arrBadBlocks
;
1205 // Controller-specific LUN options
1207 /* for tricky controllers, those can change Logical-to-Physical LUN mapping.
1208 mainly for mapping SATA ports to compatible PATA registers
1209 Treated as PHYSICAL port number, regardless of logical mapping.
1214 struct _HW_DEVICE_EXTENSION
* DeviceExtension
;
1215 struct _HW_CHANNEL
* chan
;
1218 ULONGLONG errLastLba
;
1221 UCHAR errPadding
[3];
1223 #ifdef IO_STATISTICS
1225 LONGLONG ModeErrorCount
[MAX_RETRIES
];
1226 LONGLONG RecoverCount
[MAX_RETRIES
];
1228 LONGLONG BlockIoCount
;
1230 #endif//IO_STATISTICS
1231 } HW_LU_EXTENSION
, *PHW_LU_EXTENSION
;
1234 typedef struct _HW_DEVICE_EXTENSION
{
1236 //PIDE_REGISTERS_1 BaseIoAddress1[IDE_MAX_CHAN]; // Base register locations
1237 //PIDE_REGISTERS_2 BaseIoAddress2[IDE_MAX_CHAN];
1238 ULONG BusInterruptLevel
; // Interrupt level
1239 ULONG InterruptMode
; // Interrupt Mode (Level or Edge)
1240 ULONG BusInterruptVector
;
1241 // Number of channels being supported by one instantiation
1242 // of the device extension. Normally (and correctly) one, but
1243 // with so many broken PCI IDE controllers being sold, we have
1245 ULONG NumberChannels
;
1247 ULONG FirstChannelToCheck
;
1249 HW_LU_EXTENSION lun
[IDE_MAX_LUN
];
1250 HW_CHANNEL chan
[AHCI_MAX_PORT
/*IDE_MAX_CHAN*/];
1252 PHW_LU_EXTENSION lun
; // lun array
1253 PHW_CHANNEL chan
; // channel array
1255 UCHAR LastInterruptedChannel
;
1256 // Indicates the number of blocks transferred per int. according to the
1258 BOOLEAN DriverMustPoll
; // Driver is being used by the crash dump utility or ntldr.
1260 BOOLEAN UseDpc
; // Indicates use of DPC on long waits
1261 IDENTIFY_DATA FullIdentifyData
; // Identify data for device
1262 // BusMaster specific data
1263 // PBM_DMA_ENTRY dma_tab_0;
1264 //KSPIN_LOCK DpcSpinLock;
1266 ULONG ActiveDpcChan
;
1268 ULONG ExpectingInterrupt
; // Indicates entire controller expecting an interrupt
1270 PHW_TIMER HwScsiTimer1;
1271 PHW_TIMER HwScsiTimer2;
1277 PDEVICE_OBJECT Isr2DevObj
;
1279 //PIDE_BUSMASTER_REGISTERS BaseIoAddressBM_0;
1280 IORES BaseIoAddressBM_0
;
1281 //PIDE_BUSMASTER_REGISTERS BaseIoAddressBM[IDE_MAX_CHAN];
1283 // Device identification
1287 ULONG SystemIoBusNumber
;
1290 ULONG InitMethod
; // vendor specific
1295 BOOLEAN simplexOnly
;
1301 BOOLEAN DWordIO
; // Indicates use of 32-bit PIO
1302 /* // Indicates, that HW Initialized is already called for this controller
1303 // 0 bit for Primary, 1 - for Secondary. Is used to manage AltInit under w2k+
1304 UCHAR Initialized; */
1309 ULONG MaxTransferMode
; // max transfer mode supported by controller
1311 INTERFACE_TYPE OrigAdapterInterfaceType
;
1312 INTERFACE_TYPE AdapterInterfaceType
;
1313 ULONG MaximumDmaTransferLength
;
1314 ULONG AlignmentMask
;
1315 ULONG DmaSegmentLength
;
1316 ULONG DmaSegmentAlignmentMask
; // must be PAGE-aligned
1318 //ULONG BaseMemAddress;
1320 //PIDE_SATA_REGISTERS BaseIoAddressSATA_0;
1321 IORES BaseIoAddressSATA_0
;
1322 //PIDE_SATA_REGISTERS BaseIoAddressSATA[IDE_MAX_CHAN];
1325 //PIDE_AHCI_PORT_REGISTERS BaseIoAHCIPort[AHCI_MAX_PORT];
1328 ULONG AHCI_PI_mask
; // for port exclusion, usually = AHCI_PI
1329 PATA_REQ AhciInternalAtaReq0
;
1330 PSCSI_REQUEST_BLOCK AhciInternalSrb0
;
1332 BOOLEAN opt_AtapiDmaZeroTransfer
; // default FALSE
1333 BOOLEAN opt_AtapiDmaControlCmd
; // default FALSE
1334 BOOLEAN opt_AtapiDmaRawRead
; // default TRUE
1335 BOOLEAN opt_AtapiDmaReadWrite
; // default TRUE
1339 // Controller specific state/options
1344 } HW_DEVICE_EXTENSION
, *PHW_DEVICE_EXTENSION
;
1346 typedef struct _ISR2_DEVICE_EXTENSION
{
1347 PHW_DEVICE_EXTENSION HwDeviceExtension
;
1349 } ISR2_DEVICE_EXTENSION
, *PISR2_DEVICE_EXTENSION
;
1351 typedef ISR2_DEVICE_EXTENSION PCIIDE_DEVICE_EXTENSION
;
1352 typedef PISR2_DEVICE_EXTENSION PPCIIDE_DEVICE_EXTENSION
;
1354 #define HBAFLAGS_DMA_DISABLED 0x01
1355 #define HBAFLAGS_DMA_DISABLED_LBA48 0x02
1357 extern UCHAR pciBuffer
[256];
1358 extern PBUSMASTER_CONTROLLER_INFORMATION BMList
;
1359 extern ULONG BMListLen
;
1360 extern ULONG IsaCount
;
1361 extern ULONG MCACount
;
1362 extern UNICODE_STRING SavedRegPath
;
1364 //extern const CHAR retry_Wdma[MAX_RETRIES+1];
1365 //extern const CHAR retry_Udma[MAX_RETRIES+1];
1369 UniataEnumBusMasterController(
1370 IN PVOID DriverObject
,
1375 UniataFindCompatBusMasterController1(
1376 IN PVOID HwDeviceExtension
,
1378 IN PVOID BusInformation
,
1379 IN PCHAR ArgumentString
,
1380 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
1385 UniataFindCompatBusMasterController2(
1386 IN PVOID HwDeviceExtension
,
1388 IN PVOID BusInformation
,
1389 IN PCHAR ArgumentString
,
1390 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
1394 #define UNIATA_ALLOCATE_NEW_LUNS 0x00
1396 extern BOOLEAN NTAPI
1397 UniataAllocateLunExt(
1398 PHW_DEVICE_EXTENSION deviceExtension
,
1399 ULONG NewNumberChannels
1404 PHW_DEVICE_EXTENSION deviceExtension
1408 UniataFindBusMasterController(
1409 IN PVOID HwDeviceExtension
,
1411 IN PVOID BusInformation
,
1412 IN PCHAR ArgumentString
,
1413 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
1419 UniataClaimLegacyPCIIDE(
1426 IN PVOID HwDeviceExtension
1431 UniataDisconnectIntr2(
1432 IN PVOID HwDeviceExtension
1437 ScsiPortGetBusDataByOffset(
1438 IN PVOID HwDeviceExtension
,
1439 IN BUS_DATA_TYPE BusDataType
,
1441 IN ULONG SlotNumber
,
1447 #define PCIBUSNUM_NOT_SPECIFIED (0xffffffffL)
1448 #define PCISLOTNUM_NOT_SPECIFIED (0xffffffffL)
1453 PBUSMASTER_CONTROLLER_INFORMATION_BASE BusMasterAdapters
,
1455 IN PVOID HwDeviceExtension
,
1457 IN ULONG SlotNumber
,
1458 OUT PCI_SLOT_NUMBER
* _slotData
// optional
1464 IN PVOID HwDeviceExtension
,
1465 IN BUS_DATA_TYPE BusDataType
,
1467 IN ULONG SlotNumber
,
1475 IN PVOID HwDeviceExtension
,
1476 IN PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
1477 IN ULONG lChannel
// logical channel,
1483 IN PVOID HwDeviceExtension
,
1484 IN ULONG DeviceNumber
,
1485 IN ULONG lChannel
, // logical channel,
1486 IN PSCSI_REQUEST_BLOCK Srb
,
1494 PVOID HwDeviceExtension
,
1495 PSCSI_REQUEST_BLOCK Srb
,
1504 PSCSI_REQUEST_BLOCK Srb
1510 IN PVOID HwDeviceExtension
,
1512 PSCSI_REQUEST_BLOCK Srb
1518 IN PVOID HwDeviceExtension
,
1519 IN ULONG DeviceNumber
,
1520 IN ULONG lChannel
, // logical channel,
1521 IN PSCSI_REQUEST_BLOCK Srb
1527 IN PVOID HwDeviceExtension
,
1528 IN ULONG DeviceNumber
,
1529 IN ULONG lChannel
, // logical channel,
1530 IN PSCSI_REQUEST_BLOCK Srb
1536 IN PHW_DEVICE_EXTENSION deviceExtension
,
1537 IN PHW_LU_EXTENSION LunExt
,
1544 IN PHW_DEVICE_EXTENSION deviceExtension
,
1545 IN PHW_LU_EXTENSION LunExt
1551 IN PVOID HwDeviceExtension
,
1552 IN ULONG DeviceNumber
,
1553 IN ULONG lChannel
, // logical channel,
1554 // is always 0 except simplex-only and multi-channel controllers
1560 extern BOOLEAN NTAPI
1562 IN PKINTERRUPT Interrupt
,
1563 IN PVOID HwDeviceExtension
1566 extern PDRIVER_OBJECT SavedDriverObject
;
1570 UniataChipDetectChannels(
1571 IN PVOID HwDeviceExtension
,
1572 IN PPCI_COMMON_CONFIG pciData
, // optional
1573 IN ULONG DeviceNumber
,
1574 IN PPORT_CONFIGURATION_INFORMATION ConfigInfo
1580 IN PVOID HwDeviceExtension
,
1581 IN PPCI_COMMON_CONFIG pciData
, // optional
1582 IN ULONG DeviceNumber
,
1583 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
1584 IN BOOLEAN
* simplexOnly
1590 IN PVOID HwDeviceExtension
,
1591 IN ULONG DeviceNumber
,
1598 IN PVOID HwDeviceExtension
,
1599 IN PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
1600 IN PPCI_COMMON_CONFIG pciData
,
1601 IN ULONG SystemIoBusNumber
,
1604 IN ULONG length
//range id
1611 IN ULONG slotNumber
,
1612 IN OUT PPCI_COMMON_CONFIG pciData
1615 /****************** 1 *****************/
1616 #define GetPciConfig1(offs, op) { \
1617 ScsiPortGetBusDataByOffset(HwDeviceExtension, \
1619 SystemIoBusNumber, \
1626 #define SetPciConfig1(offs, op) { \
1628 ScsiPortSetBusDataByOffset(HwDeviceExtension, \
1630 SystemIoBusNumber, \
1637 #define ChangePciConfig1(offs, _op) { \
1639 GetPciConfig1(offs, a); \
1641 SetPciConfig1(offs, a); \
1644 /****************** 2 *****************/
1645 #define GetPciConfig2(offs, op) { \
1646 ScsiPortGetBusDataByOffset(HwDeviceExtension, \
1648 SystemIoBusNumber, \
1655 #define SetPciConfig2(offs, op) { \
1657 ScsiPortSetBusDataByOffset(HwDeviceExtension, \
1659 SystemIoBusNumber, \
1666 #define ChangePciConfig2(offs, _op) { \
1668 GetPciConfig2(offs, a); \
1669 a = (USHORT)(_op); \
1670 SetPciConfig2(offs, a); \
1673 /****************** 4 *****************/
1674 #define GetPciConfig4(offs, op) { \
1675 ScsiPortGetBusDataByOffset(HwDeviceExtension, \
1677 SystemIoBusNumber, \
1684 #define SetPciConfig4(offs, op) { \
1686 ScsiPortSetBusDataByOffset(HwDeviceExtension, \
1688 SystemIoBusNumber, \
1695 #define ChangePciConfig4(offs, _op) { \
1697 GetPciConfig4(offs, a); \
1699 SetPciConfig4(offs, a); \
1702 #define DMA_MODE_NONE 0x00
1703 #define DMA_MODE_BM 0x01
1704 #define DMA_MODE_AHCI 0x02
1706 #ifndef GetDmaStatus
1707 #define GetDmaStatus(de, c) \
1708 (((de)->BusMaster == DMA_MODE_BM) ? AtapiReadPort1(&((de)->chan[c]), IDX_BM_Status) : 0)
1709 #endif //GetDmaStatus
1712 #define AtapiVirtToPhysAddr(hwde, srb, phaddr, plen, phaddru) \
1713 AtapiVirtToPhysAddr_(hwde, srb, phaddr, plen, phaddru);
1715 #define AtapiVirtToPhysAddr(hwde, srb, phaddr, plen, phaddru) \
1716 (ScsiPortConvertPhysicalAddressToUlong/*(ULONG)ScsiPortGetVirtualAddress*/(/*hwde,*/ \
1717 ScsiPortGetPhysicalAddress(hwde, srb, phaddr, plen)))
1718 #endif //USE_OWN_DMA
1723 IN PHW_CHANNEL chan
,
1724 IN ULONGIO_PTR port
,
1731 IN PHW_CHANNEL chan
,
1732 IN ULONGIO_PTR port
,
1739 IN PHW_CHANNEL chan
,
1740 IN ULONGIO_PTR port
,
1747 IN PHW_CHANNEL chan
,
1748 IN ULONGIO_PTR port
,
1756 IN PHW_CHANNEL chan
,
1757 IN ULONGIO_PTR port
,
1765 IN PHW_CHANNEL chan
,
1772 IN PHW_CHANNEL chan
,
1779 IN PHW_CHANNEL chan
,
1786 IN PHW_CHANNEL chan
,
1787 IN ULONGIO_PTR port
,
1794 IN PHW_CHANNEL chan
,
1795 IN ULONGIO_PTR port
,
1802 IN PHW_CHANNEL chan
,
1803 IN ULONGIO_PTR _port
,
1812 IN PHW_CHANNEL chan
,
1813 IN ULONGIO_PTR _port
,
1822 IN PHW_CHANNEL chan
,
1823 IN ULONGIO_PTR _port
,
1832 IN PHW_CHANNEL chan
,
1833 IN ULONGIO_PTR _port
,
1839 /*#define GET_CHANNEL(Srb) (Srb->TargetId >> 1)
1840 #define GET_LDEV(Srb) (Srb->TargetId)
1841 #define GET_LDEV2(P, T, L) (T)*/
1843 #define GET_CHANNEL(Srb) (Srb->PathId)
1844 //#define GET_LDEV(Srb) (Srb->TargetId | (Srb->PathId << 1))
1845 //#define GET_LDEV2(P, T, L) (T | ((P)<<1))
1846 #define GET_CDEV(Srb) (Srb->TargetId)
1851 IN PHW_CHANNEL chan
,
1852 IN PHW_DEVICE_EXTENSION deviceExtension
,
1856 #define AtapiSetupLunPtrs(chan, deviceExtension, c) \
1858 chan->DeviceExtension = deviceExtension; \
1859 chan->lChannel = c; \
1860 chan->lun[0] = &(deviceExtension->lun[c*2+0]); \
1861 chan->lun[1] = &(deviceExtension->lun[c*2+1]); \
1862 chan->AltRegMap = deviceExtension->AltRegMap; \
1863 chan->NextDpcChan = -1; \
1864 chan->lun[0]->DeviceExtension = deviceExtension; \
1865 chan->lun[1]->DeviceExtension = deviceExtension; \
1870 AtapiReadChipConfig(
1871 IN PVOID HwDeviceExtension
,
1872 IN ULONG DeviceNumber
,
1873 IN ULONG channel
// physical channel
1879 PHW_LU_EXTENSION LunExt
1882 extern ULONG SkipRaids
;
1883 extern ULONG ForceSimplex
;
1884 extern BOOLEAN g_opt_AtapiDmaRawRead
;
1885 extern BOOLEAN hasPCI
;
1887 extern BOOLEAN InDriverEntry
;
1888 extern BOOLEAN g_Dump
;
1890 extern BOOLEAN g_opt_Verbose
;
1891 extern ULONG g_opt_VirtualMachine
;
1893 extern ULONG g_opt_WaitBusyResetCount
;
1895 extern ULONG CPU_num
;
1897 #define VM_AUTO 0x00
1898 #define VM_NONE 0x01
1899 #define VM_VBOX 0x02
1900 #define VM_VMWARE 0x03
1901 #define VM_QEMU 0x04
1902 #define VM_BOCHS 0x05
1903 #define VM_PCEM 0x06
1905 #define VM_MAX_KNOWN VM_PCEM
1907 extern BOOLEAN WinVer_WDM_Model
;
1911 #endif //__IDE_BUSMASTER_H__