3 Copyright (c) 2002-2005 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-2007
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)
88 #define ATA_DMA_ENTRIES 256 /* PAGESIZE/2/sizeof(BM_DMA_ENTRY)*/
89 #define ATA_DMA_EOT 0x80000000
93 #define ATAPI_MAGIC_LSB 0x14
94 #define ATAPI_MAGIC_MSB 0xeb
96 #define AHCI_MAX_PORT 32
98 typedef struct _BUSMASTER_CTX
{
99 PBUSMASTER_CONTROLLER_INFORMATION
* BMListPtr
;
101 } BUSMASTER_CTX
, *PBUSMASTER_CTX
;
103 #define PCI_DEV_CLASS_STORAGE 0x01
105 #define PCI_DEV_SUBCLASS_IDE 0x01
106 #define PCI_DEV_SUBCLASS_RAID 0x04
107 #define PCI_DEV_SUBCLASS_ATA 0x05
108 #define PCI_DEV_SUBCLASS_SATA 0x06
110 /* structure for holding DMA address data */
111 typedef struct BM_DMA_ENTRY
{
114 } BM_DMA_ENTRY
, *PBM_DMA_ENTRY
;
116 typedef struct _IDE_BUSMASTER_REGISTERS
{
118 UCHAR DeviceSpecific0
;
120 UCHAR DeviceSpecific1
;
122 } IDE_BUSMASTER_REGISTERS
, *PIDE_BUSMASTER_REGISTERS
;
124 #define BM_STATUS_ACTIVE 0x01
125 #define BM_STATUS_ERR 0x02
126 #define BM_STATUS_INTR 0x04
127 #define BM_STATUS_MASK 0x07
128 #define BM_STATUS_DRIVE_0_DMA 0x20
129 #define BM_STATUS_DRIVE_1_DMA 0x40
130 #define BM_STATUS_SIMPLEX_ONLY 0x80
132 #define BM_COMMAND_START_STOP 0x01
133 /*#define BM_COMMAND_WRITE 0x08
134 #define BM_COMMAND_READ 0x00*/
135 #define BM_COMMAND_WRITE 0x00
136 #define BM_COMMAND_READ 0x08
138 #define BM_DS0_SII_DMA_ENABLE (1 << 0) /* DMA run switch */
139 #define BM_DS0_SII_IRQ (1 << 3) /* ??? */
140 #define BM_DS0_SII_DMA_SATA_IRQ (1 << 4) /* OR of all SATA IRQs */
141 #define BM_DS0_SII_DMA_ERROR (1 << 17) /* PCI bus error */
142 #define BM_DS0_SII_DMA_COMPLETE (1 << 18) /* cmd complete / IRQ pending */
145 #define IDX_BM_IO (IDX_IO2_o+IDX_IO2_o_SZ)
146 //#define IDX_BM_IO_SZ sizeof(IDE_BUSMASTER_REGISTERS)
147 #define IDX_BM_IO_SZ 5
149 #define IDX_BM_Command (FIELD_OFFSET(IDE_BUSMASTER_REGISTERS, Command )+IDX_BM_IO)
150 #define IDX_BM_DeviceSpecific0 (FIELD_OFFSET(IDE_BUSMASTER_REGISTERS, DeviceSpecific0)+IDX_BM_IO)
151 #define IDX_BM_Status (FIELD_OFFSET(IDE_BUSMASTER_REGISTERS, Status )+IDX_BM_IO)
152 #define IDX_BM_DeviceSpecific1 (FIELD_OFFSET(IDE_BUSMASTER_REGISTERS, DeviceSpecific1)+IDX_BM_IO)
153 #define IDX_BM_PRD_Table (FIELD_OFFSET(IDE_BUSMASTER_REGISTERS, PRD_Table )+IDX_BM_IO)
155 typedef struct _IDE_AHCI_REGISTERS
{
158 ULONG NOP
:5; // number of ports
160 ULONG NCS
:5; // number of command slots
161 ULONG PSC
:1; // partial state capable
162 ULONG SSC
:1; // slumber state capable
163 ULONG PMD
:1; // PIO multiple DRQ block
166 ULONG SPM
:1; // port multiplier
167 ULONG SAM
:1; // AHCI mode only
168 ULONG SNZO
:1; // non-zero DMA offset
169 ULONG ISS
:4; // interface speed
170 ULONG SCLO
:1; // command list override
171 ULONG SAL
:1; // activity LED
172 ULONG SALP
:1; // aggressive link power management
173 ULONG SSS
:1; // staggered spin-up
174 ULONG SIS
:1; // interlock switch
176 ULONG SNCQ
:1; // native command queue
177 ULONG S64A
:1; // 64bit addr
180 #define AHCI_CAP_NOP_MASK 0x0000001f
181 #define AHCI_CAP_S64A 0x80000000
183 // Global HBA Control
185 ULONG HR
:1; // HBA Reset
186 ULONG IE
:1; // interrupt enable
187 ULONG Reserved2_30
:1;
188 ULONG AE
:1; // AHCI enable
191 #define AHCI_GHC_HR 0x00000001
192 #define AHCI_GHC_IE 0x00000002
193 #define AHCI_GHC_AE 0x80000000
195 // Interrupt status (bit mask)
197 // Ports implemented (bit mask)
203 UCHAR Reserved2
[0x80];
205 UCHAR VendorSpec
[0x60];
206 } IDE_AHCI_REGISTERS
, *PIDE_AHCI_REGISTERS
;
208 #define IDX_AHCI_CAP (FIELD_OFFSET(IDE_AHCI_REGISTERS, CAP))
209 #define IDX_AHCI_GHC (FIELD_OFFSET(IDE_AHCI_REGISTERS, GHC))
210 #define IDX_AHCI_IS (FIELD_OFFSET(IDE_AHCI_REGISTERS, IS))
211 #define IDX_AHCI_VS (FIELD_OFFSET(IDE_AHCI_REGISTERS, VS))
212 #define IDX_AHCI_PI (FIELD_OFFSET(IDE_AHCI_REGISTERS, PI))
215 typedef union _SATA_SSTATUS_REG
{
218 ULONG DET
:4; // Device Detection
220 #define SStatus_DET_NoDev 0x00
221 #define SStatus_DET_Dev_NoPhy 0x01
222 #define SStatus_DET_Dev_Ok 0x03
223 #define SStatus_DET_Offline 0x04
225 ULONG SPD
:4; // Current Interface Speed
227 #define SStatus_SPD_NoDev 0x00
228 #define SStatus_SPD_Gen1 0x01
229 #define SStatus_SPD_Gen2 0x02
231 ULONG IPM
:4; // Interface Power Management
233 #define SStatus_IPM_NoDev 0x00
234 #define SStatus_IPM_Active 0x01
235 #define SStatus_IPM_Partial 0x02
236 #define SStatus_IPM_Slumber 0x06
242 } SATA_SSTATUS_REG
, *PSATA_SSTATUS_REG
;
245 typedef union _SATA_SCONTROL_REG
{
248 ULONG DET
:4; // Device Detection Init
250 #define SControl_DET_DoNothing 0x00
251 #define SControl_DET_Idle 0x00
252 #define SControl_DET_Init 0x01
253 #define SControl_DET_Disable 0x04
255 ULONG SPD
:4; // Speed Allowed
257 #define SControl_SPD_NoRestrict 0x00
258 #define SControl_SPD_LimGen1 0x01
259 #define SControl_SPD_LimGen2 0x02
261 ULONG IPM
:4; // Interface Power Management Transitions Allowed
263 #define SControl_IPM_NoRestrict 0x00
264 #define SControl_IPM_NoPartial 0x01
265 #define SControl_IPM_NoSlumber 0x02
266 #define SControl_IPM_NoPartialSlumber 0x03
268 ULONG SPM
:4; // Select Power Management, unused by AHCI
269 ULONG PMP
:4; // Port Multiplier Port, unused by AHCI
274 } SATA_SCONTROL_REG
, *PSATA_SCONTROL_REG
;
277 typedef union _SATA_SERROR_REG
{
281 UCHAR I
:1; // Recovered Data Integrity Error
282 UCHAR M
:1; // Recovered Communications Error
283 UCHAR Reserved_2_7
:6;
285 UCHAR T
:1; // Transient Data Integrity Error
286 UCHAR C
:1; // Persistent Communication or Data Integrity Error
287 UCHAR P
:1; // Protocol Error
288 UCHAR E
:1; // Internal Error
289 UCHAR Reserved_12_15
:4;
293 UCHAR N
:1; // PhyRdy Change, PIS.PRCS
294 UCHAR I
:1; // Phy Internal Error
295 UCHAR W
:1; // Comm Wake
296 UCHAR B
:1; // 10B to 8B Decode Error
297 UCHAR D
:1; // Disparity Error, not used by AHCI
298 UCHAR C
:1; // CRC Error
299 UCHAR H
:1; // Handshake Error
300 UCHAR S
:1; // Link Sequence Error
302 UCHAR T
:1; // Transport state transition error
303 UCHAR F
:1; // Unknown FIS Type
304 UCHAR X
:1; // Exchanged
305 UCHAR Reserved_27_31
:5;
310 } SATA_SERROR_REG
, *PSATA_SERROR_REG
;
313 typedef struct _IDE_SATA_REGISTERS
{
315 SATA_SSTATUS_REG SStatus
;
319 SATA_SERROR_REG SError
;
323 SATA_SCONTROL_REG SControl
;
333 USHORT PMN
; // PM Notify, bitmask
338 } IDE_SATA_REGISTERS
, *PIDE_SATA_REGISTERS
;
340 #define IDX_SATA_IO (IDX_BM_IO+IDX_BM_IO_SZ)
341 //#define IDX_SATA_IO_SZ sizeof(IDE_SATA_REGISTERS)
342 #define IDX_SATA_IO_SZ 5
344 #define IDX_SATA_SStatus (0+IDX_SATA_IO)
345 #define IDX_SATA_SError (1+IDX_SATA_IO)
346 #define IDX_SATA_SControl (2+IDX_SATA_IO)
347 #define IDX_SATA_SActive (3+IDX_SATA_IO)
348 #define IDX_SATA_SNTF_PMN (4+IDX_SATA_IO)
350 #define IDX_MAX_REG (IDX_SATA_IO+IDX_SATA_IO_SZ)
352 typedef union _AHCI_IS_REG
{
354 ULONG DHRS
:1;// Device to Host Register FIS Interrupt
355 ULONG PSS
:1; // PIO Setup FIS Interrupt
356 ULONG DSS
:1; // DMA Setup FIS Interrupt
357 ULONG SDBS
:1;// Set Device Bits Interrupt
358 ULONG UFS
:1; // Unknown FIS Interrupt
359 ULONG DPS
:1; // Descriptor Processed
360 ULONG PCS
:1; // Port Connect Change Status
361 ULONG DMPS
:1;// Device Mechanical Presence Status
363 ULONG Reserved_8_21
:14;
364 ULONG PRCS
:1;// PhyRdy Change Status
365 ULONG IPMS
:1;// Incorrect Port Multiplier Status
367 ULONG OFS
:1; // Overflow Status
369 ULONG INFS
:1;// Interface Non-fatal Error Status
370 ULONG IFS
:1; // Interface Fatal Error Status
371 ULONG HBDS
:1;// Host Bus Data Error Status
372 ULONG HBFS
:1;// Host Bus Fatal Error Status
373 ULONG TFES
:1;// Task File Error Status
374 ULONG CPDS
:1;// Cold Port Detect Status
377 } AHCI_IS_REG
, *PAHCI_IS_REG
;
380 typedef struct _IDE_AHCI_PORT_REGISTERS
{
383 ULONG CLB
; // command list base address
384 ULONG CLBU
; // command list base address (upper 32bits)
391 ULONG FB
; // FIS base address
392 ULONG FBU
; // FIS base address (upper 32bits)
398 ULONG IS_Reg
; // interrupt status
403 ULONG Reg
; // interrupt enable
405 ULONG DHRE
:1;// Device to Host Register FIS Interrupt Enable
406 ULONG PSE
:1; // PIO Setup FIS Interrupt Enable
407 ULONG DSE
:1; // DMA Setup FIS Interrupt Enable
408 ULONG SDBE
:1;// Set Device Bits FIS Interrupt Enable
409 ULONG UFE
:1; // Unknown FIS Interrupt Enable
410 ULONG DPE
:1; // Descriptor Processed Interrupt Enable
411 ULONG PCE
:1; // Port Change Interrupt Enable
412 ULONG DPME
:1;// Device Mechanical Presence Enable
414 ULONG Reserved_8_21
:14;
415 ULONG PRCE
:1;// PhyRdy Change Interrupt Enable
416 ULONG IPME
:1;// Incorrect Port Multiplier Enable
417 ULONG OFE
:1; // Overflow Enable
419 ULONG INFE
:1;// Interface Non-fatal Error Enable
420 ULONG IFE
:1; // Interface Fatal Error Enable
421 ULONG HBDE
:1;// Host Bus Data Error Enable
422 ULONG HBFE
:1;// Host Bus Fatal Error Enable
423 ULONG TFEE
:1;// Task File Error Enable
424 ULONG CPDE
:1;// Cold Port Detect Enable
429 ULONG Reg
; // command register
433 ULONG SUD
:1; // Spin-Up Device
434 ULONG POD
:1; // Power On Device
435 ULONG CLO
:1; // Command List Override
436 ULONG FRE
:1; // FIS Receive Enable
437 ULONG Reserved_5_7
:3;
439 ULONG CCS
:5; // Current Command Slot
440 ULONG MPSS
:1;// Mechanical Presence Switch State
441 ULONG FR
:1; // FIS Receive Running
442 ULONG CR
:1; // Command List Running
444 ULONG CPS
:1; // Cold Presence State
445 ULONG PMA
:1; // Port Multiplier Attached
446 ULONG HPCP
:1;// Hot Plug Capable Port
447 ULONG MPSP
:1;// Mechanical Presence Switch Attached to Port
448 ULONG CPD
:1; // Cold Presence Detection
449 ULONG ESP
:1; // External SATA Port
450 ULONG Reserved_22_23
:2;
452 ULONG ATAPI
:1; // Device is ATAPI
453 ULONG DLAE
:1;// Drive LED on ATAPI Enable
454 ULONG ALPE
:1;// Aggressive Link Power Management Enable
455 ULONG ASP
:1; // Aggressive Slumber / Partial
456 ULONG ICC
:4; // Interface Communication Control
458 #define SATA_CMD_ICC_Idle 0x00
459 #define SATA_CMD_ICC_NoOp 0x00
460 #define SATA_CMD_ICC_Active 0x01
461 #define SATA_CMD_ICC_Partial 0x02
462 #define SATA_CMD_ICC_Slumber 0x06
469 ULONG Reg
; // Task File Data
473 UCHAR cs1
:2;// command-specific
475 UCHAR cs2
:3;// command-specific
478 UCHAR ERR
; // Contains the latest copy of the task file error register.
484 ULONG Reg
; // signature
493 ULONG SStatus
; // SCR0
494 SATA_SSTATUS_REG SSTS
;
497 ULONG SControl
; // SCR2
498 SATA_SCONTROL_REG SCTL
;
501 ULONG SError
; // SCR1
502 SATA_SERROR_REG SERR
;
506 ULONG SActive
; // bitmask
508 ULONG CI
; // Command issue, bitmask
514 USHORT PMN
; // PM Notify, bitmask
518 ULONG FIS_Switching_Reserved
[12];
519 UCHAR VendorSpec
[16];
521 } IDE_AHCI_PORT_REGISTERS
, *PIDE_AHCI_PORT_REGISTERS
;
523 #define IDX_AHCI_P_IS (FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, IS))
524 #define IDX_AHCI_P_CI (FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, CI))
526 typedef struct _IDE_AHCI_PRD_ENTRY
{
544 } IDE_AHCI_PRD_ENTRY
, *PIDE_AHCI_PRD_ENTRY
;
546 #define ATA_AHCI_DMA_ENTRIES (PAGE_SIZE/2/sizeof(IDE_AHCI_PRD_ENTRY)) /* 128 */
548 typedef struct _IDE_AHCI_CMD
{
552 IDE_AHCI_PRD_ENTRY prd_tab
[ATA_AHCI_DMA_ENTRIES
];
553 } IDE_AHCI_CMD
, *PIDE_AHCI_CMD
;
555 typedef struct _IDE_AHCI_CMD_LIST
{
557 USHORT prd_length
; /* PRD entries */
559 ULONGLONG cmd_table_phys
; /* 128byte aligned */
560 } IDE_AHCI_CMD_LIST
, *PIDE_AHCI_CMD_LIST
;
562 #define IsBusMaster(pciData) \
563 ( ((pciData)->Command & (PCI_ENABLE_BUS_MASTER/* | PCI_ENABLE_IO_SPACE*/)) == \
564 (PCI_ENABLE_BUS_MASTER/* | PCI_ENABLE_IO_SPACE*/))
566 #define PCI_IDE_PROGIF_NATIVE_1 0x01
567 #define PCI_IDE_PROGIF_NATIVE_2 0x04
568 #define PCI_IDE_PROGIF_NATIVE_ALL 0x05
570 #define IsMasterDev(pciData) \
571 ( ((pciData)->ProgIf & 0x80) && \
572 ((pciData)->ProgIf & PCI_IDE_PROGIF_NATIVE_ALL) != PCI_IDE_PROGIF_NATIVE_ALL )
574 //#define INT_Q_SIZE 32
575 #define MIN_REQ_TTL 4
579 typedef union _ATA_REQ
{
580 // ULONG reqId; // serial
586 union _ATA_REQ
* next_req
;
587 union _ATA_REQ
* prev_req
;
589 PSCSI_REQUEST_BLOCK Srb
; // Current request on controller.
591 PUSHORT DataBuffer
; // Data buffer pointer.
592 ULONG WordsLeft
; // Data words left.
593 ULONG TransferLength
; // Originally requested transfer length
595 ULONG WordsTransfered
;// Data words already transfered.
604 PSCSI_REQUEST_BLOCK OriginalSrb
; // Mechanism Status Srb Data
609 ULONGLONG ahci_base64
; // for AHCI
612 UCHAR padding_128b
[128];
616 BM_DMA_ENTRY dma_tab
[ATA_DMA_ENTRIES
];
617 IDE_AHCI_CMD ahci_cmd
; // for AHCI
622 UCHAR padding_4kb
[PAGE_SIZE
];
624 } ATA_REQ
, *PATA_REQ
;
626 #define REQ_FLAG_FORCE_DOWNRATE 0x01
627 #define REQ_FLAG_DMA_OPERATION 0x02
628 #define REQ_FLAG_REORDERABLE_CMD 0x04
629 #define REQ_FLAG_RW_MASK 0x08
630 #define REQ_FLAG_READ 0x08
631 #define REQ_FLAG_WRITE 0x00
632 #define REQ_FLAG_FORCE_DOWNRATE_LBA48 0x10
633 #define REQ_FLAG_DMA_DBUF 0x20
634 #define REQ_FLAG_DMA_DBUF_PRD 0x40
637 #define REQ_STATE_NONE 0x00
638 #define REQ_STATE_QUEUED 0x10
640 #define REQ_STATE_PREPARE_TO_TRANSFER 0x20
641 #define REQ_STATE_PREPARE_TO_NEXT 0x21
642 #define REQ_STATE_READY_TO_TRANSFER 0x30
644 #define REQ_STATE_EXPECTING_INTR 0x40
645 #define REQ_STATE_ATAPI_EXPECTING_CMD_INTR 0x41
646 #define REQ_STATE_ATAPI_EXPECTING_DATA_INTR 0x42
647 #define REQ_STATE_ATAPI_DO_NOTHING_INTR 0x43
649 #define REQ_STATE_EARLY_INTR 0x48
651 #define REQ_STATE_PROCESSING_INTR 0x50
653 #define REQ_STATE_DPC_INTR_REQ 0x51
654 #define REQ_STATE_DPC_RESET_REQ 0x52
655 #define REQ_STATE_DPC_COMPLETE_REQ 0x53
657 #define REQ_STATE_DPC_WAIT_BUSY0 0x57
658 #define REQ_STATE_DPC_WAIT_BUSY1 0x58
659 #define REQ_STATE_DPC_WAIT_BUSY 0x59
660 #define REQ_STATE_DPC_WAIT_DRQ 0x5a
661 #define REQ_STATE_DPC_WAIT_DRQ0 0x5b
662 #define REQ_STATE_DPC_WAIT_DRQ_ERR 0x5c
664 #define REQ_STATE_TRANSFER_COMPLETE 0x7f
667 #define CMD_ACTION_PREPARE 0x01
668 #define CMD_ACTION_EXEC 0x02
669 #define CMD_ACTION_ALL (CMD_ACTION_PREPARE | CMD_ACTION_EXEC)
671 // predefined Reorder costs
672 #define REORDER_COST_MAX ((DEF_I64(0x1) << 60) - 1)
673 #define REORDER_COST_TTL (REORDER_COST_MAX - 1)
674 #define REORDER_COST_INTERSECT (REORDER_COST_MAX - 2)
675 #define REORDER_COST_DENIED (REORDER_COST_MAX - 3)
676 #define REORDER_COST_RESELECT (REORDER_COST_MAX/4)
678 #define REORDER_COST_SWITCH_RW_CD (REORDER_COST_MAX/8)
679 #define REORDER_MCOST_SWITCH_RW_CD (0)
680 #define REORDER_MCOST_SEEK_BACK_CD (16)
682 #define REORDER_COST_SWITCH_RW_HDD (0)
683 #define REORDER_MCOST_SWITCH_RW_HDD (4)
684 #define REORDER_MCOST_SEEK_BACK_HDD (2)
686 /*typedef struct _ATA_QUEUE {
687 struct _ATA_REQ* head_req; // index
688 struct _ATA_REQ* tail_req; // index
691 BM_DMA_ENTRY dma_tab[ATA_DMA_ENTRIES];
692 } ATA_QUEUE, *PATA_QUEUE;*/
694 struct _HW_DEVICE_EXTENSION
;
695 struct _HW_LU_EXTENSION
;
697 typedef struct _IORES
{
704 typedef struct _HW_CHANNEL
{
708 /* PATA_REQ first_req;
711 ULONG ChannelSelectWaitCount
;
715 BOOLEAN ExpectingInterrupt
; // Indicates expecting an interrupt
716 BOOLEAN RDP
; // Indicate last tape command was DSC Restrictive.
717 // Indicates whether '0x1f0' is the base address. Used
718 // in SMART Ioctl calls.
719 BOOLEAN PrimaryAddress
;
720 // Placeholder for the sub-command value of the last
725 // Placeholder for status register after a GET_MEDIA_STATUS command
726 UCHAR ReturningMediaStatus
;
728 BOOLEAN CopyDmaBuffer
;
734 MECHANICAL_STATUS_INFORMATION_HEADER MechStatusData
;
735 SENSE_DATA MechStatusSense
;
736 ULONG MechStatusRetryCount
;
737 SCSI_REQUEST_BLOCK InternalSrb
;
739 ULONG MaxTransferMode
; // may differ from Controller's value due to 40-pin cable
741 ULONG ChannelCtrlFlags
;
742 ULONG ResetInProgress
; // flag
748 #define CHECK_INTR_ACTIVE 0x03
749 #define CHECK_INTR_DETECTED 0x02
750 #define CHECK_INTR_CHECK 0x01
751 #define CHECK_INTR_IDLE 0x00
754 PHW_TIMER HwScsiTimer
;
757 PHW_TIMER HwScsiTimer1
;
758 PHW_TIMER HwScsiTimer2
;
761 // LARGE_INTEGER ActivationTime;
765 // PHW_TIMER HwScsiTimer;
766 // KSPIN_LOCK QueueSpinLock;
767 // KIRQL QueueOldIrql;
769 struct _HW_DEVICE_EXTENSION
* DeviceExtension
;
770 struct _HW_LU_EXTENSION
* lun
[2];
772 // Double-buffering support
781 PIDE_AHCI_CMD_LIST AHCI_CL
;
782 ULONGLONG AHCI_CL_PhAddr
;
783 PVOID AHCI_FIS
; // is not actually used by UniATA now, but is required by AHCI controller
784 ULONGLONG AHCI_FIS_PhAddr
;
785 // Note: in contrast to FBSD, we keep PRD and CMD item in AtaReq structure
787 #ifdef QUEUE_STATISTICS
788 LONGLONG QueueStat
[MAX_QUEUE_STAT
];
789 LONGLONG ReorderCount
;
790 LONGLONG IntersectCount
;
791 LONGLONG TryReorderCount
;
792 LONGLONG TryReorderHeadCount
;
793 LONGLONG TryReorderTailCount
; /* in-order requests */
794 #endif //QUEUE_STATISTICS
796 //ULONG BaseMemAddress;
797 //ULONG BaseMemAddressOffset;
798 IORES RegTranslation
[IDX_MAX_REG
];
800 } HW_CHANNEL
, *PHW_CHANNEL
;
802 #define CTRFLAGS_DMA_ACTIVE 0x0001
803 #define CTRFLAGS_DMA_RO 0x0002
804 #define CTRFLAGS_DMA_OPERATION 0x0004
805 #define CTRFLAGS_INTR_DISABLED 0x0008
806 #define CTRFLAGS_DPC_REQ 0x0010
807 #define CTRFLAGS_ENABLE_INTR_REQ 0x0020
808 #define CTRFLAGS_LBA48 0x0040
809 #define CTRFLAGS_DSC_BSY 0x0080
810 #define CTRFLAGS_NO_SLAVE 0x0100
812 #define GEOM_AUTO 0xffffffff
813 #define GEOM_STD 0x0000
814 #define GEOM_UNIATA 0x0001
815 #define GEOM_ORIG 0x0002
816 #define GEOM_MANUAL 0x0003
818 #define DPC_STATE_NONE 0x00
819 #define DPC_STATE_ISR 0x10
820 #define DPC_STATE_DPC 0x20
821 #define DPC_STATE_TIMER 0x30
822 #define DPC_STATE_COMPLETE 0x40
824 // Logical unit extension
825 typedef struct _HW_LU_EXTENSION
{
826 IDENTIFY_DATA2 IdentifyData
;
827 ULONGLONG NumOfSectors
;
828 ULONG DeviceFlags
; // Flags word for each possible device. DFLAGS_XXX
829 ULONG DiscsPresent
; // Indicates number of platters on changer-ish devices.
830 BOOLEAN DWordIO
; // Indicates use of 32-bit PIO
831 UCHAR ReturningMediaStatus
;
833 UCHAR TransferMode
; // current transfer mode
834 UCHAR LimitedTransferMode
; // user-defined or IDE cable limitation
835 UCHAR OrigTransferMode
; // transfer mode, returned by device IDENTIFY (can be changed via IOCTL)
837 UCHAR MaximumBlockXfer
;
838 UCHAR Padding0
[2]; // padding
839 ULONG ErrorCount
; // Count of errors. Used to turn off features.
840 // ATA_QUEUE cmd_queue;
841 LONGLONG ReadCmdCost
;
842 LONGLONG WriteCmdCost
;
843 LONGLONG OtherCmdCost
;
844 LONGLONG RwSwitchCost
;
845 LONGLONG RwSwitchMCost
;
846 LONGLONG SeekBackMCost
;
853 ULONG LunSelectWaitCount
;
857 ULONG opt_MaxTransferMode
;
858 ULONG opt_PreferedTransferMode
;
859 BOOLEAN opt_ReadCacheEnable
;
860 BOOLEAN opt_WriteCacheEnable
;
863 BOOLEAN opt_reserved
[1];
865 struct _SBadBlockListItem
* bbListDescr
;
866 struct _SBadBlockRange
* arrBadBlocks
;
869 struct _HW_DEVICE_EXTENSION
* DeviceExtension
;
873 LONGLONG ModeErrorCount
[MAX_RETRIES
];
874 LONGLONG RecoverCount
[MAX_RETRIES
];
877 #endif//IO_STATISTICS
878 } HW_LU_EXTENSION
, *PHW_LU_EXTENSION
;
881 typedef struct _HW_DEVICE_EXTENSION
{
883 //PIDE_REGISTERS_1 BaseIoAddress1[IDE_MAX_CHAN]; // Base register locations
884 //PIDE_REGISTERS_2 BaseIoAddress2[IDE_MAX_CHAN];
885 ULONG BusInterruptLevel
; // Interrupt level
886 ULONG InterruptMode
; // Interrupt Mode (Level or Edge)
887 ULONG BusInterruptVector
;
888 // Number of channels being supported by one instantiation
889 // of the device extension. Normally (and correctly) one, but
890 // with so many broken PCI IDE controllers being sold, we have
892 ULONG NumberChannels
;
894 ULONG FirstChannelToCheck
;
896 HW_LU_EXTENSION lun
[IDE_MAX_LUN
];
897 HW_CHANNEL chan
[AHCI_MAX_PORT
/*IDE_MAX_CHAN*/];
899 PHW_LU_EXTENSION lun
;
902 UCHAR LastInterruptedChannel
;
903 // Indicates the number of blocks transferred per int. according to the
905 BOOLEAN DriverMustPoll
; // Driver is being used by the crash dump utility or ntldr.
907 BOOLEAN UseDpc
; // Indicates use of DPC on long waits
908 IDENTIFY_DATA FullIdentifyData
; // Identify data for device
909 // BusMaster specific data
910 // PBM_DMA_ENTRY dma_tab_0;
911 //KSPIN_LOCK DpcSpinLock;
916 PHW_TIMER HwScsiTimer1;
917 PHW_TIMER HwScsiTimer2;
923 PDEVICE_OBJECT Isr2DevObj
;
925 //PIDE_BUSMASTER_REGISTERS BaseIoAddressBM_0;
926 IORES BaseIoAddressBM_0
;
927 //PIDE_BUSMASTER_REGISTERS BaseIoAddressBM[IDE_MAX_CHAN];
929 // Device identification
933 ULONG SystemIoBusNumber
;
936 ULONG InitMethod
; // vendor specific
947 BOOLEAN DWordIO
; // Indicates use of 32-bit PIO
952 ULONG MaxTransferMode
; // max transfer mode supported by controller
954 INTERFACE_TYPE OrigAdapterInterfaceType
;
955 INTERFACE_TYPE AdapterInterfaceType
;
956 ULONG MaximumDmaTransferLength
;
959 //ULONG BaseMemAddress;
961 //PIDE_SATA_REGISTERS BaseIoAddressSATA_0;
962 IORES BaseIoAddressSATA_0
;
963 //PIDE_SATA_REGISTERS BaseIoAddressSATA[IDE_MAX_CHAN];
966 //PIDE_AHCI_PORT_REGISTERS BaseIoAHCIPort[AHCI_MAX_PORT];
968 BOOLEAN opt_AtapiDmaZeroTransfer
; // default FALSE
969 BOOLEAN opt_AtapiDmaControlCmd
; // default FALSE
970 BOOLEAN opt_AtapiDmaRawRead
; // default TRUE
971 BOOLEAN opt_AtapiDmaReadWrite
; // default TRUE
975 } HW_DEVICE_EXTENSION
, *PHW_DEVICE_EXTENSION
;
977 typedef struct _ISR2_DEVICE_EXTENSION
{
978 PHW_DEVICE_EXTENSION HwDeviceExtension
;
980 } ISR2_DEVICE_EXTENSION
, *PISR2_DEVICE_EXTENSION
;
982 #define HBAFLAGS_DMA_DISABLED 0x01
983 #define HBAFLAGS_DMA_DISABLED_LBA48 0x02
985 extern UCHAR pciBuffer
[256];
986 extern PBUSMASTER_CONTROLLER_INFORMATION BMList
;
987 extern ULONG BMListLen
;
988 extern ULONG IsaCount
;
989 extern ULONG MCACount
;
991 //extern const CHAR retry_Wdma[MAX_RETRIES+1];
992 //extern const CHAR retry_Udma[MAX_RETRIES+1];
995 UniataEnumBusMasterController(
996 IN PVOID DriverObject
,
1001 UniataFindCompatBusMasterController1(
1002 IN PVOID HwDeviceExtension
,
1004 IN PVOID BusInformation
,
1005 IN PCHAR ArgumentString
,
1006 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
1011 UniataFindCompatBusMasterController2(
1012 IN PVOID HwDeviceExtension
,
1014 IN PVOID BusInformation
,
1015 IN PCHAR ArgumentString
,
1016 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
1021 UniataFindBusMasterController(
1022 IN PVOID HwDeviceExtension
,
1024 IN PVOID BusInformation
,
1025 IN PCHAR ArgumentString
,
1026 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
1031 UniataFindFakeBusMasterController(
1032 IN PVOID HwDeviceExtension
,
1034 IN PVOID BusInformation
,
1035 IN PCHAR ArgumentString
,
1036 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
1042 IN PVOID HwDeviceExtension
1046 UniataDisconnectIntr2(
1047 IN PVOID HwDeviceExtension
1051 ScsiPortGetBusDataByOffset(
1052 IN PVOID HwDeviceExtension
,
1053 IN BUS_DATA_TYPE BusDataType
,
1055 IN ULONG SlotNumber
,
1061 #define PCIBUSNUM_NOT_SPECIFIED (0xffffffffL)
1062 #define PCISLOTNUM_NOT_SPECIFIED (0xffffffffL)
1066 PBUSMASTER_CONTROLLER_INFORMATION BusMasterAdapters
,
1068 IN PVOID HwDeviceExtension
,
1070 IN ULONG SlotNumber
,
1071 OUT PCI_SLOT_NUMBER
* _slotData
// optional
1076 IN PVOID HwDeviceExtension
,
1077 IN BUS_DATA_TYPE BusDataType
,
1079 IN ULONG SlotNumber
,
1086 IN PVOID HwDeviceExtension
,
1087 IN PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
1088 IN ULONG lChannel
// logical channel,
1093 IN PVOID HwDeviceExtension
,
1094 IN ULONG DeviceNumber
,
1095 IN ULONG lChannel
, // logical channel,
1096 IN PSCSI_REQUEST_BLOCK Srb
,
1103 PVOID HwDeviceExtension
,
1104 PSCSI_REQUEST_BLOCK Srb
,
1112 PSCSI_REQUEST_BLOCK Srb
1117 IN PVOID HwDeviceExtension
,
1118 IN ULONG DeviceNumber
,
1119 IN ULONG lChannel
, // logical channel,
1120 IN PSCSI_REQUEST_BLOCK Srb
1125 IN PVOID HwDeviceExtension
,
1126 IN ULONG DeviceNumber
,
1127 IN ULONG lChannel
, // logical channel,
1128 IN PSCSI_REQUEST_BLOCK Srb
1133 IN PHW_DEVICE_EXTENSION deviceExtension
,
1140 IN PHW_DEVICE_EXTENSION deviceExtension
,
1146 IN PVOID HwDeviceExtension
,
1147 IN ULONG DeviceNumber
,
1148 IN ULONG lChannel
, // logical channel,
1149 // is always 0 except simplex-only controllers
1155 extern BOOLEAN NTAPI
1157 IN PKINTERRUPT Interrupt
,
1158 IN PVOID HwDeviceExtension
1161 extern PDRIVER_OBJECT SavedDriverObject
;
1165 IN PVOID HwDeviceExtension
,
1166 IN PPCI_COMMON_CONFIG pciData
, // optional
1167 IN ULONG DeviceNumber
,
1168 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
1169 IN BOOLEAN
* simplexOnly
1174 IN PVOID HwDeviceExtension
,
1175 IN ULONG DeviceNumber
,
1181 IN PVOID HwDeviceExtension
,
1182 IN PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
1183 IN PPCI_COMMON_CONFIG pciData
,
1184 IN ULONG SystemIoBusNumber
,
1187 IN ULONG length
//range id
1190 /****************** 1 *****************/
1191 #define GetPciConfig1(offs, op) { \
1192 ScsiPortGetBusDataByOffset(HwDeviceExtension, \
1194 SystemIoBusNumber, \
1201 #define SetPciConfig1(offs, op) { \
1203 ScsiPortSetBusDataByOffset(HwDeviceExtension, \
1205 SystemIoBusNumber, \
1212 #define ChangePciConfig1(offs, _op) { \
1214 GetPciConfig1(offs, a); \
1216 SetPciConfig1(offs, a); \
1219 /****************** 2 *****************/
1220 #define GetPciConfig2(offs, op) { \
1221 ScsiPortGetBusDataByOffset(HwDeviceExtension, \
1223 SystemIoBusNumber, \
1230 #define SetPciConfig2(offs, op) { \
1232 ScsiPortSetBusDataByOffset(HwDeviceExtension, \
1234 SystemIoBusNumber, \
1241 #define ChangePciConfig2(offs, _op) { \
1243 GetPciConfig2(offs, a); \
1244 a = (USHORT)(_op); \
1245 SetPciConfig2(offs, a); \
1248 /****************** 4 *****************/
1249 #define GetPciConfig4(offs, op) { \
1250 ScsiPortGetBusDataByOffset(HwDeviceExtension, \
1252 SystemIoBusNumber, \
1259 #define SetPciConfig4(offs, op) { \
1261 ScsiPortSetBusDataByOffset(HwDeviceExtension, \
1263 SystemIoBusNumber, \
1270 #define ChangePciConfig4(offs, _op) { \
1272 GetPciConfig4(offs, a); \
1274 SetPciConfig4(offs, a); \
1277 #ifndef GetDmaStatus
1278 #define GetDmaStatus(de, c) \
1279 (((de)->BusMaster) ? AtapiReadPort1(&((de)->chan[c]), IDX_BM_Status) : 0)
1280 #endif //GetDmaStatus
1283 #define AtapiVirtToPhysAddr(hwde, srb, phaddr, plen, phaddru) \
1284 AtapiVirtToPhysAddr_(hwde, srb, phaddr, plen, phaddru);
1286 #define AtapiVirtToPhysAddr(hwde, srb, phaddr, plen, phaddru) \
1287 (ScsiPortConvertPhysicalAddressToUlong/*(ULONG)ScsiPortGetVirtualAddress*/(/*hwde,*/ \
1288 ScsiPortGetPhysicalAddress(hwde, srb, phaddr, plen)))
1289 #endif //USE_OWN_DMA
1294 IN PHW_CHANNEL chan
,
1302 IN PHW_CHANNEL chan
,
1310 IN PHW_CHANNEL chan
,
1318 IN PHW_CHANNEL chan
,
1327 IN PHW_CHANNEL chan
,
1336 IN PHW_CHANNEL chan
,
1343 IN PHW_CHANNEL chan
,
1350 IN PHW_CHANNEL chan
,
1357 IN PHW_CHANNEL chan
,
1365 IN PHW_CHANNEL chan
,
1373 IN PHW_CHANNEL chan
,
1383 IN PHW_CHANNEL chan
,
1393 IN PHW_CHANNEL chan
,
1403 IN PHW_CHANNEL chan
,
1410 /*#define GET_CHANNEL(Srb) (Srb->TargetId >> 1)
1411 #define GET_LDEV(Srb) (Srb->TargetId)
1412 #define GET_LDEV2(P, T, L) (T)*/
1414 #define GET_CHANNEL(Srb) (Srb->PathId)
1415 #define GET_LDEV(Srb) (Srb->TargetId | (Srb->PathId << 1))
1416 #define GET_LDEV2(P, T, L) (T | ((P)<<1))
1417 #define GET_CDEV(Srb) (Srb->TargetId)
1419 #define AtapiSetupLunPtrs(chan, deviceExtension, c) \
1421 chan->DeviceExtension = deviceExtension; \
1422 chan->lChannel = c; \
1423 chan->lun[0] = &(deviceExtension->lun[c*2+0]); \
1424 chan->lun[1] = &(deviceExtension->lun[c*2+1]); \
1425 chan->AltRegMap = deviceExtension->AltRegMap; \
1426 chan->NextDpcChan = -1; \
1427 chan->lun[0]->DeviceExtension = deviceExtension; \
1428 chan->lun[1]->DeviceExtension = deviceExtension; \
1432 AtapiReadChipConfig(
1433 IN PVOID HwDeviceExtension
,
1434 IN ULONG DeviceNumber
,
1435 IN ULONG channel
// physical channel
1440 PHW_LU_EXTENSION LunExt
1443 extern ULONG SkipRaids
;
1444 extern ULONG ForceSimplex
;
1446 extern BOOLEAN InDriverEntry
;
1448 extern BOOLEAN g_opt_Verbose
;
1450 extern BOOLEAN WinVer_WDM_Model
;
1452 #endif //__IDE_BUSMASTER_H__