svn commit: r282429 - head/usr.sbin/bhyve

Alexander Motin mav at FreeBSD.org
Mon May 4 19:55:02 UTC 2015


Author: mav
Date: Mon May  4 19:55:01 2015
New Revision: 282429
URL: https://svnweb.freebsd.org/changeset/base/282429

Log:
  Implement in-order execution of non-NCQ commands.
  
  Using status updates in r282364, block queue on BSY, DRQ or ERR bits set.
  This can be a performance penalization for non-NCQ commands, but it is
  required for proper error recovery and standard compliance.
  
  MFC after:	2 weeks

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

Modified: head/usr.sbin/bhyve/pci_ahci.c
==============================================================================
--- head/usr.sbin/bhyve/pci_ahci.c	Mon May  4 19:34:59 2015	(r282428)
+++ head/usr.sbin/bhyve/pci_ahci.c	Mon May  4 19:55:01 2015	(r282429)
@@ -140,6 +140,7 @@ struct ahci_port {
 	uint8_t err_cfis[20];
 	uint8_t sense_key;
 	uint8_t asc;
+	u_int ccs;
 	uint32_t pending;
 
 	uint32_t clb;
@@ -204,6 +205,8 @@ struct pci_ahci_softc {
 };
 #define	ahci_ctx(sc)	((sc)->asc_pi->pi_vmctx)
 
+static void ahci_handle_port(struct ahci_port *p);
+
 static inline void lba_to_msf(uint8_t *buf, int lba)
 {
 	lba += 150;
@@ -406,6 +409,7 @@ ahci_check_stopped(struct ahci_port *p)
 	 */
 	if (!(p->cmd & AHCI_P_CMD_ST)) {
 		if (p->pending == 0) {
+			p->ccs = 0;
 			p->cmd &= ~(AHCI_P_CMD_CR | AHCI_P_CMD_CCS_MASK);
 			p->ci = 0;
 			p->sact = 0;
@@ -783,6 +787,8 @@ next:
 			ahci_write_fis_d2h(p, slot, cfis, ATA_S_READY | ATA_S_DSC);
 			p->pending &= ~(1 << slot);
 			ahci_check_stopped(p);
+			if (!first)
+				ahci_handle_port(p);
 			return;
 		}
 		goto next;
@@ -1754,20 +1760,21 @@ ahci_handle_slot(struct ahci_port *p, in
 static void
 ahci_handle_port(struct ahci_port *p)
 {
-	int i;
 
 	if (!(p->cmd & AHCI_P_CMD_ST))
 		return;
 
 	/*
 	 * Search for any new commands to issue ignoring those that
-	 * are already in-flight.
+	 * are already in-flight.  Stop if device is busy or in error.
 	 */
-	for (i = 0; (i < 32) && p->ci; i++) {
-		if ((p->ci & (1 << i)) && !(p->pending & (1 << i))) {
+	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)
+			break;
+		if ((p->ci & ~p->pending & (1 << p->ccs)) != 0) {
 			p->cmd &= ~AHCI_P_CMD_CCS_MASK;
-			p->cmd |= i << AHCI_P_CMD_CCS_SHIFT;
-			ahci_handle_slot(p, i);
+			p->cmd |= p->ccs << AHCI_P_CMD_CCS_SHIFT;
+			ahci_handle_slot(p, p->ccs);
 		}
 	}
 }
@@ -1844,6 +1851,7 @@ ata_ioreq_cb(struct blockif_req *br, int
 	p->pending &= ~(1 << slot);
 
 	ahci_check_stopped(p);
+	ahci_handle_port(p);
 out:
 	pthread_mutex_unlock(&sc->mtx);
 	DPRINTF("%s exit\n", __func__);
@@ -1905,6 +1913,7 @@ atapi_ioreq_cb(struct blockif_req *br, i
 	p->pending &= ~(1 << slot);
 
 	ahci_check_stopped(p);
+	ahci_handle_port(p);
 out:
 	pthread_mutex_unlock(&sc->mtx);
 	DPRINTF("%s exit\n", __func__);


More information about the svn-src-all mailing list