aboutsummaryrefslogtreecommitdiff
path: root/src/hw
diff options
context:
space:
mode:
Diffstat (limited to 'src/hw')
-rw-r--r--src/hw/ahci.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/src/hw/ahci.c b/src/hw/ahci.c
index 4f0f640..7e7a03d 100644
--- a/src/hw/ahci.c
+++ b/src/hw/ahci.c
@@ -637,7 +637,7 @@ static void
ahci_controller_setup(struct pci_device *pci)
{
struct ahci_port_s *port;
- u32 val, pnr, max;
+ u32 pnr, max;
if (create_bounce_buf() < 0)
return;
@@ -660,8 +660,23 @@ ahci_controller_setup(struct pci_device *pci)
pci_enable_busmaster(pci);
- val = ahci_ctrl_readl(ctrl, HOST_CTL);
+ u32 val = ahci_ctrl_readl(ctrl, HOST_CTL);
+ ahci_ctrl_writel(ctrl, HOST_CTL, val | HOST_CTL_RESET);
+ u32 end = timer_calc(AHCI_RESET_TIMEOUT);
+ for (;;) {
+ val = ahci_ctrl_readl(ctrl, HOST_CTL);
+ if (!(val & HOST_CTL_RESET))
+ break;
+ if (timer_check(end)) {
+ warn_timeout();
+ dprintf(1, "AHCI: controller reset failed\n");
+ free(ctrl);
+ return;
+ }
+ yield();
+ }
ahci_ctrl_writel(ctrl, HOST_CTL, val | HOST_CTL_AHCI_EN);
+ (void)ahci_ctrl_readl(ctrl, HOST_CTL); /* Flush */
ctrl->caps = ahci_ctrl_readl(ctrl, HOST_CAP);
ctrl->ports = ahci_ctrl_readl(ctrl, HOST_PORTS_IMPL);