summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/amd64/amd64/machdep.c1
-rw-r--r--sys/conf/files.amd642
-rw-r--r--sys/conf/files.i3861
-rw-r--r--sys/dev/acpica/acpi_pci.c2
-rw-r--r--sys/i386/i386/machdep.c3
-rw-r--r--sys/x86/include/init.h1
-rw-r--r--sys/x86/x86/local_apic.c3
-rw-r--r--sys/x86/xen/pv.c3
-rw-r--r--sys/x86/xen/xen_intr.c60
-rw-r--r--sys/x86/xen/xen_msi.c125
-rw-r--r--sys/x86/xen/xen_nexus.c45
-rw-r--r--sys/x86/xen/xen_pci.c108
-rw-r--r--sys/xen/interface/physdev.h1
-rw-r--r--sys/xen/xen_intr.h22
-rw-r--r--sys/xen/xen_msi.h39
15 files changed, 414 insertions, 2 deletions
diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c
index 278409d..ab82771 100644
--- a/sys/amd64/amd64/machdep.c
+++ b/sys/amd64/amd64/machdep.c
@@ -177,6 +177,7 @@ struct init_ops init_ops = {
.mp_bootaddress = mp_bootaddress,
.start_all_aps = native_start_all_aps,
#endif
+ .msi_init = msi_init,
};
/*
diff --git a/sys/conf/files.amd64 b/sys/conf/files.amd64
index b75732f..9e5a2ed 100644
--- a/sys/conf/files.amd64
+++ b/sys/conf/files.amd64
@@ -582,3 +582,5 @@ x86/xen/pvcpu_enum.c optional xenhvm
x86/xen/xen_apic.c optional xenhvm
x86/xen/xenpv.c optional xenhvm
x86/xen/xen_nexus.c optional xenhvm
+x86/xen/xen_msi.c optional xenhvm
+x86/xen/xen_pci.c optional xenhvm
diff --git a/sys/conf/files.i386 b/sys/conf/files.i386
index db6b2aa..0e4519d 100644
--- a/sys/conf/files.i386
+++ b/sys/conf/files.i386
@@ -599,3 +599,4 @@ x86/xen/xen_intr.c optional xen | xenhvm
x86/xen/xen_apic.c optional xenhvm
x86/xen/xenpv.c optional xen | xenhvm
x86/xen/xen_nexus.c optional xen | xenhvm
+x86/xen/xen_msi.c optional xen | xenhvm
diff --git a/sys/dev/acpica/acpi_pci.c b/sys/dev/acpica/acpi_pci.c
index f4e794a..d94b6f0 100644
--- a/sys/dev/acpica/acpi_pci.c
+++ b/sys/dev/acpica/acpi_pci.c
@@ -282,7 +282,7 @@ acpi_pci_probe(device_t dev)
if (acpi_get_handle(dev) == NULL)
return (ENXIO);
device_set_desc(dev, "ACPI PCI bus");
- return (0);
+ return (BUS_PROBE_DEFAULT);
}
static int
diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c
index a3990ed..8892c56 100644
--- a/sys/i386/i386/machdep.c
+++ b/sys/i386/i386/machdep.c
@@ -248,6 +248,9 @@ struct mem_range_softc mem_range_softc;
struct init_ops init_ops = {
.early_clock_source_init = i8254_init,
.early_delay = i8254_delay,
+#ifdef DEV_APIC
+ .msi_init = msi_init,
+#endif
};
static void
diff --git a/sys/x86/include/init.h b/sys/x86/include/init.h
index 47dc4f5..7cc6798 100644
--- a/sys/x86/include/init.h
+++ b/sys/x86/include/init.h
@@ -41,6 +41,7 @@ struct init_ops {
void (*parse_memmap)(caddr_t, vm_paddr_t *, int *);
u_int (*mp_bootaddress)(u_int);
int (*start_all_aps)(void);
+ void (*msi_init)(void);
};
extern struct init_ops init_ops;
diff --git a/sys/x86/x86/local_apic.c b/sys/x86/x86/local_apic.c
index 50f00d0..2aa18f5 100644
--- a/sys/x86/x86/local_apic.c
+++ b/sys/x86/x86/local_apic.c
@@ -63,6 +63,7 @@ __FBSDID("$FreeBSD$");
#include <machine/md_var.h>
#include <machine/smp.h>
#include <machine/specialreg.h>
+#include <x86/init.h>
#ifdef DDB
#include <sys/interrupt.h>
@@ -1438,7 +1439,7 @@ apic_setup_io(void *dummy __unused)
lapic_dump("BSP");
/* Enable the MSI "pic". */
- msi_init();
+ init_ops.msi_init();
}
SYSINIT(apic_setup_io, SI_SUB_INTR, SI_ORDER_THIRD, apic_setup_io, NULL);
diff --git a/sys/x86/xen/pv.c b/sys/x86/xen/pv.c
index ee2cd6b..140d13f 100644
--- a/sys/x86/xen/pv.c
+++ b/sys/x86/xen/pv.c
@@ -60,11 +60,13 @@ __FBSDID("$FreeBSD$");
#include <x86/init.h>
#include <machine/pc/bios.h>
#include <machine/smp.h>
+#include <machine/intr_machdep.h>
#include <xen/xen-os.h>
#include <xen/hypervisor.h>
#include <xen/xenstore/xenstorevar.h>
#include <xen/xen_pv.h>
+#include <xen/xen_msi.h>
#include <xen/interface/vcpu.h>
@@ -117,6 +119,7 @@ struct init_ops xen_init_ops = {
#ifdef SMP
.start_all_aps = xen_pv_start_all_aps,
#endif
+ .msi_init = xen_msi_init,
};
static struct bios_smap xen_smap[MAX_E820_ENTRIES];
diff --git a/sys/x86/xen/xen_intr.c b/sys/x86/xen/xen_intr.c
index 40b65f7..83f1db3 100644
--- a/sys/x86/xen/xen_intr.c
+++ b/sys/x86/xen/xen_intr.c
@@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$");
#include <machine/intr_machdep.h>
#include <x86/apicvar.h>
+#include <x86/apicreg.h>
#include <machine/smp.h>
#include <machine/stdarg.h>
@@ -63,6 +64,7 @@ __FBSDID("$FreeBSD$");
#include <xen/evtchn/evtchnvar.h>
#include <dev/xen/xenpci/xenpcivar.h>
+#include <dev/pci/pcivar.h>
#ifdef DDB
#include <ddb/ddb.h>
@@ -1373,6 +1375,64 @@ xen_register_pirq(int vector, enum intr_trigger trig, enum intr_polarity pol)
}
int
+xen_register_msi(device_t dev, int vector, int count)
+{
+ struct physdev_map_pirq msi_irq;
+ struct xenisrc *isrc;
+ int ret;
+
+ memset(&msi_irq, 0, sizeof(msi_irq));
+ msi_irq.domid = DOMID_SELF;
+ msi_irq.type = count == 1 ?
+ MAP_PIRQ_TYPE_MSI_SEG : MAP_PIRQ_TYPE_MULTI_MSI;
+ msi_irq.index = -1;
+ msi_irq.pirq = -1;
+ msi_irq.bus = pci_get_bus(dev) | (pci_get_domain(dev) << 16);
+ msi_irq.devfn = (pci_get_slot(dev) << 3) | pci_get_function(dev);
+ msi_irq.entry_nr = count;
+
+ ret = HYPERVISOR_physdev_op(PHYSDEVOP_map_pirq, &msi_irq);
+ if (ret != 0)
+ return (ret);
+ if (count != msi_irq.entry_nr) {
+ panic("unable to setup all requested MSI vectors "
+ "(expected %d got %d)", count, msi_irq.entry_nr);
+ }
+
+ mtx_lock(&xen_intr_isrc_lock);
+ for (int i = 0; i < count; i++) {
+ isrc = xen_intr_alloc_isrc(EVTCHN_TYPE_PIRQ, vector + i);
+ KASSERT(isrc != NULL,
+ ("xen: unable to allocate isrc for interrupt"));
+ isrc->xi_pirq = msi_irq.pirq + i;
+ }
+ mtx_unlock(&xen_intr_isrc_lock);
+
+ return (0);
+}
+
+int
+xen_release_msi(int vector)
+{
+ struct physdev_unmap_pirq unmap;
+ struct xenisrc *isrc;
+ int ret;
+
+ isrc = (struct xenisrc *)intr_lookup_source(vector);
+ if (isrc == NULL)
+ return (ENXIO);
+
+ unmap.pirq = isrc->xi_pirq;
+ ret = HYPERVISOR_physdev_op(PHYSDEVOP_unmap_pirq, &unmap);
+ if (ret != 0)
+ return (ret);
+
+ xen_intr_release_isrc(isrc);
+
+ return (0);
+}
+
+int
xen_intr_describe(xen_intr_handle_t port_handle, const char *fmt, ...)
{
char descr[MAXCOMLEN + 1];
diff --git a/sys/x86/xen/xen_msi.c b/sys/x86/xen/xen_msi.c
new file mode 100644
index 0000000..0f678b1
--- /dev/null
+++ b/sys/x86/xen/xen_msi.c
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2014 Roger Pau Monné <roger.pau@citrix.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/mutex.h>
+#include <sys/sx.h>
+#include <sys/systm.h>
+#include <x86/apicreg.h>
+#include <machine/cputypes.h>
+#include <machine/md_var.h>
+#include <machine/frame.h>
+#include <machine/intr_machdep.h>
+#include <x86/apicvar.h>
+#include <machine/specialreg.h>
+#include <dev/pci/pcivar.h>
+
+#include <xen/xen_intr.h>
+#include <xen/xen_msi.h>
+
+static struct mtx msi_lock;
+static int msi_last_irq;
+
+void
+xen_msi_init(void)
+{
+
+ mtx_init(&msi_lock, "msi", NULL, MTX_DEF);
+}
+
+/*
+ * Try to allocate 'count' interrupt sources with contiguous IDT values.
+ */
+int
+xen_msi_alloc(device_t dev, int count, int maxcount, int *irqs)
+{
+ int i, ret = 0;
+
+ mtx_lock(&msi_lock);
+
+ /* If we would exceed the max, give up. */
+ if ((msi_last_irq + count) > NUM_MSI_INTS) {
+ mtx_unlock(&msi_lock);
+ return (ENXIO);
+ }
+
+ /* Allocate MSI vectors */
+ for (i = 0; i < count; i++)
+ irqs[i] = FIRST_MSI_INT + msi_last_irq++;
+
+ mtx_unlock(&msi_lock);
+
+ ret = xen_register_msi(dev, irqs[0], count);
+ if (ret != 0)
+ return (ret);
+
+ for (i = 0; i < count; i++)
+ nexus_add_irq(irqs[i]);
+
+ return (0);
+}
+
+int
+xen_msi_release(int *irqs, int count)
+{
+ int i, ret;
+
+ for (i = 0; i < count; i++) {
+ ret = xen_release_msi(irqs[i]);
+ if (ret != 0)
+ return (ret);
+ }
+
+ return (0);
+}
+
+int
+xen_msi_map(int irq, uint64_t *addr, uint32_t *data)
+{
+
+ return (0);
+}
+
+int
+xen_msix_alloc(device_t dev, int *irq)
+{
+
+ return (ENXIO);
+}
+
+int
+xen_msix_release(int irq)
+{
+
+ return (ENOENT);
+}
diff --git a/sys/x86/xen/xen_nexus.c b/sys/x86/xen/xen_nexus.c
index e4634f9..1baeb7d 100644
--- a/sys/x86/xen/xen_nexus.c
+++ b/sys/x86/xen/xen_nexus.c
@@ -45,6 +45,9 @@ __FBSDID("$FreeBSD$");
#include <xen/xen-os.h>
#include <xen/xen_intr.h>
+#include <xen/xen_msi.h>
+
+#include "pcib_if.h"
/*
* Xen nexus(4) driver.
@@ -111,6 +114,41 @@ nexus_xen_config_intr(device_t dev, int irq, enum intr_trigger trig,
return (intr_config_intr(irq, trig, pol));
}
+static int
+nexus_xen_alloc_msix(device_t pcib, device_t dev, int *irq)
+{
+
+ return (xen_msix_alloc(dev, irq));
+}
+
+static int
+nexus_xen_release_msix(device_t pcib, device_t dev, int irq)
+{
+
+ return (xen_msix_release(irq));
+}
+
+static int
+nexus_xen_alloc_msi(device_t pcib, device_t dev, int count, int maxcount, int *irqs)
+{
+
+ return (xen_msi_alloc(dev, count, maxcount, irqs));
+}
+
+static int
+nexus_xen_release_msi(device_t pcib, device_t dev, int count, int *irqs)
+{
+
+ return (xen_msi_release(irqs, count));
+}
+
+static int
+nexus_xen_map_msi(device_t pcib, device_t dev, int irq, uint64_t *addr, uint32_t *data)
+{
+
+ return (xen_msi_map(irq, addr, data));
+}
+
static device_method_t nexus_xen_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, nexus_xen_probe),
@@ -119,6 +157,13 @@ static device_method_t nexus_xen_methods[] = {
/* INTR */
DEVMETHOD(bus_config_intr, nexus_xen_config_intr),
+ /* MSI */
+ DEVMETHOD(pcib_alloc_msi, nexus_xen_alloc_msi),
+ DEVMETHOD(pcib_release_msi, nexus_xen_release_msi),
+ DEVMETHOD(pcib_alloc_msix, nexus_xen_alloc_msix),
+ DEVMETHOD(pcib_release_msix, nexus_xen_release_msix),
+ DEVMETHOD(pcib_map_msi, nexus_xen_map_msi),
+
{ 0, 0 }
};
diff --git a/sys/x86/xen/xen_pci.c b/sys/x86/xen/xen_pci.c
new file mode 100644
index 0000000..5a186c5
--- /dev/null
+++ b/sys/x86/xen/xen_pci.c
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2014 Roger Pau Monné <roger.pau@citrix.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+
+#include <sys/pciio.h>
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pci_private.h>
+
+#include <xen/xen-os.h>
+
+#include "pcib_if.h"
+#include "pci_if.h"
+
+static int xen_pci_probe(device_t dev);
+
+static void xen_pci_enable_msi_method(device_t dev, device_t child,
+ uint64_t address, uint16_t data);
+static void xen_pci_disable_msi_method(device_t dev, device_t child);
+
+static device_method_t xen_pci_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, xen_pci_probe),
+
+ /* PCI interface overwrites */
+ DEVMETHOD(pci_enable_msi, xen_pci_enable_msi_method),
+ DEVMETHOD(pci_disable_msi, xen_pci_disable_msi_method),
+
+ DEVMETHOD_END
+};
+
+static devclass_t pci_devclass;
+
+DECLARE_CLASS(acpi_pci_driver);
+DEFINE_CLASS_1(pci, xen_pci_driver, xen_pci_methods, sizeof(struct pci_softc),
+ acpi_pci_driver);
+DRIVER_MODULE(xen_pci, pcib, xen_pci_driver, pci_devclass, 0, 0);
+MODULE_DEPEND(xen_pci, pci, 1, 1, 1);
+MODULE_DEPEND(xen_pci, acpi, 1, 1, 1);
+MODULE_VERSION(xen_pci, 1);
+
+static int
+xen_pci_probe(device_t dev)
+{
+
+ device_set_desc(dev, "Xen PCI bus");
+
+ if (!xen_pv_domain())
+ return (ENXIO);
+
+ return (BUS_PROBE_SPECIFIC);
+}
+
+static void
+xen_pci_enable_msi_method(device_t dev, device_t child, uint64_t address,
+ uint16_t data)
+{
+ struct pci_devinfo *dinfo = device_get_ivars(child);
+ struct pcicfg_msi *msi = &dinfo->cfg.msi;
+
+ /* Enable MSI in the control register. */
+ msi->msi_ctrl |= PCIM_MSICTRL_MSI_ENABLE;
+ pci_write_config(child, msi->msi_location + PCIR_MSI_CTRL,
+ msi->msi_ctrl, 2);
+}
+
+static void
+xen_pci_disable_msi_method(device_t dev, device_t child)
+{
+ struct pci_devinfo *dinfo = device_get_ivars(child);
+ struct pcicfg_msi *msi = &dinfo->cfg.msi;
+
+ msi->msi_ctrl &= ~PCIM_MSICTRL_MSI_ENABLE;
+ pci_write_config(child, msi->msi_location + PCIR_MSI_CTRL,
+ msi->msi_ctrl, 2);
+}
diff --git a/sys/xen/interface/physdev.h b/sys/xen/interface/physdev.h
index b78eeba..56b8be0 100644
--- a/sys/xen/interface/physdev.h
+++ b/sys/xen/interface/physdev.h
@@ -151,6 +151,7 @@ DEFINE_XEN_GUEST_HANDLE(physdev_irq_t);
#define MAP_PIRQ_TYPE_GSI 0x1
#define MAP_PIRQ_TYPE_UNKNOWN 0x2
#define MAP_PIRQ_TYPE_MSI_SEG 0x3
+#define MAP_PIRQ_TYPE_MULTI_MSI 0x4
#define PHYSDEVOP_map_pirq 13
struct physdev_map_pirq {
diff --git a/sys/xen/xen_intr.h b/sys/xen/xen_intr.h
index a1ff666..a29414d 100644
--- a/sys/xen/xen_intr.h
+++ b/sys/xen/xen_intr.h
@@ -224,4 +224,26 @@ void xen_intr_signal(xen_intr_handle_t handle);
*/
evtchn_port_t xen_intr_port(xen_intr_handle_t handle);
+/**
+ * Setup MSI vector interrupt(s).
+ *
+ * \param dev The device that requests the binding.
+ *
+ * \param vector Requested initial vector to bind the MSI interrupt(s) to.
+ *
+ * \param count Number of vectors to allocate.
+ *
+ * \returns 0 on success, otherwise an errno.
+ */
+int xen_register_msi(device_t dev, int vector, int count);
+
+/**
+ * Teardown a MSI vector interrupt.
+ *
+ * \param vector Requested vector to release.
+ *
+ * \returns 0 on success, otherwise an errno.
+ */
+int xen_release_msi(int vector);
+
#endif /* _XEN_INTR_H_ */
diff --git a/sys/xen/xen_msi.h b/sys/xen/xen_msi.h
new file mode 100644
index 0000000..baec4c1a
--- /dev/null
+++ b/sys/xen/xen_msi.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2014 Roger Pau Monné <roger.pau@citrix.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef __XEN_MSI_H__
+#define __XEN_MSI_H__
+
+void xen_msi_init(void);
+int xen_msi_map(int irq, uint64_t *addr, uint32_t *data);
+int xen_msi_alloc(device_t dev, int count, int maxcount, int *irqs);
+int xen_msi_release(int *irqs, int count);
+int xen_msix_alloc(device_t dev, int *irq);
+int xen_msix_release(int irq);
+
+#endif /* !__XEN_MSI_H__ */ \ No newline at end of file
OpenPOWER on IntegriCloud