diff options
author | mav <mav@FreeBSD.org> | 2010-06-14 07:10:37 +0000 |
---|---|---|
committer | mav <mav@FreeBSD.org> | 2010-06-14 07:10:37 +0000 |
commit | ea954fa396b041bd7926fa93cc6d5dc99f8e181a (patch) | |
tree | 423ab29863b618eb95213b9452c47472bc992ceb /sys | |
parent | e63e5eff064b854e57039ef919e33a4c0813018d (diff) | |
download | FreeBSD-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.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/pci/pci.c | 10 | ||||
-rw-r--r-- | sys/dev/pci/pcivar.h | 6 | ||||
-rw-r--r-- | sys/kern/bus_if.m | 22 | ||||
-rw-r--r-- | sys/x86/x86/msi.c | 3 |
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 |