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

zcore at FreeBSD.org zcore at FreeBSD.org
Sun Jul 28 09:08:31 UTC 2013


Author: zcore
Date: Sun Jul 28 09:08:31 2013
New Revision: 255258
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=255258

Log:
  add reset and interrupt support

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	Sun Jul 28 09:07:08 2013	(r255257)
+++ soc2013/zcore/head/usr.sbin/bhyve/pci_ahci.c	Sun Jul 28 09:08:31 2013	(r255258)
@@ -127,6 +127,27 @@
 };
 
 /*
+ * generate HBA intr depending on whether or not ports within
+ * the controller have an interrupt pending.
+ */
+static void
+ahci_generate_intr(struct pci_ahci_softc *sc)
+{
+	int i;
+
+	for (i = 0; i < sc->ports; i++) {
+		struct ahci_port *pr;
+		pr = &sc->port[i];
+		if (pr->is & pr->ie)
+			sc->is |= (1 << i);
+	}
+
+	DPRINTF(("%s %x\n", __func__, sc->is));
+	if (sc->is && (sc->ghc & AHCI_GHC_IE))
+		pci_generate_msi(sc->asc_pi, 0);
+}
+
+/*
  * blockif callback routine - this runs in the context of the blockif
  * i/o thread, so the mutex needs to be acquired.
  */
@@ -146,6 +167,7 @@
 
 	/* TODO */
 
+	ahci_generate_intr(sc);
 	/*
 	 * Move the blockif request back to the free list
 	 */
@@ -154,7 +176,6 @@
 
 	pthread_mutex_unlock(&sc->mtx);
 	DPRINTF(("%s exit\n", __func__));
-
 }
 
 static void
@@ -180,6 +201,30 @@
 	}
 }
 
+static void
+ahci_port_reset(struct ahci_port *pr)
+{
+	memset(&pr->clb, 0, 17 * sizeof(uint32_t));
+	pr->sig = 0xFFFFFFFF;
+	pr->tfd = 0x7F;
+	if (pr->bctx)
+		pr->ssts = ATA_SS_DET_PHY_ONLINE | ATA_SS_SPD_GEN2 |
+			ATA_SS_IPM_ACTIVE;
+	else
+		pr->ssts = ATA_SS_DET_NO_DEVICE;
+}
+
+static void
+ahci_reset(struct pci_ahci_softc *sc)
+{
+	int i;
+
+	sc->ghc = AHCI_GHC_AE;
+	sc->is = 0;
+	for (i = 0; i < sc->ports; i++)
+		ahci_port_reset(&sc->port[i]);
+}
+
 static int
 pci_ahci_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts)
 {
@@ -235,6 +280,7 @@
 	sc->pi = (1 << sc->ports) - 1;
 	sc->vs = 0x10300;
 	sc->cap2 = AHCI_CAP2_APST;
+	ahci_reset(sc);
 
 	pci_set_cfgdata16(pi, PCIR_DEVICE, 0x1c03);
 	pci_set_cfgdata16(pi, PCIR_VENDOR, 0x8086);
@@ -273,9 +319,11 @@
 		break;
 	case AHCI_P_IS:
 		p->is &= ~value;
+		ahci_generate_intr(sc);
 		break;
 	case AHCI_P_IE:
-		p->ie = value & 0xfdc000ff;
+		p->ie = value & 0xFDC000FF;
+		ahci_generate_intr(sc);
 		break;
 	case AHCI_P_CMD:
 		/* TODO */
@@ -286,14 +334,20 @@
 		WPRINTF(("pci_ahci_port: read only registers 0x%lx\n", offset));
 		break;
 	case AHCI_P_SCTL:
-		/* TODO */
+		if (!(p->cmd & AHCI_P_CMD_ST)) {
+			if (value & ATA_SC_DET_RESET)
+				ahci_port_reset(p);
+			p->sctl = value;
+		}
 		break;
 	case AHCI_P_SERR:
 		p->serr &= ~value;
 		break;
 	case AHCI_P_SACT:
+		p->sact |= value;
 		break;
 	case AHCI_P_CI:
+		p->ci |= value;
 		/* TODO */
 		break;
 	case AHCI_P_SNTF:
@@ -316,6 +370,18 @@
 	case AHCI_CAP2:
 		WPRINTF(("pci_ahci_host: read only registers 0x%lx\n", offset));
 		break;
+	case AHCI_GHC:
+		if (value & AHCI_GHC_HR)
+			ahci_reset(sc);
+		else if (value & AHCI_GHC_IE) {
+			sc->ghc |= AHCI_GHC_IE;
+			ahci_generate_intr(sc);
+		}
+		break;
+	case AHCI_IS:
+		sc->is &= ~value;
+		ahci_generate_intr(sc);
+		break;
 	default:
 		break;
 	}
@@ -396,6 +462,7 @@
 	case AHCI_P_SCTL:
 	case AHCI_P_SERR:
 	case AHCI_P_SACT:
+		/* TODO */
 	case AHCI_P_CI:
 	case AHCI_P_SNTF:
 	case AHCI_P_FBS:


More information about the svn-soc-all mailing list