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

Last change on this file since 211 was 211, checked in by David Azarewicz, 2 years ago

Added workaround to help with VirtualBox issues.
Improved diagnostic messages.
Changed how timeouts are reset and how ctx hooks are triggered.
Added quirk for devices with issues executing some standard commands.
Changed to make /N the default.

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