socsvn commit: r257083 - soc2013/zcore/head/usr.sbin/bhyve

zcore at FreeBSD.org zcore at FreeBSD.org
Sat Sep 7 16:08:00 UTC 2013


Author: zcore
Date: Sat Sep  7 16:08:00 2013
New Revision: 257083
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=257083

Log:
  support ATA_FLUSHCACHE and ATA_FLUSHCACHE48

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

Modified: soc2013/zcore/head/usr.sbin/bhyve/pci_ahci.c
==============================================================================
--- soc2013/zcore/head/usr.sbin/bhyve/pci_ahci.c	Sat Sep  7 16:07:01 2013	(r257082)
+++ soc2013/zcore/head/usr.sbin/bhyve/pci_ahci.c	Sat Sep  7 16:08:00 2013	(r257083)
@@ -54,6 +54,8 @@
 #include "ahci.h"
 #include "block_if.h"
 
+#define MAX_PORTS	6 /* Intel Cougar Point AHCI support 6 ports*/
+
 #define	PxSIG_ATA	0x00000101 /* ATA drive */
 #define	PxSIG_ATAPI	0xeb140101 /* ATAPI drive */
 
@@ -82,8 +84,6 @@
 	STAILQ_ENTRY(ahci_ioreq) io_list;
 	uint8_t *cfis;
 	int slot;
-	uint8_t status;
-	uint8_t error;
 };
 
 struct ahci_port {
@@ -94,8 +94,10 @@
 	int atapi;
 	int reset;
 	int mult_sectors;
+	int flush_pending;
 	uint32_t unhandled_read;
 	uint32_t unhandled_write;
+	pthread_cond_t flush_cond;
 	uint8_t xfermode;
 
 	uint32_t clb;
@@ -154,7 +156,7 @@
 	uint32_t em_ctl;
 	uint32_t cap2;
 	uint32_t bohc;
-	struct ahci_port port[AHCI_MAX_PORTS];
+	struct ahci_port port[MAX_PORTS];
 };
 #define	ahci_ctx(sc)	((sc)->asc_pi->pi_vmctx)
 
@@ -215,16 +217,18 @@
 	}
 }
 
-static void ahci_write_fis_d2h(struct ahci_port *p, struct ahci_ioreq *aior)
+static void ahci_write_fis_d2h(struct ahci_port *p, int slot,
+				uint8_t *cfis, uint32_t tfd)
 {
 	uint8_t fis[20];
-	uint8_t *cfis = aior->cfis;
+	uint8_t error;
 
+	error = (tfd >> 8) & 0xff;
 	memset(fis, 0, sizeof(fis));
 	fis[0] = FIS_TYPE_REGD2H;
 	fis[1] = (1 << 6);
-	fis[2] = aior->status;
-	fis[3] = aior->error;
+	fis[2] = tfd & 0xff;
+	fis[3] = error;
 	fis[4] = cfis[4];
 	fis[5] = cfis[5];
 	fis[6] = cfis[6];
@@ -235,10 +239,10 @@
 	fis[11] = cfis[11];
 	fis[12] = cfis[12];
 	fis[13] = cfis[13];
-	if (aior->error & ATA_S_ERROR)
+	if (error & ATA_S_ERROR)
 		p->is |= AHCI_P_IX_TFE;
-	p->tfd = (aior->error << 8) | aior->status;
-	p->ci &= ~(1 << aior->slot);
+	p->tfd = tfd;
+	p->ci &= ~(1 << slot);
 	ahci_write_fis(p, FIS_TYPE_REGD2H, fis);
 }
 
@@ -386,6 +390,19 @@
 }
 
 static void
+handle_flush(struct ahci_port *p, int slot, uint8_t *cfis)
+{
+	struct pci_ahci_softc *sc = p->pr_sc;
+
+	if (p->unhandled_write) {
+		p->flush_pending = 1;
+		pthread_cond_wait(&p->flush_cond, &sc->mtx);
+		p->flush_pending = 0;
+	}
+	ahci_write_fis_d2h(p, slot, cfis, ATA_S_READY | ATA_S_DSC);
+}
+
+static void
 handle_cmd(struct ahci_port *p, int slot, uint8_t *cfis)
 {
 	struct pci_ahci_softc *sc = p->pr_sc;
@@ -516,6 +533,10 @@
 	case ATA_WRITE_DMA48:
 		handle_dma(p, slot, cfis);
 		break;
+	case ATA_FLUSHCACHE:
+	case ATA_FLUSHCACHE48:
+		handle_flush(p, slot, cfis);
+		break;
 	default:
 		break;
 	}
@@ -596,6 +617,7 @@
 	struct ahci_port *p;
 	struct pci_ahci_softc *sc;
 	struct ahci_ioreq *aior;
+	uint32_t tfd;
 
 	aior = br->br_param;
 	p = aior->io_pr;
@@ -604,14 +626,11 @@
 	DPRINTF(("ahci_ioreq_cb %d\n", err));
 	pthread_mutex_lock(&sc->mtx);
 
-	if (err) {
-		aior->status = ATA_S_READY | ATA_S_ERROR;
-		aior->error = ATA_E_ABORT;
-	} else {
-		aior->status = ATA_S_READY | ATA_S_DSC;
-		aior->error = 0;
-	}
-	ahci_write_fis_d2h(p, aior);
+	if (err)
+		tfd = (ATA_E_ABORT << 8) | ATA_S_READY | ATA_S_ERROR;
+	else
+		tfd = ATA_S_READY | ATA_S_DSC;
+	ahci_write_fis_d2h(p, aior->slot, aior->cfis, tfd);
 
 	/*
 	 * Move the blockif request back to the free list
@@ -636,6 +655,8 @@
 		}
 		p->unhandled_read &= unhandled;
 		p->unhandled_write &= unhandled;
+		if (!p->unhandled_write && p->flush_pending)
+			pthread_cond_signal(&p->flush_cond);
 	}
 
 	pthread_mutex_unlock(&sc->mtx);
@@ -700,20 +721,22 @@
 
 	sc->port[0].bctx = bctxt;
 
-	for (i = 0; i < AHCI_MAX_PORTS; i++) {
+	sc->ports = MAX_PORTS;
+	for (i = 0; i < sc->ports; i++) {
+		if (!sc->port[i].bctx)
+			continue;
 		sc->port[i].pr_sc = sc;
+		pthread_cond_init(&sc->port[i].flush_cond, NULL);
 		/*
 		 * Allocate blockif request structures and add them
 		 * to the free list
 		 */
-		if (sc->port[i].bctx)
-			pci_ahci_ioreq_init(&sc->port[i]);
+		pci_ahci_ioreq_init(&sc->port[i]);
 	}
 
 	pthread_mutex_init(&sc->mtx, NULL);
 
 	/* Intel Cougar Point AHCI */
-	sc->ports = 6;
 	sc->cap = AHCI_CAP_64BIT | AHCI_CAP_SNCQ | AHCI_CAP_SSNTF |
 		AHCI_CAP_SMPS | AHCI_CAP_SSS | AHCI_CAP_SALP |
 		AHCI_CAP_SAL | AHCI_CAP_SCLO | (0x3 << AHCI_CAP_ISS_SHIFT)|


More information about the svn-soc-all mailing list