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

Last change on this file since 198 was 198, checked in by David Azarewicz, 7 years ago

Added Usable Disk option.

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(1,"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,"ahci_save_bios_config: 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,"ahci_restore_bios_config: 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,"ahci_restore_initial_config: 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,"ahci_complete_init: 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 DPRINTF(2,"registering interrupt #%d\n", ai->irq);
561
562 rc = Dev32Help_SetIRQ(ahci_intr, ai->irq, p, ai->irq);
563 if (rc && p) /* if failed and was shared */
564 {
565 p = 0; /* try exclusive */
566 rc = Dev32Help_SetIRQ(ahci_intr, ai->irq, p, ai->irq);
567 }
568 if (rc)
569 {
570 dprintf(0,"failed to register interrupt %d\n", ai->irq);
571 return(-1);
572 }
573 irq_used[irq_used_cnt++] = ai->irq;
574 ai->int_set = 1;
575 RmUpdateAddIrq(rm_drvh, ai->rm_adh, ai->irq, ai->irq_pin, p?RS_IRQ_SHARED:RS_IRQ_EXCLUSIVE);
576 }
577 }
578
579 /* enable AHCI mode */
580 if ((rc = ahci_enable_ahci(ai)) != 0) return(rc);
581
582 /* Start all ports. The main purpose is to set the command list and FIS
583 * receive area addresses properly and to enable port-level interrupts; we
584 * don't really care about the return status because we'll find out soon
585 * enough if a previously detected device has problems.
586 */
587 for (p = 0; p <= ai->port_max; p++)
588 {
589 if (ai->port_map & (1UL << p))
590 {
591 if (init_reset)
592 {
593 DPRINTF(3,"ahci_complete_init: resetting port %d\n", p);
594 ahci_reset_port(ai, p, 1);
595 }
596 else
597 {
598 DPRINTF(3,"ahci_complete_init: restarting port #%d\n", p);
599 ahci_stop_port(ai, p);
600 ahci_start_port(ai, p, 1);
601 }
602 }
603 }
604
605 /* clear pending interrupt status */
606 writel(ai->mmio + HOST_IRQ_STAT, readl(ai->mmio + HOST_IRQ_STAT));
607 readl(ai->mmio + HOST_IRQ_STAT); /* flush */
608
609 /* enable adapter-level interrupts */
610 writel(ai->mmio + HOST_CTL, readl(ai->mmio + HOST_CTL) | HOST_IRQ_EN);
611 readl(ai->mmio + HOST_CTL); /* flush */
612
613 /* enable interrupts on PCI-level (PCI 2.3 added a feature to disable INTs) */
614 /* pci_enable_int(ai->bus, ai->dev_func); */
615
616 DPRINTF(1,"ahci_complete_init: done\n");
617 return(0);
618}
619
620static int IsUsableDisk(AD_INFO *ai, int p, int d)
621{
622 union {
623 u8 b[512];
624 u16 w[256];
625 u32 l[128];
626 } *pSector0;
627 int iRetVal;
628
629 if (!use_mbr_test) return 1;
630 if (ai->ports[p].devs[d].removable) return 1;
631
632 do
633 {
634 iRetVal = 0;
635 pSector0 = MemAlloc(512);
636 if (!pSector0) break;
637
638 if (ahci_exec_polled_cmd(ai, p, 0, 500, ATA_CMD_READ,
639 AP_SECTOR_28, 0,
640 AP_COUNT, 1,
641 AP_VADDR, (void *)pSector0, 512,
642 AP_DEVICE, 0x40,
643 AP_END)) break;
644
645 DHEXDUMP(5, pSector0, 512, "Sector0:\n");
646
647 /* check for wiped disk */
648 if ((pSector0->l[0] == 0) && (pSector0->l[127] == 0))
649 {
650 iRetVal = 1;
651 break;
652 }
653
654 /* check for a valid MBR */
655 if (pSector0->w[255] != 0xaa55) break; /* Not valid if no MBR signature */
656 if (pSector0->b[0x1c2] == 0xee) break; /* Not valid if guard partition */
657 if (pSector0->b[0x1d2] == 0xee) break; /* Not valid if guard partition */
658 if (pSector0->b[0x1e2] == 0xee) break; /* Not valid if guard partition */
659 if (pSector0->b[0x1f2] == 0xee) break; /* Not valid if guard partition */
660 iRetVal = 1;
661 } while (0);
662
663 if (pSector0) MemFree(pSector0);
664 return iRetVal;
665}
666
667/******************************************************************************
668 * Set up device attached to the specified port based on ATA_IDENTFY_DEVICE or
669 * ATA_IDENTFY_PACKET_DEVICE data.
670 *
671 * NOTE: Port multipliers are not supported, yet, thus the device number is
672 * expected to be 0 for the time being.
673 */
674static void ahci_setup_device(AD_INFO *ai, int p, int d, u16 *id_buf)
675{
676 DEVICESTRUCT ds;
677 ADJUNCT adj;
678 HDEVICE dh;
679 char dev_name[RM_MAX_PREFIX_LEN+ATA_ID_PROD_LEN+1];
680 char *pDevName;
681 static u8 total_dev_cnt;
682
683 if (p >= AHCI_MAX_PORTS) return;
684 if (d >= AHCI_MAX_DEVS) return;
685
686 if (ai->port_max < p) ai->port_max = p;
687 if (ai->ports[p].dev_max < d) ai->ports[p].dev_max = d;
688 memset(ai->ports[p].devs + d, 0x00, sizeof(*ai->ports[p].devs));
689
690 /* set generic device information (assuming an ATA disk device for now) */
691 ai->ports[p].devs[d].present = 1;
692 ai->ports[p].devs[d].removable = (id_buf[ATA_ID_CONFIG] & 0x0080U) != 0;
693 ai->ports[p].devs[d].dev_type = UIB_TYPE_DISK;
694 pDevName = ai->ports[p].devs[d].dev_name;
695 strlcpy(pDevName, ata_dev_name(id_buf), sizeof(ai->ports[0].devs[0].dev_name));
696
697 if (id_buf[ATA_ID_CONFIG] & 0x8000U)
698 {
699 /* this is an ATAPI device; augment device information */
700 ai->ports[p].devs[d].atapi = 1;
701 ai->ports[p].devs[d].atapi_16 = (id_buf[ATA_ID_CONFIG] & 0x0001U) != 0;
702 ai->ports[p].devs[d].dev_type = (id_buf[ATA_ID_CONFIG] & 0x1f00U) >> 8;
703 ai->ports[p].devs[d].ncq_max = 1;
704
705 }
706 else
707 {
708 /* complete ATA-specific device information */
709 if (enable_ncq[ad_no(ai)][p])
710 {
711 ai->ports[p].devs[d].ncq_max = id_buf[ATA_ID_QUEUE_DEPTH] & 0x001fU;
712 }
713 if (ai->ports[p].devs[d].ncq_max < 1)
714 {
715 /* NCQ not enabled for this device, or device doesn't support NCQ */
716 ai->ports[p].devs[d].ncq_max = 1;
717 }
718 if (id_buf[ATA_ID_CFS_ENABLE_2] & 0x0400U)
719 {
720 ai->ports[p].devs[d].lba48 = 1;
721 }
722 }
723
724 DPRINTF(2,"found device %d.%d.%d: removable=%d dev_type=%d atapi=%d ncq_max=%d\n",
725 ad_no(ai), p, d,
726 ai->ports[p].devs[d].removable,
727 ai->ports[p].devs[d].dev_type,
728 ai->ports[p].devs[d].atapi,
729 ai->ports[p].devs[d].ncq_max);
730
731 /* add device to resource manager; we don't really care about errors here */
732 memset(&ds, 0x00, sizeof(ds));
733 memset(&adj, 0x00, sizeof(adj));
734
735 adj.pNextAdj = NULL;
736 adj.AdjLength = sizeof(adj);
737 adj.AdjType = ADJ_ADD_UNIT;
738 adj.Add_Unit.ADDHandle = rm_drvh;
739 adj.Add_Unit.UnitHandle = (USHORT)total_dev_cnt;
740
741 /* create Resource Manager device key string;
742 * we distinguish only HDs and CD drives for now
743 */
744 if (ai->ports[p].devs[d].removable)
745 {
746 snprintf(dev_name, sizeof(dev_name), RM_CD_PREFIX "%s", p, d, pDevName);
747 }
748 else
749 {
750 snprintf(dev_name, sizeof(dev_name), RM_HD_PREFIX "%s", p, d, pDevName);
751 }
752
753 ds.DevDescriptName = dev_name;
754 ds.DevFlags = (ai->ports[p].devs[d].removable) ? DS_REMOVEABLE_MEDIA
755 : DS_FIXED_LOGICALNAME;
756 ds.DevType = ai->ports[p].devs[d].dev_type;
757 ds.pAdjunctList = &adj;
758
759 RMCreateDevice(rm_drvh, &dh, &ds, ai->rm_adh, NULL);
760
761 total_dev_cnt++;
762
763 /* try to detect virtualbox environment to enable a hack for IRQ routing */
764 if (ai == ad_infos && ai->pci_vendor == 0x8086 && ai->pci_device == 0x2829 &&
765 !memcmp(pDevName, "VBOX HARDDISK", 13))
766 {
767 /* running inside virtualbox */
768 pci_hack_virtualbox();
769 }
770}
771
772/******************************************************************************
773 * Scan all ports for connected devices and fill in the corresponding device
774 * information.
775 *
776 * NOTES:
777 *
778 * - The adapter is temporarily configured for os2ahci but the original BIOS
779 * configuration will be restored when done. This happens only until we
780 * have received the IOCC_COMPLETE_INIT command.
781 *
782 * - Subsequent calls are currently not planned but may be required for
783 * suspend/resume handling, hot swap functionality, etc.
784 *
785 * - This function is expected to be called with the spinlock released but
786 * the corresponding adapter's busy flag set. It will aquire the spinlock
787 * temporarily to allocate/free memory for the ATA identify buffer.
788 *
789 * Called from iocm_device_table()
790 */
791int ahci_scan_ports(AD_INFO *ai)
792{
793 AHCI_PORT_CFG *pc = NULL;
794 u16 *id_buf;
795 int is_ata;
796 int rc;
797 int p;
798 int i;
799 TIMER Timer;
800
801 if ((id_buf = MemAlloc(ATA_ID_WORDS * sizeof(u16))) == NULL) return(-1);
802
803 if (ai->bios_config[0] == 0) ahci_save_bios_config(ai); /* first call */
804
805 if (ahci_enable_ahci(ai)) goto exit_port_scan;
806
807 /* perform port scan */
808 DPRINTF(1,__func__": scanning ports on adapter %d\n", ad_no(ai));
809 for (p = 0; p < AHCI_MAX_PORTS; p++)
810 {
811 if (!(ai->port_map & (1UL << p))) continue;
812 if (port_ignore[ad_no(ai)][p]) continue;
813
814 // DAZ allocate port structure here
815
816 DPRINTF(3,__func__": Wait till not busy on port %d\n", p);
817 /* wait until all active commands have completed on this port */
818 TimerInit(&Timer, 250);
819 while (ahci_port_busy(ai, p))
820 {
821 if (TimerCheckAndBlock(&Timer)) break;
822 }
823
824 if (!init_complete)
825 {
826 if ((pc = ahci_save_port_config(ai, p)) == NULL) goto exit_port_scan;
827 }
828
829 /* start/reset port; if no device is attached, this is expected to fail */
830 if (init_reset)
831 {
832 rc = ahci_reset_port(ai, p, 0);
833 }
834 else
835 {
836 DPRINTF(3,__func__": (re)starting port %d\n", p);
837 ahci_stop_port(ai, p);
838 rc = ahci_start_port(ai, p, 0);
839 }
840
841 if (rc == 0)
842 {
843 /* this port seems to have a device attached and ready for commands */
844 DPRINTF(1,__func__": port %d seems to be attached to a device; probing...\n", p);
845
846 #ifdef DAZ_NEW_CODE
847 ai->ports[p].dma_buf = MemAllocAlign(AHCI_PORT_PRIV_DMA_SZ, 1024);
848 ai->ports[p].dma_buf_phys = MemPhysAdr(ai->ports[p].dma_buf);
849 #endif
850
851 /* Get ATA(PI) identity. The so-called signature gives us a hint whether
852 * this is an ATA or an ATAPI device but we'll try both in either case;
853 * the signature will merely determine whether we're going to probe for
854 * an ATA or ATAPI device, first, in order to reduce the chance of sending
855 * the wrong command (which would result in a port reset given the way
856 * ahci_exec_polled_cmd() was implemented).
857 */
858 is_ata = readl(port_base(ai, p) + PORT_SIG) == 0x00000101UL;
859 for (i = 0; i < 2; i++)
860 {
861 rc = ahci_exec_polled_cmd(ai, p, 0, 500,
862 (is_ata) ? ATA_CMD_ID_ATA : ATA_CMD_ID_ATAPI,
863 AP_VADDR, (void *) id_buf, ATA_ID_WORDS * sizeof(u16),
864 AP_END);
865 if (rc == 0) break;
866
867 /* try again with ATA/ATAPI swapped */
868 is_ata = !is_ata;
869 }
870 }
871
872 if (rc == 0)
873 {
874 /* we have a valid IDENTIFY or IDENTIFY_PACKET response */
875 DHEXDUMP(5,id_buf, ATA_ID_WORDS * sizeof(u16), "ATA_IDENTIFY%s results:\n", (is_ata) ? "" : "_PACKET");
876 ahci_setup_device(ai, p, 0, id_buf);
877 if (!IsUsableDisk(ai, p, 0)) ai->ports[p].devs[0].ignored = 1;
878 }
879 else
880 {
881 /* no device attached to this port */
882 ai->port_map &= ~(1UL << p);
883 #ifdef DAZ_NEW_CODE
884 if (ai->ports[p].dma_buf) MemFree(ai->ports[p].dma_buf);
885 ai->ports[p].dma_buf = NULL;
886 #endif
887 }
888
889 if (pc != NULL) ahci_restore_port_config(ai, p, pc);
890 }
891
892exit_port_scan:
893 if (!init_complete)
894 {
895 ahci_restore_bios_config(ai);
896 }
897 MemFree(id_buf);
898 return(0);
899}
900
901/******************************************************************************
902 * Reset specified port. This function is typically called during adapter
903 * initialization and first gets the port into a defined status, then resets
904 * the port by sending a COMRESET signal.
905 *
906 * This function is also the location of the link speed initialization (link
907 * needs to be restablished after changing link speed, anyway).
908 *
909 * NOTE: This function uses a busy loop to wait for DMA engines to stop and
910 * the COMRESET to complete. It should only be called at task time
911 * during initialization or in a context hook.
912 */
913int ahci_reset_port(AD_INFO *ai, int p, int ei)
914{
915 u8 *port_mmio = port_base(ai, p);
916 u32 tmp;
917 TIMER Timer;
918
919 DPRINTF(2,"ahci_reset_port: resetting port %d.%d\n", ad_no(ai), p);
920 DUMP_PORT_REGS(2,ai,p);
921
922 /* stop port engines (we don't care whether there is an error doing so) */
923 ahci_stop_port(ai, p);
924
925 /* clear SError */
926 tmp = readl(port_mmio + PORT_SCR_ERR);
927 writel(port_mmio + PORT_SCR_ERR, tmp);
928
929 /* Some hardware reports incorrect status so just set these bits unconditionally */
930 tmp = readl(port_mmio + PORT_CMD);
931 tmp &= ~PORT_CMD_ALPE; /* turn off agressive power management */
932 tmp |= (PORT_CMD_SPIN_UP | PORT_CMD_POWER_ON); /* power up and spin up the drive */
933 writel(port_mmio + PORT_CMD, tmp);
934
935 /* set link speed and power management options */
936 DPRINTF(3,"ahci_reset_port: setting link speed and power management options\n");
937 tmp = readl(port_mmio + PORT_SCR_CTL) & ~0x00000fffUL;
938 tmp |= (link_speed[ad_no(ai)][p] & 0x0f) << 4;
939 tmp |= (link_power[ad_no(ai)][p] & 0x0f) << 8;
940 writel(port_mmio + PORT_SCR_CTL, tmp);
941
942 /* issue COMRESET on the port */
943 DPRINTF(3,"ahci_reset_port: issuing COMRESET on port %d\n", p);
944 writel(port_mmio + PORT_SCR_CTL, tmp | 1);
945 readl(port_mmio + PORT_SCR_CTL); /* flush */
946
947 /* spec says "leave reset bit on for at least 1ms"; make it 2ms */
948 udelay(2000);
949
950 writel(port_mmio + PORT_SCR_CTL, tmp);
951 readl(port_mmio + PORT_SCR_CTL); /* flush */
952
953 /* wait for communication to be re-established after port reset */
954 DPRINTF(2,"Wait for communication...\n");
955 TimerInit(&Timer, 500);
956 while (((tmp = readl(port_mmio + PORT_SCR_STAT)) & 3) != 3)
957 {
958 if (TimerCheckAndBlock(&Timer))
959 {
960 DPRINTF(0,"no device present after resetting port #%d (PORT_SCR_STAT = 0x%x)\n", p, tmp);
961 return(-1);
962 }
963 }
964
965 /* clear SError again (recommended by AHCI spec) */
966 tmp = readl(port_mmio + PORT_SCR_ERR);
967 writel(port_mmio + PORT_SCR_ERR, tmp);
968
969 /* start port so we can receive the COMRESET FIS */
970 DPRINTF(2,"ahci_reset_port: starting port %d again\n", p);
971 ahci_start_port(ai, p, ei);
972
973 /* wait for device to be ready ((PxTFD & (BSY | DRQ | ERR)) == 0) */
974 TimerInit(&Timer, 1000);
975 while (((tmp = readl(port_mmio + PORT_TFDATA)) & 0x89) != 0)
976 {
977 if (TimerCheckAndBlock(&Timer))
978 {
979 DPRINTF(0,"device not ready on port #%d (PORT_TFDATA = 0x%x)\n", p, tmp);
980 ahci_stop_port(ai, p);
981 return(-1);
982 }
983 }
984 DPRINTF(3,"ahci_reset_port: PORT_TFDATA = 0x%x\n", readl(port_mmio + PORT_TFDATA));
985
986 return(0);
987}
988
989/******************************************************************************
990 * Start specified port.
991 */
992int ahci_start_port(AD_INFO *ai, int p, int ei)
993{
994 u8 *port_mmio = port_base(ai, p);
995 u32 status;
996
997 DPRINTF(3,"ahci_start_port %d.%d\n", ad_no(ai), p);
998 /* check whether device presence is detected and link established */
999
1000 status = readl(port_mmio + PORT_SCR_STAT);
1001 DPRINTF(3,"ahci_start_port: PORT_SCR_STAT = 0x%x\n", status);
1002 if ((status & 0xf) != 3) return(-1);
1003
1004 /* clear SError, if any */
1005 status = readl(port_mmio + PORT_SCR_ERR);
1006 DPRINTF(3,"ahci_start_port: PORT_SCR_ERR = 0x%x\n", status);
1007 writel(port_mmio + PORT_SCR_ERR, status);
1008
1009 /* enable FIS reception */
1010 ahci_start_fis_rx(ai, p);
1011
1012 /* enable command engine */
1013 ahci_start_engine(ai, p);
1014
1015 if (ei)
1016 {
1017 /* clear any pending interrupts on this port */
1018 if ((status = readl(port_mmio + PORT_IRQ_STAT)) != 0)
1019 {
1020 writel(port_mmio + PORT_IRQ_STAT, status);
1021 }
1022
1023 /* enable port interrupts */
1024 writel(port_mmio + PORT_IRQ_MASK, PORT_IRQ_TF_ERR |
1025 PORT_IRQ_HBUS_ERR |
1026 PORT_IRQ_HBUS_DATA_ERR |
1027 PORT_IRQ_IF_ERR |
1028 PORT_IRQ_OVERFLOW |
1029 PORT_IRQ_BAD_PMP |
1030 PORT_IRQ_UNK_FIS |
1031 PORT_IRQ_SDB_FIS |
1032 PORT_IRQ_DMAS_FIS |
1033 PORT_IRQ_PIOS_FIS |
1034 PORT_IRQ_D2H_REG_FIS);
1035 }
1036 else
1037 {
1038 writel(port_mmio + PORT_IRQ_MASK, 0);
1039 }
1040 readl(port_mmio + PORT_IRQ_MASK); /* flush */
1041
1042 return(0);
1043}
1044
1045/******************************************************************************
1046 * Start port FIS reception. Copied from Linux AHCI driver and adopted to
1047 * OS2AHCI.
1048 */
1049void ahci_start_fis_rx(AD_INFO *ai, int p)
1050{
1051 u8 *port_mmio = port_base(ai, p);
1052 u32 port_dma = port_dma_base_phys(ai, p);
1053 u32 tmp;
1054
1055 /* set command header and FIS address registers */
1056 writel(port_mmio + PORT_LST_ADDR, port_dma + offsetof(AHCI_PORT_DMA, cmd_hdr));
1057 writel(port_mmio + PORT_LST_ADDR_HI, 0);
1058 writel(port_mmio + PORT_FIS_ADDR, port_dma + offsetof(AHCI_PORT_DMA, rx_fis));
1059 writel(port_mmio + PORT_FIS_ADDR_HI, 0);
1060
1061 /* enable FIS reception */
1062 tmp = readl(port_mmio + PORT_CMD);
1063 tmp |= PORT_CMD_FIS_RX;
1064 writel(port_mmio + PORT_CMD, tmp);
1065
1066 /* flush */
1067 readl(port_mmio + PORT_CMD);
1068}
1069
1070/******************************************************************************
1071 * Start port HW engine. Copied from Linux AHCI driver and adopted to OS2AHCI.
1072 */
1073void ahci_start_engine(AD_INFO *ai, int p)
1074{
1075 u8 *port_mmio = port_base(ai, p);
1076 u32 tmp;
1077
1078 /* start DMA */
1079 tmp = readl(port_mmio + PORT_CMD);
1080 tmp |= PORT_CMD_START;
1081 writel(port_mmio + PORT_CMD, tmp);
1082 readl(port_mmio + PORT_CMD); /* flush */
1083}
1084
1085/******************************************************************************
1086 * Stop specified port
1087 */
1088int ahci_stop_port(AD_INFO *ai, int p)
1089{
1090 u8 *port_mmio = port_base(ai, p);
1091 u32 tmp;
1092 int rc;
1093
1094 DPRINTF(3,"ahci_stop_port %d.%d\n", ad_no(ai), p);
1095
1096 /* disable port interrupts */
1097 writel(port_mmio + PORT_IRQ_MASK, 0);
1098
1099 /* disable FIS reception */
1100 if ((rc = ahci_stop_fis_rx(ai, p)) != 0)
1101 {
1102 dprintf(0,"error: failed to stop FIS receive (%d)\n", rc);
1103 return(rc);
1104 }
1105
1106 /* disable command engine */
1107 if ((rc = ahci_stop_engine(ai, p)) != 0)
1108 {
1109 dprintf(0,"error: failed to stop port HW engine (%d)\n", rc);
1110 return(rc);
1111 }
1112
1113 /* clear any pending port IRQs */
1114 tmp = readl(port_mmio + PORT_IRQ_STAT);
1115 if (tmp) writel(port_mmio + PORT_IRQ_STAT, tmp);
1116 writel(ai->mmio + HOST_IRQ_STAT, 1UL << p);
1117
1118 /* reset PxSACT register (tagged command queues, not reset by COMRESET) */
1119 writel(port_mmio + PORT_SCR_ACT, 0);
1120 readl(port_mmio + PORT_SCR_ACT); /* flush */
1121
1122 return(0);
1123}
1124
1125/******************************************************************************
1126 * Stop port FIS reception. Copied from Linux AHCI driver and adopted to
1127 * OS2AHCI.
1128 *
1129 * NOTE: This function uses a busy loop to wait for the DMA engine to stop. It
1130 * should only be called at task time during initialization or in a
1131 * context hook (e.g. when resetting a port).
1132 */
1133int ahci_stop_fis_rx(AD_INFO *ai, int p)
1134{
1135 u8 *port_mmio = port_base(ai, p);
1136 TIMER Timer;
1137 u32 tmp;
1138 int status;
1139
1140 /* disable FIS reception */
1141 tmp = readl(port_mmio + PORT_CMD);
1142 tmp &= ~PORT_CMD_FIS_RX;
1143 writel(port_mmio + PORT_CMD, tmp);
1144
1145 /* wait for completion, spec says 500ms, give it 1000ms */
1146 status = 0;
1147 TimerInit(&Timer, 1000);
1148 while (readl(port_mmio + PORT_CMD) & PORT_CMD_FIS_ON)
1149 {
1150 status = TimerCheckAndBlock(&Timer);
1151 if (status) break;
1152 }
1153
1154 return(status ? -1 : 0);
1155}
1156
1157/******************************************************************************
1158 * Stop port HW engine. Copied from Linux AHCI driver and adopted to OS2AHCI.
1159 *
1160 * NOTE: This function uses a busy loop to wait for the DMA engine to stop. It
1161 * should only be called at task time during initialization or in a
1162 * context hook (e.g. when resetting a port).
1163 */
1164int ahci_stop_engine(AD_INFO *ai, int p)
1165{
1166 u8 *port_mmio = port_base(ai, p);
1167 TIMER Timer;
1168 int status;
1169 u32 tmp;
1170
1171 tmp = readl(port_mmio + PORT_CMD);
1172
1173 /* check if the port is already stopped */
1174 if ((tmp & (PORT_CMD_START | PORT_CMD_LIST_ON)) == 0) return 0;
1175
1176 /* set port to idle */
1177 tmp &= ~PORT_CMD_START;
1178 writel(port_mmio + PORT_CMD, tmp);
1179
1180 /* wait for engine to stop. This could be as long as 500 msec */
1181 status = 0;
1182 TimerInit(&Timer, 500);
1183 while (readl(port_mmio + PORT_CMD) & PORT_CMD_LIST_ON)
1184 {
1185 status = TimerCheckAndBlock(&Timer);
1186 if (status) break;
1187 }
1188
1189 return(status ? -1 : 0);
1190}
1191
1192/******************************************************************************
1193 * Determine whether a port is busy executing commands.
1194 */
1195int ahci_port_busy(AD_INFO *ai, int p)
1196{
1197 u8 *port_mmio = port_base(ai, p);
1198
1199 return(readl(port_mmio + PORT_SCR_ACT) != 0 || readl(port_mmio + PORT_CMD_ISSUE) != 0);
1200}
1201
1202/******************************************************************************
1203 * Execute AHCI command for given IORB. This includes all steps typically
1204 * required by any of the ahci_*() IORB processing functions.
1205 *
1206 * NOTE: In order to prevent race conditions with port restart and reset
1207 * handlers, we either need to keep the spinlock during the whole
1208 * operation or set the adapter's busy flag. Since the expectation
1209 * is that command preparation will be quick (it certainly doesn't
1210 * involve delays), we're going with the spinlock for the time being.
1211 */
1212void ahci_exec_iorb(IORBH FAR16DATA *vIorb, IORBH *pIorb, int ncq_capable, int (*func)(IORBH FAR16DATA *, IORBH *pIorb, int))
1213{
1214 volatile u32 *cmds;
1215 ADD_WORKSPACE *aws = add_workspace(pIorb);
1216 AD_INFO *ai = &ad_infos[iorb_unit_adapter(pIorb)];
1217 P_INFO *port = &ai->ports[iorb_unit_port(pIorb)];
1218 ULONG timeout;
1219 u8 *port_mmio = port_base(ai, iorb_unit_port(pIorb));
1220 u16 cmd_max = ai->cmd_max;
1221 int i;
1222
1223 /* determine timeout in milliseconds */
1224 switch (pIorb->Timeout)
1225 {
1226 case 0:
1227 timeout = DEFAULT_TIMEOUT;
1228 break;
1229 case 0xffffffffUL:
1230 timeout = 0xffffffffUL;
1231 break;
1232 default:
1233 timeout = pIorb->Timeout * 1000;
1234 break;
1235 }
1236
1237 DPRINTF(7,"---------- ahci_exec_iorb: iorb=%x\n", vIorb);
1238
1239 /* Enable AHCI mode; apparently, the AHCI mode may end up becoming
1240 * disabled, either during the boot sequence (by the BIOS) or by
1241 * something else. The Linux AHCI drivers have this call in the
1242 * command processing chain, and apparently for a good reason because
1243 * without this, commands won't be executed.
1244 */
1245 ahci_enable_ahci(ai);
1246
1247 /* determine whether this will be an NCQ request */
1248 aws->is_ncq = 0;
1249 if (ncq_capable && port->devs[iorb_unit_device(pIorb)].ncq_max > 1 &&
1250 (ai->cap & HOST_CAP_NCQ) && !aws->no_ncq && init_complete)
1251 {
1252
1253 /* We can make this an NCQ request; limit command slots to the maximum
1254 * NCQ tag number reported by the device - 1. Why "minus one"? I seem to
1255 * recall an issue related to using all 32 tag numbers but can't quite
1256 * pinpoint it right now. One less won't make much of a difference...
1257 */
1258 aws->is_ncq = 1;
1259 if ((cmd_max = port->devs[iorb_unit_device(pIorb)].ncq_max - 1) > ai->cmd_max)
1260 {
1261 cmd_max = ai->cmd_max;
1262 }
1263 DPRINTF(8,"NCQ command; cmd_max = %d->%d\n", ai->cmd_max, cmd_max);
1264 }
1265
1266 /* make sure adapter is available */
1267 spin_lock(drv_lock);
1268 if (!ai->busy)
1269 {
1270
1271 if (!init_complete)
1272 {
1273 /* no IRQ handlers or context hooks availabe at this point */
1274 ai->busy = 1;
1275 spin_unlock(drv_lock);
1276 ahci_exec_polled_iorb(vIorb, pIorb, func, timeout);
1277 ai->busy = 0;
1278 return;
1279 }
1280
1281 /* make sure we don't mix NCQ and regular commands */
1282 if (aws->is_ncq && port->reg_cmds == 0 || !aws->is_ncq && port->ncq_cmds == 0)
1283 {
1284 /* Find next available command slot. We use a simple round-robin
1285 * algorithm for this to prevent commands with higher slot indexes
1286 * from stalling when new commands are coming in frequently.
1287 */
1288 cmds = (aws->is_ncq) ? &port->ncq_cmds : &port->reg_cmds;
1289 for (i = 0; i <= cmd_max; i++)
1290 {
1291 if (++(port->cmd_slot) > cmd_max) port->cmd_slot = 0;
1292 if ((*cmds & (1UL << port->cmd_slot)) == 0) break;
1293 }
1294
1295 if ((*cmds & (1UL << port->cmd_slot)) == 0)
1296 {
1297 /* found idle command slot; prepare command */
1298 if (func(vIorb, pIorb, port->cmd_slot))
1299 {
1300 /* Command preparation failed, or no HW command required; IORB
1301 * will already have the error code if there was an error.
1302 */
1303 spin_unlock(drv_lock);
1304 iorb_done(vIorb, pIorb);
1305 return;
1306 }
1307
1308 /* start timer for this IORB */
1309 Timer_StartTimerMS(&aws->timer, timeout, timeout_callback, CastFar16ToULONG(vIorb));
1310
1311 /* issue command to hardware */
1312 *cmds |= (1UL << port->cmd_slot);
1313 aws->queued_hw = 1;
1314 aws->cmd_slot = port->cmd_slot;
1315
1316 DPRINTF(7,"Issuing command Slot=%d cmds=%x\n", port->cmd_slot, *cmds);
1317 if (aws->is_ncq)
1318 {
1319 writel(port_mmio + PORT_SCR_ACT, (1UL << port->cmd_slot));
1320 readl(port_mmio + PORT_SCR_ACT); /* flush */
1321 }
1322 writel(port_mmio + PORT_CMD_ISSUE, (1UL << port->cmd_slot));
1323 readl(port_mmio + PORT_CMD_ISSUE); /* flush */
1324
1325 spin_unlock(drv_lock);
1326 return;
1327 }
1328 }
1329 }
1330
1331 /* requeue this IORB; it will be picked up again in trigger_engine() */
1332 aws->processing = 0;
1333 spin_unlock(drv_lock);
1334}
1335
1336/******************************************************************************
1337 * Execute polled IORB command. This function is called by ahci_exec_iorb()
1338 * when the initialization has not yet completed. The reasons for polling until
1339 * initialization has completed are:
1340 *
1341 * - We need to restore the BIOS configuration after we're done with this
1342 * command because someone might still call int 13h routines; sending
1343 * asynchronous commands and waiting for interrupts to indicate completion
1344 * won't work in such a scenario.
1345 * - Our context hooks won't work while the device managers are initializing
1346 * (they can't yield at init time).
1347 * - The device managers typically poll for command completion during
1348 * initialization so it won't make much of a difference, anyway.
1349 *
1350 * NOTE: This function must be called with the adapter-level busy flag set but
1351 * without the driver-level spinlock held.
1352 */
1353void ahci_exec_polled_iorb(IORBH FAR16DATA *vIorb, IORBH *pIorb, int (*func)(IORBH FAR16DATA *, IORBH *pIorb, int), ULONG timeout)
1354{
1355 AHCI_PORT_CFG *pc = NULL;
1356 AD_INFO *ai = ad_infos + iorb_unit_adapter(vIorb);
1357 int p = iorb_unit_port(pIorb);
1358 u8 *port_mmio = port_base(ai, p);
1359 TIMER Timer;
1360 int rc;
1361
1362 /* enable AHCI mode */
1363 if (ahci_enable_ahci(ai) != 0)
1364 {
1365 iorb_seterr(pIorb, IOERR_ADAPTER_NONSPECIFIC);
1366 goto restore_bios_config;
1367 }
1368
1369 /* check whether command slot 0 is available */
1370 if ((readl(port_mmio + PORT_CMD_ISSUE) & 1) != 0)
1371 {
1372 iorb_seterr(pIorb, IOERR_DEVICE_BUSY);
1373 goto restore_bios_config;
1374 }
1375
1376 /* save port configuration */
1377 if ((pc = ahci_save_port_config(ai, p)) == NULL)
1378 {
1379 iorb_seterr(pIorb, IOERR_CMD_SW_RESOURCE);
1380 goto restore_bios_config;
1381 }
1382
1383 /* restart/reset port (includes the necessary port configuration) */
1384 if (init_reset)
1385 {
1386 /* As outlined in ahci_restore_bios_config(), switching back and
1387 * forth between SATA and AHCI mode requires a COMRESET to force
1388 * the corresponding controller subsystem to rediscover attached
1389 * devices. Thus, we'll reset the port instead of stopping and
1390 * starting it.
1391 */
1392 if (ahci_reset_port(ai, p, 0))
1393 {
1394 iorb_seterr(pIorb, IOERR_ADAPTER_NONSPECIFIC);
1395 goto restore_bios_config;
1396 }
1397
1398 }
1399 else if (ahci_stop_port(ai, p) || ahci_start_port(ai, p, 0))
1400 {
1401 iorb_seterr(pIorb, IOERR_ADAPTER_NONSPECIFIC);
1402 goto restore_bios_config;
1403 }
1404
1405 /* prepare command */
1406 if (func(vIorb, pIorb, 0) == 0)
1407 {
1408 /* successfully prepared cmd; issue cmd and wait for completion */
1409 DPRINTF(3,"---------- executing polled cmd on slot 0...");
1410 writel(port_mmio + PORT_CMD_ISSUE, 1);
1411 TimerInit(&Timer, timeout);
1412 while (readl(port_mmio + PORT_CMD_ISSUE) & 1)
1413 {
1414 rc = TimerCheckAndBlock(&Timer);
1415 if (rc) break;
1416 }
1417
1418 /* 0x89 = BSY(0x80) | DRQ(0x08) | ERR(0x01) */
1419 if (rc)
1420 {
1421 DPRINTF(3," timeout for IORB %x", vIorb);
1422 iorb_seterr(pIorb, IOERR_ADAPTER_TIMEOUT);
1423 }
1424 else if (readl(port_mmio + PORT_SCR_ERR) != 0 || readl(port_mmio + PORT_TFDATA) & 0x89)
1425 {
1426 DPRINTF(3," polled cmd error for IORB %x", vIorb);
1427 iorb_seterr(pIorb, IOERR_DEVICE_NONSPECIFIC);
1428 ahci_reset_port(ai, iorb_unit_port(pIorb), 0);
1429 }
1430 else
1431 {
1432 /* successfully executed command */
1433 if (add_workspace(pIorb)->ppfunc != NULL)
1434 {
1435 add_workspace(pIorb)->ppfunc(vIorb, pIorb);
1436 }
1437 else
1438 {
1439 add_workspace(pIorb)->complete = 1;
1440 }
1441 }
1442 DPRINTF(3,"\n");
1443 }
1444
1445restore_bios_config:
1446 /* restore BIOS configuration */
1447 if (pc != NULL)
1448 {
1449 ahci_restore_port_config(ai, p, pc);
1450 }
1451 ahci_restore_bios_config(ai);
1452
1453 if (add_workspace(pIorb)->complete | (pIorb->Status | IORB_ERROR))
1454 {
1455 iorb_done(vIorb, pIorb);
1456 }
1457 return;
1458}
1459
1460/******************************************************************************
1461 * Execute polled ATA/ATAPI command. This function will block until the command
1462 * has completed or the timeout has expired, thus it should only be used during
1463 * initialization. Furthermore, it will always use command slot zero.
1464 *
1465 * The difference to ahci_exec_polled_iorb() is that this function executes
1466 * arbitrary ATA/ATAPI commands outside the context of an IORB. It's typically
1467 * used when scanning for devices during initialization.
1468 */
1469int ahci_exec_polled_cmd(AD_INFO *ai, int p, int d, int timeout, int cmd, ...)
1470{
1471 va_list va;
1472 u8 *port_mmio = port_base(ai, p);
1473 u32 tmp;
1474 int rc;
1475 TIMER Timer;
1476
1477 /* verify that command slot 0 is idle */
1478 if (readl(port_mmio + PORT_CMD_ISSUE) & 1)
1479 {
1480 DPRINTF(3,"port %d slot 0 is not idle; not executing polled cmd\n", p);
1481 return(-1);
1482 }
1483
1484 /* fill in command slot 0 */
1485 va_start(va, cmd);
1486 if ((rc = v_ata_cmd(ai, p, d, 0, cmd, va)) != 0) return(rc);
1487
1488 /* start command execution for slot 0 */
1489 DPRINTF(3,"---------- executing polled cmd...");
1490 writel(port_mmio + PORT_CMD_ISSUE, 1);
1491
1492 /* wait until command has completed */
1493 TimerInit(&Timer, timeout);
1494 rc = 0;
1495 while (readl(port_mmio + PORT_CMD_ISSUE) & 1)
1496 {
1497 rc = TimerCheckAndBlock(&Timer);
1498 if (rc)
1499 {
1500 DPRINTF(2," Timeout");
1501 break;
1502 }
1503 }
1504
1505 tmp = readl(port_mmio + PORT_SCR_ERR);
1506 if (tmp & PORT_ERR_FAIL_BITS)
1507 {
1508 DPRINTF(2," SERR = 0x%08lx", tmp);
1509 rc = 1;
1510 }
1511 /* 0x89 = BSY(0x80) | DRQ(0x08) | ERR(0x01) */
1512 if (((tmp = readl(port_mmio + PORT_TFDATA)) & 0x89) != 0)
1513 {
1514 DPRINTF(2," TFDATA = 0x%08lx", tmp);
1515 rc = 1;
1516 }
1517
1518 if (rc)
1519 {
1520 DPRINTF(3,"failed\n");
1521 ahci_reset_port(ai, p, 0);
1522 return(-1);
1523 }
1524 DPRINTF(3,"success\n");
1525 return(0);
1526}
1527
1528/******************************************************************************
1529 * Flush write cache of the specified device. Since there's no equivalent IORB
1530 * command, we'll execute this command directly using polling. Otherwise, we
1531 * would have to create a fake IORB, add it to the port's IORB queue, ...
1532 *
1533 * Besides, this function is only called when shutting down and the code there
1534 * would have to wait for the flush cache command to complete as well, using
1535 * polling just the same...
1536 */
1537int ahci_flush_cache(AD_INFO *ai, int p, int d)
1538{
1539 if (!ai->ports[p].devs[d].atapi)
1540 {
1541 DPRINTF(2,"flushing cache on %d.%d.%d\n", ad_no(ai), p, d);
1542 return(ahci_exec_polled_cmd(ai, p, d, 30000,
1543 ai->ports[p].devs[d].lba48 ? ATA_CMD_FLUSH_EXT : ATA_CMD_FLUSH, AP_END));
1544 }
1545 return 0;
1546}
1547
1548/******************************************************************************
1549 * Set device into IDLE mode (spin down); this was used during
1550 * debugging/testing and is now unused; it's still there in case we need it
1551 * again...
1552 *
1553 * If 'idle' is != 0, the idle timeout is set to 5 seconds, otherwise it
1554 * is turned off.
1555 */
1556int ahci_set_dev_idle(AD_INFO *ai, int p, int d, int idle)
1557{
1558 DPRINTF(3,"sending IDLE=%d command to port %d\n", idle, p);
1559 return ahci_exec_polled_cmd(ai, p, d, 500, ATA_CMD_IDLE, AP_COUNT, idle ? 1 : 0, AP_END);
1560}
1561
1562/******************************************************************************
1563 * AHCI top-level hardware interrupt handler. This handler finds the adapters
1564 * and ports which have issued the interrupt and calls the corresponding
1565 * port interrupt handler.
1566 *
1567 * On entry, OS/2 will have processor interrupts enabled because we're using
1568 * shared IRQs but we won't be preempted by another interrupt on the same
1569 * IRQ level until we indicated EOI. We'll keep it this way, only requesting
1570 * the driver-level spinlock when actually changing the driver state (IORB
1571 * queues, ...)
1572 */
1573#pragma aux ahci_intr parm [eax]
1574int ahci_intr(u32 irq)
1575{
1576 u32 irq_stat;
1577 int handled = 0;
1578 int a;
1579 int p;
1580
1581 /* find adapter(s) with pending interrupts */
1582 for (a = 0; a < ad_info_cnt; a++)
1583 {
1584 AD_INFO *ai = ad_infos + a;
1585
1586 if (ai->irq == irq && (irq_stat = readl(ai->mmio + HOST_IRQ_STAT)) != 0)
1587 {
1588 /* this adapter has interrupts pending */
1589 u32 irq_masked = irq_stat & ai->port_map;
1590
1591 for (p = 0; p <= ai->port_max; p++)
1592 {
1593 if (irq_masked & (1UL << p))
1594 {
1595 ahci_port_intr(ai, p);
1596 }
1597 }
1598
1599 /* clear interrupt condition on the adapter */
1600 writel(ai->mmio + HOST_IRQ_STAT, irq_stat);
1601 readl(ai->mmio + HOST_IRQ_STAT); /* flush */
1602 handled = 1;
1603 }
1604 }
1605
1606 if (handled)
1607 {
1608 /* Trigger state machine to process next IORBs, if any. Due to excessive
1609 * IORB requeue operations (e.g. when processing large unaligned reads or
1610 * writes), we may be stacking interrupts on top of each other. If we
1611 * detect this, we'll pass this on to the engine context hook.
1612 */
1613 #if 0
1614 if ((u32)&irq_stat < 0xf000)
1615 {
1616 DPRINTF(0,"IRQ stack running low; arming engine context hook\n");
1617 /* Rousseau:
1618 * A context hook cannot be re-armed before it has completed.
1619 * (?:\IBMDDK\DOCS\PDDREF.INF->Device Helper (DevHlp) Services)->ArmCtxHook)
1620 * Also, it is executed at task-time, thus in the context of some
1621 * application thread. Stacked interrupts with a stack below the
1622 * threshold specified above, (0xf000), will repeatly try to arm the
1623 * context hook, but since we are in an interrupted interrupt handler,
1624 * it's highly unlikely the hook has completed.
1625 * So, possibly only the first arming is succesful and subsequent armings
1626 * will fail because no task-time thread has run between the stacked
1627 * interrupts. One hint would be that if the dispatching truely worked,
1628 * excessive stacked interrupts in VBox would not be a problem.
1629 * This needs some more investigation.
1630 */
1631 KernArmHook(engine_ctxhook_h, 0, 0);
1632 }
1633 else
1634 #endif
1635 {
1636 spin_lock(drv_lock);
1637 trigger_engine();
1638 spin_unlock(drv_lock);
1639 }
1640 DevCli();
1641 Dev32Help_EOI(irq);
1642 return(1); /* handled */
1643 }
1644
1645 return(0); /* not handled */
1646}
1647
1648/******************************************************************************
1649 * AHCI port-level interrupt handler. As described above, processor interrupts
1650 * are enabled on entry thus we have to protect shared resources with a
1651 * spinlock.
1652 */
1653void ahci_port_intr(AD_INFO *ai, int p)
1654{
1655 IORB_QUEUE done_queue;
1656 IORBH FAR16DATA *vIorb;
1657 IORBH FAR16DATA *vNext = FAR16NULL;
1658 u8 *port_mmio = port_base(ai, p);
1659 u32 irq_stat;
1660 u32 active_cmds;
1661 u32 done_mask;
1662
1663 /* get interrupt status and clear it right away */
1664 irq_stat = readl(port_mmio + PORT_IRQ_STAT);
1665 writel(port_mmio + PORT_IRQ_STAT, irq_stat);
1666 readl(port_mmio + PORT_IRQ_STAT); /* flush */
1667
1668 memset(&done_queue, 0x00, sizeof(done_queue));
1669
1670 if (irq_stat & PORT_IRQ_ERROR)
1671 {
1672 /* this is an error interrupt;
1673 * disable port interrupts to avoid IRQ storm until error condition
1674 * has been cleared by the restart handler
1675 */
1676 writel(port_mmio + PORT_IRQ_MASK, 0);
1677 ahci_error_intr(ai, p, irq_stat);
1678 return;
1679 }
1680
1681 spin_lock(drv_lock);
1682
1683 /* Find out which command slots have completed. Since error recovery for
1684 * NCQ commands interfers with non-NCQ commands, the upper layers will
1685 * make sure there's never a mixture of NCQ and non-NCQ commands active
1686 * on any port at any given time. This makes it easier to find out which
1687 * commands have completed, too.
1688 */
1689 if (ai->ports[p].ncq_cmds != 0)
1690 {
1691 active_cmds = readl(port_mmio + PORT_SCR_ACT);
1692 done_mask = ai->ports[p].ncq_cmds ^ active_cmds;
1693 DPRINTF(7,"[ncq_cmds]: active_cmds=0x%08x done_mask=0x%08x\n", active_cmds, done_mask);
1694 }
1695 else
1696 {
1697 active_cmds = readl(port_mmio + PORT_CMD_ISSUE);
1698 done_mask = ai->ports[p].reg_cmds ^ active_cmds;
1699 DPRINTF(7,"[reg_cmds]: active_cmds=0x%08x done_mask=0x%08x\n", active_cmds, done_mask);
1700 }
1701
1702 /* Find the IORBs related to the completed commands and complete them.
1703 *
1704 * NOTES: The spinlock must not be released while in this loop to prevent
1705 * race conditions with timeout handlers or other threads in SMP
1706 * systems.
1707 *
1708 * Since we hold the spinlock when IORBs complete, we can't call the
1709 * IORB notification routine right away because this routine might
1710 * schedule another IORB which could cause a deadlock. Thus, we'll
1711 * add all IORBs to be completed to a temporary queue which will be
1712 * processed after releasing the spinlock.
1713 */
1714 for (vIorb = ai->ports[p].iorb_queue.vRoot; vIorb != FAR16NULL; vIorb = vNext)
1715 {
1716 IORBH *pIorb = Far16ToFlat(vIorb);
1717 ADD_WORKSPACE *aws = (ADD_WORKSPACE *) &pIorb->ADDWorkSpace;
1718
1719 vNext = pIorb->pNxtIORB;
1720 if (aws->queued_hw && (done_mask & (1UL << aws->cmd_slot)))
1721 {
1722 /* this hardware command has completed */
1723 ai->ports[p].ncq_cmds &= ~(1UL << aws->cmd_slot);
1724 ai->ports[p].reg_cmds &= ~(1UL << aws->cmd_slot);
1725
1726 /* call post-processing function, if any */
1727 if (aws->ppfunc != NULL) aws->ppfunc(vIorb, pIorb);
1728 else aws->complete = 1;
1729
1730 if (aws->complete)
1731 {
1732 /* this IORB is complete; move IORB to our temporary done queue */
1733 iorb_queue_del(&ai->ports[p].iorb_queue, vIorb);
1734 iorb_queue_add(&done_queue, vIorb, pIorb);
1735 aws_free(add_workspace(pIorb));
1736 }
1737 }
1738 }
1739
1740 spin_unlock(drv_lock);
1741
1742 /* complete all IORBs in the done queue */
1743 for (vIorb = done_queue.vRoot; vIorb != FAR16NULL; vIorb = vNext)
1744 {
1745 IORBH *pIorb = Far16ToFlat(vIorb);
1746
1747 vNext = pIorb->pNxtIORB;
1748
1749 iorb_complete(vIorb, pIorb);
1750 }
1751}
1752
1753/******************************************************************************
1754 * AHCI error interrupt handler. Errors include interface errors and device
1755 * errors (usually triggered by the error bit in the AHCI task file register).
1756 *
1757 * Since this involves long-running operations such as restarting or even
1758 * resetting a port, this function is invoked at task time via a context
1759 * hook.
1760 *
1761 * NOTE: AHCI controllers stop all processing when encountering an error
1762 * condition in order to give the driver time to find out what exactly
1763 * went wrong. This means no new commands will be processed until we
1764 * clear the error register and restore the "commands issued" register.
1765 */
1766void ahci_error_intr(AD_INFO *ai, int p, u32 irq_stat)
1767{
1768 int reset_port = 0;
1769
1770 /* Handle adapter and interface errors. Those typically require a port
1771 * reset, or worse.
1772 */
1773 ai->ports[p].error_count++;
1774
1775 if (irq_stat & PORT_IRQ_UNK_FIS)
1776 {
1777 #ifdef DEBUG
1778 u32 *unk = (u32 *) (port_dma_base(ai, p)->rx_fis + RX_FIS_UNK);
1779 DPRINTF(0,"warning: unknown FIS %08lx %08lx %08lx %08lx\n", unk[0], unk[1], unk[2], unk[3]);
1780 #endif
1781 reset_port = 1;
1782 }
1783 if (irq_stat & (PORT_IRQ_HBUS_ERR | PORT_IRQ_HBUS_DATA_ERR))
1784 {
1785 dprintf(0,"warning: host bus [data] error for port #%d\n", p);
1786 reset_port = 1;
1787 }
1788 if (irq_stat & PORT_IRQ_IF_ERR && !(ai->flags & AHCI_HFLAG_IGN_IRQ_IF_ERR))
1789 {
1790 dprintf(0,"warning: interface fatal error for port #%d\n", p);
1791 reset_port = 1;
1792 }
1793 if (reset_port)
1794 {
1795 /* need to reset the port; leave this to the reset context hook */
1796
1797 ports_to_reset[ad_no(ai)] |= 1UL << p;
1798 KernArmHook(reset_ctxhook_h, 0, 0);
1799
1800 /* no point analyzing device errors after a reset... */
1801 return;
1802 }
1803
1804 dprintf(0,"port #%d interrupt error status: 0x%08lx; restarting port\n", p, irq_stat);
1805
1806 /* Handle device-specific errors. Those errors typically involve restarting
1807 * the corresponding port to resume operations which can take some time,
1808 * thus we need to offload this functionality to the restart context hook.
1809 */
1810 ports_to_restart[ad_no(ai)] |= 1UL << p;
1811 KernArmHook(restart_ctxhook_h, 0, 0);
1812}
1813
1814/******************************************************************************
1815 * Get device or media geometry. Device and media geometry are expected to be
1816 * the same for non-removable devices.
1817 */
1818void ahci_get_geometry(IORBH FAR16DATA *vIorb, IORBH *pIorb)
1819{
1820 DPRINTF(7,"ahci_get_geometry(%d.%d.%d)\n", iorb_unit_adapter(pIorb),
1821 iorb_unit_port(pIorb), iorb_unit_device(pIorb));
1822
1823 ahci_exec_iorb(vIorb, pIorb, 0, cmd_func(pIorb, get_geometry));
1824}
1825
1826/******************************************************************************
1827 * Test whether unit is ready.
1828 */
1829void ahci_unit_ready(IORBH FAR16DATA *vIorb, IORBH *pIorb)
1830{
1831 DPRINTF(7,"ahci_unit_ready(%d.%d.%d)\n", iorb_unit_adapter(pIorb),
1832 iorb_unit_port(pIorb), iorb_unit_device(pIorb));
1833
1834 ahci_exec_iorb(vIorb, pIorb, 0, cmd_func(pIorb, unit_ready));
1835}
1836
1837/******************************************************************************
1838 * Read sectors from AHCI device.
1839 */
1840void ahci_read(IORBH FAR16DATA *vIorb, IORBH *pIorb)
1841{
1842 DPRINTF(7,"ahci_read(%d.%d.%d, %d, %d)\n", iorb_unit_adapter(vIorb),
1843 iorb_unit_port(pIorb), iorb_unit_device(pIorb),
1844 ((IORB_EXECUTEIO *) pIorb)->RBA,
1845 ((IORB_EXECUTEIO *) pIorb)->BlockCount);
1846
1847 ahci_exec_iorb(vIorb, pIorb, 1, cmd_func(pIorb, read));
1848}
1849
1850/******************************************************************************
1851 * Verify readability of sectors on AHCI device.
1852 */
1853void ahci_verify(IORBH FAR16DATA *vIorb, IORBH *pIorb)
1854{
1855 DPRINTF(7,"ahci_verify(%d.%d.%d, %d, %d)\n", iorb_unit_adapter(pIorb),
1856 iorb_unit_port(pIorb), iorb_unit_device(pIorb),
1857 ((IORB_EXECUTEIO *)pIorb)->RBA,
1858 ((IORB_EXECUTEIO *)pIorb)->BlockCount);
1859
1860 ahci_exec_iorb(vIorb, pIorb, 0, cmd_func(pIorb, verify));
1861}
1862
1863/******************************************************************************
1864 * Write sectors to AHCI device.
1865 */
1866void ahci_write(IORBH FAR16DATA *vIorb, IORBH *pIorb)
1867{
1868 DPRINTF(7,"ahci_write(%d.%d.%d, %d, %d)\n", iorb_unit_adapter(pIorb),
1869 iorb_unit_port(pIorb), iorb_unit_device(pIorb),
1870 ((IORB_EXECUTEIO *)pIorb)->RBA,
1871 ((IORB_EXECUTEIO *)pIorb)->BlockCount);
1872
1873 ahci_exec_iorb(vIorb, pIorb, 1, cmd_func(pIorb, write));
1874}
1875
1876/******************************************************************************
1877 * Execute SCSI (ATAPI) command.
1878 */
1879void ahci_execute_cdb(IORBH FAR16DATA *vIorb, IORBH *pIorb)
1880{
1881 int a = iorb_unit_adapter(pIorb);
1882 int p = iorb_unit_port(pIorb);
1883 int d = iorb_unit_device(pIorb);
1884
1885 DHEXDUMP(5,Far16ToFlat(((IORB_ADAPTER_PASSTHRU *)pIorb)->pControllerCmd),
1886 ((IORB_ADAPTER_PASSTHRU *)pIorb)->ControllerCmdLen,
1887 "ahci_execute_cdb(%d.%d.%d): ", a, p, d);
1888
1889 if (ad_infos[a].ports[p].devs[d].atapi)
1890 {
1891 ahci_exec_iorb(vIorb, pIorb, 0, atapi_execute_cdb);
1892 }
1893 else
1894 {
1895 iorb_seterr(pIorb, IOERR_CMD_NOT_SUPPORTED);
1896 iorb_done(vIorb, pIorb);
1897 }
1898}
1899
1900/******************************************************************************
1901 * Execute ATA command. Please note that this is allowed for both ATA and
1902 * ATAPI devices because ATAPI devices will process some ATA commands as well.
1903 */
1904void ahci_execute_ata(IORBH FAR16DATA *vIorb, IORBH *pIorb)
1905{
1906 #ifdef DEBUG
1907 int a = iorb_unit_adapter(pIorb);
1908 int p = iorb_unit_port(pIorb);
1909 int d = iorb_unit_device(pIorb);
1910
1911 DHEXDUMP(5,Far16ToFlat(((IORB_ADAPTER_PASSTHRU *)pIorb)->pControllerCmd),
1912 ((IORB_ADAPTER_PASSTHRU *)pIorb)->ControllerCmdLen,
1913 "ahci_execute_ata(%d.%d.%d): ", a, p, d);
1914 #endif
1915
1916 ahci_exec_iorb(vIorb, pIorb, 0, ata_execute_ata);
1917}
1918
Note: See TracBrowser for help on using the repository browser.