3 Copyright (c) 2002-2012 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-2008
36 Some definitions were taken from FreeBSD 4.3-4.6 ATA driver by
37 Søren Schmidt, Copyright (c) 1998,1999,2000,2001
41 #ifndef __IDE_BUSMASTER_H__
42 #define __IDE_BUSMASTER_H__
52 #define ATA_IMMEDIATE 0x1
53 #define ATA_WAIT_INTR 0x2
54 #define ATA_WAIT_READY 0x3
55 #define ATA_ACTIVE 0x4
56 #define ATA_ACTIVE_ATA 0x5
57 #define ATA_ACTIVE_ATAPI 0x6
58 #define ATA_REINITING 0x7
59 #define ATA_WAIT_BASE_READY 0x8
60 #define ATA_WAIT_IDLE 0x9
73 #define IO_WD1 0x1F0 /* Primary Fixed Disk Controller */
74 #define IO_WD2 0x170 /* Secondary Fixed Disk Controller */
75 #define IP_PC98_BANK 0x432
77 #define PCI_ADDRESS_IOMASK 0xfffffff0
79 #define ATA_BM_OFFSET1 0x08
80 #define ATA_IOSIZE 0x08
81 #define ATA_ALTOFFSET 0x206 /* alternate registers offset */
82 #define ATA_PCCARD_ALTOFFSET 0x0e /* do for PCCARD devices */
83 #define ATA_ALTIOSIZE 0x01 /* alternate registers size */
84 #define ATA_BMIOSIZE 0x20
85 #define ATA_PC98_BANKIOSIZE 0x01
86 //#define ATA_MAX_LBA28 DEF_U64(0x0fffffff)
87 // Hitachi 1 Tb HDD didn't allow LBA28 with BCount > 1 beyond this LBA
88 #define ATA_MAX_IOLBA28 DEF_U64(0x0fffff80)
89 #define ATA_MAX_LBA28 DEF_U64(0x0fffffff)
91 #define ATA_DMA_ENTRIES 256 /* PAGESIZE/2/sizeof(BM_DMA_ENTRY)*/
92 #define ATA_DMA_EOT 0x80000000
96 #define ATAPI_MAGIC_LSB 0x14
97 #define ATAPI_MAGIC_MSB 0xeb
99 #define AHCI_MAX_PORT 32
101 #define SATA_MAX_PM_UNITS 16
103 typedef struct _BUSMASTER_CTX
{
104 PBUSMASTER_CONTROLLER_INFORMATION
* BMListPtr
;
106 } BUSMASTER_CTX
, *PBUSMASTER_CTX
;
108 #define PCI_DEV_CLASS_STORAGE 0x01
110 #define PCI_DEV_SUBCLASS_IDE 0x01
111 #define PCI_DEV_SUBCLASS_RAID 0x04
112 #define PCI_DEV_SUBCLASS_ATA 0x05
113 #define PCI_DEV_SUBCLASS_SATA 0x06
115 #define PCI_DEV_PROGIF_AHCI_1_0 0x01
117 /* structure for holding DMA address data */
118 typedef struct BM_DMA_ENTRY
{
121 } BM_DMA_ENTRY
, *PBM_DMA_ENTRY
;
123 typedef struct _IDE_BUSMASTER_REGISTERS
{
125 UCHAR DeviceSpecific0
;
127 UCHAR DeviceSpecific1
;
129 } IDE_BUSMASTER_REGISTERS
, *PIDE_BUSMASTER_REGISTERS
;
131 #define BM_STATUS_ACTIVE 0x01
132 #define BM_STATUS_ERR 0x02
133 #define BM_STATUS_INTR 0x04
134 #define BM_STATUS_MASK 0x07
135 #define BM_STATUS_DRIVE_0_DMA 0x20
136 #define BM_STATUS_DRIVE_1_DMA 0x40
137 #define BM_STATUS_SIMPLEX_ONLY 0x80
139 #define BM_COMMAND_START_STOP 0x01
140 /*#define BM_COMMAND_WRITE 0x08
141 #define BM_COMMAND_READ 0x00*/
142 #define BM_COMMAND_WRITE 0x00
143 #define BM_COMMAND_READ 0x08
145 #define BM_DS0_SII_DMA_ENABLE (1 << 0) /* DMA run switch */
146 #define BM_DS0_SII_IRQ (1 << 3) /* ??? */
147 #define BM_DS0_SII_DMA_SATA_IRQ (1 << 4) /* OR of all SATA IRQs */
148 #define BM_DS0_SII_DMA_ERROR (1 << 17) /* PCI bus error */
149 #define BM_DS0_SII_DMA_COMPLETE (1 << 18) /* cmd complete / IRQ pending */
152 #define IDX_BM_IO (IDX_IO2_o+IDX_IO2_o_SZ)
153 //#define IDX_BM_IO_SZ sizeof(IDE_BUSMASTER_REGISTERS)
154 #define IDX_BM_IO_SZ 5
156 #define IDX_BM_Command (FIELD_OFFSET(IDE_BUSMASTER_REGISTERS, Command )+IDX_BM_IO)
157 #define IDX_BM_DeviceSpecific0 (FIELD_OFFSET(IDE_BUSMASTER_REGISTERS, DeviceSpecific0)+IDX_BM_IO)
158 #define IDX_BM_Status (FIELD_OFFSET(IDE_BUSMASTER_REGISTERS, Status )+IDX_BM_IO)
159 #define IDX_BM_DeviceSpecific1 (FIELD_OFFSET(IDE_BUSMASTER_REGISTERS, DeviceSpecific1)+IDX_BM_IO)
160 #define IDX_BM_PRD_Table (FIELD_OFFSET(IDE_BUSMASTER_REGISTERS, PRD_Table )+IDX_BM_IO)
162 typedef struct _IDE_AHCI_REGISTERS
{
165 ULONG NOP
:5; // number of ports
166 ULONG SXS
:1; // Supports External SATA
167 ULONG EMS
:1; // Enclosure Management Supported
168 ULONG CCCS
:1; // Command Completion Coalescing Supported
169 ULONG NCS
:5; // number of command slots
170 ULONG PSC
:1; // partial state capable
171 ULONG SSC
:1; // slumber state capable
172 ULONG PMD
:1; // PIO multiple DRQ block
173 ULONG FBSS
:1; // FIS-based Switching Supported
175 ULONG SPM
:1; // port multiplier
176 ULONG SAM
:1; // AHCI mode only
177 ULONG SNZO
:1; // non-zero DMA offset
178 ULONG ISS
:4; // interface speed
179 ULONG SCLO
:1; // command list override
180 ULONG SAL
:1; // activity LED
181 ULONG SALP
:1; // aggressive link power management
182 ULONG SSS
:1; // staggered spin-up
183 ULONG SIS
:1; // interlock switch
184 ULONG SSNTF
:1; // Supports SNotification Register
185 ULONG SNCQ
:1; // native command queue
186 ULONG S64A
:1; // 64bit addr
189 #define AHCI_CAP_NOP_MASK 0x0000001f
190 #define AHCI_CAP_CCC 0x00000080
191 #define AHCI_CAP_NCS_MASK 0x00001f00
192 #define AHCI_CAP_PMD 0x00008000
193 #define AHCI_CAP_SPM 0x00020000
194 #define AHCI_CAP_SAM 0x00040000
195 #define AHCI_CAP_ISS_MASK 0x00f00000
196 #define AHCI_CAP_SCLO 0x01000000
197 #define AHCI_CAP_SNTF 0x20000000
198 #define AHCI_CAP_NCQ 0x40000000
199 #define AHCI_CAP_S64A 0x80000000
201 // Global HBA Control
203 ULONG HR
:1; // HBA Reset
204 ULONG IE
:1; // interrupt enable
205 ULONG Reserved2_30
:1;
206 ULONG AE
:1; // AHCI enable
209 #define AHCI_GHC 0x04
210 #define AHCI_GHC_HR 0x00000001
211 #define AHCI_GHC_IE 0x00000002
212 #define AHCI_GHC_AE 0x80000000
214 // Interrupt status (bit mask)
216 // Ports implemented (bit mask)
221 ULONG CCC_CTL
; // 0x14
222 ULONG CCC_PORTS
; // 0x18
223 ULONG EM_LOC
; // 0x1c
224 ULONG EM_CTL
; // 0x20
226 // Extended HBA Capabilities
228 ULONG BOH
:1; // BIOS/OS Handoff
229 ULONG NVMP
:1; // NVMHCI Present
230 ULONG APST
:1; // Automatic Partial to Slumber Transitions
234 #define AHCI_CAP2_BOH 0x00000001
235 #define AHCI_CAP2_NVMP 0x00000002
236 #define AHCI_CAP2_APST 0x00000004
238 // BIOS/OS Handoff Control and Status
240 ULONG BB
:1; // BIOS Busy
241 ULONG OOC
:1; // OS Ownership Change
242 ULONG SOOE
:1; // SMI on OS Ownership Change Enable
243 ULONG OOS
:1; // OS Owned Semaphore
244 ULONG BOS
:1; // BIOS Owned Semaphore
248 UCHAR Reserved2
[0x74];
250 UCHAR VendorSpec
[0x60];
251 } IDE_AHCI_REGISTERS
, *PIDE_AHCI_REGISTERS
;
253 #define IDX_AHCI_CAP (FIELD_OFFSET(IDE_AHCI_REGISTERS, CAP))
254 #define IDX_AHCI_GHC (FIELD_OFFSET(IDE_AHCI_REGISTERS, GHC))
255 #define IDX_AHCI_IS (FIELD_OFFSET(IDE_AHCI_REGISTERS, IS))
256 #define IDX_AHCI_VS (FIELD_OFFSET(IDE_AHCI_REGISTERS, VS))
257 #define IDX_AHCI_PI (FIELD_OFFSET(IDE_AHCI_REGISTERS, PI))
258 #define IDX_AHCI_CAP2 (FIELD_OFFSET(IDE_AHCI_REGISTERS, CAP2))
259 #define IDX_AHCI_BOHC (FIELD_OFFSET(IDE_AHCI_REGISTERS, BOHC))
262 typedef union _SATA_SSTATUS_REG
{
265 ULONG DET
:4; // Device Detection
267 #define SStatus_DET_NoDev 0x00
268 #define SStatus_DET_Dev_NoPhy 0x01
269 #define SStatus_DET_Dev_Ok 0x03
270 #define SStatus_DET_Offline 0x04
272 ULONG SPD
:4; // Current Interface Speed
274 #define SStatus_SPD_NoDev 0x00
275 #define SStatus_SPD_Gen1 0x01
276 #define SStatus_SPD_Gen2 0x02
277 #define SStatus_SPD_Gen3 0x03
279 ULONG IPM
:4; // Interface Power Management
281 #define SStatus_IPM_NoDev 0x00
282 #define SStatus_IPM_Active 0x01
283 #define SStatus_IPM_Partial 0x02
284 #define SStatus_IPM_Slumber 0x06
290 } SATA_SSTATUS_REG
, *PSATA_SSTATUS_REG
;
293 typedef union _SATA_SCONTROL_REG
{
296 ULONG DET
:4; // Device Detection Init
298 #define SControl_DET_DoNothing 0x00
299 #define SControl_DET_Idle 0x00
300 #define SControl_DET_Init 0x01
301 #define SControl_DET_Disable 0x04
303 ULONG SPD
:4; // Speed Allowed
305 #define SControl_SPD_NoRestrict 0x00
306 #define SControl_SPD_LimGen1 0x01
307 #define SControl_SPD_LimGen2 0x02
308 #define SControl_SPD_LimGen3 0x03
310 ULONG IPM
:4; // Interface Power Management Transitions Allowed
312 #define SControl_IPM_NoRestrict 0x00
313 #define SControl_IPM_NoPartial 0x01
314 #define SControl_IPM_NoSlumber 0x02
315 #define SControl_IPM_NoPartialSlumber 0x03
317 ULONG SPM
:4; // Select Power Management, unused by AHCI
318 ULONG PMP
:4; // Port Multiplier Port, unused by AHCI
323 } SATA_SCONTROL_REG
, *PSATA_SCONTROL_REG
;
326 typedef union _SATA_SERROR_REG
{
330 UCHAR I
:1; // Recovered Data Integrity Error
331 UCHAR M
:1; // Recovered Communications Error
332 UCHAR Reserved_2_7
:6;
334 UCHAR T
:1; // Transient Data Integrity Error
335 UCHAR C
:1; // Persistent Communication or Data Integrity Error
336 UCHAR P
:1; // Protocol Error
337 UCHAR E
:1; // Internal Error
338 UCHAR Reserved_12_15
:4;
342 UCHAR N
:1; // PhyRdy Change, PIS.PRCS
343 UCHAR I
:1; // Phy Internal Error
344 UCHAR W
:1; // Comm Wake
345 UCHAR B
:1; // 10B to 8B Decode Error
346 UCHAR D
:1; // Disparity Error, not used by AHCI
347 UCHAR C
:1; // CRC Error
348 UCHAR H
:1; // Handshake Error
349 UCHAR S
:1; // Link Sequence Error
351 UCHAR T
:1; // Transport state transition error
352 UCHAR F
:1; // Unknown FIS Type
353 UCHAR X
:1; // Exchanged
354 UCHAR Reserved_27_31
:5;
359 } SATA_SERROR_REG
, *PSATA_SERROR_REG
;
362 typedef struct _IDE_SATA_REGISTERS
{
364 SATA_SSTATUS_REG SStatus
;
368 SATA_SERROR_REG SError
;
372 SATA_SCONTROL_REG SControl
;
382 USHORT PMN
; // PM Notify, bitmask
387 } IDE_SATA_REGISTERS
, *PIDE_SATA_REGISTERS
;
389 #define IDX_SATA_IO (IDX_BM_IO+IDX_BM_IO_SZ)
390 //#define IDX_SATA_IO_SZ sizeof(IDE_SATA_REGISTERS)
391 #define IDX_SATA_IO_SZ 5
393 #define IDX_SATA_SStatus (0+IDX_SATA_IO)
394 #define IDX_SATA_SError (1+IDX_SATA_IO)
395 #define IDX_SATA_SControl (2+IDX_SATA_IO)
396 #define IDX_SATA_SActive (3+IDX_SATA_IO)
397 #define IDX_SATA_SNTF_PMN (4+IDX_SATA_IO)
399 #define IDX_INDEXED_IO (IDX_SATA_IO+IDX_SATA_IO_SZ)
400 #define IDX_INDEXED_IO_SZ 2
402 #define IDX_INDEXED_ADDR (0+IDX_INDEXED_IO)
403 #define IDX_INDEXED_DATA (1+IDX_INDEXED_IO)
405 #define IDX_MAX_REG (IDX_INDEXED_IO+IDX_INDEXED_IO_SZ)
408 typedef union _AHCI_IS_REG
{
410 ULONG DHRS
:1;// Device to Host Register FIS Interrupt
411 ULONG PSS
:1; // PIO Setup FIS Interrupt
412 ULONG DSS
:1; // DMA Setup FIS Interrupt
413 ULONG SDBS
:1;// Set Device Bits Interrupt
414 ULONG UFS
:1; // Unknown FIS Interrupt
415 ULONG DPS
:1; // Descriptor Processed
416 ULONG PCS
:1; // Port Connect Change Status
417 ULONG DMPS
:1;// Device Mechanical Presence Status
419 ULONG Reserved_8_21
:14;
420 ULONG PRCS
:1;// PhyRdy Change Status
421 ULONG IPMS
:1;// Incorrect Port Multiplier Status
423 ULONG OFS
:1; // Overflow Status
425 ULONG INFS
:1;// Interface Non-fatal Error Status
426 ULONG IFS
:1; // Interface Fatal Error Status
427 ULONG HBDS
:1;// Host Bus Data Error Status
428 ULONG HBFS
:1;// Host Bus Fatal Error Status
429 ULONG TFES
:1;// Task File Error Status
430 ULONG CPDS
:1;// Cold Port Detect Status
433 } AHCI_IS_REG
, *PAHCI_IS_REG
;
435 #define ATA_AHCI_P_IX_DHR 0x00000001
436 #define ATA_AHCI_P_IX_PS 0x00000002
437 #define ATA_AHCI_P_IX_DS 0x00000004
438 #define ATA_AHCI_P_IX_SDB 0x00000008
439 #define ATA_AHCI_P_IX_UF 0x00000010
440 #define ATA_AHCI_P_IX_DP 0x00000020
441 #define ATA_AHCI_P_IX_PC 0x00000040
442 #define ATA_AHCI_P_IX_DI 0x00000080
444 #define ATA_AHCI_P_IX_PRC 0x00400000
445 #define ATA_AHCI_P_IX_IPM 0x00800000
446 #define ATA_AHCI_P_IX_OF 0x01000000
447 #define ATA_AHCI_P_IX_INF 0x04000000
448 #define ATA_AHCI_P_IX_IF 0x08000000
449 #define ATA_AHCI_P_IX_HBD 0x10000000
450 #define ATA_AHCI_P_IX_HBF 0x20000000
451 #define ATA_AHCI_P_IX_TFE 0x40000000
452 #define ATA_AHCI_P_IX_CPD 0x80000000
454 #define AHCI_CLB_ALIGNEMENT_MASK ((ULONGLONG)(1024-1))
455 #define AHCI_FIS_ALIGNEMENT_MASK ((ULONGLONG)(256-1))
456 #define AHCI_CMD_ALIGNEMENT_MASK ((ULONGLONG)(128-1))
458 typedef struct _IDE_AHCI_PORT_REGISTERS
{
461 ULONG CLB
; // command list base address, 1K-aligned
462 ULONG CLBU
; // command list base address (upper 32bits)
465 }; // 0x100 + 0x80*c + 0x0000
469 ULONG FB
; // FIS base address
470 ULONG FBU
; // FIS base address (upper 32bits)
473 }; // 0x100 + 0x80*c + 0x0008
476 ULONG IS_Reg
; // interrupt status
478 }; // 0x100 + 0x80*c + 0x0010
481 ULONG Reg
; // interrupt enable
483 ULONG DHRE
:1;// Device to Host Register FIS Interrupt Enable
484 ULONG PSE
:1; // PIO Setup FIS Interrupt Enable
485 ULONG DSE
:1; // DMA Setup FIS Interrupt Enable
486 ULONG SDBE
:1;// Set Device Bits FIS Interrupt Enable
487 ULONG UFE
:1; // Unknown FIS Interrupt Enable
488 ULONG DPE
:1; // Descriptor Processed Interrupt Enable
489 ULONG PCE
:1; // Port Change Interrupt Enable
490 ULONG DPME
:1;// Device Mechanical Presence Enable
492 ULONG Reserved_8_21
:14;
493 ULONG PRCE
:1;// PhyRdy Change Interrupt Enable
494 ULONG IPME
:1;// Incorrect Port Multiplier Enable
495 ULONG OFE
:1; // Overflow Enable
497 ULONG INFE
:1;// Interface Non-fatal Error Enable
498 ULONG IFE
:1; // Interface Fatal Error Enable
499 ULONG HBDE
:1;// Host Bus Data Error Enable
500 ULONG HBFE
:1;// Host Bus Fatal Error Enable
501 ULONG TFEE
:1;// Task File Error Enable
502 ULONG CPDE
:1;// Cold Port Detect Enable
504 } IE
; // 0x100 + 0x80*c + 0x0014
507 ULONG Reg
; // command register
511 ULONG SUD
:1; // Spin-Up Device
512 ULONG POD
:1; // Power On Device
513 ULONG CLO
:1; // Command List Override
514 ULONG FRE
:1; // FIS Receive Enable
515 ULONG Reserved_5_7
:3;
517 ULONG CCS
:5; // Current Command Slot
518 ULONG MPSS
:1;// Mechanical Presence Switch State
519 ULONG FR
:1; // FIS Receive Running
520 ULONG CR
:1; // Command List Running
522 ULONG CPS
:1; // Cold Presence State
523 ULONG PMA
:1; // Port Multiplier Attached
524 ULONG HPCP
:1;// Hot Plug Capable Port
525 ULONG MPSP
:1;// Mechanical Presence Switch Attached to Port
526 ULONG CPD
:1; // Cold Presence Detection
527 ULONG ESP
:1; // External SATA Port
528 ULONG Reserved_22_23
:2;
530 ULONG ATAPI
:1; // Device is ATAPI
531 ULONG DLAE
:1;// Drive LED on ATAPI Enable
532 ULONG ALPE
:1;// Aggressive Link Power Management Enable
533 ULONG ASP
:1; // Aggressive Slumber / Partial
534 ULONG ICC
:4; // Interface Communication Control
536 #define SATA_CMD_ICC_Idle 0x00
537 #define SATA_CMD_ICC_NoOp 0x00
538 #define SATA_CMD_ICC_Active 0x01
539 #define SATA_CMD_ICC_Partial 0x02
540 #define SATA_CMD_ICC_Slumber 0x06
542 } CMD
; // 0x100 + 0x80*c + 0x0018
547 ULONG Reg
; // Task File Data
551 UCHAR cs1
:2;// command-specific
553 UCHAR cs2
:3;// command-specific
556 UCHAR ERR
; // Contains the latest copy of the task file error register.
559 } TFD
; // 0x100 + 0x80*c + 0x0020
562 ULONG Reg
; // signature
569 } SIG
; // 0x100 + 0x80*c + 0x0024
571 ULONG SStatus
; // SCR0
572 SATA_SSTATUS_REG SSTS
;
573 }; // 0x100 + 0x80*c + 0x0028
575 ULONG SControl
; // SCR2
576 SATA_SCONTROL_REG SCTL
;
577 }; // 0x100 + 0x80*c + 0x002c
579 ULONG SError
; // SCR1
580 SATA_SERROR_REG SERR
;
581 }; // 0x100 + 0x80*c + 0x0030
584 ULONG SActive
; // bitmask
585 }; // 0x100 + 0x80*c + 0x0034
587 ULONG CI
; // Command issue, bitmask, 0x100 + 0x80*c + 0x0038
593 USHORT PMN
; // PM Notify, bitmask
596 } SNTF
; // 0x100 + 0x80*c + 0x003c
602 ULONG EN
:1; // Enable
603 ULONG DEC
:1; // Device Error Clear
604 ULONG SDE
:1; // Single Device Error
605 ULONG Reserved_3_7
:5; // Reserved
606 ULONG DEV
:4; // Device To Issue
607 ULONG ADO
:4; // Active Device Optimization (recommended parallelism)
608 ULONG DWE
:4; // Device With Error
609 ULONG Reserved_20_31
:12; // Reserved
611 } FBS
; // 0x100 + 0x80*c + 0x0040
613 ULONG Reserved_44_7f
[11];
614 UCHAR VendorSpec
[16];
616 } IDE_AHCI_PORT_REGISTERS
, *PIDE_AHCI_PORT_REGISTERS
;
618 #define IDX_AHCI_P_CLB (FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, CLB))
619 #define IDX_AHCI_P_FB (FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, FB))
620 #define IDX_AHCI_P_IS (FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, IS))
621 #define IDX_AHCI_P_IE (FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, IE))
622 #define IDX_AHCI_P_CI (FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, CI))
623 #define IDX_AHCI_P_TFD (FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, TFD))
624 #define IDX_AHCI_P_SIG (FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, SIG))
625 #define IDX_AHCI_P_CMD (FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, CMD))
626 #define IDX_AHCI_P_ACT (FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, SACT))
628 #define IDX_AHCI_P_SNTF (FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, SNTF))
630 // AHCI commands ( -> IDX_AHCI_P_CMD)
631 #define ATA_AHCI_P_CMD_ST 0x00000001
632 #define ATA_AHCI_P_CMD_SUD 0x00000002
633 #define ATA_AHCI_P_CMD_POD 0x00000004
634 #define ATA_AHCI_P_CMD_CLO 0x00000008
635 #define ATA_AHCI_P_CMD_FRE 0x00000010
636 #define ATA_AHCI_P_CMD_CCS_MASK 0x00001f00
637 #define ATA_AHCI_P_CMD_ISS 0x00002000
638 #define ATA_AHCI_P_CMD_FR 0x00004000
639 #define ATA_AHCI_P_CMD_CR 0x00008000
640 #define ATA_AHCI_P_CMD_CPS 0x00010000
641 #define ATA_AHCI_P_CMD_PMA 0x00020000
642 #define ATA_AHCI_P_CMD_HPCP 0x00040000
643 #define ATA_AHCI_P_CMD_ISP 0x00080000
644 #define ATA_AHCI_P_CMD_CPD 0x00100000
645 #define ATA_AHCI_P_CMD_ATAPI 0x01000000
646 #define ATA_AHCI_P_CMD_DLAE 0x02000000
647 #define ATA_AHCI_P_CMD_ALPE 0x04000000
648 #define ATA_AHCI_P_CMD_ASP 0x08000000
649 #define ATA_AHCI_P_CMD_ICC_MASK 0xf0000000
650 #define ATA_AHCI_P_CMD_NOOP 0x00000000
651 #define ATA_AHCI_P_CMD_ACTIVE 0x10000000
652 #define ATA_AHCI_P_CMD_PARTIAL 0x20000000
653 #define ATA_AHCI_P_CMD_SLUMBER 0x60000000
656 typedef struct _IDE_AHCI_PRD_ENTRY
{
679 } IDE_AHCI_PRD_ENTRY
, *PIDE_AHCI_PRD_ENTRY
;
681 #define ATA_AHCI_DMA_ENTRIES (PAGE_SIZE/2/sizeof(IDE_AHCI_PRD_ENTRY)) /* 128 */
682 #define ATA_AHCI_MAX_TAGS 32
684 #define AHCI_FIS_TYPE_ATA_H2D 0x27
685 #define AHCI_FIS_TYPE_ATA_D2H 0x34
686 #define AHCI_FIS_TYPE_DMA_D2H 0x39
687 #define AHCI_FIS_TYPE_DMA_BiDi 0x41
688 #define AHCI_FIS_TYPE_DATA_BiDi 0x46
689 #define AHCI_FIS_TYPE_BIST_BiDi 0x58
690 #define AHCI_FIS_TYPE_PIO_D2H 0x5f
691 #define AHCI_FIS_TYPE_DEV_BITS_D2H 0xA1
693 typedef struct _AHCI_ATA_H2D_FIS
{
694 UCHAR FIS_Type
; // = 0x27
696 UCHAR Cmd
:1; // update Command register
697 UCHAR Command
; // [2]
698 UCHAR Feature
; // [3]
700 UCHAR BlockNumber
; // [4]
701 UCHAR CylinderLow
; // [5]
702 UCHAR CylinderHigh
; // [6]
703 UCHAR DriveSelect
; // [7]
705 UCHAR BlockNumberExp
; // [8]
706 UCHAR CylinderLowExp
; // [9]
707 UCHAR CylinderHighExp
; // [10]
708 UCHAR FeatureExp
; // [11]
710 UCHAR BlockCount
; // [12]
711 UCHAR BlockCountExp
; // [13]
712 UCHAR Reserved14
; // [14]
713 UCHAR Control
; // [15]
715 } AHCI_ATA_H2D_FIS
, *PAHCI_ATA_H2D_FIS
;
717 #define IDX_AHCI_o_Command (FIELD_OFFSET(AHCI_ATA_H2D_FIS, Command))
718 #define IDX_AHCI_o_Feature (FIELD_OFFSET(AHCI_ATA_H2D_FIS, Feature))
719 #define IDX_AHCI_o_BlockNumber (FIELD_OFFSET(AHCI_ATA_H2D_FIS, BlockNumber ))
720 #define IDX_AHCI_o_CylinderLow (FIELD_OFFSET(AHCI_ATA_H2D_FIS, CylinderLow ))
721 #define IDX_AHCI_o_CylinderHigh (FIELD_OFFSET(AHCI_ATA_H2D_FIS, CylinderHigh))
722 #define IDX_AHCI_o_DriveSelect (FIELD_OFFSET(AHCI_ATA_H2D_FIS, DriveSelect ))
723 #define IDX_AHCI_o_BlockCount (FIELD_OFFSET(AHCI_ATA_H2D_FIS, BlockCount))
724 #define IDX_AHCI_o_Control (FIELD_OFFSET(AHCI_ATA_H2D_FIS, Control))
725 #define IDX_AHCI_o_FeatureExp (FIELD_OFFSET(AHCI_ATA_H2D_FIS, FeatureExp))
726 #define IDX_AHCI_o_BlockNumberExp (FIELD_OFFSET(AHCI_ATA_H2D_FIS, BlockNumberExp ))
727 #define IDX_AHCI_o_CylinderLowExp (FIELD_OFFSET(AHCI_ATA_H2D_FIS, CylinderLowExp ))
728 #define IDX_AHCI_o_CylinderHighExp (FIELD_OFFSET(AHCI_ATA_H2D_FIS, CylinderHighExp))
729 #define IDX_AHCI_o_BlockCountExp (FIELD_OFFSET(AHCI_ATA_H2D_FIS, BlockCountExp))
731 #define AHCI_FIS_COMM_PM (0x80 | AHCI_DEV_SEL_PM)
733 #define AHCI_DEV_SEL_1 0x00
734 #define AHCI_DEV_SEL_2 0x01
735 #define AHCI_DEV_SEL_PM 0x0f
737 /* 128-byte aligned */
738 typedef struct _IDE_AHCI_CMD
{
742 IDE_AHCI_PRD_ENTRY prd_tab
[ATA_AHCI_DMA_ENTRIES
]; // also 128-byte aligned
743 } IDE_AHCI_CMD
, *PIDE_AHCI_CMD
;
747 #define ATA_AHCI_CMD_ATAPI 0x0020
748 #define ATA_AHCI_CMD_WRITE 0x0040
749 #define ATA_AHCI_CMD_PREFETCH 0x0080
750 #define ATA_AHCI_CMD_RESET 0x0100
751 #define ATA_AHCI_CMD_BIST 0x0200
752 #define ATA_AHCI_CMD_CLR_BUSY 0x0400
754 /* 128-byte aligned */
755 typedef struct _IDE_AHCI_CMD_LIST
{
757 USHORT prd_length
; /* PRD entries */
759 ULONGLONG cmd_table_phys
; /* points to IDE_AHCI_CMD */
761 } IDE_AHCI_CMD_LIST
, *PIDE_AHCI_CMD_LIST
;
763 /* 256-byte aligned */
764 typedef struct _IDE_AHCI_RCV_FIS
{
774 } IDE_AHCI_RCV_FIS
, *PIDE_AHCI_RCV_FIS
;
776 /* 1K-byte aligned */
777 typedef struct _IDE_AHCI_CHANNEL_CTL_BLOCK
{
778 IDE_AHCI_CMD_LIST cmd_list
[ATA_AHCI_MAX_TAGS
]; // 1K-size (32*32)
779 IDE_AHCI_RCV_FIS rcv_fis
;
780 IDE_AHCI_CMD cmd
; // for single internal commands w/o associated AtaReq
781 } IDE_AHCI_CHANNEL_CTL_BLOCK
, *PIDE_AHCI_CHANNEL_CTL_BLOCK
;
784 #define IsBusMaster(pciData) \
785 ( ((pciData)->Command & (PCI_ENABLE_BUS_MASTER/* | PCI_ENABLE_IO_SPACE*/)) == \
786 (PCI_ENABLE_BUS_MASTER/* | PCI_ENABLE_IO_SPACE*/))
788 #define PCI_IDE_PROGIF_NATIVE_1 0x01
789 #define PCI_IDE_PROGIF_NATIVE_2 0x04
790 #define PCI_IDE_PROGIF_NATIVE_ALL 0x05
792 #define IsMasterDev(pciData) \
793 ( ((pciData)->ProgIf & 0x80) && \
794 ((pciData)->ProgIf & PCI_IDE_PROGIF_NATIVE_ALL) != PCI_IDE_PROGIF_NATIVE_ALL )
796 //#define INT_Q_SIZE 32
797 #define MIN_REQ_TTL 4
801 typedef union _ATA_REQ
{
802 // ULONG reqId; // serial
808 union _ATA_REQ
* next_req
;
809 union _ATA_REQ
* prev_req
;
811 PSCSI_REQUEST_BLOCK Srb
; // Current request on controller.
813 PUSHORT DataBuffer
; // Data buffer pointer.
814 ULONG WordsLeft
; // Data words left.
815 ULONG TransferLength
; // Originally requested transfer length
817 ULONG WordsTransfered
;// Data words already transfered.
826 PSCSI_REQUEST_BLOCK OriginalSrb
; // Mechanism Status Srb Data
837 ULONGLONG ahci_base64
;
839 PIDE_AHCI_CMD ahci_cmd_ptr
;
842 USHORT io_cmd_flags
; // out
847 //UCHAR padding_128b[128]; // Note: we assume, NT allocates block > 4k as PAGE-aligned
851 BM_DMA_ENTRY dma_tab
[ATA_DMA_ENTRIES
];
852 IDE_AHCI_CMD ahci_cmd0
; // for AHCI, 128-byte aligned
857 UCHAR padding_4kb
[PAGE_SIZE
];
859 } ATA_REQ
, *PATA_REQ
;
861 #define REQ_FLAG_FORCE_DOWNRATE 0x01
862 #define REQ_FLAG_DMA_OPERATION 0x02
863 #define REQ_FLAG_REORDERABLE_CMD 0x04
864 #define REQ_FLAG_RW_MASK 0x08
865 #define REQ_FLAG_READ 0x08
866 #define REQ_FLAG_WRITE 0x00
867 #define REQ_FLAG_FORCE_DOWNRATE_LBA48 0x10
868 #define REQ_FLAG_DMA_DBUF 0x20
869 #define REQ_FLAG_DMA_DBUF_PRD 0x40
870 #define REQ_FLAG_LBA48 0x80
873 #define REQ_STATE_NONE 0x00
874 #define REQ_STATE_QUEUED 0x10
876 #define REQ_STATE_PREPARE_TO_TRANSFER 0x20
877 #define REQ_STATE_PREPARE_TO_NEXT 0x21
878 #define REQ_STATE_READY_TO_TRANSFER 0x30
880 #define REQ_STATE_EXPECTING_INTR 0x40
881 #define REQ_STATE_ATAPI_EXPECTING_CMD_INTR 0x41
882 #define REQ_STATE_ATAPI_EXPECTING_DATA_INTR 0x42
883 #define REQ_STATE_ATAPI_EXPECTING_DATA_INTR2 0x43
884 #define REQ_STATE_ATAPI_DO_NOTHING_INTR 0x44
886 #define REQ_STATE_EARLY_INTR 0x48
888 #define REQ_STATE_PROCESSING_INTR 0x50
890 #define REQ_STATE_DPC_INTR_REQ 0x51
891 #define REQ_STATE_DPC_RESET_REQ 0x52
892 #define REQ_STATE_DPC_COMPLETE_REQ 0x53
894 #define REQ_STATE_DPC_WAIT_BUSY0 0x57
895 #define REQ_STATE_DPC_WAIT_BUSY1 0x58
896 #define REQ_STATE_DPC_WAIT_BUSY 0x59
897 #define REQ_STATE_DPC_WAIT_DRQ 0x5a
898 #define REQ_STATE_DPC_WAIT_DRQ0 0x5b
899 #define REQ_STATE_DPC_WAIT_DRQ_ERR 0x5c
901 #define REQ_STATE_TRANSFER_COMPLETE 0x7f
904 #define CMD_ACTION_PREPARE 0x01
905 #define CMD_ACTION_EXEC 0x02
906 #define CMD_ACTION_ALL (CMD_ACTION_PREPARE | CMD_ACTION_EXEC)
908 // predefined Reorder costs
909 #define REORDER_COST_MAX ((DEF_I64(0x1) << 60) - 1)
910 #define REORDER_COST_TTL (REORDER_COST_MAX - 1)
911 #define REORDER_COST_INTERSECT (REORDER_COST_MAX - 2)
912 #define REORDER_COST_DENIED (REORDER_COST_MAX - 3)
913 #define REORDER_COST_RESELECT (REORDER_COST_MAX/4)
915 #define REORDER_COST_SWITCH_RW_CD (REORDER_COST_MAX/8)
916 #define REORDER_MCOST_SWITCH_RW_CD (0)
917 #define REORDER_MCOST_SEEK_BACK_CD (16)
919 #define REORDER_COST_SWITCH_RW_HDD (0)
920 #define REORDER_MCOST_SWITCH_RW_HDD (4)
921 #define REORDER_MCOST_SEEK_BACK_HDD (2)
923 /*typedef struct _ATA_QUEUE {
924 struct _ATA_REQ* head_req; // index
925 struct _ATA_REQ* tail_req; // index
928 BM_DMA_ENTRY dma_tab[ATA_DMA_ENTRIES];
929 } ATA_QUEUE, *PATA_QUEUE;*/
931 struct _HW_DEVICE_EXTENSION
;
932 struct _HW_LU_EXTENSION
;
934 typedef struct _IORES
{
936 ULONG Addr
; /* Base address*/
937 PVOID pAddr
; /* Base address in pointer form */
939 ULONG MemIo
:1; /* Memory mapping (1) vs IO ports (0) */
940 ULONG Proc
:1; /* Need special processing via IO_Proc */
945 typedef struct _HW_CHANNEL
{
949 /* PATA_REQ first_req;
952 ULONG ChannelSelectWaitCount
;
956 BOOLEAN ExpectingInterrupt
; // Indicates expecting an interrupt
957 BOOLEAN RDP
; // Indicate last tape command was DSC Restrictive.
958 // Indicates whether '0x1f0' is the base address. Used
959 // in SMART Ioctl calls.
960 BOOLEAN PrimaryAddress
;
961 // Placeholder for the sub-command value of the last
966 // Placeholder for status register after a GET_MEDIA_STATUS command
967 UCHAR ReturningMediaStatus
;
969 BOOLEAN CopyDmaBuffer
;
975 MECHANICAL_STATUS_INFORMATION_HEADER MechStatusData
;
976 SENSE_DATA MechStatusSense
;
977 ULONG MechStatusRetryCount
;
978 SCSI_REQUEST_BLOCK InternalSrb
;
980 ULONG MaxTransferMode
; // may differ from Controller's value due to 40-pin cable
982 ULONG ChannelCtrlFlags
;
983 ULONG ResetInProgress
; // flag
989 #define CHECK_INTR_ACTIVE 0x03
990 #define CHECK_INTR_DETECTED 0x02
991 #define CHECK_INTR_CHECK 0x01
992 #define CHECK_INTR_IDLE 0x00
995 PHW_TIMER HwScsiTimer
;
998 PHW_TIMER HwScsiTimer1
;
999 PHW_TIMER HwScsiTimer2
;
1001 // PHW_TIMER CurDpc;
1002 // LARGE_INTEGER ActivationTime;
1006 // PHW_TIMER HwScsiTimer;
1007 // KSPIN_LOCK QueueSpinLock;
1008 // KIRQL QueueOldIrql;
1010 struct _HW_DEVICE_EXTENSION
* DeviceExtension
;
1011 struct _HW_LU_EXTENSION
* lun
[IDE_MAX_LUN_PER_CHAN
];
1016 // Double-buffering support
1018 ULONG DB_PRD_PhAddr
;
1025 PIDE_AHCI_CHANNEL_CTL_BLOCK AhciCtlBlock0
; // unaligned
1026 PIDE_AHCI_CHANNEL_CTL_BLOCK AhciCtlBlock
; // 128-byte aligned
1027 ULONGLONG AHCI_CTL_PhAddr
;
1028 IORES BaseIoAHCI_Port
;
1030 ULONG AhciCompleteCI
;
1032 //PVOID AHCI_FIS; // is not actually used by UniATA now, but is required by AHCI controller
1033 //ULONGLONG AHCI_FIS_PhAddr;
1034 // Note: in contrast to FBSD, we keep PRD and CMD item in AtaReq structure
1035 PATA_REQ AhciInternalAtaReq
;
1036 PSCSI_REQUEST_BLOCK AhciInternalSrb
;
1038 #ifdef QUEUE_STATISTICS
1039 LONGLONG QueueStat
[MAX_QUEUE_STAT
];
1040 LONGLONG ReorderCount
;
1041 LONGLONG IntersectCount
;
1042 LONGLONG TryReorderCount
;
1043 LONGLONG TryReorderHeadCount
;
1044 LONGLONG TryReorderTailCount
; /* in-order requests */
1045 #endif //QUEUE_STATISTICS
1047 //ULONG BaseMemAddress;
1048 //ULONG BaseMemAddressOffset;
1049 IORES RegTranslation
[IDX_MAX_REG
];
1051 } HW_CHANNEL
, *PHW_CHANNEL
;
1053 #define CTRFLAGS_DMA_ACTIVE 0x0001
1054 #define CTRFLAGS_DMA_RO 0x0002
1055 #define CTRFLAGS_DMA_OPERATION 0x0004
1056 #define CTRFLAGS_INTR_DISABLED 0x0008
1057 #define CTRFLAGS_DPC_REQ 0x0010
1058 #define CTRFLAGS_ENABLE_INTR_REQ 0x0020
1059 #define CTRFLAGS_LBA48 0x0040
1060 #define CTRFLAGS_DSC_BSY 0x0080
1061 #define CTRFLAGS_NO_SLAVE 0x0100
1062 //#define CTRFLAGS_PATA 0x0200
1063 #define CTRFLAGS_AHCI_PM 0x0400
1064 #define CTRFLAGS_AHCI_PM2 0x0800
1066 #define CTRFLAGS_PERMANENT (CTRFLAGS_DMA_RO | CTRFLAGS_NO_SLAVE)
1068 #define GEOM_AUTO 0xffffffff
1069 #define GEOM_STD 0x0000
1070 #define GEOM_UNIATA 0x0001
1071 #define GEOM_ORIG 0x0002
1072 #define GEOM_MANUAL 0x0003
1074 #define DPC_STATE_NONE 0x00
1075 #define DPC_STATE_ISR 0x10
1076 #define DPC_STATE_DPC 0x20
1077 #define DPC_STATE_TIMER 0x30
1078 #define DPC_STATE_COMPLETE 0x40
1080 // Logical unit extension
1081 typedef struct _HW_LU_EXTENSION
{
1082 IDENTIFY_DATA2 IdentifyData
;
1083 ULONGLONG NumOfSectors
;
1084 ULONG DeviceFlags
; // Flags word for each possible device. DFLAGS_XXX
1085 ULONG DiscsPresent
; // Indicates number of platters on changer-ish devices.
1086 BOOLEAN DWordIO
; // Indicates use of 32-bit PIO
1087 UCHAR ReturningMediaStatus
;
1089 UCHAR TransferMode
; // current transfer mode
1090 UCHAR LimitedTransferMode
; // user-defined or IDE cable limitation
1091 UCHAR OrigTransferMode
; // transfer mode, returned by device IDENTIFY (can be changed via IOCTL)
1093 UCHAR MaximumBlockXfer
;
1094 UCHAR Padding0
[2]; // padding
1095 ULONG ErrorCount
; // Count of errors. Used to turn off features.
1096 // ATA_QUEUE cmd_queue;
1097 LONGLONG ReadCmdCost
;
1098 LONGLONG WriteCmdCost
;
1099 LONGLONG OtherCmdCost
;
1100 LONGLONG RwSwitchCost
;
1101 LONGLONG RwSwitchMCost
;
1102 LONGLONG SeekBackMCost
;
1109 ULONG LunSelectWaitCount
;
1110 ULONG AtapiReadyWaitDelay
;
1114 ULONG opt_MaxTransferMode
;
1115 ULONG opt_PreferedTransferMode
;
1116 BOOLEAN opt_ReadCacheEnable
;
1117 BOOLEAN opt_WriteCacheEnable
;
1120 BOOLEAN opt_reserved
[1];
1122 struct _SBadBlockListItem
* bbListDescr
;
1123 struct _SBadBlockRange
* arrBadBlocks
;
1126 // Controller-specific LUN options
1128 /* for tricky controllers, those can change Logical-to-Physical LUN mapping.
1129 mainly for mapping SATA ports to compatible PATA registers
1130 Treated as PHYSICAL port number, regardless of logical mapping.
1135 struct _HW_DEVICE_EXTENSION
* DeviceExtension
;
1136 struct _HW_CHANNEL
* chan
;
1139 #ifdef IO_STATISTICS
1141 LONGLONG ModeErrorCount
[MAX_RETRIES
];
1142 LONGLONG RecoverCount
[MAX_RETRIES
];
1144 LONGLONG BlockIoCount
;
1146 #endif//IO_STATISTICS
1147 } HW_LU_EXTENSION
, *PHW_LU_EXTENSION
;
1150 typedef struct _HW_DEVICE_EXTENSION
{
1152 //PIDE_REGISTERS_1 BaseIoAddress1[IDE_MAX_CHAN]; // Base register locations
1153 //PIDE_REGISTERS_2 BaseIoAddress2[IDE_MAX_CHAN];
1154 ULONG BusInterruptLevel
; // Interrupt level
1155 ULONG InterruptMode
; // Interrupt Mode (Level or Edge)
1156 ULONG BusInterruptVector
;
1157 // Number of channels being supported by one instantiation
1158 // of the device extension. Normally (and correctly) one, but
1159 // with so many broken PCI IDE controllers being sold, we have
1161 ULONG NumberChannels
;
1163 ULONG FirstChannelToCheck
;
1165 HW_LU_EXTENSION lun
[IDE_MAX_LUN
];
1166 HW_CHANNEL chan
[AHCI_MAX_PORT
/*IDE_MAX_CHAN*/];
1168 PHW_LU_EXTENSION lun
; // lun array
1169 PHW_CHANNEL chan
; // channel array
1171 UCHAR LastInterruptedChannel
;
1172 // Indicates the number of blocks transferred per int. according to the
1174 BOOLEAN DriverMustPoll
; // Driver is being used by the crash dump utility or ntldr.
1176 BOOLEAN UseDpc
; // Indicates use of DPC on long waits
1177 IDENTIFY_DATA FullIdentifyData
; // Identify data for device
1178 // BusMaster specific data
1179 // PBM_DMA_ENTRY dma_tab_0;
1180 //KSPIN_LOCK DpcSpinLock;
1182 ULONG ActiveDpcChan
;
1184 ULONG ExpectingInterrupt
; // Indicates entire controller expecting an interrupt
1186 PHW_TIMER HwScsiTimer1;
1187 PHW_TIMER HwScsiTimer2;
1193 PDEVICE_OBJECT Isr2DevObj
;
1195 //PIDE_BUSMASTER_REGISTERS BaseIoAddressBM_0;
1196 IORES BaseIoAddressBM_0
;
1197 //PIDE_BUSMASTER_REGISTERS BaseIoAddressBM[IDE_MAX_CHAN];
1199 // Device identification
1203 ULONG SystemIoBusNumber
;
1206 ULONG InitMethod
; // vendor specific
1211 BOOLEAN simplexOnly
;
1217 BOOLEAN DWordIO
; // Indicates use of 32-bit PIO
1222 ULONG MaxTransferMode
; // max transfer mode supported by controller
1224 INTERFACE_TYPE OrigAdapterInterfaceType
;
1225 INTERFACE_TYPE AdapterInterfaceType
;
1226 ULONG MaximumDmaTransferLength
;
1227 ULONG AlignmentMask
;
1228 ULONG DmaSegmentLength
;
1229 ULONG DmaSegmentAlignmentMask
; // must be PAGE-aligned
1231 //ULONG BaseMemAddress;
1233 //PIDE_SATA_REGISTERS BaseIoAddressSATA_0;
1234 IORES BaseIoAddressSATA_0
;
1235 //PIDE_SATA_REGISTERS BaseIoAddressSATA[IDE_MAX_CHAN];
1238 //PIDE_AHCI_PORT_REGISTERS BaseIoAHCIPort[AHCI_MAX_PORT];
1240 PATA_REQ AhciInternalAtaReq0
;
1241 PSCSI_REQUEST_BLOCK AhciInternalSrb0
;
1243 BOOLEAN opt_AtapiDmaZeroTransfer
; // default FALSE
1244 BOOLEAN opt_AtapiDmaControlCmd
; // default FALSE
1245 BOOLEAN opt_AtapiDmaRawRead
; // default TRUE
1246 BOOLEAN opt_AtapiDmaReadWrite
; // default TRUE
1250 // Controller specific state/options
1255 } HW_DEVICE_EXTENSION
, *PHW_DEVICE_EXTENSION
;
1257 typedef struct _ISR2_DEVICE_EXTENSION
{
1258 PHW_DEVICE_EXTENSION HwDeviceExtension
;
1260 } ISR2_DEVICE_EXTENSION
, *PISR2_DEVICE_EXTENSION
;
1262 #define HBAFLAGS_DMA_DISABLED 0x01
1263 #define HBAFLAGS_DMA_DISABLED_LBA48 0x02
1265 extern UCHAR pciBuffer
[256];
1266 extern PBUSMASTER_CONTROLLER_INFORMATION BMList
;
1267 extern ULONG BMListLen
;
1268 extern ULONG IsaCount
;
1269 extern ULONG MCACount
;
1271 //extern const CHAR retry_Wdma[MAX_RETRIES+1];
1272 //extern const CHAR retry_Udma[MAX_RETRIES+1];
1276 UniataEnumBusMasterController(
1277 IN PVOID DriverObject
,
1282 UniataFindCompatBusMasterController1(
1283 IN PVOID HwDeviceExtension
,
1285 IN PVOID BusInformation
,
1286 IN PCHAR ArgumentString
,
1287 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
1292 UniataFindCompatBusMasterController2(
1293 IN PVOID HwDeviceExtension
,
1295 IN PVOID BusInformation
,
1296 IN PCHAR ArgumentString
,
1297 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
1301 #define UNIATA_ALLOCATE_NEW_LUNS 0x00
1303 extern BOOLEAN NTAPI
1304 UniataAllocateLunExt(
1305 PHW_DEVICE_EXTENSION deviceExtension
,
1306 ULONG NewNumberChannels
1311 PHW_DEVICE_EXTENSION deviceExtension
1315 UniataFindBusMasterController(
1316 IN PVOID HwDeviceExtension
,
1318 IN PVOID BusInformation
,
1319 IN PCHAR ArgumentString
,
1320 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
1325 UniataFindFakeBusMasterController(
1326 IN PVOID HwDeviceExtension
,
1328 IN PVOID BusInformation
,
1329 IN PCHAR ArgumentString
,
1330 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
1337 IN PVOID HwDeviceExtension
1342 UniataDisconnectIntr2(
1343 IN PVOID HwDeviceExtension
1348 ScsiPortGetBusDataByOffset(
1349 IN PVOID HwDeviceExtension
,
1350 IN BUS_DATA_TYPE BusDataType
,
1352 IN ULONG SlotNumber
,
1358 #define PCIBUSNUM_NOT_SPECIFIED (0xffffffffL)
1359 #define PCISLOTNUM_NOT_SPECIFIED (0xffffffffL)
1364 PBUSMASTER_CONTROLLER_INFORMATION BusMasterAdapters
,
1366 IN PVOID HwDeviceExtension
,
1368 IN ULONG SlotNumber
,
1369 OUT PCI_SLOT_NUMBER
* _slotData
// optional
1375 IN PVOID HwDeviceExtension
,
1376 IN BUS_DATA_TYPE BusDataType
,
1378 IN ULONG SlotNumber
,
1386 IN PVOID HwDeviceExtension
,
1387 IN PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
1388 IN ULONG lChannel
// logical channel,
1394 IN PVOID HwDeviceExtension
,
1395 IN ULONG DeviceNumber
,
1396 IN ULONG lChannel
, // logical channel,
1397 IN PSCSI_REQUEST_BLOCK Srb
,
1405 PVOID HwDeviceExtension
,
1406 PSCSI_REQUEST_BLOCK Srb
,
1415 PSCSI_REQUEST_BLOCK Srb
1421 IN PVOID HwDeviceExtension
,
1422 IN ULONG DeviceNumber
,
1423 IN ULONG lChannel
, // logical channel,
1424 IN PSCSI_REQUEST_BLOCK Srb
1430 IN PVOID HwDeviceExtension
,
1431 IN ULONG DeviceNumber
,
1432 IN ULONG lChannel
, // logical channel,
1433 IN PSCSI_REQUEST_BLOCK Srb
1439 IN PHW_DEVICE_EXTENSION deviceExtension
,
1440 IN PHW_LU_EXTENSION LunExt
,
1447 IN PHW_DEVICE_EXTENSION deviceExtension
,
1448 IN PHW_LU_EXTENSION LunExt
1454 IN PVOID HwDeviceExtension
,
1455 IN ULONG DeviceNumber
,
1456 IN ULONG lChannel
, // logical channel,
1457 // is always 0 except simplex-only and multi-channel controllers
1463 extern BOOLEAN NTAPI
1465 IN PKINTERRUPT Interrupt
,
1466 IN PVOID HwDeviceExtension
1469 extern PDRIVER_OBJECT SavedDriverObject
;
1473 UniataChipDetectChannels(
1474 IN PVOID HwDeviceExtension
,
1475 IN PPCI_COMMON_CONFIG pciData
, // optional
1476 IN ULONG DeviceNumber
,
1477 IN PPORT_CONFIGURATION_INFORMATION ConfigInfo
1483 IN PVOID HwDeviceExtension
,
1484 IN PPCI_COMMON_CONFIG pciData
, // optional
1485 IN ULONG DeviceNumber
,
1486 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
1487 IN BOOLEAN
* simplexOnly
1493 IN PVOID HwDeviceExtension
,
1494 IN ULONG DeviceNumber
,
1501 IN PVOID HwDeviceExtension
,
1502 IN PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
1503 IN PPCI_COMMON_CONFIG pciData
,
1504 IN ULONG SystemIoBusNumber
,
1507 IN ULONG length
//range id
1510 /****************** 1 *****************/
1511 #define GetPciConfig1(offs, op) { \
1512 ScsiPortGetBusDataByOffset(HwDeviceExtension, \
1514 SystemIoBusNumber, \
1521 #define SetPciConfig1(offs, op) { \
1523 ScsiPortSetBusDataByOffset(HwDeviceExtension, \
1525 SystemIoBusNumber, \
1532 #define ChangePciConfig1(offs, _op) { \
1534 GetPciConfig1(offs, a); \
1536 SetPciConfig1(offs, a); \
1539 /****************** 2 *****************/
1540 #define GetPciConfig2(offs, op) { \
1541 ScsiPortGetBusDataByOffset(HwDeviceExtension, \
1543 SystemIoBusNumber, \
1550 #define SetPciConfig2(offs, op) { \
1552 ScsiPortSetBusDataByOffset(HwDeviceExtension, \
1554 SystemIoBusNumber, \
1561 #define ChangePciConfig2(offs, _op) { \
1563 GetPciConfig2(offs, a); \
1564 a = (USHORT)(_op); \
1565 SetPciConfig2(offs, a); \
1568 /****************** 4 *****************/
1569 #define GetPciConfig4(offs, op) { \
1570 ScsiPortGetBusDataByOffset(HwDeviceExtension, \
1572 SystemIoBusNumber, \
1579 #define SetPciConfig4(offs, op) { \
1581 ScsiPortSetBusDataByOffset(HwDeviceExtension, \
1583 SystemIoBusNumber, \
1590 #define ChangePciConfig4(offs, _op) { \
1592 GetPciConfig4(offs, a); \
1594 SetPciConfig4(offs, a); \
1597 #define DMA_MODE_NONE 0x00
1598 #define DMA_MODE_BM 0x01
1599 #define DMA_MODE_AHCI 0x02
1601 #ifndef GetDmaStatus
1602 #define GetDmaStatus(de, c) \
1603 (((de)->BusMaster == DMA_MODE_BM) ? AtapiReadPort1(&((de)->chan[c]), IDX_BM_Status) : 0)
1604 #endif //GetDmaStatus
1607 #define AtapiVirtToPhysAddr(hwde, srb, phaddr, plen, phaddru) \
1608 AtapiVirtToPhysAddr_(hwde, srb, phaddr, plen, phaddru);
1610 #define AtapiVirtToPhysAddr(hwde, srb, phaddr, plen, phaddru) \
1611 (ScsiPortConvertPhysicalAddressToUlong/*(ULONG)ScsiPortGetVirtualAddress*/(/*hwde,*/ \
1612 ScsiPortGetPhysicalAddress(hwde, srb, phaddr, plen)))
1613 #endif //USE_OWN_DMA
1618 IN PHW_CHANNEL chan
,
1619 IN ULONGIO_PTR port
,
1626 IN PHW_CHANNEL chan
,
1627 IN ULONGIO_PTR port
,
1634 IN PHW_CHANNEL chan
,
1635 IN ULONGIO_PTR port
,
1642 IN PHW_CHANNEL chan
,
1643 IN ULONGIO_PTR port
,
1651 IN PHW_CHANNEL chan
,
1652 IN ULONGIO_PTR port
,
1660 IN PHW_CHANNEL chan
,
1667 IN PHW_CHANNEL chan
,
1674 IN PHW_CHANNEL chan
,
1681 IN PHW_CHANNEL chan
,
1682 IN ULONGIO_PTR port
,
1689 IN PHW_CHANNEL chan
,
1690 IN ULONGIO_PTR port
,
1697 IN PHW_CHANNEL chan
,
1698 IN ULONGIO_PTR _port
,
1707 IN PHW_CHANNEL chan
,
1708 IN ULONGIO_PTR _port
,
1717 IN PHW_CHANNEL chan
,
1718 IN ULONGIO_PTR _port
,
1727 IN PHW_CHANNEL chan
,
1728 IN ULONGIO_PTR _port
,
1734 /*#define GET_CHANNEL(Srb) (Srb->TargetId >> 1)
1735 #define GET_LDEV(Srb) (Srb->TargetId)
1736 #define GET_LDEV2(P, T, L) (T)*/
1738 #define GET_CHANNEL(Srb) (Srb->PathId)
1739 //#define GET_LDEV(Srb) (Srb->TargetId | (Srb->PathId << 1))
1740 //#define GET_LDEV2(P, T, L) (T | ((P)<<1))
1741 #define GET_CDEV(Srb) (Srb->TargetId)
1746 IN PHW_CHANNEL chan
,
1747 IN PHW_DEVICE_EXTENSION deviceExtension
,
1751 #define AtapiSetupLunPtrs(chan, deviceExtension, c) \
1753 chan->DeviceExtension = deviceExtension; \
1754 chan->lChannel = c; \
1755 chan->lun[0] = &(deviceExtension->lun[c*2+0]); \
1756 chan->lun[1] = &(deviceExtension->lun[c*2+1]); \
1757 chan->AltRegMap = deviceExtension->AltRegMap; \
1758 chan->NextDpcChan = -1; \
1759 chan->lun[0]->DeviceExtension = deviceExtension; \
1760 chan->lun[1]->DeviceExtension = deviceExtension; \
1765 AtapiReadChipConfig(
1766 IN PVOID HwDeviceExtension
,
1767 IN ULONG DeviceNumber
,
1768 IN ULONG channel
// physical channel
1774 PHW_LU_EXTENSION LunExt
1777 extern ULONG SkipRaids
;
1778 extern ULONG ForceSimplex
;
1779 extern BOOLEAN g_opt_AtapiDmaRawRead
;
1780 extern BOOLEAN hasPCI
;
1782 extern BOOLEAN InDriverEntry
;
1784 extern BOOLEAN g_opt_Verbose
;
1785 extern ULONG g_opt_VirtualMachine
;
1787 #define VM_AUTO 0x00
1788 #define VM_NONE 0x01
1789 #define VM_VBOX 0x02
1790 #define VM_VMWARE 0x03
1791 #define VM_QEMU 0x04
1793 #define VM_MAX_KNOWN VM_QEMU
1795 extern BOOLEAN WinVer_WDM_Model
;
1797 #endif //__IDE_BUSMASTER_H__