summaryrefslogtreecommitdiffstats
path: root/usr.sbin/bhyve
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2015-05-06 09:59:19 +0000
committermav <mav@FreeBSD.org>2015-05-06 09:59:19 +0000
commit6b7074e362d7c693e94219d430c13f1092ab6a1b (patch)
tree294ee3f14bd5a57ad9fd462b3fe8e493abb258b7 /usr.sbin/bhyve
parenta7d547aa9756f1c2d8ba8dc4abd95c4c42a69ef8 (diff)
downloadFreeBSD-src-6b7074e362d7c693e94219d430c13f1092ab6a1b.zip
FreeBSD-src-6b7074e362d7c693e94219d430c13f1092ab6a1b.tar.gz
Reimplement queue freeze on error, added in r282429:
It is not required to use CLO to recover from task file error, it should be enough to do only stop/start, that does not clear the PxTFD.STS.ERR. MFC after: 13 days
Diffstat (limited to 'usr.sbin/bhyve')
-rw-r--r--usr.sbin/bhyve/pci_ahci.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/usr.sbin/bhyve/pci_ahci.c b/usr.sbin/bhyve/pci_ahci.c
index 922a783..31e02f8 100644
--- a/usr.sbin/bhyve/pci_ahci.c
+++ b/usr.sbin/bhyve/pci_ahci.c
@@ -135,6 +135,7 @@ struct ahci_port {
char ident[20 + 1];
int atapi;
int reset;
+ int waitforclear;
int mult_sectors;
uint8_t xfermode;
uint8_t err_cfis[20];
@@ -288,8 +289,10 @@ ahci_write_fis(struct ahci_port *p, enum sata_fis_type ft, uint8_t *fis)
WPRINTF("unsupported fis type %d\n", ft);
return;
}
- if (fis[2] & ATA_S_ERROR)
+ if (fis[2] & ATA_S_ERROR) {
+ p->waitforclear = 1;
irq |= AHCI_P_IX_TFE;
+ }
memcpy(p->rfis + offset, fis, len);
if (irq) {
p->is |= irq;
@@ -413,6 +416,7 @@ ahci_check_stopped(struct ahci_port *p)
p->cmd &= ~(AHCI_P_CMD_CR | AHCI_P_CMD_CCS_MASK);
p->ci = 0;
p->sact = 0;
+ p->waitforclear = 0;
}
}
}
@@ -1769,7 +1773,9 @@ ahci_handle_port(struct ahci_port *p)
* are already in-flight. Stop if device is busy or in error.
*/
for (; (p->ci & ~p->pending) != 0; p->ccs = ((p->ccs + 1) & 31)) {
- if ((p->tfd & (ATA_S_BUSY | ATA_S_DRQ | ATA_S_ERROR)) != 0)
+ if ((p->tfd & (ATA_S_BUSY | ATA_S_DRQ)) != 0)
+ break;
+ if (p->waitforclear)
break;
if ((p->ci & ~p->pending & (1 << p->ccs)) != 0) {
p->cmd &= ~AHCI_P_CMD_CCS_MASK;
@@ -2010,7 +2016,7 @@ pci_ahci_port_write(struct pci_ahci_softc *sc, uint64_t offset, uint64_t value)
}
if (value & AHCI_P_CMD_CLO) {
- p->tfd = 0;
+ p->tfd &= ~(ATA_S_BUSY | ATA_S_DRQ);
p->cmd &= ~AHCI_P_CMD_CLO;
}
OpenPOWER on IntegriCloud