source: trunk/src/os2ahci/ahci.h@ 174

Last change on this file since 174 was 174, checked in by David Azarewicz, 12 years ago

Fix for hardware that reports incorrect status.
Now report both real and fake devices when SCSI emulation is enabled.

File size: 15.8 KB
Line 
1/******************************************************************************
2 * ahci.h - AHCI-specific constants for os2ahci.h
3 *
4 * Copyright (c) 2011 thi.guten Software Development
5 * Copyright (c) 2011 Mensys B.V.
6 *
7 * Authors: Christian Mueller, Markus Thielen
8 *
9 * Parts copied from/inspired by the Linux AHCI driver;
10 * those parts are (c) Linux AHCI/ATA maintainers
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 */
26
27/* ----------------------------- include files ----------------------------- */
28
29/* -------------------------- macros and constants ------------------------- */
30
31/******************************************************************************
32 * device prefix strings for Resource Manager
33 */
34#define RM_HD_PREFIX "HD_(%d,%d) "
35#define RM_HD_PREFIX_LEN (sizeof(RM_HD_PREFIX) - 1)
36#define RM_CD_PREFIX "CD_(%d,%d) "
37#define RM_CD_PREFIX_LEN (sizeof(RM_CD_PREFIX) - 1)
38#define RM_TAPE_PREFIX "TAPE_(%d,%d) "
39#define RM_TAPE_PREFIX_LEN (sizeof(RM_TAPE_PREFIX) - 1)
40#define RM_MAX_PREFIX_LEN RM_TAPE_PREFIX_LEN
41
42/******************************************************************************
43 * AHCI flags and constants; those were initially copied from the Linux AHCI
44 * driver but converted to macros because enums are 16 bits for OS/2 drivers
45 * (unless we use KEE and a 32-bit compiler, which we don't)
46 *
47 * Changes from the Linux source:
48 *
49 * - reduced AHCI_MAX_SG from 168 to 48 because the port-specific DMA scratch
50 * buffer needs to be less than 64K to allow mapping the whole DMA area to a
51 * 16-bit memory segment
52 *
53 * - added AHCI_MAX_SG_ELEMENT_LEN constant
54 *
55 * - replaced much of the top-level size/offset math with real structs and
56 * corresponding sizeof() directives.
57 */
58#define AHCI_PCI_BAR 5
59#define AHCI_MAX_PORTS 16 /* Spec says 32, but we only support 16 */
60#define AHCI_MAX_DEVS 8
61#define AHCI_MAX_SG 48 /* hardware max is 64K */
62#define AHCI_MAX_SG_ELEMENT_LEN (1UL << 22)
63#define AHCI_MAX_CMDS 32
64#define AHCI_RX_FIS_SZ 256
65
66/* port-specific DMA scratch buffer aligned to 1024 bytes */
67#define AHCI_PORT_PRIV_DMA_SZ (((sizeof(AHCI_PORT_DMA) + 1023U) / 1024U) * 1024U)
68
69#define AHCI_IRQ_ON_SG (1UL << 31)
70#define AHCI_CMD_ATAPI (1UL << 5)
71#define AHCI_CMD_WRITE (1UL << 6)
72#define AHCI_CMD_PREFETCH (1UL << 7)
73#define AHCI_CMD_RESET (1UL << 8)
74#define AHCI_CMD_CLR_BUSY (1UL << 10)
75
76#define RX_FIS_D2H_REG 0x40 /* offset of D2H Register FIS data */
77#define RX_FIS_SDB 0x58 /* offset of SDB FIS data */
78#define RX_FIS_UNK 0x60 /* offset of Unknown FIS data */
79
80#define board_ahci 0
81#define board_ahci_vt8251 1
82#define board_ahci_ign_iferr 2
83#define board_ahci_sb600 3
84#define board_ahci_mv 4
85#define board_ahci_sb700 5 /* for SB700 and SB800 */
86#define board_ahci_mcp65 6
87#define board_ahci_nopmp 7
88#define board_ahci_yesncq 8
89#define board_ahci_nosntf 9
90
91/* global controller registers */
92#define HOST_CAP 0x00 /* host capabilities */
93#define HOST_CTL 0x04 /* global host control */
94#define HOST_IRQ_STAT 0x08 /* interrupt status */
95#define HOST_PORTS_IMPL 0x0c /* bitmap of implemented ports */
96#define HOST_VERSION 0x10 /* AHCI spec. version compliancy */
97#define HOST_CCC 0x14 /* Command Completion Coalescing Control */
98#define HOST_CCC_PORTS 0x18 /* CCC ports */
99#define HOST_EM_LOC 0x1c /* Enclosure Management location */
100#define HOST_EM_CTL 0x20 /* Enclosure Management Control */
101#define HOST_CAP2 0x24 /* host capabilities, extended */
102#define HOST_BOHC 0x28 /* BIOS hand off control and status */
103
104/* HOST_CTL bits */
105#define HOST_RESET (1UL << 0) /* reset controller; self-clear */
106#define HOST_IRQ_EN (1UL << 1) /* global IRQ enable */
107#define HOST_AHCI_EN (1UL << 31) /* AHCI enabled */
108
109/* HOST_CAP bits */
110#define HOST_CAP_SXS (1UL << 5) /* Supports External SATA */
111#define HOST_CAP_EMS (1UL << 6) /* Enclosure Management support */
112#define HOST_CAP_CCC (1UL << 7) /* Command Completion Coalescing */
113#define HOST_CAP_PART (1UL << 13) /* Partial state capable */
114#define HOST_CAP_SSC (1UL << 14) /* Slumber state capable */
115#define HOST_CAP_PIO_MULTI (1UL << 15) /* PIO multiple DRQ support */
116#define HOST_CAP_FBS (1UL << 16) /* FIS-based switching support */
117#define HOST_CAP_PMP (1UL << 17) /* Port Multiplier support */
118#define HOST_CAP_ONLY (1UL << 18) /* Supports AHCI mode only */
119#define HOST_CAP_CLO (1UL << 24) /* Command List Override support */
120#define HOST_CAP_LED (1UL << 25) /* Supports activity LED */
121#define HOST_CAP_ALPM (1UL << 26) /* Aggressive Link PM support */
122#define HOST_CAP_SSS (1UL << 27) /* Staggered Spin-up */
123#define HOST_CAP_MPS (1UL << 28) /* Mechanical presence switch */
124#define HOST_CAP_SNTF (1UL << 29) /* SNotification register */
125#define HOST_CAP_NCQ (1UL << 30) /* Native Command Queueing */
126#define HOST_CAP_64 (1UL << 31) /* PCI DAC (64-bit DMA) support */
127
128/* HOST_CAP2 bits */
129#define HOST_CAP2_BOH (1UL << 0) /* BIOS/OS handoff supported */
130#define HOST_CAP2_NVMHCI (1UL << 1) /* NVMHCI supported */
131#define HOST_CAP2_APST (1UL << 2) /* Automatic partial to slumber */
132
133/* HOST_BOHC bits */
134#define HOST_BOHC_BOS (1UL << 0) /* BIOS owned (semaphore bit) */
135#define HOST_BOHC_OOS (1UL << 1) /* OS owned (semaphore bit) */
136#define HOST_BOHC_SOOE (1UL << 2) /* SMI on ownership change enable */
137#define HOST_BOHC_OOC (1UL << 3) /* OS ownership change */
138#define HOST_BOHC_BB (1UL << 4) /* BIOS is busy changing ownership */
139
140/* registers for each SATA port */
141#define PORT_LST_ADDR 0x00 /* command list DMA addr */
142#define PORT_LST_ADDR_HI 0x04 /* command list DMA addr hi */
143#define PORT_FIS_ADDR 0x08 /* FIS rx buf addr */
144#define PORT_FIS_ADDR_HI 0x0c /* FIS rx buf addr hi */
145#define PORT_IRQ_STAT 0x10 /* interrupt status */
146#define PORT_IRQ_MASK 0x14 /* interrupt enable/disable mask */
147#define PORT_CMD 0x18 /* port command */
148#define PORT_TFDATA 0x20 /* taskfile data */
149#define PORT_SIG 0x24 /* device TF signature */
150#define PORT_CMD_ISSUE 0x38 /* command issue */
151#define PORT_SCR_STAT 0x28 /* SATA phy register: SStatus */
152#define PORT_SCR_CTL 0x2c /* SATA phy register: SControl */
153#define PORT_SCR_ERR 0x30 /* SATA phy register: SError */
154#define PORT_SCR_ACT 0x34 /* SATA phy register: SActive */
155#define PORT_SCR_NTF 0x3c /* SATA phy register: SNotification */
156
157/* PORT_IRQ_{STAT,MASK} bits */
158#define PORT_IRQ_COLD_PRES (1UL << 31) /* cold presence detect */
159#define PORT_IRQ_TF_ERR (1UL << 30) /* task file error */
160#define PORT_IRQ_HBUS_ERR (1UL << 29) /* host bus fatal error */
161#define PORT_IRQ_HBUS_DATA_ERR (1UL << 28) /* host bus data error */
162#define PORT_IRQ_IF_ERR (1UL << 27) /* interface fatal error */
163#define PORT_IRQ_IF_NONFATAL (1UL << 26) /* interface non-fatal error */
164#define PORT_IRQ_OVERFLOW (1UL << 24) /* xfer exhausted available S/G */
165#define PORT_IRQ_BAD_PMP (1UL << 23) /* incorrect port multiplier */
166#define PORT_IRQ_PHYRDY (1UL << 22) /* PhyRdy changed */
167#define PORT_IRQ_DEV_ILCK (1UL << 7) /* device interlock */
168#define PORT_IRQ_CONNECT (1UL << 6) /* port connect change status */
169#define PORT_IRQ_SG_DONE (1UL << 5) /* descriptor processed */
170#define PORT_IRQ_UNK_FIS (1UL << 4) /* unknown FIS rx'd */
171#define PORT_IRQ_SDB_FIS (1UL << 3) /* Set Device Bits FIS rx'd */
172#define PORT_IRQ_DMAS_FIS (1UL << 2) /* DMA Setup FIS rx'd */
173#define PORT_IRQ_PIOS_FIS (1UL << 1) /* PIO Setup FIS rx'd */
174#define PORT_IRQ_D2H_REG_FIS (1UL << 0) /* D2H Register FIS rx'd */
175#define PORT_IRQ_FREEZE (PORT_IRQ_HBUS_ERR | PORT_IRQ_IF_ERR | \
176 PORT_IRQ_CONNECT | PORT_IRQ_PHYRDY | \
177 PORT_IRQ_UNK_FIS | PORT_IRQ_BAD_PMP)
178#define PORT_IRQ_ERROR (PORT_IRQ_FREEZE | PORT_IRQ_TF_ERR | \
179 PORT_IRQ_OVERFLOW | PORT_IRQ_HBUS_DATA_ERR)
180#define DEF_PORT_IRQ (PORT_IRQ_ERROR | PORT_IRQ_SG_DONE | \
181 PORT_IRQ_SDB_FIS | PORT_IRQ_DMAS_FIS | \
182 PORT_IRQ_PIOS_FIS | PORT_IRQ_D2H_REG_FIS)
183
184#define PORT_ERR_X (1UL << 26) /* Exchanged */
185#define PORT_ERR_FIS (1UL << 25) /* Unknown FIS type */
186#define PORT_ERR_TP (1UL << 24) /* Transport State Transition Error */
187#define PORT_ERR_S (1UL << 23) /* Link Sequence Error */
188#define PORT_ERR_H (1UL << 22) /* Handshake Error */
189#define PORT_ERR_CRC (1UL << 21) /* CRC Error */
190#define PORT_ERR_D (1UL << 20) /* Disparity Error */
191#define PORT_ERR_B (1UL << 19) /* 10B to 8B Decode Error */
192#define PORT_ERR_W (1UL << 18) /* Comm Wake */
193#define PORT_ERR_PI (1UL << 17) /* Phy Internal Error */
194#define PORT_ERR_N (1UL << 16) /* PhyRdy Change */
195#define PORT_ERR_IE (1UL << 11) /* Internal Error */
196#define PORT_ERR_P (1UL << 10) /* Protocol Error */
197#define PORT_ERR_C (1UL << 9) /* Persistent Communication or Data Integrity Error */
198#define PORT_ERR_TD (1UL << 8) /* Transient Data Integrity Error */
199#define PORT_ERR_M (1UL << 1) /* Recovered Communications Error */
200#define PORT_ERR_DI (1UL << 0) /* Recoverred Data Integrity Error */
201#define PORT_ERR_FAIL_BITS (PORT_ERR_X | PORT_ERR_FIS | PORT_ERR_TP | PORT_ERR_S | PORT_ERR_H | PORT_ERR_CRC | \
202 PORT_ERR_D | PORT_ERR_B | PORT_ERR_W | PORT_ERR_PI | PORT_ERR_IE | PORT_ERR_P | \
203 PORT_ERR_C | PORT_ERR_TD)
204
205/* PORT_CMD bits */
206#define PORT_CMD_ASP (1UL << 27) /* Aggressive Slumber/Partial */
207#define PORT_CMD_ALPE (1UL << 26) /* Aggressive Link PM enable */
208#define PORT_CMD_ATAPI (1UL << 24) /* Device is ATAPI */
209#define PORT_CMD_PMP (1UL << 17) /* PMP attached */
210#define PORT_CMD_LIST_ON (1UL << 15) /* cmd list DMA engine running */
211#define PORT_CMD_FIS_ON (1UL << 14) /* FIS DMA engine running */
212#define PORT_CMD_FIS_RX (1UL << 4) /* Enable FIS receive DMA engine */
213#define PORT_CMD_CLO (1UL << 3) /* Command list override */
214#define PORT_CMD_POWER_ON (1UL << 2) /* Power up device */
215#define PORT_CMD_SPIN_UP (1UL << 1) /* Spin up device */
216#define PORT_CMD_START (1UL << 0) /* Enable port DMA engine */
217
218#define PORT_CMD_ICC_MASK (0xfUL << 28) /* i/f ICC state mask */
219#define PORT_CMD_ICC_ACTIVE (0x1UL << 28) /* Put i/f in active state */
220#define PORT_CMD_ICC_PARTIAL (0x2UL << 28) /* Put i/f in partial state */
221#define PORT_CMD_ICC_SLUMBER (0x6UL << 28) /* Put i/f in slumber state */
222
223/* driver status bits */
224#define AHCI_HFLAG_NO_NCQ (1UL << 0) /* no native cmd queuing */
225#define AHCI_HFLAG_IGN_IRQ_IF_ERR (1UL << 1) /* ignore IRQ_IF_ERR */
226#define AHCI_HFLAG_IGN_SERR_INTERNAL (1UL << 2) /* ignore SERR_INTERNAL */
227#define AHCI_HFLAG_32BIT_ONLY (1UL << 3) /* force 32bit */
228#define AHCI_HFLAG_MV_PATA (1UL << 4) /* PATA port */
229#define AHCI_HFLAG_NO_MSI (1UL << 5) /* no PCI MSI */
230#define AHCI_HFLAG_NO_PMP (1UL << 6) /* no PMP */
231#define AHCI_HFLAG_NO_HOTPLUG (1UL << 7) /* ignore PxSERR.DIAG.N */
232#define AHCI_HFLAG_SECT255 (1UL << 8) /* max 255 sectors */
233#define AHCI_HFLAG_YES_NCQ (1UL << 9) /* force NCQ cap on */
234#define AHCI_HFLAG_NO_SUSPEND (1UL << 10) /* don't suspend */
235#define AHCI_HFLAG_SRST_TOUT_IS_OFFLINE (1UL << 11) /* treat SRST timeout as
236 link offline */
237#define AHCI_HFLAG_NO_SNTF (1UL << 12) /* no sntf */
238
239#define ICH_MAP 0x90 /* ICH MAP register */
240
241/* em constants */
242#define EM_MAX_SLOTS 8
243#define EM_MAX_RETRY 5
244
245/* em_ctl bits */
246#define EM_CTL_RST (1UL << 9) /* Reset */
247#define EM_CTL_TM (1UL << 8) /* Transmit Message */
248#define EM_CTL_ALHD (1UL << 26) /* Activity LED */
249
250/* ------------------------ typedefs and structures ------------------------ */
251
252/* Primitive types
253 *
254 * Note: Since OS/2 is essentially an x86 OS and this driver, as well as the
255 * interface it's developed for, is based on x86 design patterns, we're
256 * not even going to start making a difference between little and big
257 * endian architectures. PCI is little endian, AHCI is little endian,
258 * x86 is little endian, and that's it.
259 */
260typedef unsigned char u8;
261typedef unsigned short u16;
262typedef unsigned long u32;
263
264/* AHCI S/G structure */
265typedef struct {
266 u32 addr; /* address of S/G element */
267 u32 addr_hi; /* address of S/G element (upper 32 bits) */
268 u32 reserved;
269 u32 size; /* size of S/G element - 1; the high 10 bits are flags:
270 * 31 : interrupt on completion of this S/G
271 * 30-22 : reserved */
272} AHCI_SG;
273
274/* AHCI command header */
275typedef struct {
276 u32 options; /* command options */
277 u32 status; /* command status */
278 u32 tbl_addr; /* command table address */
279 u32 tbl_addr_high; /* command table address (upper 32 bits) */
280 u32 reserved[4];
281} AHCI_CMD_HDR;
282
283/* AHCI command table */
284typedef struct {
285 u8 cmd_fis[64]; /* ATA command FIS */
286 u8 atapi_cmd[16]; /* ATAPI command */
287 u8 reserved[48];
288 AHCI_SG sg_list[AHCI_MAX_SG]; /* AHCI S/G list */
289} AHCI_CMD_TBL;
290
291/* AHCI port DMA scratch area */
292typedef struct {
293 AHCI_CMD_HDR cmd_hdr[AHCI_MAX_CMDS]; /* command headers */
294 u8 rx_fis[AHCI_RX_FIS_SZ]; /* FIS RX area */
295 AHCI_CMD_TBL cmd_tbl[AHCI_MAX_CMDS]; /* command table */
296} AHCI_PORT_DMA;
297
298/* AHCI port BIOS configuration save area */
299typedef struct {
300 u32 cmd_list; /* cmd list base address */
301 u32 cmd_list_h; /* cmd list base address high */
302 u32 fis_rx; /* FIS receive buffer */
303 u32 fis_rx_h; /* FIS receive bufffer high */
304 u32 irq_mask; /* IRQ mask */
305 u32 port_cmd; /* port engine status */
306} AHCI_PORT_CFG;
307
Note: See TracBrowser for help on using the repository browser.