summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2010-06-14 07:10:37 +0000
committermav <mav@FreeBSD.org>2010-06-14 07:10:37 +0000
commitea954fa396b041bd7926fa93cc6d5dc99f8e181a (patch)
tree423ab29863b618eb95213b9452c47472bc992ceb
parente63e5eff064b854e57039ef919e33a4c0813018d (diff)
downloadFreeBSD-src-ea954fa396b041bd7926fa93cc6d5dc99f8e181a.zip
FreeBSD-src-ea954fa396b041bd7926fa93cc6d5dc99f8e181a.tar.gz
Virtualize pci_remap_msi_irq() call from general MSI code. It allows MSI
(FSB interrupts) to be used by non-PCI devices, such as HPET.
-rw-r--r--sys/dev/pci/pci.c10
-rw-r--r--sys/dev/pci/pcivar.h6
-rw-r--r--sys/kern/bus_if.m22
-rw-r--r--sys/x86/x86/msi.c3
4 files changed, 29 insertions, 12 deletions
diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c
index 04e8c5f..1f66f22 100644
--- a/sys/dev/pci/pci.c
+++ b/sys/dev/pci/pci.c
@@ -118,6 +118,8 @@ static void pci_unmask_msix(device_t dev, u_int index);
static int pci_msi_blacklisted(void);
static void pci_resume_msi(device_t dev);
static void pci_resume_msix(device_t dev);
+static int pci_remap_intr_method(device_t bus, device_t dev,
+ u_int irq);
static device_method_t pci_methods[] = {
/* Device interface */
@@ -147,6 +149,7 @@ static device_method_t pci_methods[] = {
DEVMETHOD(bus_deactivate_resource, pci_deactivate_resource),
DEVMETHOD(bus_child_pnpinfo_str, pci_child_pnpinfo_str_method),
DEVMETHOD(bus_child_location_str, pci_child_location_str_method),
+ DEVMETHOD(bus_remap_intr, pci_remap_intr_method),
/* PCI interface */
DEVMETHOD(pci_read_config, pci_read_config_method),
@@ -1736,21 +1739,18 @@ pci_resume_msi(device_t dev)
2);
}
-int
-pci_remap_msi_irq(device_t dev, u_int irq)
+static int
+pci_remap_intr_method(device_t bus, device_t dev, u_int irq)
{
struct pci_devinfo *dinfo = device_get_ivars(dev);
pcicfgregs *cfg = &dinfo->cfg;
struct resource_list_entry *rle;
struct msix_table_entry *mte;
struct msix_vector *mv;
- device_t bus;
uint64_t addr;
uint32_t data;
int error, i, j;
- bus = device_get_parent(dev);
-
/*
* Handle MSI first. We try to find this IRQ among our list
* of MSI IRQs. If we find it, we request updated address and
diff --git a/sys/dev/pci/pcivar.h b/sys/dev/pci/pcivar.h
index 9483708..d6a2a0e 100644
--- a/sys/dev/pci/pcivar.h
+++ b/sys/dev/pci/pcivar.h
@@ -445,12 +445,6 @@ device_t pci_find_bsf(uint8_t, uint8_t, uint8_t);
device_t pci_find_dbsf(uint32_t, uint8_t, uint8_t, uint8_t);
device_t pci_find_device(uint16_t, uint16_t);
-/*
- * Can be used by MD code to request the PCI bus to re-map an MSI or
- * MSI-X message.
- */
-int pci_remap_msi_irq(device_t dev, u_int irq);
-
/* Can be used by drivers to manage the MSI-X table. */
int pci_pending_msix(device_t dev, u_int index);
diff --git a/sys/kern/bus_if.m b/sys/kern/bus_if.m
index c0924c8..326156e 100644
--- a/sys/kern/bus_if.m
+++ b/sys/kern/bus_if.m
@@ -47,6 +47,15 @@ CODE {
{
return (0);
}
+
+ static int
+ null_remap_intr(device_t bus, device_t dev, u_int irq)
+ {
+
+ if (dev != NULL)
+ return (BUS_REMAP_INTR(dev, NULL, irq));
+ return (ENXIO);
+ }
};
/**
@@ -600,3 +609,16 @@ METHOD void hint_device_unit {
METHOD void new_pass {
device_t _dev;
} DEFAULT bus_generic_new_pass;
+
+/**
+ * @brief Notify a bus that specified child's IRQ should be remapped.
+ *
+ * @param _dev the bus device
+ * @param _child the child device
+ * @param _irq the irq number
+ */
+METHOD int remap_intr {
+ device_t _dev;
+ device_t _child;
+ u_int _irq;
+} DEFAULT null_remap_intr;
diff --git a/sys/x86/x86/msi.c b/sys/x86/x86/msi.c
index 6745ce2..428894e 100644
--- a/sys/x86/x86/msi.c
+++ b/sys/x86/x86/msi.c
@@ -247,7 +247,8 @@ msi_assign_cpu(struct intsrc *isrc, u_int apic_id)
"msi: Assigning MSI IRQ %d to local APIC %u vector %u\n",
sib->msi_irq, sib->msi_cpu, sib->msi_vector);
}
- pci_remap_msi_irq(msi->msi_dev, msi->msi_irq);
+ BUS_REMAP_INTR(device_get_parent(msi->msi_dev), msi->msi_dev,
+ msi->msi_irq);
/*
* Free the old vector after the new one is established. This is done
OpenPOWER on IntegriCloud