Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 6 May 2015 09:59:19 +0000 (UTC)
From:      Alexander Motin <mav@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r282524 - head/usr.sbin/bhyve
Message-ID:  <201505060959.t469xJLN092904@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mav
Date: Wed May  6 09:59:19 2015
New Revision: 282524
URL: https://svnweb.freebsd.org/changeset/base/282524

Log:
  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

Modified:
  head/usr.sbin/bhyve/pci_ahci.c

Modified: head/usr.sbin/bhyve/pci_ahci.c
==============================================================================
--- head/usr.sbin/bhyve/pci_ahci.c	Wed May  6 09:38:44 2015	(r282523)
+++ head/usr.sbin/bhyve/pci_ahci.c	Wed May  6 09:59:19 2015	(r282524)
@@ -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
 		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_soft
 		}
 
 		if (value & AHCI_P_CMD_CLO) {
-			p->tfd = 0;
+			p->tfd &= ~(ATA_S_BUSY | ATA_S_DRQ);
 			p->cmd &= ~AHCI_P_CMD_CLO;
 		}
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201505060959.t469xJLN092904>