svn commit: r265058 - head/usr.sbin/bhyve
Peter Grehan
grehan at FreeBSD.org
Mon Apr 28 18:41:26 UTC 2014
Author: grehan
Date: Mon Apr 28 18:41:25 2014
New Revision: 265058
URL: http://svnweb.freebsd.org/changeset/base/265058
Log:
Implement legacy interrupts for the AHCI device emulation
according to the method outlined in the AHCI spec.
Tested with FreeBSD 9/10/11 with MSI disabled,
and also NetBSD/amd64 (lightly).
Reviewed by: neel, tychon
MFC after: 3 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 Apr 28 18:25:21 2014 (r265057)
+++ head/usr.sbin/bhyve/pci_ahci.c Mon Apr 28 18:41:25 2014 (r265058)
@@ -192,6 +192,7 @@ struct pci_ahci_softc {
uint32_t em_ctl;
uint32_t cap2;
uint32_t bohc;
+ uint32_t lintr;
struct ahci_port port[MAX_PORTS];
};
#define ahci_ctx(sc) ((sc)->asc_pi->pi_vmctx)
@@ -211,8 +212,11 @@ static inline void lba_to_msf(uint8_t *b
static void
ahci_generate_intr(struct pci_ahci_softc *sc)
{
+ struct pci_devinst *pi;
int i;
+ pi = sc->asc_pi;
+
for (i = 0; i < sc->ports; i++) {
struct ahci_port *pr;
pr = &sc->port[i];
@@ -222,8 +226,28 @@ ahci_generate_intr(struct pci_ahci_softc
DPRINTF("%s %x\n", __func__, sc->is);
- if (sc->is && (sc->ghc & AHCI_GHC_IE))
- pci_generate_msi(sc->asc_pi, 0);
+ if (sc->is && (sc->ghc & AHCI_GHC_IE)) {
+ if (pci_msi_enabled(pi)) {
+ /*
+ * Generate an MSI interrupt on every edge
+ */
+ pci_generate_msi(pi, 0);
+ } else if (!sc->lintr) {
+ /*
+ * Only generate a pin-based interrupt if one wasn't
+ * in progress
+ */
+ sc->lintr = 1;
+ pci_lintr_assert(pi);
+ }
+ } else if (sc->lintr) {
+ /*
+ * No interrupts: deassert pin-based signal if it had
+ * been asserted
+ */
+ pci_lintr_deassert(pi);
+ sc->lintr = 0;
+ }
}
static void
@@ -367,6 +391,12 @@ ahci_reset(struct pci_ahci_softc *sc)
sc->ghc = AHCI_GHC_AE;
sc->is = 0;
+
+ if (sc->lintr) {
+ pci_lintr_deassert(sc->asc_pi);
+ sc->lintr = 0;
+ }
+
for (i = 0; i < sc->ports; i++) {
sc->port[i].ie = 0;
sc->port[i].is = 0;
@@ -1814,6 +1844,8 @@ pci_ahci_init(struct vmctx *ctx, struct
pci_emul_alloc_bar(pi, 5, PCIBAR_MEM32,
AHCI_OFFSET + sc->ports * AHCI_STEP);
+ pci_lintr_request(pi);
+
open_fail:
if (ret) {
blockif_close(sc->port[0].bctx);
More information about the svn-src-all
mailing list