source: trunk/src/os2ahci/ahci.c@ 204

Last change on this file since 204 was 204, checked in by David Azarewicz, 5 years ago

Variable name changes.

File size: 64.4 KB
Line 
1/******************************************************************************
2 * ahci.c - ahci hardware access functions
3 *
4 * Copyright (c) 2011 thi.guten Software Development
5 * Copyright (c) 2011 Mensys B.V.
6 * Copyright (c) 2013-2018 David Azarewicz
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#include "os2ahci.h"
29#include "ata.h"
30#include "atapi.h"
31
32/* -------------------------- macros and constants ------------------------- */
33
34/* produce ata/atapi function pointer with the given func name */
35#define cmd_func(iorb, func) ad_infos[iorb_unit_adapter(iorb)]. \
36 ports[iorb_unit_port(iorb)]. \
37 devs[iorb_unit_device(iorb)].atapi \
38 ? atapi_##func : ata_##func
39
40
41/* ------------------------ global/static variables ------------------------ */
42
43/* Initial driver status flags indexed by the board_* constants in os2ahci.h
44 *
45 * NOTE: The Linux AHCI driver uses a combination of board-specific quirk
46 * flags and overriding certain libata service functions to handle
47 * adapter flaws. However, there were only three overrides at the time
48 * os2ahci was written, one for hard adapter resets and two for port
49 * resets, and we can easily implement those within the corresponding
50 * reset handlers. If this becomes more complex, this array of flags
51 * should be converted into a structure array which contains function
52 * pointers to all handler functions which may need to be overridden.
53 */
54u16 initial_flags[] =
55{
56 0, /* board_ahci */
57 AHCI_HFLAG_NO_NCQ | /* board_ahci_vt8251 */
58 AHCI_HFLAG_NO_PMP,
59 AHCI_HFLAG_IGN_IRQ_IF_ERR, /* board_ahci_ign_iferr */
60 AHCI_HFLAG_IGN_SERR_INTERNAL | /* board_ahci_sb600 */
61 AHCI_HFLAG_NO_MSI |
62 AHCI_HFLAG_SECT255 |
63 AHCI_HFLAG_32BIT_ONLY,
64 AHCI_HFLAG_NO_NCQ | /* board_ahci_mv */
65 AHCI_HFLAG_NO_MSI |
66 AHCI_HFLAG_MV_PATA |
67 AHCI_HFLAG_NO_PMP,
68 AHCI_HFLAG_IGN_SERR_INTERNAL, /* board_ahci_sb700 */
69 AHCI_HFLAG_YES_NCQ, /* board_ahci_mcp65 */
70 AHCI_HFLAG_NO_PMP, /* board_ahci_nopmp */
71 AHCI_HFLAG_YES_NCQ, /* board_ahci_yesncq */
72 AHCI_HFLAG_NO_SNTF, /* board_ahci_nosntf */
73};
74
75#define MAX_IRQ_HANDLERS 8 /* This is the maximum number of handlers that Dev32Help_SetIRQ can register */
76static u16 irq_used[MAX_IRQ_HANDLERS]; /* IRQ level for each used IRQ */
77static int irq_used_cnt; /* number of IRQs used */
78
79/* ----------------------------- start of code ----------------------------- */
80
81#ifdef DEBUG
82void ahci_dump_host_regs(AD_INFO *ai, int bios_regs)
83{
84 int i;
85 u32 version;
86
87 DPRINTF(2,"AHCI global registers for adapter %d %d:%d:%d irq=%d addr=0x%x\n",
88 ad_no(ai),
89 PCI_BUS_FROM_BDF(ai->bus_dev_func), PCI_DEV_FROM_BDF(ai->bus_dev_func),
90 PCI_FUNC_FROM_BDF(ai->bus_dev_func), ai->irq, ai->mmio_phys);
91
92 for (i = 0; i <= HOST_CAP2; i += sizeof(u32)) {
93 u32 val;
94
95 if (bios_regs) val = ai->bios_config[i/sizeof(u32)];
96 else
97 {
98 /* HOST_CAP2 only exists for AHCI V1.2 and later */
99 if ((i == HOST_CAP2) && (version < 0x00010200L)) val = 0;
100 else val = readl(ai->mmio + i);
101 }
102 if (i == HOST_VERSION) version = val;
103
104 dprintf(0," %02x: %08lx", i, val);
105
106 if (i == HOST_CAP) {
107 dprintf(0," -");
108 if (val & HOST_CAP_64) dprintf(0," 64bit");
109 if (val & HOST_CAP_NCQ) dprintf(0," ncq");
110 if (val & HOST_CAP_SNTF) dprintf(0," sntf");
111 if (val & HOST_CAP_MPS) dprintf(0," mps");
112 if (val & HOST_CAP_SSS) dprintf(0," sss");
113 if (val & HOST_CAP_ALPM) dprintf(0," alpm");
114 if (val & HOST_CAP_LED) dprintf(0," led");
115 if (val & HOST_CAP_CLO) dprintf(0," clo");
116 if (val & HOST_CAP_ONLY) dprintf(0," ahci_only");
117 if (val & HOST_CAP_PMP) dprintf(0," pmp");
118 if (val & HOST_CAP_FBS) dprintf(0," fbs");
119 if (val & HOST_CAP_PIO_MULTI) dprintf(0," pio_multi");
120 if (val & HOST_CAP_SSC) dprintf(0," ssc");
121 if (val & HOST_CAP_PART) dprintf(0," part");
122 if (val & HOST_CAP_CCC) dprintf(0," ccc");
123 if (val & HOST_CAP_EMS) dprintf(0," ems");
124 if (val & HOST_CAP_SXS) dprintf(0," sxs");
125 dprintf(0," cmd_slots:%d", ((val >> 8) & 0x1f) + 1);
126 dprintf(0," ports:%d", (val & 0x1f) + 1);
127 } else if (i == HOST_CTL) {
128 dprintf(0," -");
129 if (val & HOST_AHCI_EN) dprintf(0," ahci_enabled");
130 if (val & HOST_IRQ_EN) dprintf(0," irq_enabled");
131 if (val & HOST_RESET) dprintf(0," resetting");
132 } else if (i == HOST_CAP2) {
133 dprintf(0," -");
134 if (val & HOST_CAP2_BOH) dprintf(0," boh");
135 if (val & HOST_CAP2_NVMHCI) dprintf(0," nvmhci");
136 if (val & HOST_CAP2_APST) dprintf(0," apst");
137 }
138 dprintf(0,"\n");
139 }
140}
141
142void ahci_dump_port_regs(AD_INFO *ai, int p)
143{
144 u8 *port_mmio = port_base(ai, p);
145
146 dprintf(0,"AHCI port %d registers:\n", p);
147 dprintf(0," PORT_CMD = 0x%x\n", readl(port_mmio + PORT_CMD));
148 dprintf(0," command engine status:\n");
149 dprintf(0," PORT_SCR_ACT = 0x%x\n", readl(port_mmio + PORT_SCR_ACT));
150 dprintf(0," PORT_CMD_ISSUE = 0x%x\n", readl(port_mmio + PORT_CMD_ISSUE));
151 dprintf(0," link/device status:\n");
152 dprintf(0," PORT_SCR_STAT = 0x%x\n", readl(port_mmio + PORT_SCR_STAT));
153 dprintf(0," PORT_SCR_CTL = 0x%x\n", readl(port_mmio + PORT_SCR_CTL));
154 dprintf(0," PORT_SCR_ERR = 0x%x\n", readl(port_mmio + PORT_SCR_ERR));
155 dprintf(0," PORT_TFDATA = 0x%x\n", readl(port_mmio + PORT_TFDATA));
156 dprintf(0," interrupt status:\n");
157 dprintf(0," PORT_IRQ_STAT = 0x%x\n", readl(port_mmio + PORT_IRQ_STAT));
158 dprintf(0," PORT_IRQ_MASK = 0x%x\n", readl(port_mmio + PORT_IRQ_MASK));
159 dprintf(0," HOST_IRQ_STAT = 0x%x\n", readl(ai->mmio + HOST_IRQ_STAT));
160}
161#endif
162
163/******************************************************************************
164 * setup the CAPS and other adapter information for this adapter.
165 *
166 * This function saves working copies of the CAP and CAP2 registers
167 * as well as the initial port map in the AD_INFO structure after
168 * removing features which are known to cause trouble on this specific
169 * piece of hardware.
170 */
171int ahci_config_caps(AD_INFO *ai)
172{
173 int ports;
174 int i;
175
176 ai->cap = readl(ai->mmio + HOST_CAP);
177 ai->port_map = readl(ai->mmio + HOST_PORTS_IMPL);
178
179 /* HOST_CAP2 only exists for AHCI V1.2 and later */
180 if (readl(ai->mmio + HOST_VERSION) >= 0x00010200L) ai->cap2 = readl(ai->mmio + HOST_CAP2);
181
182 if (ai->pci->board >= sizeof(initial_flags) / sizeof(*initial_flags))
183 {
184 dprintf(0,"error: invalid board index in PCI info\n");
185 return(-1);
186 }
187 ai->flags = initial_flags[ai->pci->board];
188 ai->hw_ports = (ai->cap & 0x1f) + 1;
189
190 if ((ai->cap & HOST_CAP_64) && (ai->flags & AHCI_HFLAG_32BIT_ONLY))
191 {
192 /* disable 64-bit support for faulty controllers; OS/2 can't do 64 bits at
193 * this point, of course, but who knows where all this will be in a few
194 * years...
195 */
196 ai->cap &= ~HOST_CAP_64;
197 }
198
199 /* Remove broken feature bits. This is largely copied from the Linux AHCI driver -- the wisdom
200 * around quirks and faulty hardware is hard to come by...
201 */
202 if ((ai->cap & HOST_CAP_NCQ) && (ai->flags & AHCI_HFLAG_NO_NCQ))
203 {
204 DPRINTF(1,"controller can't do NCQ, turning off CAP_NCQ\n");
205 ai->cap &= ~HOST_CAP_NCQ;
206 }
207
208 if (!(ai->cap & HOST_CAP_NCQ) && (ai->flags & AHCI_HFLAG_YES_NCQ))
209 {
210 DPRINTF(1,"controller can do NCQ, turning on CAP_NCQ\n");
211 ai->cap |= HOST_CAP_NCQ;
212 }
213
214 if ((ai->cap & HOST_CAP_PMP) && (ai->flags & AHCI_HFLAG_NO_PMP))
215 {
216 DPRINTF(1,"controller can't do PMP, turning off CAP_PMP\n");
217 ai->cap |= HOST_CAP_PMP;
218 }
219
220 if ((ai->cap & HOST_CAP_SNTF) && (ai->flags & AHCI_HFLAG_NO_SNTF))
221 {
222 DPRINTF(1,"controller can't do SNTF, turning off CAP_SNTF\n");
223 ai->cap &= ~HOST_CAP_SNTF;
224 }
225
226 if (ai->pci_vendor == PCI_VENDOR_ID_JMICRON && ai->pci_device == 0x2361 && ai->port_map != 1)
227 {
228 DPRINTF(1,"JMB361 has only one port, port_map 0x%x -> 0x%x\n", ai->port_map, 1);
229 ai->port_map = 1;
230 ai->hw_ports = 1;
231 }
232
233 /* Correlate port map to number of ports reported in HOST_CAP
234 *
235 * NOTE: Port map and number of ports handling differs a bit from the
236 * Linux AHCI driver because we're storing both in AI_INFO. As in the
237 * Linux driver, the port map is the main driver for port scanning but
238 * we're also saving a maximum port number in AI_INFO to reduce the
239 * number of IORB queues to look at in trigger_engine(). This is done
240 * in ahci_scan_ports().
241 */
242 ports = ai->hw_ports;
243 for (i = 0; i < AHCI_MAX_PORTS; i++)
244 {
245 if (ai->port_map & (1UL << i)) ports--;
246 }
247 if (ports < 0)
248 {
249 /* more ports in port_map than in HOST_CAP & 0x1f */
250 ports = ai->hw_ports;
251 DPRINTF(0,"implemented port map (0x%x) contains more ports than hw_ports (%d), using hw_ports\n", ai->port_map, ports);
252 ai->port_map = (1UL << ports) - 1UL;
253 }
254
255 /* set maximum command slot number */
256 ai->cmd_max = ((ai->cap >> 8) & 0x1f);
257
258 return(0);
259}
260
261/******************************************************************************
262 * Save BIOS configuration of AHCI adapter. As a side effect, this also saves
263 * generic configuration information which we may have to restore after an
264 * adapter reset.
265 */
266int ahci_save_bios_config(AD_INFO *ai)
267{
268 int i;
269
270 /* save BIOS configuration */
271 for (i = 0; i < HOST_CAP2; i += sizeof(u32))
272 {
273 ai->bios_config[i / sizeof(u32)] = readl(ai->mmio + i);
274 }
275
276 DPRINTF(3,__func__": BIOS AHCI mode is %d\n", ai->bios_config[HOST_CTL / sizeof(u32)] & HOST_AHCI_EN);
277
278 if ((ai->bios_config[HOST_CTL / sizeof(u32)] & HOST_AHCI_EN) == 0 && ai->pci_vendor == PCI_VENDOR_ID_INTEL)
279 {
280 /* Adapter is not in AHCI mode and the spec says a COMRESET is
281 * required when switching from SATA to AHCI mode and vice versa.
282 */
283 init_reset = 1;
284 }
285
286 DUMP_HOST_REGS(2,ai,1);
287
288 return(0);
289}
290
291/******************************************************************************
292 * Restore BIOS configuration of AHCI adapter. This is needed after scanning
293 * for devices because we still need the BIOS until the initial boot sequence
294 * has completed.
295 */
296int ahci_restore_bios_config(AD_INFO *ai)
297{
298 DPRINTF(3,__func__": restoring AHCI BIOS configuration on adapter %d\n", ad_no(ai));
299
300 /* Restore saved BIOS configuration; please note that HOST_CTL is restored
301 * last because it may cause AHCI mode to be turned off again.
302 */
303 writel(ai->mmio + HOST_CCC, ai->bios_config[HOST_CCC / sizeof(u32)]);
304 writel(ai->mmio + HOST_CCC_PORTS, ai->bios_config[HOST_CCC_PORTS / sizeof(u32)]);
305 writel(ai->mmio + HOST_EM_CTL, ai->bios_config[HOST_EM_CTL / sizeof(u32)]);
306 writel(ai->mmio + HOST_CTL, ai->bios_config[HOST_CTL / sizeof(u32)]);
307
308 /* flush PCI MMIO delayed write buffers */
309 readl(ai->mmio + HOST_CTL);
310
311 if ((ai->bios_config[HOST_CTL / sizeof(u32)] & HOST_AHCI_EN) == 0 && ai->pci_vendor == PCI_VENDOR_ID_INTEL)
312 {
313 /* This BIOS apparently accesses the controller via SATA registers and
314 * the AHCI spec says that we should issue a COMRESET on each port after
315 * disabling AHCI mode to allow the SATA controller to re-recognize attached
316 * devices. How to do this depends on the controller, of course, but so
317 * far I've only seen Dell notebook BIOSs with Intel chipsets to behave
318 * like this; all other BIOS implementations I've seen so far seem to take
319 * AHCI mode literally and operate the controller in AHCI mode from the
320 * beginning.
321 *
322 * We'll use a feature on Intel ICH7/8 controllers which provides MMIO
323 * mappings for the AHCI SCR registers even when not in AHCI mode.
324 */
325 int p;
326
327 for (p = 0; p <= ai->port_max; p++)
328 {
329 if (ai->port_map & (1UL << p))
330 {
331 u8 *port_mmio = port_base(ai, p);
332 u32 tmp;
333
334 tmp = readl(port_mmio + PORT_SCR_CTL) & ~0x0000000fUL;
335 writel(port_mmio + PORT_SCR_CTL, tmp | 1);
336 readl(port_mmio + PORT_SCR_CTL); /* flush */
337
338 /* spec says "leave reset bit on for at least 1ms"; make it 2ms */
339 udelay(2000);
340
341 writel(port_mmio + PORT_SCR_CTL, tmp);
342 readl(port_mmio + PORT_SCR_CTL); /* flush */
343 }
344 }
345 }
346
347 return(0);
348}
349
350/******************************************************************************
351 * Restore initial configuration (e.g. after an adapter reset). This relies
352 * on information saved by 'ahci_save_bios_config()'.
353 */
354int ahci_restore_initial_config(AD_INFO *ai)
355{
356 DPRINTF(3,__func__": restoring initial configuration on adapter %d\n", ad_no(ai));
357
358 /* restore saved BIOS configuration */
359 //writel(ai->mmio + HOST_CCC, ai->bios_config[HOST_CCC / sizeof(u32)]);
360 //writel(ai->mmio + HOST_CCC_PORTS, ai->bios_config[HOST_CCC_PORTS / sizeof(u32)]);
361 //writel(ai->mmio + HOST_EM_CTL, ai->bios_config[HOST_EM_CTL / sizeof(u32)]);
362 //writel(ai->mmio + HOST_CTL, ai->bios_config[HOST_CTL / sizeof(u32)]);
363
364 writel(ai->mmio + HOST_CAP, ai->bios_config[HOST_CAP / sizeof(u32)]);
365 if (ai->bios_config[HOST_CAP2 / sizeof(u32)])
366 writel(ai->mmio + HOST_CAP2, ai->bios_config[HOST_CAP2 / sizeof(u32)]);
367 writel(ai->mmio + HOST_PORTS_IMPL, ai->bios_config[HOST_PORTS_IMPL / sizeof(u32)]);
368
369 /* flush PCI MMIO delayed write buffers */
370 readl(ai->mmio + HOST_PORTS_IMPL);
371
372 return(0);
373}
374
375#ifdef NOT_USED
376int ahci_reset_controller(AD_INFO *ai)
377{
378 u32 tmp;
379 TIMER Timer;
380
381 DPRINTF(2,"controller reset starting on adapter %d\n", ad_no(ai));
382
383 /* we must be in AHCI mode, before using anything AHCI-specific, such as HOST_RESET. */
384 ahci_enable_ahci(ai);
385
386 /* global controller reset */
387 tmp = readl(ai->mmio + HOST_CTL);
388 if ((tmp & HOST_RESET) == 0) {
389 writel(ai->mmio + HOST_CTL, tmp | HOST_RESET);
390 readl(ai->mmio + HOST_CTL); /* flush */
391 }
392
393 /*
394 * to perform host reset, OS should set HOST_RESET
395 * and poll until this bit is read to be "0".
396 * reset must complete within 1 second, or
397 * the hardware should be considered fried.
398 */
399 TimerInit(&Timer, 1000);
400 while (((tmp = readl(ai->mmio + HOST_CTL)) & HOST_RESET) != 0) {
401 if (TimerCheckAndBlock(&Timer)) {
402 dprintf(0,"controller reset failed (0x%x)\n", tmp);
403 return(-1);
404 }
405 }
406
407 /* turn on AHCI mode */
408 ahci_enable_ahci(ai);
409
410 /* Some registers might be cleared on reset. Restore initial values. */
411 ahci_restore_initial_config(ai);
412
413 if (ai->pci_vendor == PCI_VENDOR_ID_INTEL) {
414 u32 tmp16 = 0;
415
416 DPRINTF(1,"ahci_reset_controller: intel detected\n");
417 /* configure PCS */
418 PciReadConfig(ai->bus, ai->dev_func, 0x92, sizeof(u16), &tmp16);
419 if ((tmp16 & ai->port_map) != ai->port_map) {
420 DPRINTF(3,"ahci_reset_controller: updating PCS %x/%x\n", tmp16, ai->port_map);
421 tmp16 |= ai->port_map;
422 PciWriteConfig(ai->bus, ai->dev_func, 0x92, sizeof(u16), tmp16);
423 }
424 }
425
426 return 0;
427}
428#endif
429
430/******************************************************************************
431 * Save port configuration. This is primarily used to save the BIOS port
432 * configuration (command list and FIS buffers and the IRQ mask).
433 *
434 * The port configuration returned by this function is dynamically allocated
435 * and automatically freed when calling ahci_restore_port_config().
436 */
437AHCI_PORT_CFG *ahci_save_port_config(AD_INFO *ai, int p)
438{
439 AHCI_PORT_CFG *pc;
440 u8 *port_mmio = port_base(ai, p);
441
442 if ((pc = MemAlloc(sizeof(*pc))) == NULL) return(NULL);
443
444 pc->cmd_list = readl(port_mmio + PORT_LST_ADDR);
445 pc->cmd_list_h = readl(port_mmio + PORT_LST_ADDR_HI);
446 pc->fis_rx = readl(port_mmio + PORT_FIS_ADDR);
447 pc->fis_rx_h = readl(port_mmio + PORT_FIS_ADDR_HI);
448 pc->irq_mask = readl(port_mmio + PORT_IRQ_MASK);
449 pc->port_cmd = readl(port_mmio + PORT_CMD);
450
451 return(pc);
452}
453
454/******************************************************************************
455 * Restore port configuration. This is primarily used to restore the BIOS port
456 * configuration (command list and FIS buffers and the IRQ mask).
457 *
458 * The port configuration is automatically freed.
459 */
460void ahci_restore_port_config(AD_INFO *ai, int p, AHCI_PORT_CFG *pc)
461{
462 u8 *port_mmio = port_base(ai, p);
463
464 /* stop the port, first */
465 ahci_stop_port(ai, p);
466
467 if (ai->bios_config[HOST_CTL / sizeof(u32)] & HOST_AHCI_EN)
468 {
469 /* BIOS uses AHCI, too, so we need to restore the port settings;
470 * restoring PORT_CMD may well start the port again but that's what
471 * this function is all about.
472 */
473 writel(port_mmio + PORT_LST_ADDR, pc->cmd_list);
474 writel(port_mmio + PORT_LST_ADDR_HI, pc->cmd_list_h);
475 writel(port_mmio + PORT_FIS_ADDR, pc->fis_rx);
476 writel(port_mmio + PORT_FIS_ADDR_HI, pc->fis_rx_h);
477 writel(port_mmio + PORT_IRQ_MASK, pc->irq_mask);
478 writel(port_mmio + PORT_CMD, pc->port_cmd);
479
480 readl(port_base(ai, p) + PORT_IRQ_MASK); /* flush */
481 }
482
483 MemFree(pc);
484}
485
486/******************************************************************************
487 * Enable AHCI mode on this controller.
488 */
489int ahci_enable_ahci(AD_INFO *ai)
490{
491 u32 ctl = readl(ai->mmio + HOST_CTL);
492 int i;
493
494 if (ctl & HOST_AHCI_EN)
495 {
496 /* AHCI mode already enabled */
497 return(0);
498 }
499
500 if (ai->pci_vendor == PCI_VENDOR_ID_INTEL)
501 {
502 /* Adapter is not in AHCI mode and the spec says a COMRESET is
503 * required when switching from SATA to AHCI mode and vice versa.
504 */
505 init_reset = 1;
506 }
507
508 /* some controllers need AHCI_EN to be written multiple times */
509 for (i = 0; i < 5; i++)
510 {
511 ctl |= HOST_AHCI_EN;
512 writel(ai->mmio + HOST_CTL, ctl);
513 ctl = readl(ai->mmio + HOST_CTL); /* flush && sanity check */
514 if (ctl & HOST_AHCI_EN)
515 {
516 return(0);
517 }
518 msleep(10);
519 }
520
521 /* couldn't enable AHCI mode */
522 dprintf(0,"failed to enable AHCI mode on adapter %d\n", ad_no(ai));
523 return(1);
524}
525
526/******************************************************************************
527 * Complete initialization of adapter. This includes restarting all active
528 * ports and initializing interrupt processing. This is called when receiving
529 * the IOCM_COMPLETE_INIT request.
530 */
531int ahci_complete_init(AD_INFO *ai)
532{
533 int rc;
534 u32 p;
535 int i;
536
537 DPRINTF(1,__func__": completing initialization of adapter #%d\n", ad_no(ai));
538
539 if (!ai->int_set)
540 {
541 /* register IRQ handler; each IRQ level is registered only once */
542 p = 1; /* int count */
543 if (!(ai->flags & AHCI_HFLAG_NO_MSI))
544 {
545 if (PsdMsiAlloc(ai->bus_dev_func, &p, &ai->irq)) p = 1; /* shared flag */
546 else
547 {
548 /* we have an msi interrupt */
549 ai->irq_pin = 0;
550 p = 0; /* exclusive flag */
551 }
552 }
553 for (i = 0; i < irq_used_cnt; i++)
554 {
555 if (irq_used[i] == ai->irq) break; /* we already have this IRQ registered */
556 }
557 if (i >= irq_used_cnt)
558 {
559 if (i >= MAX_IRQ_HANDLERS) return -1; /* no more handlers available */
560
561 DPRINTF(2,"registering interrupt %d pin=%d\n", ai->irq, ai->irq_pin);
562
563 rc = Dev32Help_SetIRQ(ahci_intr, ai->irq, p, ai->irq);
564 if (rc && p) /* if failed and was shared */
565 {
566 p = 0; /* try exclusive */
567 rc = Dev32Help_SetIRQ(ahci_intr, ai->irq, p, ai->irq);
568 }
569 if (rc)
570 {
571 dprintf(0,"failed to register interrupt %d\n", ai->irq);
572 return(-1);
573 }
574 irq_used[irq_used_cnt++] = ai->irq;
575 ai->int_set = 1;
576 RmUpdateAddIrq(rm_drvh, ai->rm_adh, ai->irq, ai->irq_pin, p?RS_IRQ_SHARED:RS_IRQ_EXCLUSIVE);
577 }
578 }
579
580 /* enable AHCI mode */
581 if ((rc = ahci_enable_ahci(ai)) != 0) return(rc);
582
583 /* Start all ports. The main purpose is to set the command list and FIS
584 * receive area addresses properly and to enable port-level interrupts; we
585 * don't really care about the return status because we'll find out soon
586 * enough if a previously detected device has problems.
587 */
588 for (p = 0; p <= ai->port_max; p++)
589 {
590 if (ai->port_map & (1UL << p))
591 {
592 if (init_reset)
593 {
594 DPRINTF(3,__func__": resetting port %d\n", p);
595 ahci_reset_port(ai, p, 1);
596 }
597 else
598 {
599 DPRINTF(3,__func__": restarting port #%d\n", p);
600 ahci_stop_port(ai, p);
601 ahci_start_port(ai, p, 1);
602 }
603 }
604 }
605
606 /* clear pending interrupt status */
607 writel(ai->mmio + HOST_IRQ_STAT, readl(ai->mmio + HOST_IRQ_STAT));
608 readl(ai->mmio + HOST_IRQ_STAT); /* flush */
609
610 /* enable adapter-level interrupts */
611 writel(ai->mmio + HOST_CTL, readl(ai->mmio + HOST_CTL) | HOST_IRQ_EN);
612 readl(ai->mmio + HOST_CTL); /* flush */
613
614 /* enable interrupts on PCI-level (PCI 2.3 added a feature to disable INTs) */
615 /* pci_enable_int(ai->bus, ai->dev_func); */
616
617 DPRINTF(1,__func__": done\n");
618 return(0);
619}
620
621static int IsUsableDisk(AD_INFO *ai, int p, int d)
622{
623 union {
624 u8 b[512];
625 u16 w[256];
626 u32 l[128];
627 } *pSector0;
628 int iRetVal;
629
630 if (!use_mbr_test) return 1;
631 if (ai->ports[p].devs[d].removable) return 1;
632
633 do
634 {
635 iRetVal = 0;
636 pSector0 = MemAlloc(512);
637 if (!pSector0) break;
638
639 if (ahci_exec_polled_cmd(ai, p, 0, 500, ATA_CMD_READ,
640 AP_SECTOR_28, 0,
641 AP_COUNT, 1,
642 AP_VADDR, (void *)pSector0, 512,
643 AP_DEVICE, 0x40,
644 AP_END)) break;
645
646 DHEXDUMP(5, pSector0, 512, "Sector0:\n");
647
648 /* check for wiped disk */
649 if ((pSector0->l[0] == 0) && (pSector0->l[127] == 0))
650 {
651 iRetVal = 1;
652 break;
653 }
654
655 /* check for a valid MBR */
656 if (pSector0->w[255] != 0xaa55) break; /* Not valid if no MBR signature */
657 if (pSector0->b[0x1c2] == 0xee) break; /* Not valid if guard partition */
658 if (pSector0->b[0x1d2] == 0xee) break; /* Not valid if guard partition */
659 if (pSector0->b[0x1e2] == 0xee) break; /* Not valid if guard partition */
660 if (pSector0->b[0x1f2] == 0xee) break; /* Not valid if guard partition */
661 iRetVal = 1;
662 } while (0);
663
664 if (pSector0) MemFree(pSector0);
665 return iRetVal;
666}
667
668/******************************************************************************
669 * Set up device attached to the specified port based on ATA_IDENTFY_DEVICE or
670 * ATA_IDENTFY_PACKET_DEVICE data.
671 *
672 * NOTE: Port multipliers are not supported, yet, thus the device number is
673 * expected to be 0 for the time being.
674 */
675static void ahci_setup_device(AD_INFO *ai, int p, int d, u16 *id_buf)
676{
677 DEVICESTRUCT ds;
678 ADJUNCT adj;
679 HDEVICE dh;
680 char dev_name[RM_MAX_PREFIX_LEN+ATA_ID_PROD_LEN+1];
681 char *pDevName;
682 static u8 total_dev_cnt;
683
684 if (p >= AHCI_MAX_PORTS) return;
685 if (d >= AHCI_MAX_DEVS) return;
686
687 if (ai->port_max < p) ai->port_max = p;
688 if (ai->ports[p].dev_max < d) ai->ports[p].dev_max = d;
689 memset(ai->ports[p].devs + d, 0x00, sizeof(*ai->ports[p].devs));
690
691 /* set generic device information (assuming an ATA disk device for now) */
692 ai->ports[p].devs[d].present = 1;
693 ai->ports[p].devs[d].removable = (id_buf[ATA_ID_CONFIG] & 0x0080U) != 0;
694 ai->ports[p].devs[d].dev_type = UIB_TYPE_DISK;
695 pDevName = ai->ports[p].devs[d].dev_name;
696 strlcpy(pDevName, ata_dev_name(id_buf), sizeof(ai->ports[0].devs[0].dev_name));
697
698 if (id_buf[ATA_ID_CONFIG] & 0x8000U)
699 {
700 /* this is an ATAPI device; augment device information */
701 ai->ports[p].devs[d].atapi = 1;
702 ai->ports[p].devs[d].atapi_16 = (id_buf[ATA_ID_CONFIG] & 0x0001U) != 0;
703 ai->ports[p].devs[d].dev_type = (id_buf[ATA_ID_CONFIG] & 0x1f00U) >> 8;
704 ai->ports[p].devs[d].ncq_max = 1;
705
706 }
707 else
708 {
709 /* complete ATA-specific device information */
710 if (enable_ncq[ad_no(ai)][p])
711 {
712 ai->ports[p].devs[d].ncq_max = id_buf[ATA_ID_QUEUE_DEPTH] & 0x001fU;
713 }
714 if (ai->ports[p].devs[d].ncq_max < 1)
715 {
716 /* NCQ not enabled for this device, or device doesn't support NCQ */
717 ai->ports[p].devs[d].ncq_max = 1;
718 }
719 if (id_buf[ATA_ID_CFS_ENABLE_2] & 0x0400U)
720 {
721 ai->ports[p].devs[d].lba48 = 1;
722 }
723 }
724
725 DPRINTF(2,"found device %d.%d.%d: removable=%d dev_type=%d atapi=%d ncq_max=%d\n",
726 ad_no(ai), p, d,
727 ai->ports[p].devs[d].removable,
728 ai->ports[p].devs[d].dev_type,
729 ai->ports[p].devs[d].atapi,
730 ai->ports[p].devs[d].ncq_max);
731
732 /* add device to resource manager; we don't really care about errors here */
733 memset(&ds, 0x00, sizeof(ds));
734 memset(&adj, 0x00, sizeof(adj));
735
736 adj.pNextAdj = NULL;
737 adj.AdjLength = sizeof(adj);
738 adj.AdjType = ADJ_ADD_UNIT;
739 adj.Add_Unit.ADDHandle = rm_drvh;
740 adj.Add_Unit.UnitHandle = (USHORT)total_dev_cnt;
741
742 /* create Resource Manager device key string;
743 * we distinguish only HDs and CD drives for now
744 */
745 if (ai->ports[p].devs[d].removable)
746 {
747 snprintf(dev_name, sizeof(dev_name), RM_CD_PREFIX "%s", p, d, pDevName);
748 }
749 else
750 {
751 snprintf(dev_name, sizeof(dev_name), RM_HD_PREFIX "%s", p, d, pDevName);
752 }
753
754 ds.DevDescriptName = dev_name;
755 ds.DevFlags = (ai->ports[p].devs[d].removable) ? DS_REMOVEABLE_MEDIA
756 : DS_FIXED_LOGICALNAME;
757 ds.DevType = ai->ports[p].devs[d].dev_type;
758 ds.pAdjunctList = &adj;
759
760 RMCreateDevice(rm_drvh, &dh, &ds, ai->rm_adh, NULL);
761
762 total_dev_cnt++;
763
764 /* try to detect virtualbox environment to enable a hack for IRQ routing */
765 if (ai == ad_infos && ai->pci_vendor == 0x8086 && ai->pci_device == 0x2829 &&
766 !memcmp(pDevName, "VBOX HARDDISK", 13))
767 {
768 /* running inside virtualbox */
769 pci_hack_virtualbox();
770 }
771}
772
773/******************************************************************************
774 * Scan all ports for connected devices and fill in the corresponding device
775 * information.
776 *
777 * NOTES:
778 *
779 * - The adapter is temporarily configured for os2ahci but the original BIOS
780 * configuration will be restored when done. This happens only until we
781 * have received the IOCC_COMPLETE_INIT command.
782 *
783 * - Subsequent calls are currently not planned but may be required for
784 * suspend/resume handling, hot swap functionality, etc.
785 *
786 * - This function is expected to be called with the spinlock released but
787 * the corresponding adapter's busy flag set. It will aquire the spinlock
788 * temporarily to allocate/free memory for the ATA identify buffer.
789 *
790 * Called from iocm_device_table()
791 */
792int ahci_scan_ports(AD_INFO *ai)
793{
794 AHCI_PORT_CFG *pc = NULL;
795 u16 *id_buf;
796 int is_ata;
797 int rc;
798 int p;
799 int i;
800 TIMER Timer;
801
802 if ((id_buf = MemAlloc(ATA_ID_WORDS * sizeof(u16))) == NULL) return(-1);
803
804 if (ai->bios_config[0] == 0) ahci_save_bios_config(ai); /* first call */
805
806 if (ahci_enable_ahci(ai)) goto exit_port_scan;
807
808 /* perform port scan */
809 DPRINTF(1,__func__": scanning ports on adapter %d\n", ad_no(ai));
810 for (p = 0; p < AHCI_MAX_PORTS; p++)
811 {
812 if (!(ai->port_map & (1UL << p))) continue;
813 if (port_ignore[ad_no(ai)][p]) continue;
814
815 // DAZ allocate port structure here
816
817 DPRINTF(3,__func__": Wait till not busy on port %d\n", p);
818 /* wait until all active commands have completed on this port */
819 TimerInit(&Timer, 250);
820 while (ahci_port_busy(ai, p))
821 {
822 if (TimerCheckAndBlock(&Timer)) break;
823 }
824
825 if (!init_complete)
826 {
827 if ((pc = ahci_save_port_config(ai, p)) == NULL) goto exit_port_scan;
828 }
829
830 /* start/reset port; if no device is attached, this is expected to fail */
831 if (init_reset)
832 {
833 rc = ahci_reset_port(ai, p, 0);
834 }
835 else
836 {
837 DPRINTF(3,__func__": (re)starting port %d\n", p);
838 ahci_stop_port(ai, p);
839 rc = ahci_start_port(ai, p, 0);
840 }
841
842 if (rc == 0)
843 {
844 /* this port seems to have a device attached and ready for commands */
845 DPRINTF(1,__func__": port %d seems to be attached to a device; probing...\n", p);
846
847 #ifdef DAZ_NEW_CODE
848 ai->ports[p].dma_buf = MemAllocAlign(AHCI_PORT_PRIV_DMA_SZ, 1024);
849 ai->ports[p].dma_buf_phys = MemPhysAdr(ai->ports[p].dma_buf);
850 #endif
851
852 /* Get ATA(PI) identity. The so-called signature gives us a hint whether
853 * this is an ATA or an ATAPI device but we'll try both in either case;
854 * the signature will merely determine whether we're going to probe for
855 * an ATA or ATAPI device, first, in order to reduce the chance of sending
856 * the wrong command (which would result in a port reset given the way
857 * ahci_exec_polled_cmd() was implemented).
858 */
859 is_ata = readl(port_base(ai, p) + PORT_SIG) == 0x00000101UL;
860 for (i = 0; i < 2; i++)
861 {
862 rc = ahci_exec_polled_cmd(ai, p, 0, 500,
863 (is_ata) ? ATA_CMD_ID_ATA : ATA_CMD_ID_ATAPI,
864 AP_VADDR, (void *) id_buf, ATA_ID_WORDS * sizeof(u16),
865 AP_END);
866 if (rc == 0) break;
867
868 /* try again with ATA/ATAPI swapped */
869 is_ata = !is_ata;
870 }
871 }
872
873 if (rc == 0)
874 {
875 /* we have a valid IDENTIFY or IDENTIFY_PACKET response */
876 DHEXDUMP(5,id_buf, ATA_ID_WORDS * sizeof(u16), "ATA_IDENTIFY%s results:\n", (is_ata) ? "" : "_PACKET");
877 ahci_setup_device(ai, p, 0, id_buf);
878 if (!IsUsableDisk(ai, p, 0)) ai->ports[p].devs[0].ignored = 1;
879 }
880 else
881 {
882 /* no device attached to this port */
883 ai->port_map &= ~(1UL << p);
884 #ifdef DAZ_NEW_CODE
885 if (ai->ports[p].dma_buf) MemFree(ai->ports[p].dma_buf);
886 ai->ports[p].dma_buf = NULL;
887 #endif
888 }
889
890 if (pc != NULL) ahci_restore_port_config(ai, p, pc);
891 }
892
893exit_port_scan:
894 if (!init_complete)
895 {
896 ahci_restore_bios_config(ai);
897 }
898 MemFree(id_buf);
899 return(0);
900}
901
902/******************************************************************************
903 * Reset specified port. This function is typically called during adapter
904 * initialization and first gets the port into a defined status, then resets
905 * the port by sending a COMRESET signal.
906 *
907 * This function is also the location of the link speed initialization (link
908 * needs to be restablished after changing link speed, anyway).
909 *
910 * NOTE: This function uses a busy loop to wait for DMA engines to stop and
911 * the COMRESET to complete. It should only be called at task time
912 * during initialization or in a context hook.
913 */
914int ahci_reset_port(AD_INFO *ai, int p, int ei)
915{
916 u8 *port_mmio = port_base(ai, p);
917 u32 tmp;
918 TIMER Timer;
919
920 DPRINTF(2,__func__": resetting port %d.%d\n", ad_no(ai), p);
921 DUMP_PORT_REGS(2,ai,p);
922
923 /* stop port engines (we don't care whether there is an error doing so) */
924 ahci_stop_port(ai, p);
925
926 /* clear SError */
927 tmp = readl(port_mmio + PORT_SCR_ERR);
928 writel(port_mmio + PORT_SCR_ERR, tmp);
929
930 /* Some hardware reports incorrect status so just set these bits unconditionally */
931 tmp = readl(port_mmio + PORT_CMD);
932 tmp &= ~PORT_CMD_ALPE; /* turn off agressive power management */
933 tmp |= (PORT_CMD_SPIN_UP | PORT_CMD_POWER_ON); /* power up and spin up the drive */
934 writel(port_mmio + PORT_CMD, tmp);
935
936 /* set link speed and power management options */
937 DPRINTF(3,__func__": setting link speed and power management options\n");
938 tmp = readl(port_mmio + PORT_SCR_CTL) & ~0x00000fffUL;
939 tmp |= (link_speed[ad_no(ai)][p] & 0x0f) << 4;
940 tmp |= (link_power[ad_no(ai)][p] & 0x0f) << 8;
941 writel(port_mmio + PORT_SCR_CTL, tmp);
942
943 /* issue COMRESET on the port */
944 DPRINTF(3,__func__": issuing COMRESET on port %d\n", p);
945 writel(port_mmio + PORT_SCR_CTL, tmp | 1);
946 readl(port_mmio + PORT_SCR_CTL); /* flush */
947
948 /* spec says "leave reset bit on for at least 1ms"; make it 2ms */
949 udelay(2000);
950
951 writel(port_mmio + PORT_SCR_CTL, tmp);
952 readl(port_mmio + PORT_SCR_CTL); /* flush */
953
954 /* wait for communication to be re-established after port reset */
955 DPRINTF(2,"Wait for communication...\n");
956 TimerInit(&Timer, 500);
957 while (((tmp = readl(port_mmio + PORT_SCR_STAT)) & 3) != 3)
958 {
959 if (TimerCheckAndBlock(&Timer))
960 {
961 DPRINTF(0,"no device present after resetting port #%d (PORT_SCR_STAT = 0x%x)\n", p, tmp);
962 return(-1);
963 }
964 }
965
966 /* clear SError again (recommended by AHCI spec) */
967 tmp = readl(port_mmio + PORT_SCR_ERR);
968 writel(port_mmio + PORT_SCR_ERR, tmp);
969
970 /* start port so we can receive the COMRESET FIS */
971 DPRINTF(2,__func__": starting port %d again\n", p);
972 ahci_start_port(ai, p, ei);
973
974 /* wait for device to be ready ((PxTFD & (BSY | DRQ | ERR)) == 0) */
975 TimerInit(&Timer, 1000);
976 while (((tmp = readl(port_mmio + PORT_TFDATA)) & 0x89) != 0)
977 {
978 if (TimerCheckAndBlock(&Timer))
979 {
980 DPRINTF(0,"device not ready on port #%d (PORT_TFDATA = 0x%x)\n", p, tmp);
981 ahci_stop_port(ai, p);
982 return(-1);
983 }
984 }
985 DPRINTF(3,__func__": PORT_TFDATA = 0x%x\n", readl(port_mmio + PORT_TFDATA));
986
987 return(0);
988}
989
990/******************************************************************************
991 * Start specified port.
992 */
993int ahci_start_port(AD_INFO *ai, int p, int ei)
994{
995 u8 *port_mmio = port_base(ai, p);
996 u32 status;
997
998 DPRINTF(3,__func__": %d.%d\n", ad_no(ai), p);
999 /* check whether device presence is detected and link established */
1000
1001 status = readl(port_mmio + PORT_SCR_STAT);
1002 DPRINTF(3,__func__": PORT_SCR_STAT = 0x%x\n", status);
1003 if ((status & 0xf) != 3) return(-1);
1004
1005 /* clear SError, if any */
1006 status = readl(port_mmio + PORT_SCR_ERR);
1007 DPRINTF(3,__func__": PORT_SCR_ERR = 0x%x\n", status);
1008 writel(port_mmio + PORT_SCR_ERR, status);
1009
1010 /* enable FIS reception */
1011 ahci_start_fis_rx(ai, p);
1012
1013 /* enable command engine */
1014 ahci_start_engine(ai, p);
1015
1016 if (ei)
1017 {
1018 /* clear any pending interrupts on this port */
1019 if ((status = readl(port_mmio + PORT_IRQ_STAT)) != 0)
1020 {
1021 writel(port_mmio + PORT_IRQ_STAT, status);
1022 }
1023
1024 /* enable port interrupts */
1025 writel(port_mmio + PORT_IRQ_MASK, PORT_IRQ_TF_ERR |
1026 PORT_IRQ_HBUS_ERR |
1027 PORT_IRQ_HBUS_DATA_ERR |
1028 PORT_IRQ_IF_ERR |
1029 PORT_IRQ_OVERFLOW |
1030 PORT_IRQ_BAD_PMP |
1031 PORT_IRQ_UNK_FIS |
1032 PORT_IRQ_SDB_FIS |
1033 PORT_IRQ_DMAS_FIS |
1034 PORT_IRQ_PIOS_FIS |
1035 PORT_IRQ_D2H_REG_FIS);
1036 }
1037 else
1038 {
1039 writel(port_mmio + PORT_IRQ_MASK, 0);
1040 }
1041 readl(port_mmio + PORT_IRQ_MASK); /* flush */
1042
1043 return(0);
1044}
1045
1046/******************************************************************************
1047 * Start port FIS reception. Copied from Linux AHCI driver and adopted to
1048 * OS2AHCI.
1049 */
1050void ahci_start_fis_rx(AD_INFO *ai, int p)
1051{
1052 u8 *port_mmio = port_base(ai, p);
1053 u32 port_dma = port_dma_base_phys(ai, p);
1054 u32 tmp;
1055
1056 /* set command header and FIS address registers */
1057 writel(port_mmio + PORT_LST_ADDR, port_dma + offsetof(AHCI_PORT_DMA, cmd_hdr));
1058 writel(port_mmio + PORT_LST_ADDR_HI, 0);
1059 writel(port_mmio + PORT_FIS_ADDR, port_dma + offsetof(AHCI_PORT_DMA, rx_fis));
1060 writel(port_mmio + PORT_FIS_ADDR_HI, 0);
1061
1062 /* enable FIS reception */
1063 tmp = readl(port_mmio + PORT_CMD);
1064 tmp |= PORT_CMD_FIS_RX;
1065 writel(port_mmio + PORT_CMD, tmp);
1066
1067 /* flush */
1068 readl(port_mmio + PORT_CMD);
1069}
1070
1071/******************************************************************************
1072 * Start port HW engine. Copied from Linux AHCI driver and adopted to OS2AHCI.
1073 */
1074void ahci_start_engine(AD_INFO *ai, int p)
1075{
1076 u8 *port_mmio = port_base(ai, p);
1077 u32 tmp;
1078
1079 /* start DMA */
1080 tmp = readl(port_mmio + PORT_CMD);
1081 tmp |= PORT_CMD_START;
1082 writel(port_mmio + PORT_CMD, tmp);
1083 readl(port_mmio + PORT_CMD); /* flush */
1084}
1085
1086/******************************************************************************
1087 * Stop specified port
1088 */
1089int ahci_stop_port(AD_INFO *ai, int p)
1090{
1091 u8 *port_mmio = port_base(ai, p);
1092 u32 tmp;
1093 int rc;
1094
1095 DPRINTF(3,__func__": %d.%d\n", ad_no(ai), p);
1096
1097 /* disable port interrupts */
1098 writel(port_mmio + PORT_IRQ_MASK, 0);
1099
1100 /* disable FIS reception */
1101 if ((rc = ahci_stop_fis_rx(ai, p)) != 0)
1102 {
1103 dprintf(0,__func__": failed to stop FIS receive (%d)\n", rc);
1104 return(rc);
1105 }
1106
1107 /* disable command engine */
1108 if ((rc = ahci_stop_engine(ai, p)) != 0)
1109 {
1110 dprintf(0,__func__": failed to stop port HW engine (%d)\n", rc);
1111 return(rc);
1112 }
1113
1114 /* clear any pending port IRQs */
1115 tmp = readl(port_mmio + PORT_IRQ_STAT);
1116 if (tmp) writel(port_mmio + PORT_IRQ_STAT, tmp);
1117 writel(ai->mmio + HOST_IRQ_STAT, 1UL << p);
1118
1119 /* reset PxSACT register (tagged command queues, not reset by COMRESET) */
1120 writel(port_mmio + PORT_SCR_ACT, 0);
1121 readl(port_mmio + PORT_SCR_ACT); /* flush */
1122
1123 return(0);
1124}
1125
1126/******************************************************************************
1127 * Stop port FIS reception. Copied from Linux AHCI driver and adopted to
1128 * OS2AHCI.
1129 *
1130 * NOTE: This function uses a busy loop to wait for the DMA engine to stop. It
1131 * should only be called at task time during initialization or in a
1132 * context hook (e.g. when resetting a port).
1133 */
1134int ahci_stop_fis_rx(AD_INFO *ai, int p)
1135{
1136 u8 *port_mmio = port_base(ai, p);
1137 TIMER Timer;
1138 u32 tmp;
1139 int status;
1140
1141 /* disable FIS reception */
1142 tmp = readl(port_mmio + PORT_CMD);
1143 tmp &= ~PORT_CMD_FIS_RX;
1144 writel(port_mmio + PORT_CMD, tmp);
1145
1146 /* wait for completion, spec says 500ms, give it 1000ms */
1147 status = 0;
1148 TimerInit(&Timer, 1000);
1149 while (readl(port_mmio + PORT_CMD) & PORT_CMD_FIS_ON)
1150 {
1151 status = TimerCheckAndBlock(&Timer);
1152 if (status) break;
1153 }
1154
1155 return(status ? -1 : 0);
1156}
1157
1158/******************************************************************************
1159 * Stop port HW engine. Copied from Linux AHCI driver and adopted to OS2AHCI.
1160 *
1161 * NOTE: This function uses a busy loop to wait for the DMA engine to stop. It
1162 * should only be called at task time during initialization or in a
1163 * context hook (e.g. when resetting a port).
1164 */
1165int ahci_stop_engine(AD_INFO *ai, int p)
1166{
1167 u8 *port_mmio = port_base(ai, p);
1168 TIMER Timer;
1169 int status;
1170 u32 tmp;
1171
1172 tmp = readl(port_mmio + PORT_CMD);
1173
1174 /* check if the port is already stopped */
1175 if ((tmp & (PORT_CMD_START | PORT_CMD_LIST_ON)) == 0) return 0;
1176
1177 /* set port to idle */
1178 tmp &= ~PORT_CMD_START;
1179 writel(port_mmio + PORT_CMD, tmp);
1180
1181 /* wait for engine to stop. This could be as long as 500 msec */
1182 status = 0;
1183 TimerInit(&Timer, 500);
1184 while (readl(port_mmio + PORT_CMD) & PORT_CMD_LIST_ON)
1185 {
1186 status = TimerCheckAndBlock(&Timer);
1187 if (status) break;
1188 }
1189
1190 return(status ? -1 : 0);
1191}
1192
1193/******************************************************************************
1194 * Determine whether a port is busy executing commands.
1195 */
1196int ahci_port_busy(AD_INFO *ai, int p)
1197{
1198 u8 *port_mmio = port_base(ai, p);
1199
1200 return(readl(port_mmio + PORT_SCR_ACT) != 0 || readl(port_mmio + PORT_CMD_ISSUE) != 0);
1201}
1202
1203/******************************************************************************
1204 * Execute AHCI command for given IORB. This includes all steps typically
1205 * required by any of the ahci_*() IORB processing functions.
1206 *
1207 * NOTE: In order to prevent race conditions with port restart and reset
1208 * handlers, we either need to keep the spinlock during the whole
1209 * operation or set the adapter's busy flag. Since the expectation
1210 * is that command preparation will be quick (it certainly doesn't
1211 * involve delays), we're going with the spinlock for the time being.
1212 */
1213void ahci_exec_iorb(IORBH FAR16DATA *vIorb, IORBH *pIorb, int ncq_capable, int (*func)(IORBH FAR16DATA *, IORBH *pIorb, int))
1214{
1215 volatile u32 *cmds;
1216 ADD_WORKSPACE *aws = add_workspace(pIorb);
1217 AD_INFO *ai = &ad_infos[iorb_unit_adapter(pIorb)];
1218 P_INFO *port = &ai->ports[iorb_unit_port(pIorb)];
1219 ULONG timeout;
1220 u8 *port_mmio = port_base(ai, iorb_unit_port(pIorb));
1221 u16 cmd_max = ai->cmd_max;
1222 int i;
1223
1224 /* determine timeout in milliseconds */
1225 switch (pIorb->Timeout)
1226 {
1227 case 0:
1228 timeout = DEFAULT_TIMEOUT;
1229 break;
1230 case 0xffffffffUL:
1231 timeout = 0xffffffffUL;
1232 break;
1233 default:
1234 timeout = pIorb->Timeout * 1000;
1235 break;
1236 }
1237
1238 DPRINTF(7,"---------- "__func__": iorb=%x\n", vIorb);
1239
1240 /* Enable AHCI mode; apparently, the AHCI mode may end up becoming
1241 * disabled, either during the boot sequence (by the BIOS) or by
1242 * something else. The Linux AHCI drivers have this call in the
1243 * command processing chain, and apparently for a good reason because
1244 * without this, commands won't be executed.
1245 */
1246 ahci_enable_ahci(ai);
1247
1248 /* determine whether this will be an NCQ request */
1249 aws->is_ncq = 0;
1250 if (ncq_capable && port->devs[iorb_unit_device(pIorb)].ncq_max > 1 &&
1251 (ai->cap & HOST_CAP_NCQ) && !aws->no_ncq && init_complete)
1252 {
1253
1254 /* We can make this an NCQ request; limit command slots to the maximum
1255 * NCQ tag number reported by the device - 1. Why "minus one"? I seem to
1256 * recall an issue related to using all 32 tag numbers but can't quite
1257 * pinpoint it right now. One less won't make much of a difference...
1258 */
1259 aws->is_ncq = 1;
1260 if ((cmd_max = port->devs[iorb_unit_device(pIorb)].ncq_max - 1) > ai->cmd_max)
1261 {
1262 cmd_max = ai->cmd_max;
1263 }
1264 DPRINTF(8,__func__": NCQ command; cmd_max = %d->%d\n", ai->cmd_max, cmd_max);
1265 }
1266
1267 /* make sure adapter is available */
1268 spin_lock(drv_lock);
1269 if (!ai->busy)
1270 {
1271
1272 if (!init_complete)
1273 {
1274 /* no IRQ handlers or context hooks availabe at this point */
1275 ai->busy = 1;
1276 spin_unlock(drv_lock);
1277 ahci_exec_polled_iorb(vIorb, pIorb, func, timeout);
1278 ai->busy = 0;
1279 return;
1280 }
1281
1282 /* make sure we don't mix NCQ and regular commands */
1283 if (aws->is_ncq && port->reg_cmds == 0 || !aws->is_ncq && port->ncq_cmds == 0)
1284 {
1285 /* Find next available command slot. We use a simple round-robin
1286 * algorithm for this to prevent commands with higher slot indexes
1287 * from stalling when new commands are coming in frequently.
1288 */
1289 cmds = (aws->is_ncq) ? &port->ncq_cmds : &port->reg_cmds;
1290 for (i = 0; i <= cmd_max; i++)
1291 {
1292 if (++(port->cmd_slot) > cmd_max) port->cmd_slot = 0;
1293 if ((*cmds & (1UL << port->cmd_slot)) == 0) break;
1294 }
1295
1296 if ((*cmds & (1UL << port->cmd_slot)) == 0)
1297 {
1298 /* found idle command slot; prepare command */
1299 if (func(vIorb, pIorb, port->cmd_slot))
1300 {
1301 /* Command preparation failed, or no HW command required; IORB
1302 * will already have the error code if there was an error.
1303 */
1304 spin_unlock(drv_lock);
1305 iorb_done(vIorb, pIorb);
1306 return;
1307 }
1308
1309 /* start timer for this IORB */
1310 Timer_StartTimerMS(&aws->timer, timeout, timeout_callback, CastFar16ToULONG(vIorb));
1311
1312 /* issue command to hardware */
1313 *cmds |= (1UL << port->cmd_slot);
1314 aws->queued_hw = 1;
1315 aws->cmd_slot = port->cmd_slot;
1316
1317 DPRINTF(7,__func__": Issuing command Slot=%d cmds=%x\n", port->cmd_slot, *cmds);
1318 if (aws->is_ncq)
1319 {
1320 writel(port_mmio + PORT_SCR_ACT, (1UL << port->cmd_slot));
1321 readl(port_mmio + PORT_SCR_ACT); /* flush */
1322 }
1323 writel(port_mmio + PORT_CMD_ISSUE, (1UL << port->cmd_slot));
1324 readl(port_mmio + PORT_CMD_ISSUE); /* flush */
1325
1326 spin_unlock(drv_lock);
1327 return;
1328 }
1329 }
1330 }
1331
1332 /* requeue this IORB; it will be picked up again in trigger_engine() */
1333 aws->processing = 0;
1334 spin_unlock(drv_lock);
1335}
1336
1337/******************************************************************************
1338 * Execute polled IORB command. This function is called by ahci_exec_iorb()
1339 * when the initialization has not yet completed. The reasons for polling until
1340 * initialization has completed are:
1341 *
1342 * - We need to restore the BIOS configuration after we're done with this
1343 * command because someone might still call int 13h routines; sending
1344 * asynchronous commands and waiting for interrupts to indicate completion
1345 * won't work in such a scenario.
1346 * - Our context hooks won't work while the device managers are initializing
1347 * (they can't yield at init time).
1348 * - The device managers typically poll for command completion during
1349 * initialization so it won't make much of a difference, anyway.
1350 *
1351 * NOTE: This function must be called with the adapter-level busy flag set but
1352 * without the driver-level spinlock held.
1353 */
1354void ahci_exec_polled_iorb(IORBH FAR16DATA *vIorb, IORBH *pIorb, int (*func)(IORBH FAR16DATA *, IORBH *pIorb, int), ULONG timeout)
1355{
1356 AHCI_PORT_CFG *pc = NULL;
1357 AD_INFO *ai = ad_infos + iorb_unit_adapter(vIorb);
1358 int p = iorb_unit_port(pIorb);
1359 u8 *port_mmio = port_base(ai, p);
1360 TIMER Timer;
1361 int rc;
1362
1363 /* enable AHCI mode */
1364 if (ahci_enable_ahci(ai) != 0)
1365 {
1366 iorb_seterr(pIorb, IOERR_ADAPTER_NONSPECIFIC);
1367 goto restore_bios_config;
1368 }
1369
1370 /* check whether command slot 0 is available */
1371 if ((readl(port_mmio + PORT_CMD_ISSUE) & 1) != 0)
1372 {
1373 iorb_seterr(pIorb, IOERR_DEVICE_BUSY);
1374 goto restore_bios_config;
1375 }
1376
1377 /* save port configuration */
1378 if ((pc = ahci_save_port_config(ai, p)) == NULL)
1379 {
1380 iorb_seterr(pIorb, IOERR_CMD_SW_RESOURCE);
1381 goto restore_bios_config;
1382 }
1383
1384 /* restart/reset port (includes the necessary port configuration) */
1385 if (init_reset)
1386 {
1387 /* As outlined in ahci_restore_bios_config(), switching back and
1388 * forth between SATA and AHCI mode requires a COMRESET to force
1389 * the corresponding controller subsystem to rediscover attached
1390 * devices. Thus, we'll reset the port instead of stopping and
1391 * starting it.
1392 */
1393 if (ahci_reset_port(ai, p, 0))
1394 {
1395 iorb_seterr(pIorb, IOERR_ADAPTER_NONSPECIFIC);
1396 goto restore_bios_config;
1397 }
1398
1399 }
1400 else if (ahci_stop_port(ai, p) || ahci_start_port(ai, p, 0))
1401 {
1402 iorb_seterr(pIorb, IOERR_ADAPTER_NONSPECIFIC);
1403 goto restore_bios_config;
1404 }
1405
1406 /* prepare command */
1407 if (func(vIorb, pIorb, 0) == 0)
1408 {
1409 /* successfully prepared cmd; issue cmd and wait for completion */
1410 DPRINTF(3,"---------- "__func__" executing polled cmd on slot 0...");
1411 writel(port_mmio + PORT_CMD_ISSUE, 1);
1412 TimerInit(&Timer, timeout);
1413 while (readl(port_mmio + PORT_CMD_ISSUE) & 1)
1414 {
1415 rc = TimerCheckAndBlock(&Timer);
1416 if (rc) break;
1417 }
1418
1419 /* 0x89 = BSY(0x80) | DRQ(0x08) | ERR(0x01) */
1420 if (rc)
1421 {
1422 DPRINTF(3," timeout for IORB %x", vIorb);
1423 iorb_seterr(pIorb, IOERR_ADAPTER_TIMEOUT);
1424 }
1425 else if (readl(port_mmio + PORT_SCR_ERR) != 0 || readl(port_mmio + PORT_TFDATA) & 0x89)
1426 {
1427 DPRINTF(3," polled cmd error for IORB %x", vIorb);
1428 iorb_seterr(pIorb, IOERR_DEVICE_NONSPECIFIC);
1429 ahci_reset_port(ai, iorb_unit_port(pIorb), 0);
1430 }
1431 else
1432 {
1433 /* successfully executed command */
1434 if (add_workspace(pIorb)->ppfunc != NULL)
1435 {
1436 add_workspace(pIorb)->ppfunc(vIorb, pIorb);
1437 }
1438 else
1439 {
1440 add_workspace(pIorb)->complete = 1;
1441 }
1442 }
1443 DPRINTF(3,"\n");
1444 }
1445
1446restore_bios_config:
1447 /* restore BIOS configuration */
1448 if (pc != NULL)
1449 {
1450 ahci_restore_port_config(ai, p, pc);
1451 }
1452 ahci_restore_bios_config(ai);
1453
1454 if (add_workspace(pIorb)->complete | (pIorb->Status | IORB_ERROR))
1455 {
1456 iorb_done(vIorb, pIorb);
1457 }
1458 return;
1459}
1460
1461/******************************************************************************
1462 * Execute polled ATA/ATAPI command. This function will block until the command
1463 * has completed or the timeout has expired, thus it should only be used during
1464 * initialization. Furthermore, it will always use command slot zero.
1465 *
1466 * The difference to ahci_exec_polled_iorb() is that this function executes
1467 * arbitrary ATA/ATAPI commands outside the context of an IORB. It's typically
1468 * used when scanning for devices during initialization.
1469 */
1470int ahci_exec_polled_cmd(AD_INFO *ai, int p, int d, int timeout, int cmd, ...)
1471{
1472 va_list va;
1473 u8 *port_mmio = port_base(ai, p);
1474 u32 tmp;
1475 int rc;
1476 TIMER Timer;
1477
1478 /* verify that command slot 0 is idle */
1479 if (readl(port_mmio + PORT_CMD_ISSUE) & 1)
1480 {
1481 DPRINTF(3,__func__": port %d slot 0 is not idle; not executing polled cmd\n", p);
1482 return(-1);
1483 }
1484
1485 /* fill in command slot 0 */
1486 va_start(va, cmd);
1487 if ((rc = v_ata_cmd(ai, p, d, 0, cmd, va)) != 0) return(rc);
1488
1489 /* start command execution for slot 0 */
1490 DPRINTF(3,"---------- "__func__" executing polled cmd...");
1491 writel(port_mmio + PORT_CMD_ISSUE, 1);
1492
1493 /* wait until command has completed */
1494 TimerInit(&Timer, timeout);
1495 rc = 0;
1496 while (readl(port_mmio + PORT_CMD_ISSUE) & 1)
1497 {
1498 rc = TimerCheckAndBlock(&Timer);
1499 if (rc)
1500 {
1501 DPRINTF(2," Timeout");
1502 break;
1503 }
1504 }
1505
1506 tmp = readl(port_mmio + PORT_SCR_ERR);
1507 if (tmp & PORT_ERR_FAIL_BITS)
1508 {
1509 DPRINTF(2," SERR = 0x%08lx", tmp);
1510 rc = 1;
1511 }
1512 /* 0x89 = BSY(0x80) | DRQ(0x08) | ERR(0x01) */
1513 if (((tmp = readl(port_mmio + PORT_TFDATA)) & 0x89) != 0)
1514 {
1515 DPRINTF(2," TFDATA = 0x%08lx", tmp);
1516 rc = 1;
1517 }
1518
1519 if (rc)
1520 {
1521 DPRINTF(3,"failed\n");
1522 ahci_reset_port(ai, p, 0);
1523 return(-1);
1524 }
1525 DPRINTF(3,"success\n");
1526 return(0);
1527}
1528
1529/******************************************************************************
1530 * Flush write cache of the specified device. Since there's no equivalent IORB
1531 * command, we'll execute this command directly using polling. Otherwise, we
1532 * would have to create a fake IORB, add it to the port's IORB queue, ...
1533 *
1534 * Besides, this function is only called when shutting down and the code there
1535 * would have to wait for the flush cache command to complete as well, using
1536 * polling just the same...
1537 */
1538int ahci_flush_cache(AD_INFO *ai, int p, int d)
1539{
1540 if (!ai->ports[p].devs[d].atapi)
1541 {
1542 DPRINTF(2,__func__": flushing cache on %d.%d.%d\n", ad_no(ai), p, d);
1543 return(ahci_exec_polled_cmd(ai, p, d, 30000,
1544 ai->ports[p].devs[d].lba48 ? ATA_CMD_FLUSH_EXT : ATA_CMD_FLUSH, AP_END));
1545 }
1546 return 0;
1547}
1548
1549/******************************************************************************
1550 * Set device into IDLE mode (spin down); this was used during
1551 * debugging/testing and is now unused; it's still there in case we need it
1552 * again...
1553 *
1554 * If 'idle' is != 0, the idle timeout is set to 5 seconds, otherwise it
1555 * is turned off.
1556 */
1557int ahci_set_dev_idle(AD_INFO *ai, int p, int d, int idle)
1558{
1559 DPRINTF(3,__func__": sending IDLE=%d command to port %d\n", idle, p);
1560 return ahci_exec_polled_cmd(ai, p, d, 500, ATA_CMD_IDLE, AP_COUNT, idle ? 1 : 0, AP_END);
1561}
1562
1563/******************************************************************************
1564 * AHCI top-level hardware interrupt handler. This handler finds the adapters
1565 * and ports which have issued the interrupt and calls the corresponding
1566 * port interrupt handler.
1567 *
1568 * On entry, OS/2 will have processor interrupts enabled because we're using
1569 * shared IRQs but we won't be preempted by another interrupt on the same
1570 * IRQ level until we indicated EOI. We'll keep it this way, only requesting
1571 * the driver-level spinlock when actually changing the driver state (IORB
1572 * queues, ...)
1573 */
1574#pragma aux ahci_intr parm [eax]
1575int ahci_intr(u32 irq)
1576{
1577 u32 irq_stat;
1578 int handled = 0;
1579 int a;
1580 int p;
1581
1582 /* find adapter(s) with pending interrupts */
1583 for (a = 0; a < ad_info_cnt; a++)
1584 {
1585 AD_INFO *ai = ad_infos + a;
1586
1587 if (ai->irq == irq && (irq_stat = readl(ai->mmio + HOST_IRQ_STAT)) != 0)
1588 {
1589 /* this adapter has interrupts pending */
1590 u32 irq_masked = irq_stat & ai->port_map;
1591
1592 for (p = 0; p <= ai->port_max; p++)
1593 {
1594 if (irq_masked & (1UL << p))
1595 {
1596 ahci_port_intr(ai, p);
1597 }
1598 }
1599
1600 /* clear interrupt condition on the adapter */
1601 writel(ai->mmio + HOST_IRQ_STAT, irq_stat);
1602 readl(ai->mmio + HOST_IRQ_STAT); /* flush */
1603 handled = 1;
1604 }
1605 }
1606
1607 if (handled)
1608 {
1609 /* Trigger state machine to process next IORBs, if any. Due to excessive
1610 * IORB requeue operations (e.g. when processing large unaligned reads or
1611 * writes), we may be stacking interrupts on top of each other. If we
1612 * detect this, we'll pass this on to the engine context hook.
1613 */
1614 #if 0
1615 if ((u32)&irq_stat < 0xf000)
1616 {
1617 DPRINTF(0,__func__": IRQ stack running low; arming engine context hook\n");
1618 /* Rousseau:
1619 * A context hook cannot be re-armed before it has completed.
1620 * (?:\IBMDDK\DOCS\PDDREF.INF->Device Helper (DevHlp) Services)->ArmCtxHook)
1621 * Also, it is executed at task-time, thus in the context of some
1622 * application thread. Stacked interrupts with a stack below the
1623 * threshold specified above, (0xf000), will repeatly try to arm the
1624 * context hook, but since we are in an interrupted interrupt handler,
1625 * it's highly unlikely the hook has completed.
1626 * So, possibly only the first arming is succesful and subsequent armings
1627 * will fail because no task-time thread has run between the stacked
1628 * interrupts. One hint would be that if the dispatching truely worked,
1629 * excessive stacked interrupts in VBox would not be a problem.
1630 * This needs some more investigation.
1631 */
1632 KernArmHook(engine_ctxhook_h, 0, 0);
1633 }
1634 else
1635 #endif
1636 {
1637 spin_lock(drv_lock);
1638 trigger_engine();
1639 spin_unlock(drv_lock);
1640 }
1641 DevCli();
1642 Dev32Help_EOI(irq);
1643 return(1); /* handled */
1644 }
1645
1646 return(0); /* not handled */
1647}
1648
1649/******************************************************************************
1650 * AHCI port-level interrupt handler. As described above, processor interrupts
1651 * are enabled on entry thus we have to protect shared resources with a
1652 * spinlock.
1653 */
1654void ahci_port_intr(AD_INFO *ai, int p)
1655{
1656 IORB_QUEUE done_queue;
1657 IORBH FAR16DATA *vIorb;
1658 IORBH FAR16DATA *vNext = FAR16NULL;
1659 u8 *port_mmio = port_base(ai, p);
1660 u32 irq_stat;
1661 u32 active_cmds;
1662 u32 done_mask;
1663
1664 /* get interrupt status and clear it right away */
1665 irq_stat = readl(port_mmio + PORT_IRQ_STAT);
1666 writel(port_mmio + PORT_IRQ_STAT, irq_stat);
1667 readl(port_mmio + PORT_IRQ_STAT); /* flush */
1668
1669 memset(&done_queue, 0x00, sizeof(done_queue));
1670
1671 if (irq_stat & PORT_IRQ_ERROR)
1672 {
1673 /* this is an error interrupt;
1674 * disable port interrupts to avoid IRQ storm until error condition
1675 * has been cleared by the restart handler
1676 */
1677 writel(port_mmio + PORT_IRQ_MASK, 0);
1678 ahci_error_intr(ai, p, irq_stat);
1679 return;
1680 }
1681
1682 spin_lock(drv_lock);
1683
1684 /* Find out which command slots have completed. Since error recovery for
1685 * NCQ commands interfers with non-NCQ commands, the upper layers will
1686 * make sure there's never a mixture of NCQ and non-NCQ commands active
1687 * on any port at any given time. This makes it easier to find out which
1688 * commands have completed, too.
1689 */
1690 if (ai->ports[p].ncq_cmds != 0)
1691 {
1692 active_cmds = readl(port_mmio + PORT_SCR_ACT);
1693 done_mask = ai->ports[p].ncq_cmds ^ active_cmds;
1694 DPRINTF(7,"[ncq_cmds]: active_cmds=0x%08x done_mask=0x%08x\n", active_cmds, done_mask);
1695 }
1696 else
1697 {
1698 active_cmds = readl(port_mmio + PORT_CMD_ISSUE);
1699 done_mask = ai->ports[p].reg_cmds ^ active_cmds;
1700 DPRINTF(7,"[reg_cmds]: active_cmds=0x%08x done_mask=0x%08x\n", active_cmds, done_mask);
1701 }
1702
1703 /* Find the IORBs related to the completed commands and complete them.
1704 *
1705 * NOTES: The spinlock must not be released while in this loop to prevent
1706 * race conditions with timeout handlers or other threads in SMP
1707 * systems.
1708 *
1709 * Since we hold the spinlock when IORBs complete, we can't call the
1710 * IORB notification routine right away because this routine might
1711 * schedule another IORB which could cause a deadlock. Thus, we'll
1712 * add all IORBs to be completed to a temporary queue which will be
1713 * processed after releasing the spinlock.
1714 */
1715 for (vIorb = ai->ports[p].iorb_queue.vRoot; vIorb != FAR16NULL; vIorb = vNext)
1716 {
1717 IORBH *pIorb = Far16ToFlat(vIorb);
1718 ADD_WORKSPACE *aws = (ADD_WORKSPACE *) &pIorb->ADDWorkSpace;
1719
1720 vNext = pIorb->f16NxtIORB;
1721 if (aws->queued_hw && (done_mask & (1UL << aws->cmd_slot)))
1722 {
1723 /* this hardware command has completed */
1724 ai->ports[p].ncq_cmds &= ~(1UL << aws->cmd_slot);
1725 ai->ports[p].reg_cmds &= ~(1UL << aws->cmd_slot);
1726
1727 /* call post-processing function, if any */
1728 if (aws->ppfunc != NULL) aws->ppfunc(vIorb, pIorb);
1729 else aws->complete = 1;
1730
1731 if (aws->complete)
1732 {
1733 /* this IORB is complete; move IORB to our temporary done queue */
1734 iorb_queue_del(&ai->ports[p].iorb_queue, vIorb);
1735 iorb_queue_add(&done_queue, vIorb, pIorb);
1736 aws_free(add_workspace(pIorb));
1737 }
1738 }
1739 }
1740
1741 spin_unlock(drv_lock);
1742
1743 /* complete all IORBs in the done queue */
1744 for (vIorb = done_queue.vRoot; vIorb != FAR16NULL; vIorb = vNext)
1745 {
1746 IORBH *pIorb = Far16ToFlat(vIorb);
1747
1748 vNext = pIorb->f16NxtIORB;
1749
1750 iorb_complete(vIorb, pIorb);
1751 }
1752}
1753
1754/******************************************************************************
1755 * AHCI error interrupt handler. Errors include interface errors and device
1756 * errors (usually triggered by the error bit in the AHCI task file register).
1757 *
1758 * Since this involves long-running operations such as restarting or even
1759 * resetting a port, this function is invoked at task time via a context
1760 * hook.
1761 *
1762 * NOTE: AHCI controllers stop all processing when encountering an error
1763 * condition in order to give the driver time to find out what exactly
1764 * went wrong. This means no new commands will be processed until we
1765 * clear the error register and restore the "commands issued" register.
1766 */
1767void ahci_error_intr(AD_INFO *ai, int p, u32 irq_stat)
1768{
1769 int reset_port = 0;
1770
1771 /* Handle adapter and interface errors. Those typically require a port
1772 * reset, or worse.
1773 */
1774 ai->ports[p].error_count++;
1775
1776 if (irq_stat & PORT_IRQ_UNK_FIS)
1777 {
1778 #ifdef DEBUG
1779 u32 *unk = (u32 *) (port_dma_base(ai, p)->rx_fis + RX_FIS_UNK);
1780 DPRINTF(0,"warning: unknown FIS %08lx %08lx %08lx %08lx\n", unk[0], unk[1], unk[2], unk[3]);
1781 #endif
1782 reset_port = 1;
1783 }
1784 if (irq_stat & (PORT_IRQ_HBUS_ERR | PORT_IRQ_HBUS_DATA_ERR))
1785 {
1786 dprintf(0,"warning: host bus [data] error for port #%d\n", p);
1787 reset_port = 1;
1788 }
1789 if (irq_stat & PORT_IRQ_IF_ERR && !(ai->flags & AHCI_HFLAG_IGN_IRQ_IF_ERR))
1790 {
1791 dprintf(0,"warning: interface fatal error for port #%d\n", p);
1792 reset_port = 1;
1793 }
1794 if (reset_port)
1795 {
1796 /* need to reset the port; leave this to the reset context hook */
1797
1798 ports_to_reset[ad_no(ai)] |= 1UL << p;
1799 KernArmHook(reset_ctxhook_h, 0, 0);
1800
1801 /* no point analyzing device errors after a reset... */
1802 return;
1803 }
1804
1805 dprintf(0,"port #%d interrupt error status: 0x%08lx; restarting port\n", p, irq_stat);
1806
1807 /* Handle device-specific errors. Those errors typically involve restarting
1808 * the corresponding port to resume operations which can take some time,
1809 * thus we need to offload this functionality to the restart context hook.
1810 */
1811 ports_to_restart[ad_no(ai)] |= 1UL << p;
1812 KernArmHook(restart_ctxhook_h, 0, 0);
1813}
1814
1815/******************************************************************************
1816 * Get device or media geometry. Device and media geometry are expected to be
1817 * the same for non-removable devices.
1818 */
1819void ahci_get_geometry(IORBH FAR16DATA *vIorb, IORBH *pIorb)
1820{
1821 DPRINTF(7,"ahci_get_geometry(%d.%d.%d)\n", iorb_unit_adapter(pIorb),
1822 iorb_unit_port(pIorb), iorb_unit_device(pIorb));
1823
1824 ahci_exec_iorb(vIorb, pIorb, 0, cmd_func(pIorb, get_geometry));
1825}
1826
1827/******************************************************************************
1828 * Test whether unit is ready.
1829 */
1830void ahci_unit_ready(IORBH FAR16DATA *vIorb, IORBH *pIorb)
1831{
1832 DPRINTF(7,"ahci_unit_ready(%d.%d.%d)\n", iorb_unit_adapter(pIorb),
1833 iorb_unit_port(pIorb), iorb_unit_device(pIorb));
1834
1835 ahci_exec_iorb(vIorb, pIorb, 0, cmd_func(pIorb, unit_ready));
1836}
1837
1838/******************************************************************************
1839 * Read sectors from AHCI device.
1840 */
1841void ahci_read(IORBH FAR16DATA *vIorb, IORBH *pIorb)
1842{
1843 DPRINTF(7,"ahci_read(%d.%d.%d, %d, %d)\n", iorb_unit_adapter(vIorb),
1844 iorb_unit_port(pIorb), iorb_unit_device(pIorb),
1845 ((IORB_EXECUTEIO *) pIorb)->RBA,
1846 ((IORB_EXECUTEIO *) pIorb)->BlockCount);
1847
1848 ahci_exec_iorb(vIorb, pIorb, 1, cmd_func(pIorb, read));
1849}
1850
1851/******************************************************************************
1852 * Verify readability of sectors on AHCI device.
1853 */
1854void ahci_verify(IORBH FAR16DATA *vIorb, IORBH *pIorb)
1855{
1856 DPRINTF(7,"ahci_verify(%d.%d.%d, %d, %d)\n", iorb_unit_adapter(pIorb),
1857 iorb_unit_port(pIorb), iorb_unit_device(pIorb),
1858 ((IORB_EXECUTEIO *)pIorb)->RBA,
1859 ((IORB_EXECUTEIO *)pIorb)->BlockCount);
1860
1861 ahci_exec_iorb(vIorb, pIorb, 0, cmd_func(pIorb, verify));
1862}
1863
1864/******************************************************************************
1865 * Write sectors to AHCI device.
1866 */
1867void ahci_write(IORBH FAR16DATA *vIorb, IORBH *pIorb)
1868{
1869 DPRINTF(7,"ahci_write(%d.%d.%d, %d, %d)\n", iorb_unit_adapter(pIorb),
1870 iorb_unit_port(pIorb), iorb_unit_device(pIorb),
1871 ((IORB_EXECUTEIO *)pIorb)->RBA,
1872 ((IORB_EXECUTEIO *)pIorb)->BlockCount);
1873
1874 ahci_exec_iorb(vIorb, pIorb, 1, cmd_func(pIorb, write));
1875}
1876
1877/******************************************************************************
1878 * Execute SCSI (ATAPI) command.
1879 */
1880void ahci_execute_cdb(IORBH FAR16DATA *vIorb, IORBH *pIorb)
1881{
1882 int a = iorb_unit_adapter(pIorb);
1883 int p = iorb_unit_port(pIorb);
1884 int d = iorb_unit_device(pIorb);
1885
1886 DHEXDUMP(5,Far16ToFlat(((IORB_ADAPTER_PASSTHRU *)pIorb)->f16ControllerCmd),
1887 ((IORB_ADAPTER_PASSTHRU *)pIorb)->ControllerCmdLen,
1888 "ahci_execute_cdb(%d.%d.%d): ", a, p, d);
1889
1890 if (ad_infos[a].ports[p].devs[d].atapi)
1891 {
1892 ahci_exec_iorb(vIorb, pIorb, 0, atapi_execute_cdb);
1893 }
1894 else
1895 {
1896 iorb_seterr(pIorb, IOERR_CMD_NOT_SUPPORTED);
1897 iorb_done(vIorb, pIorb);
1898 }
1899}
1900
1901/******************************************************************************
1902 * Execute ATA command. Please note that this is allowed for both ATA and
1903 * ATAPI devices because ATAPI devices will process some ATA commands as well.
1904 */
1905void ahci_execute_ata(IORBH FAR16DATA *vIorb, IORBH *pIorb)
1906{
1907 #ifdef DEBUG
1908 int a = iorb_unit_adapter(pIorb);
1909 int p = iorb_unit_port(pIorb);
1910 int d = iorb_unit_device(pIorb);
1911
1912 DHEXDUMP(5,Far16ToFlat(((IORB_ADAPTER_PASSTHRU *)pIorb)->f16ControllerCmd),
1913 ((IORB_ADAPTER_PASSTHRU *)pIorb)->ControllerCmdLen,
1914 "ahci_execute_ata(%d.%d.%d): ", a, p, d);
1915 #endif
1916
1917 ahci_exec_iorb(vIorb, pIorb, 0, ata_execute_ata);
1918}
1919
Note: See TracBrowser for help on using the repository browser.