diff options
Diffstat (limited to 'sys/dev/ahci')
-rw-r--r-- | sys/dev/ahci/ahci.c | 25 |
1 files changed, 13 insertions, 12 deletions
diff --git a/sys/dev/ahci/ahci.c b/sys/dev/ahci/ahci.c index 2a06492..5db3a04 100644 --- a/sys/dev/ahci/ahci.c +++ b/sys/dev/ahci/ahci.c @@ -1835,9 +1835,11 @@ ahci_execute_transaction(struct ahci_slot *slot) if (!(ATA_INL(ch->r_mem, AHCI_P_CI) & (1 << slot->slot))) break; if (ATA_INL(ch->r_mem, AHCI_P_TFD) & ATA_S_ERROR) { +#if 0 device_printf(ch->dev, "Poll error on slot %d, TFD: %04x\n", slot->slot, ATA_INL(ch->r_mem, AHCI_P_TFD)); +#endif et = AHCI_ERR_TFE; break; } @@ -1877,14 +1879,12 @@ ahci_execute_transaction(struct ahci_slot *slot) } } } - ahci_end_transaction(slot, et); /* Kick controller into sane state and enable FBS. */ if ((ccb->ccb_h.func_code == XPT_ATA_IO) && (ccb->ataio.cmd.flags & CAM_ATAIO_CONTROL) && - (ccb->ataio.cmd.control & ATA_A_RESET) == 0) { - ahci_stop(ch->dev); - ahci_start(ch->dev, 1); - } + (ccb->ataio.cmd.control & ATA_A_RESET) == 0) + ch->eslots |= (1 << slot->slot); + ahci_end_transaction(slot, et); return; } /* Start command execution timeout */ @@ -2169,13 +2169,6 @@ ahci_end_transaction(struct ahci_slot *slot, enum ahci_err_type et) ch->numhslots++; } else xpt_done(ccb); - /* Unfreeze frozen command. */ - if (ch->frozen && !ahci_check_collision(dev, ch->frozen)) { - union ccb *fccb = ch->frozen; - ch->frozen = NULL; - ahci_begin_transaction(dev, fccb); - xpt_release_simq(ch->sim, TRUE); - } /* If we have no other active commands, ... */ if (ch->rslots == 0) { /* if there was fatal error - reset port. */ @@ -2185,6 +2178,7 @@ ahci_end_transaction(struct ahci_slot *slot, enum ahci_err_type et) /* if we have slots in error, we can reinit port. */ if (ch->eslots != 0) { ahci_stop(dev); + ahci_clo(dev); ahci_start(dev, 1); } /* if there commands on hold, we can do READ LOG. */ @@ -2195,6 +2189,13 @@ ahci_end_transaction(struct ahci_slot *slot, enum ahci_err_type et) } else if ((ch->rslots & ~ch->toslots) == 0 && et != AHCI_ERR_TIMEOUT) ahci_rearm_timeout(dev); + /* Unfreeze frozen command. */ + if (ch->frozen && !ahci_check_collision(dev, ch->frozen)) { + union ccb *fccb = ch->frozen; + ch->frozen = NULL; + ahci_begin_transaction(dev, fccb); + xpt_release_simq(ch->sim, TRUE); + } /* Start PM timer. */ if (ch->numrslots == 0 && ch->pm_level > 3 && (ch->curr[ch->pm_present ? 15 : 0].caps & CTS_SATA_CAPS_D_PMREQ)) { |