3 Copyright (c) 2002-2010 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)
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 #define SATA_MAX_PM_UNITS 16
100 typedef struct _BUSMASTER_CTX
{
101 PBUSMASTER_CONTROLLER_INFORMATION
* BMListPtr
;
103 } BUSMASTER_CTX
, *PBUSMASTER_CTX
;
105 #define PCI_DEV_CLASS_STORAGE 0x01
107 #define PCI_DEV_SUBCLASS_IDE 0x01
108 #define PCI_DEV_SUBCLASS_RAID 0x04
109 #define PCI_DEV_SUBCLASS_ATA 0x05
110 #define PCI_DEV_SUBCLASS_SATA 0x06
112 /* structure for holding DMA address data */
113 typedef struct BM_DMA_ENTRY
{
116 } BM_DMA_ENTRY
, *PBM_DMA_ENTRY
;
118 typedef struct _IDE_BUSMASTER_REGISTERS
{
120 UCHAR DeviceSpecific0
;
122 UCHAR DeviceSpecific1
;
124 } IDE_BUSMASTER_REGISTERS
, *PIDE_BUSMASTER_REGISTERS
;
126 #define BM_STATUS_ACTIVE 0x01
127 #define BM_STATUS_ERR 0x02
128 #define BM_STATUS_INTR 0x04
129 #define BM_STATUS_MASK 0x07
130 #define BM_STATUS_DRIVE_0_DMA 0x20
131 #define BM_STATUS_DRIVE_1_DMA 0x40
132 #define BM_STATUS_SIMPLEX_ONLY 0x80
134 #define BM_COMMAND_START_STOP 0x01
135 /*#define BM_COMMAND_WRITE 0x08
136 #define BM_COMMAND_READ 0x00*/
137 #define BM_COMMAND_WRITE 0x00
138 #define BM_COMMAND_READ 0x08
140 #define BM_DS0_SII_DMA_ENABLE (1 << 0) /* DMA run switch */
141 #define BM_DS0_SII_IRQ (1 << 3) /* ??? */
142 #define BM_DS0_SII_DMA_SATA_IRQ (1 << 4) /* OR of all SATA IRQs */
143 #define BM_DS0_SII_DMA_ERROR (1 << 17) /* PCI bus error */
144 #define BM_DS0_SII_DMA_COMPLETE (1 << 18) /* cmd complete / IRQ pending */
147 #define IDX_BM_IO (IDX_IO2_o+IDX_IO2_o_SZ)
148 //#define IDX_BM_IO_SZ sizeof(IDE_BUSMASTER_REGISTERS)
149 #define IDX_BM_IO_SZ 5
151 #define IDX_BM_Command (FIELD_OFFSET(IDE_BUSMASTER_REGISTERS, Command )+IDX_BM_IO)
152 #define IDX_BM_DeviceSpecific0 (FIELD_OFFSET(IDE_BUSMASTER_REGISTERS, DeviceSpecific0)+IDX_BM_IO)
153 #define IDX_BM_Status (FIELD_OFFSET(IDE_BUSMASTER_REGISTERS, Status )+IDX_BM_IO)
154 #define IDX_BM_DeviceSpecific1 (FIELD_OFFSET(IDE_BUSMASTER_REGISTERS, DeviceSpecific1)+IDX_BM_IO)
155 #define IDX_BM_PRD_Table (FIELD_OFFSET(IDE_BUSMASTER_REGISTERS, PRD_Table )+IDX_BM_IO)
157 typedef struct _IDE_AHCI_REGISTERS
{
160 ULONG NOP
:5; // number of ports
162 ULONG NCS
:5; // number of command slots
163 ULONG PSC
:1; // partial state capable
164 ULONG SSC
:1; // slumber state capable
165 ULONG PMD
:1; // PIO multiple DRQ block
168 ULONG SPM
:1; // port multiplier
169 ULONG SAM
:1; // AHCI mode only
170 ULONG SNZO
:1; // non-zero DMA offset
171 ULONG ISS
:4; // interface speed
172 ULONG SCLO
:1; // command list override
173 ULONG SAL
:1; // activity LED
174 ULONG SALP
:1; // aggressive link power management
175 ULONG SSS
:1; // staggered spin-up
176 ULONG SIS
:1; // interlock switch
178 ULONG SNCQ
:1; // native command queue
179 ULONG S64A
:1; // 64bit addr
182 #define AHCI_CAP_NOP_MASK 0x0000001f
183 #define AHCI_CAP_SPM 0x00010000
184 #define AHCI_CAP_S64A 0x80000000
186 // Global HBA Control
188 ULONG HR
:1; // HBA Reset
189 ULONG IE
:1; // interrupt enable
190 ULONG Reserved2_30
:1;
191 ULONG AE
:1; // AHCI enable
194 #define AHCI_GHC 0x04
195 #define AHCI_GHC_HR 0x00000001
196 #define AHCI_GHC_IE 0x00000002
197 #define AHCI_GHC_AE 0x80000000
199 // Interrupt status (bit mask)
201 // Ports implemented (bit mask)
207 UCHAR Reserved2
[0x80];
209 UCHAR VendorSpec
[0x60];
210 } IDE_AHCI_REGISTERS
, *PIDE_AHCI_REGISTERS
;
212 #define IDX_AHCI_CAP (FIELD_OFFSET(IDE_AHCI_REGISTERS, CAP))
213 #define IDX_AHCI_GHC (FIELD_OFFSET(IDE_AHCI_REGISTERS, GHC))
214 #define IDX_AHCI_IS (FIELD_OFFSET(IDE_AHCI_REGISTERS, IS))
215 #define IDX_AHCI_VS (FIELD_OFFSET(IDE_AHCI_REGISTERS, VS))
216 #define IDX_AHCI_PI (FIELD_OFFSET(IDE_AHCI_REGISTERS, PI))
219 typedef union _SATA_SSTATUS_REG
{
222 ULONG DET
:4; // Device Detection
224 #define SStatus_DET_NoDev 0x00
225 #define SStatus_DET_Dev_NoPhy 0x01
226 #define SStatus_DET_Dev_Ok 0x03
227 #define SStatus_DET_Offline 0x04
229 ULONG SPD
:4; // Current Interface Speed
231 #define SStatus_SPD_NoDev 0x00
232 #define SStatus_SPD_Gen1 0x01
233 #define SStatus_SPD_Gen2 0x02
235 ULONG IPM
:4; // Interface Power Management
237 #define SStatus_IPM_NoDev 0x00
238 #define SStatus_IPM_Active 0x01
239 #define SStatus_IPM_Partial 0x02
240 #define SStatus_IPM_Slumber 0x06
246 } SATA_SSTATUS_REG
, *PSATA_SSTATUS_REG
;
249 typedef union _SATA_SCONTROL_REG
{
252 ULONG DET
:4; // Device Detection Init
254 #define SControl_DET_DoNothing 0x00
255 #define SControl_DET_Idle 0x00
256 #define SControl_DET_Init 0x01
257 #define SControl_DET_Disable 0x04
259 ULONG SPD
:4; // Speed Allowed
261 #define SControl_SPD_NoRestrict 0x00
262 #define SControl_SPD_LimGen1 0x01
263 #define SControl_SPD_LimGen2 0x02
265 ULONG IPM
:4; // Interface Power Management Transitions Allowed
267 #define SControl_IPM_NoRestrict 0x00
268 #define SControl_IPM_NoPartial 0x01
269 #define SControl_IPM_NoSlumber 0x02
270 #define SControl_IPM_NoPartialSlumber 0x03
272 ULONG SPM
:4; // Select Power Management, unused by AHCI
273 ULONG PMP
:4; // Port Multiplier Port, unused by AHCI
278 } SATA_SCONTROL_REG
, *PSATA_SCONTROL_REG
;
281 typedef union _SATA_SERROR_REG
{
285 UCHAR I
:1; // Recovered Data Integrity Error
286 UCHAR M
:1; // Recovered Communications Error
287 UCHAR Reserved_2_7
:6;
289 UCHAR T
:1; // Transient Data Integrity Error
290 UCHAR C
:1; // Persistent Communication or Data Integrity Error
291 UCHAR P
:1; // Protocol Error
292 UCHAR E
:1; // Internal Error
293 UCHAR Reserved_12_15
:4;
297 UCHAR N
:1; // PhyRdy Change, PIS.PRCS
298 UCHAR I
:1; // Phy Internal Error
299 UCHAR W
:1; // Comm Wake
300 UCHAR B
:1; // 10B to 8B Decode Error
301 UCHAR D
:1; // Disparity Error, not used by AHCI
302 UCHAR C
:1; // CRC Error
303 UCHAR H
:1; // Handshake Error
304 UCHAR S
:1; // Link Sequence Error
306 UCHAR T
:1; // Transport state transition error
307 UCHAR F
:1; // Unknown FIS Type
308 UCHAR X
:1; // Exchanged
309 UCHAR Reserved_27_31
:5;
314 } SATA_SERROR_REG
, *PSATA_SERROR_REG
;
317 typedef struct _IDE_SATA_REGISTERS
{
319 SATA_SSTATUS_REG SStatus
;
323 SATA_SERROR_REG SError
;
327 SATA_SCONTROL_REG SControl
;
337 USHORT PMN
; // PM Notify, bitmask
342 } IDE_SATA_REGISTERS
, *PIDE_SATA_REGISTERS
;
344 #define IDX_SATA_IO (IDX_BM_IO+IDX_BM_IO_SZ)
345 //#define IDX_SATA_IO_SZ sizeof(IDE_SATA_REGISTERS)
346 #define IDX_SATA_IO_SZ 5
348 #define IDX_SATA_SStatus (0+IDX_SATA_IO)
349 #define IDX_SATA_SError (1+IDX_SATA_IO)
350 #define IDX_SATA_SControl (2+IDX_SATA_IO)
351 #define IDX_SATA_SActive (3+IDX_SATA_IO)
352 #define IDX_SATA_SNTF_PMN (4+IDX_SATA_IO)
354 #define IDX_INDEXED_IO (IDX_SATA_IO+IDX_SATA_IO_SZ)
355 #define IDX_INDEXED_IO_SZ 2
357 #define IDX_INDEXED_ADDR (0+IDX_INDEXED_IO)
358 #define IDX_INDEXED_DATA (1+IDX_INDEXED_IO)
360 #define IDX_MAX_REG (IDX_INDEXED_IO+IDX_INDEXED_IO_SZ)
363 typedef union _AHCI_IS_REG
{
365 ULONG DHRS
:1;// Device to Host Register FIS Interrupt
366 ULONG PSS
:1; // PIO Setup FIS Interrupt
367 ULONG DSS
:1; // DMA Setup FIS Interrupt
368 ULONG SDBS
:1;// Set Device Bits Interrupt
369 ULONG UFS
:1; // Unknown FIS Interrupt
370 ULONG DPS
:1; // Descriptor Processed
371 ULONG PCS
:1; // Port Connect Change Status
372 ULONG DMPS
:1;// Device Mechanical Presence Status
374 ULONG Reserved_8_21
:14;
375 ULONG PRCS
:1;// PhyRdy Change Status
376 ULONG IPMS
:1;// Incorrect Port Multiplier Status
378 ULONG OFS
:1; // Overflow Status
380 ULONG INFS
:1;// Interface Non-fatal Error Status
381 ULONG IFS
:1; // Interface Fatal Error Status
382 ULONG HBDS
:1;// Host Bus Data Error Status
383 ULONG HBFS
:1;// Host Bus Fatal Error Status
384 ULONG TFES
:1;// Task File Error Status
385 ULONG CPDS
:1;// Cold Port Detect Status
388 } AHCI_IS_REG
, *PAHCI_IS_REG
;
391 typedef struct _IDE_AHCI_PORT_REGISTERS
{
394 ULONG CLB
; // command list base address
395 ULONG CLBU
; // command list base address (upper 32bits)
402 ULONG FB
; // FIS base address
403 ULONG FBU
; // FIS base address (upper 32bits)
409 ULONG IS_Reg
; // interrupt status
414 ULONG Reg
; // interrupt enable
416 ULONG DHRE
:1;// Device to Host Register FIS Interrupt Enable
417 ULONG PSE
:1; // PIO Setup FIS Interrupt Enable
418 ULONG DSE
:1; // DMA Setup FIS Interrupt Enable
419 ULONG SDBE
:1;// Set Device Bits FIS Interrupt Enable
420 ULONG UFE
:1; // Unknown FIS Interrupt Enable
421 ULONG DPE
:1; // Descriptor Processed Interrupt Enable
422 ULONG PCE
:1; // Port Change Interrupt Enable
423 ULONG DPME
:1;// Device Mechanical Presence Enable
425 ULONG Reserved_8_21
:14;
426 ULONG PRCE
:1;// PhyRdy Change Interrupt Enable
427 ULONG IPME
:1;// Incorrect Port Multiplier Enable
428 ULONG OFE
:1; // Overflow Enable
430 ULONG INFE
:1;// Interface Non-fatal Error Enable
431 ULONG IFE
:1; // Interface Fatal Error Enable
432 ULONG HBDE
:1;// Host Bus Data Error Enable
433 ULONG HBFE
:1;// Host Bus Fatal Error Enable
434 ULONG TFEE
:1;// Task File Error Enable
435 ULONG CPDE
:1;// Cold Port Detect Enable
440 ULONG Reg
; // command register
444 ULONG SUD
:1; // Spin-Up Device
445 ULONG POD
:1; // Power On Device
446 ULONG CLO
:1; // Command List Override
447 ULONG FRE
:1; // FIS Receive Enable
448 ULONG Reserved_5_7
:3;
450 ULONG CCS
:5; // Current Command Slot
451 ULONG MPSS
:1;// Mechanical Presence Switch State
452 ULONG FR
:1; // FIS Receive Running
453 ULONG CR
:1; // Command List Running
455 ULONG CPS
:1; // Cold Presence State
456 ULONG PMA
:1; // Port Multiplier Attached
457 ULONG HPCP
:1;// Hot Plug Capable Port
458 ULONG MPSP
:1;// Mechanical Presence Switch Attached to Port
459 ULONG CPD
:1; // Cold Presence Detection
460 ULONG ESP
:1; // External SATA Port
461 ULONG Reserved_22_23
:2;
463 ULONG ATAPI
:1; // Device is ATAPI
464 ULONG DLAE
:1;// Drive LED on ATAPI Enable
465 ULONG ALPE
:1;// Aggressive Link Power Management Enable
466 ULONG ASP
:1; // Aggressive Slumber / Partial
467 ULONG ICC
:4; // Interface Communication Control
469 #define SATA_CMD_ICC_Idle 0x00
470 #define SATA_CMD_ICC_NoOp 0x00
471 #define SATA_CMD_ICC_Active 0x01
472 #define SATA_CMD_ICC_Partial 0x02
473 #define SATA_CMD_ICC_Slumber 0x06
480 ULONG Reg
; // Task File Data
484 UCHAR cs1
:2;// command-specific
486 UCHAR cs2
:3;// command-specific
489 UCHAR ERR
; // Contains the latest copy of the task file error register.
495 ULONG Reg
; // signature
504 ULONG SStatus
; // SCR0
505 SATA_SSTATUS_REG SSTS
;
508 ULONG SControl
; // SCR2
509 SATA_SCONTROL_REG SCTL
;
512 ULONG SError
; // SCR1
513 SATA_SERROR_REG SERR
;
517 ULONG SActive
; // bitmask
519 ULONG CI
; // Command issue, bitmask
525 USHORT PMN
; // PM Notify, bitmask
529 ULONG FIS_Switching_Reserved
[12];
530 UCHAR VendorSpec
[16];
532 } IDE_AHCI_PORT_REGISTERS
, *PIDE_AHCI_PORT_REGISTERS
;
534 #define IDX_AHCI_P_CLB (FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, CLB))
535 #define IDX_AHCI_P_FB (FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, FB))
536 #define IDX_AHCI_P_IS (FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, IS))
537 #define IDX_AHCI_P_CI (FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, CI))
539 typedef struct _IDE_AHCI_PRD_ENTRY
{
557 } IDE_AHCI_PRD_ENTRY
, *PIDE_AHCI_PRD_ENTRY
;
559 #define ATA_AHCI_DMA_ENTRIES (PAGE_SIZE/2/sizeof(IDE_AHCI_PRD_ENTRY)) /* 128 */
560 #define ATA_AHCI_MAX_TAGS 32
562 typedef struct _IDE_AHCI_CMD
{
566 IDE_AHCI_PRD_ENTRY prd_tab
[ATA_AHCI_DMA_ENTRIES
];
567 } IDE_AHCI_CMD
, *PIDE_AHCI_CMD
;
569 typedef struct _IDE_AHCI_CMD_LIST
{
571 USHORT prd_length
; /* PRD entries */
573 ULONGLONG cmd_table_phys
; /* 128byte aligned */
575 } IDE_AHCI_CMD_LIST
, *PIDE_AHCI_CMD_LIST
;
577 typedef struct _IDE_AHCI_RCV_FIS
{
587 } IDE_AHCI_RCV_FIS
, *PIDE_AHCI_RCV_FIS
;
590 #define IsBusMaster(pciData) \
591 ( ((pciData)->Command & (PCI_ENABLE_BUS_MASTER/* | PCI_ENABLE_IO_SPACE*/)) == \
592 (PCI_ENABLE_BUS_MASTER/* | PCI_ENABLE_IO_SPACE*/))
594 #define PCI_IDE_PROGIF_NATIVE_1 0x01
595 #define PCI_IDE_PROGIF_NATIVE_2 0x04
596 #define PCI_IDE_PROGIF_NATIVE_ALL 0x05
598 #define IsMasterDev(pciData) \
599 ( ((pciData)->ProgIf & 0x80) && \
600 ((pciData)->ProgIf & PCI_IDE_PROGIF_NATIVE_ALL) != PCI_IDE_PROGIF_NATIVE_ALL )
602 //#define INT_Q_SIZE 32
603 #define MIN_REQ_TTL 4
607 typedef union _ATA_REQ
{
608 // ULONG reqId; // serial
614 union _ATA_REQ
* next_req
;
615 union _ATA_REQ
* prev_req
;
617 PSCSI_REQUEST_BLOCK Srb
; // Current request on controller.
619 PUSHORT DataBuffer
; // Data buffer pointer.
620 ULONG WordsLeft
; // Data words left.
621 ULONG TransferLength
; // Originally requested transfer length
623 ULONG WordsTransfered
;// Data words already transfered.
632 PSCSI_REQUEST_BLOCK OriginalSrb
; // Mechanism Status Srb Data
637 ULONGLONG ahci_base64
; // for AHCI
640 UCHAR padding_128b
[128];
644 BM_DMA_ENTRY dma_tab
[ATA_DMA_ENTRIES
];
645 IDE_AHCI_CMD ahci_cmd
; // for AHCI
650 UCHAR padding_4kb
[PAGE_SIZE
];
652 } ATA_REQ
, *PATA_REQ
;
654 #define REQ_FLAG_FORCE_DOWNRATE 0x01
655 #define REQ_FLAG_DMA_OPERATION 0x02
656 #define REQ_FLAG_REORDERABLE_CMD 0x04
657 #define REQ_FLAG_RW_MASK 0x08
658 #define REQ_FLAG_READ 0x08
659 #define REQ_FLAG_WRITE 0x00
660 #define REQ_FLAG_FORCE_DOWNRATE_LBA48 0x10
661 #define REQ_FLAG_DMA_DBUF 0x20
662 #define REQ_FLAG_DMA_DBUF_PRD 0x40
665 #define REQ_STATE_NONE 0x00
666 #define REQ_STATE_QUEUED 0x10
668 #define REQ_STATE_PREPARE_TO_TRANSFER 0x20
669 #define REQ_STATE_PREPARE_TO_NEXT 0x21
670 #define REQ_STATE_READY_TO_TRANSFER 0x30
672 #define REQ_STATE_EXPECTING_INTR 0x40
673 #define REQ_STATE_ATAPI_EXPECTING_CMD_INTR 0x41
674 #define REQ_STATE_ATAPI_EXPECTING_DATA_INTR 0x42
675 #define REQ_STATE_ATAPI_DO_NOTHING_INTR 0x43
677 #define REQ_STATE_EARLY_INTR 0x48
679 #define REQ_STATE_PROCESSING_INTR 0x50
681 #define REQ_STATE_DPC_INTR_REQ 0x51
682 #define REQ_STATE_DPC_RESET_REQ 0x52
683 #define REQ_STATE_DPC_COMPLETE_REQ 0x53
685 #define REQ_STATE_DPC_WAIT_BUSY0 0x57
686 #define REQ_STATE_DPC_WAIT_BUSY1 0x58
687 #define REQ_STATE_DPC_WAIT_BUSY 0x59
688 #define REQ_STATE_DPC_WAIT_DRQ 0x5a
689 #define REQ_STATE_DPC_WAIT_DRQ0 0x5b
690 #define REQ_STATE_DPC_WAIT_DRQ_ERR 0x5c
692 #define REQ_STATE_TRANSFER_COMPLETE 0x7f
695 #define CMD_ACTION_PREPARE 0x01
696 #define CMD_ACTION_EXEC 0x02
697 #define CMD_ACTION_ALL (CMD_ACTION_PREPARE | CMD_ACTION_EXEC)
699 // predefined Reorder costs
700 #define REORDER_COST_MAX ((DEF_I64(0x1) << 60) - 1)
701 #define REORDER_COST_TTL (REORDER_COST_MAX - 1)
702 #define REORDER_COST_INTERSECT (REORDER_COST_MAX - 2)
703 #define REORDER_COST_DENIED (REORDER_COST_MAX - 3)
704 #define REORDER_COST_RESELECT (REORDER_COST_MAX/4)
706 #define REORDER_COST_SWITCH_RW_CD (REORDER_COST_MAX/8)
707 #define REORDER_MCOST_SWITCH_RW_CD (0)
708 #define REORDER_MCOST_SEEK_BACK_CD (16)
710 #define REORDER_COST_SWITCH_RW_HDD (0)
711 #define REORDER_MCOST_SWITCH_RW_HDD (4)
712 #define REORDER_MCOST_SEEK_BACK_HDD (2)
714 /*typedef struct _ATA_QUEUE {
715 struct _ATA_REQ* head_req; // index
716 struct _ATA_REQ* tail_req; // index
719 BM_DMA_ENTRY dma_tab[ATA_DMA_ENTRIES];
720 } ATA_QUEUE, *PATA_QUEUE;*/
722 struct _HW_DEVICE_EXTENSION
;
723 struct _HW_LU_EXTENSION
;
725 typedef struct _IORES
{
726 ULONG Addr
; /* Base address*/
727 ULONG MemIo
:1; /* Memory mapping (1) vs IO ports (0) */
728 ULONG Proc
:1; /* Need special process via IO_Proc */
733 typedef struct _HW_CHANNEL
{
737 /* PATA_REQ first_req;
740 ULONG ChannelSelectWaitCount
;
744 BOOLEAN ExpectingInterrupt
; // Indicates expecting an interrupt
745 BOOLEAN RDP
; // Indicate last tape command was DSC Restrictive.
746 // Indicates whether '0x1f0' is the base address. Used
747 // in SMART Ioctl calls.
748 BOOLEAN PrimaryAddress
;
749 // Placeholder for the sub-command value of the last
754 // Placeholder for status register after a GET_MEDIA_STATUS command
755 UCHAR ReturningMediaStatus
;
757 BOOLEAN CopyDmaBuffer
;
763 MECHANICAL_STATUS_INFORMATION_HEADER MechStatusData
;
764 SENSE_DATA MechStatusSense
;
765 ULONG MechStatusRetryCount
;
766 SCSI_REQUEST_BLOCK InternalSrb
;
768 ULONG MaxTransferMode
; // may differ from Controller's value due to 40-pin cable
770 ULONG ChannelCtrlFlags
;
771 ULONG ResetInProgress
; // flag
777 #define CHECK_INTR_ACTIVE 0x03
778 #define CHECK_INTR_DETECTED 0x02
779 #define CHECK_INTR_CHECK 0x01
780 #define CHECK_INTR_IDLE 0x00
783 PHW_TIMER HwScsiTimer
;
786 PHW_TIMER HwScsiTimer1
;
787 PHW_TIMER HwScsiTimer2
;
790 // LARGE_INTEGER ActivationTime;
794 // PHW_TIMER HwScsiTimer;
795 // KSPIN_LOCK QueueSpinLock;
796 // KIRQL QueueOldIrql;
798 struct _HW_DEVICE_EXTENSION
* DeviceExtension
;
799 struct _HW_LU_EXTENSION
* lun
[IDE_MAX_LUN_PER_CHAN
];
804 // Double-buffering support
813 PIDE_AHCI_CMD_LIST AHCI_CL
;
814 ULONGLONG AHCI_CL_PhAddr
;
815 PVOID AHCI_FIS
; // is not actually used by UniATA now, but is required by AHCI controller
816 ULONGLONG AHCI_FIS_PhAddr
;
817 // Note: in contrast to FBSD, we keep PRD and CMD item in AtaReq structure
819 #ifdef QUEUE_STATISTICS
820 LONGLONG QueueStat
[MAX_QUEUE_STAT
];
821 LONGLONG ReorderCount
;
822 LONGLONG IntersectCount
;
823 LONGLONG TryReorderCount
;
824 LONGLONG TryReorderHeadCount
;
825 LONGLONG TryReorderTailCount
; /* in-order requests */
826 #endif //QUEUE_STATISTICS
828 //ULONG BaseMemAddress;
829 //ULONG BaseMemAddressOffset;
830 IORES RegTranslation
[IDX_MAX_REG
];
832 } HW_CHANNEL
, *PHW_CHANNEL
;
834 #define CTRFLAGS_DMA_ACTIVE 0x0001
835 #define CTRFLAGS_DMA_RO 0x0002
836 #define CTRFLAGS_DMA_OPERATION 0x0004
837 #define CTRFLAGS_INTR_DISABLED 0x0008
838 #define CTRFLAGS_DPC_REQ 0x0010
839 #define CTRFLAGS_ENABLE_INTR_REQ 0x0020
840 #define CTRFLAGS_LBA48 0x0040
841 #define CTRFLAGS_DSC_BSY 0x0080
842 #define CTRFLAGS_NO_SLAVE 0x0100
843 //#define CTRFLAGS_PATA 0x0200
845 #define CTRFLAGS_PERMANENT (CTRFLAGS_DMA_RO | CTRFLAGS_NO_SLAVE)
847 #define GEOM_AUTO 0xffffffff
848 #define GEOM_STD 0x0000
849 #define GEOM_UNIATA 0x0001
850 #define GEOM_ORIG 0x0002
851 #define GEOM_MANUAL 0x0003
853 #define DPC_STATE_NONE 0x00
854 #define DPC_STATE_ISR 0x10
855 #define DPC_STATE_DPC 0x20
856 #define DPC_STATE_TIMER 0x30
857 #define DPC_STATE_COMPLETE 0x40
859 // Logical unit extension
860 typedef struct _HW_LU_EXTENSION
{
861 IDENTIFY_DATA2 IdentifyData
;
862 ULONGLONG NumOfSectors
;
863 ULONG DeviceFlags
; // Flags word for each possible device. DFLAGS_XXX
864 ULONG DiscsPresent
; // Indicates number of platters on changer-ish devices.
865 BOOLEAN DWordIO
; // Indicates use of 32-bit PIO
866 UCHAR ReturningMediaStatus
;
868 UCHAR TransferMode
; // current transfer mode
869 UCHAR LimitedTransferMode
; // user-defined or IDE cable limitation
870 UCHAR OrigTransferMode
; // transfer mode, returned by device IDENTIFY (can be changed via IOCTL)
872 UCHAR MaximumBlockXfer
;
873 UCHAR Padding0
[2]; // padding
874 ULONG ErrorCount
; // Count of errors. Used to turn off features.
875 // ATA_QUEUE cmd_queue;
876 LONGLONG ReadCmdCost
;
877 LONGLONG WriteCmdCost
;
878 LONGLONG OtherCmdCost
;
879 LONGLONG RwSwitchCost
;
880 LONGLONG RwSwitchMCost
;
881 LONGLONG SeekBackMCost
;
888 ULONG LunSelectWaitCount
;
892 ULONG opt_MaxTransferMode
;
893 ULONG opt_PreferedTransferMode
;
894 BOOLEAN opt_ReadCacheEnable
;
895 BOOLEAN opt_WriteCacheEnable
;
898 BOOLEAN opt_reserved
[1];
900 struct _SBadBlockListItem
* bbListDescr
;
901 struct _SBadBlockRange
* arrBadBlocks
;
904 // Controller-specific LUN options
906 /* for tricky controllers, those can change Logical-to-Physical LUN mapping.
907 Treated as PHYSICAL port number, regardless of logical mapping.
912 struct _HW_DEVICE_EXTENSION
* DeviceExtension
;
916 LONGLONG ModeErrorCount
[MAX_RETRIES
];
917 LONGLONG RecoverCount
[MAX_RETRIES
];
920 #endif//IO_STATISTICS
921 } HW_LU_EXTENSION
, *PHW_LU_EXTENSION
;
924 typedef struct _HW_DEVICE_EXTENSION
{
926 //PIDE_REGISTERS_1 BaseIoAddress1[IDE_MAX_CHAN]; // Base register locations
927 //PIDE_REGISTERS_2 BaseIoAddress2[IDE_MAX_CHAN];
928 ULONG BusInterruptLevel
; // Interrupt level
929 ULONG InterruptMode
; // Interrupt Mode (Level or Edge)
930 ULONG BusInterruptVector
;
931 // Number of channels being supported by one instantiation
932 // of the device extension. Normally (and correctly) one, but
933 // with so many broken PCI IDE controllers being sold, we have
935 ULONG NumberChannels
;
937 ULONG FirstChannelToCheck
;
939 HW_LU_EXTENSION lun
[IDE_MAX_LUN
];
940 HW_CHANNEL chan
[AHCI_MAX_PORT
/*IDE_MAX_CHAN*/];
942 PHW_LU_EXTENSION lun
;
945 UCHAR LastInterruptedChannel
;
946 // Indicates the number of blocks transferred per int. according to the
948 BOOLEAN DriverMustPoll
; // Driver is being used by the crash dump utility or ntldr.
950 BOOLEAN UseDpc
; // Indicates use of DPC on long waits
951 IDENTIFY_DATA FullIdentifyData
; // Identify data for device
952 // BusMaster specific data
953 // PBM_DMA_ENTRY dma_tab_0;
954 //KSPIN_LOCK DpcSpinLock;
959 PHW_TIMER HwScsiTimer1;
960 PHW_TIMER HwScsiTimer2;
966 PDEVICE_OBJECT Isr2DevObj
;
968 //PIDE_BUSMASTER_REGISTERS BaseIoAddressBM_0;
969 IORES BaseIoAddressBM_0
;
970 //PIDE_BUSMASTER_REGISTERS BaseIoAddressBM[IDE_MAX_CHAN];
972 // Device identification
976 ULONG SystemIoBusNumber
;
979 ULONG InitMethod
; // vendor specific
990 BOOLEAN DWordIO
; // Indicates use of 32-bit PIO
995 ULONG MaxTransferMode
; // max transfer mode supported by controller
997 INTERFACE_TYPE OrigAdapterInterfaceType
;
998 INTERFACE_TYPE AdapterInterfaceType
;
999 ULONG MaximumDmaTransferLength
;
1000 ULONG AlignmentMask
;
1002 //ULONG BaseMemAddress;
1004 //PIDE_SATA_REGISTERS BaseIoAddressSATA_0;
1005 IORES BaseIoAddressSATA_0
;
1006 //PIDE_SATA_REGISTERS BaseIoAddressSATA[IDE_MAX_CHAN];
1009 //PIDE_AHCI_PORT_REGISTERS BaseIoAHCIPort[AHCI_MAX_PORT];
1011 BOOLEAN opt_AtapiDmaZeroTransfer
; // default FALSE
1012 BOOLEAN opt_AtapiDmaControlCmd
; // default FALSE
1013 BOOLEAN opt_AtapiDmaRawRead
; // default TRUE
1014 BOOLEAN opt_AtapiDmaReadWrite
; // default TRUE
1018 // Controller specific state/options
1023 } HW_DEVICE_EXTENSION
, *PHW_DEVICE_EXTENSION
;
1025 typedef struct _ISR2_DEVICE_EXTENSION
{
1026 PHW_DEVICE_EXTENSION HwDeviceExtension
;
1028 } ISR2_DEVICE_EXTENSION
, *PISR2_DEVICE_EXTENSION
;
1030 #define HBAFLAGS_DMA_DISABLED 0x01
1031 #define HBAFLAGS_DMA_DISABLED_LBA48 0x02
1033 extern UCHAR pciBuffer
[256];
1034 extern PBUSMASTER_CONTROLLER_INFORMATION BMList
;
1035 extern ULONG BMListLen
;
1036 extern ULONG IsaCount
;
1037 extern ULONG MCACount
;
1039 //extern const CHAR retry_Wdma[MAX_RETRIES+1];
1040 //extern const CHAR retry_Udma[MAX_RETRIES+1];
1044 UniataEnumBusMasterController(
1045 IN PVOID DriverObject
,
1050 UniataFindCompatBusMasterController1(
1051 IN PVOID HwDeviceExtension
,
1053 IN PVOID BusInformation
,
1054 IN PCHAR ArgumentString
,
1055 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
1060 UniataFindCompatBusMasterController2(
1061 IN PVOID HwDeviceExtension
,
1063 IN PVOID BusInformation
,
1064 IN PCHAR ArgumentString
,
1065 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
1069 #define UNIATA_ALLOCATE_NEW_LUNS 0x00
1073 UniataAllocateLunExt(
1074 PHW_DEVICE_EXTENSION deviceExtension
,
1075 ULONG NewNumberChannels
1079 UniataFindBusMasterController(
1080 IN PVOID HwDeviceExtension
,
1082 IN PVOID BusInformation
,
1083 IN PCHAR ArgumentString
,
1084 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
1089 UniataFindFakeBusMasterController(
1090 IN PVOID HwDeviceExtension
,
1092 IN PVOID BusInformation
,
1093 IN PCHAR ArgumentString
,
1094 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
1101 IN PVOID HwDeviceExtension
1106 UniataDisconnectIntr2(
1107 IN PVOID HwDeviceExtension
1112 ScsiPortGetBusDataByOffset(
1113 IN PVOID HwDeviceExtension
,
1114 IN BUS_DATA_TYPE BusDataType
,
1116 IN ULONG SlotNumber
,
1122 #define PCIBUSNUM_NOT_SPECIFIED (0xffffffffL)
1123 #define PCISLOTNUM_NOT_SPECIFIED (0xffffffffL)
1128 PBUSMASTER_CONTROLLER_INFORMATION BusMasterAdapters
,
1130 IN PVOID HwDeviceExtension
,
1132 IN ULONG SlotNumber
,
1133 OUT PCI_SLOT_NUMBER
* _slotData
// optional
1139 IN PVOID HwDeviceExtension
,
1140 IN BUS_DATA_TYPE BusDataType
,
1142 IN ULONG SlotNumber
,
1150 IN PVOID HwDeviceExtension
,
1151 IN PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
1152 IN ULONG lChannel
// logical channel,
1158 IN PVOID HwDeviceExtension
,
1159 IN ULONG DeviceNumber
,
1160 IN ULONG lChannel
, // logical channel,
1161 IN PSCSI_REQUEST_BLOCK Srb
,
1169 PVOID HwDeviceExtension
,
1170 PSCSI_REQUEST_BLOCK Srb
,
1179 PSCSI_REQUEST_BLOCK Srb
1185 IN PVOID HwDeviceExtension
,
1186 IN ULONG DeviceNumber
,
1187 IN ULONG lChannel
, // logical channel,
1188 IN PSCSI_REQUEST_BLOCK Srb
1194 IN PVOID HwDeviceExtension
,
1195 IN ULONG DeviceNumber
,
1196 IN ULONG lChannel
, // logical channel,
1197 IN PSCSI_REQUEST_BLOCK Srb
1203 IN PHW_DEVICE_EXTENSION deviceExtension
,
1211 IN PHW_DEVICE_EXTENSION deviceExtension
,
1218 IN PVOID HwDeviceExtension
,
1219 IN ULONG DeviceNumber
,
1220 IN ULONG lChannel
, // logical channel,
1221 // is always 0 except simplex-only controllers
1227 extern BOOLEAN NTAPI
1229 IN PKINTERRUPT Interrupt
,
1230 IN PVOID HwDeviceExtension
1233 extern PDRIVER_OBJECT SavedDriverObject
;
1237 UniataChipDetectChannels(
1238 IN PVOID HwDeviceExtension
,
1239 IN PPCI_COMMON_CONFIG pciData
, // optional
1240 IN ULONG DeviceNumber
,
1241 IN PPORT_CONFIGURATION_INFORMATION ConfigInfo
1247 IN PVOID HwDeviceExtension
,
1248 IN PPCI_COMMON_CONFIG pciData
, // optional
1249 IN ULONG DeviceNumber
,
1250 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
1251 IN BOOLEAN
* simplexOnly
1257 IN PVOID HwDeviceExtension
,
1258 IN ULONG DeviceNumber
,
1265 IN PVOID HwDeviceExtension
,
1266 IN PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
1267 IN PPCI_COMMON_CONFIG pciData
,
1268 IN ULONG SystemIoBusNumber
,
1271 IN ULONG length
//range id
1274 /****************** 1 *****************/
1275 #define GetPciConfig1(offs, op) { \
1276 ScsiPortGetBusDataByOffset(HwDeviceExtension, \
1278 SystemIoBusNumber, \
1285 #define SetPciConfig1(offs, op) { \
1287 ScsiPortSetBusDataByOffset(HwDeviceExtension, \
1289 SystemIoBusNumber, \
1296 #define ChangePciConfig1(offs, _op) { \
1298 GetPciConfig1(offs, a); \
1300 SetPciConfig1(offs, a); \
1303 /****************** 2 *****************/
1304 #define GetPciConfig2(offs, op) { \
1305 ScsiPortGetBusDataByOffset(HwDeviceExtension, \
1307 SystemIoBusNumber, \
1314 #define SetPciConfig2(offs, op) { \
1316 ScsiPortSetBusDataByOffset(HwDeviceExtension, \
1318 SystemIoBusNumber, \
1325 #define ChangePciConfig2(offs, _op) { \
1327 GetPciConfig2(offs, a); \
1328 a = (USHORT)(_op); \
1329 SetPciConfig2(offs, a); \
1332 /****************** 4 *****************/
1333 #define GetPciConfig4(offs, op) { \
1334 ScsiPortGetBusDataByOffset(HwDeviceExtension, \
1336 SystemIoBusNumber, \
1343 #define SetPciConfig4(offs, op) { \
1345 ScsiPortSetBusDataByOffset(HwDeviceExtension, \
1347 SystemIoBusNumber, \
1354 #define ChangePciConfig4(offs, _op) { \
1356 GetPciConfig4(offs, a); \
1358 SetPciConfig4(offs, a); \
1361 #ifndef GetDmaStatus
1362 #define GetDmaStatus(de, c) \
1363 (((de)->BusMaster) ? AtapiReadPort1(&((de)->chan[c]), IDX_BM_Status) : 0)
1364 #endif //GetDmaStatus
1367 #define AtapiVirtToPhysAddr(hwde, srb, phaddr, plen, phaddru) \
1368 AtapiVirtToPhysAddr_(hwde, srb, phaddr, plen, phaddru);
1370 #define AtapiVirtToPhysAddr(hwde, srb, phaddr, plen, phaddru) \
1371 (ScsiPortConvertPhysicalAddressToUlong/*(ULONG)ScsiPortGetVirtualAddress*/(/*hwde,*/ \
1372 ScsiPortGetPhysicalAddress(hwde, srb, phaddr, plen)))
1373 #endif //USE_OWN_DMA
1378 IN PHW_CHANNEL chan
,
1386 IN PHW_CHANNEL chan
,
1394 IN PHW_CHANNEL chan
,
1402 IN PHW_CHANNEL chan
,
1411 IN PHW_CHANNEL chan
,
1420 IN PHW_CHANNEL chan
,
1427 IN PHW_CHANNEL chan
,
1434 IN PHW_CHANNEL chan
,
1441 IN PHW_CHANNEL chan
,
1449 IN PHW_CHANNEL chan
,
1457 IN PHW_CHANNEL chan
,
1467 IN PHW_CHANNEL chan
,
1477 IN PHW_CHANNEL chan
,
1487 IN PHW_CHANNEL chan
,
1494 /*#define GET_CHANNEL(Srb) (Srb->TargetId >> 1)
1495 #define GET_LDEV(Srb) (Srb->TargetId)
1496 #define GET_LDEV2(P, T, L) (T)*/
1498 #define GET_CHANNEL(Srb) (Srb->PathId)
1499 #define GET_LDEV(Srb) (Srb->TargetId | (Srb->PathId << 1))
1500 #define GET_LDEV2(P, T, L) (T | ((P)<<1))
1501 #define GET_CDEV(Srb) (Srb->TargetId)
1506 IN PHW_CHANNEL chan
,
1507 IN PHW_DEVICE_EXTENSION deviceExtension
,
1511 #define AtapiSetupLunPtrs(chan, deviceExtension, c) \
1513 chan->DeviceExtension = deviceExtension; \
1514 chan->lChannel = c; \
1515 chan->lun[0] = &(deviceExtension->lun[c*2+0]); \
1516 chan->lun[1] = &(deviceExtension->lun[c*2+1]); \
1517 chan->AltRegMap = deviceExtension->AltRegMap; \
1518 chan->NextDpcChan = -1; \
1519 chan->lun[0]->DeviceExtension = deviceExtension; \
1520 chan->lun[1]->DeviceExtension = deviceExtension; \
1525 AtapiReadChipConfig(
1526 IN PVOID HwDeviceExtension
,
1527 IN ULONG DeviceNumber
,
1528 IN ULONG channel
// physical channel
1534 PHW_LU_EXTENSION LunExt
1537 extern ULONG SkipRaids
;
1538 extern ULONG ForceSimplex
;
1540 extern BOOLEAN InDriverEntry
;
1542 extern BOOLEAN g_opt_Verbose
;
1544 extern BOOLEAN WinVer_WDM_Model
;
1546 #endif //__IDE_BUSMASTER_H__