diff options
author | tmm <tmm@FreeBSD.org> | 2003-07-01 14:08:33 +0000 |
---|---|---|
committer | tmm <tmm@FreeBSD.org> | 2003-07-01 14:08:33 +0000 |
commit | e8331fe2626d7026214cc367d516271b160e1eb0 (patch) | |
tree | b5480064abfcffaff06714c0eb461a58c67df3b6 /sys/dev | |
parent | 18ac6e463e26994f023ddbddfd54825f2a1c7a92 (diff) | |
download | FreeBSD-src-e8331fe2626d7026214cc367d516271b160e1eb0.zip FreeBSD-src-e8331fe2626d7026214cc367d516271b160e1eb0.tar.gz |
Add a new PCI interface method, assign_interrupt, to determine the
interrupt to be used for a device. This is intended solely for internal
use of PCI bus implementations, and exists so that PCI bus drivers
implementing special interrupt assignment methods which require
additional work at the bus level to work right can be easily derived
from the generic driver (or any other one) without resorting to hacks.
It will be used in the sparc64 ofw_pcibus driver, which will be
committed shortly.
Make use of this method in the generic implementation, and add it to
the method table of bus drivers derived from the PCI one.
Reviewed by: imp, -hackers
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/acpica/acpi_pci.c | 1 | ||||
-rw-r--r-- | sys/dev/cardbus/cardbus.c | 1 | ||||
-rw-r--r-- | sys/dev/pci/pci.c | 23 | ||||
-rw-r--r-- | sys/dev/pci/pci_if.m | 5 | ||||
-rw-r--r-- | sys/dev/pci/pci_private.h | 1 |
5 files changed, 25 insertions, 6 deletions
diff --git a/sys/dev/acpica/acpi_pci.c b/sys/dev/acpica/acpi_pci.c index 2448b62..04319b6 100644 --- a/sys/dev/acpica/acpi_pci.c +++ b/sys/dev/acpica/acpi_pci.c @@ -111,6 +111,7 @@ static device_method_t acpi_pci_methods[] = { /* XXX: We should override these two. */ DEVMETHOD(pci_get_powerstate, pci_get_powerstate_method), DEVMETHOD(pci_set_powerstate, pci_set_powerstate_method), + DEVMETHOD(pci_assign_interrupt, pci_assign_interrupt_method), { 0, 0 } }; diff --git a/sys/dev/cardbus/cardbus.c b/sys/dev/cardbus/cardbus.c index 1559712..5c34c85 100644 --- a/sys/dev/cardbus/cardbus.c +++ b/sys/dev/cardbus/cardbus.c @@ -387,6 +387,7 @@ static device_method_t cardbus_methods[] = { DEVMETHOD(pci_disable_io, pci_disable_io_method), DEVMETHOD(pci_get_powerstate, pci_get_powerstate_method), DEVMETHOD(pci_set_powerstate, pci_set_powerstate_method), + DEVMETHOD(pci_assign_interrupt, pci_assign_interrupt_method), {0,0} }; diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c index 71865a8..f4681f1 100644 --- a/sys/dev/pci/pci.c +++ b/sys/dev/pci/pci.c @@ -70,7 +70,8 @@ static int pci_porten(device_t pcib, int b, int s, int f); static int pci_memen(device_t pcib, int b, int s, int f); static int pci_add_map(device_t pcib, int b, int s, int f, int reg, struct resource_list *rl); -static void pci_add_resources(device_t pcib, device_t dev); +static void pci_add_resources(device_t pcib, device_t bus, + device_t dev); static int pci_probe(device_t dev); static int pci_attach(device_t dev); static void pci_load_vendor_data(void); @@ -119,6 +120,7 @@ static device_method_t pci_methods[] = { DEVMETHOD(pci_disable_io, pci_disable_io_method), DEVMETHOD(pci_get_powerstate, pci_get_powerstate_method), DEVMETHOD(pci_set_powerstate, pci_set_powerstate_method), + DEVMETHOD(pci_assign_interrupt, pci_assign_interrupt_method), { 0, 0 } }; @@ -776,7 +778,7 @@ pci_add_map(device_t pcib, int b, int s, int f, int reg, } static void -pci_add_resources(device_t pcib, device_t dev) +pci_add_resources(device_t pcib, device_t bus, device_t dev) { struct pci_devinfo *dinfo = device_get_ivars(dev); pcicfgregs *cfg = &dinfo->cfg; @@ -805,7 +807,7 @@ pci_add_resources(device_t pcib, device_t dev) * If the re-route fails, then just stick with what we * have. */ - irq = PCIB_ROUTE_INTERRUPT(pcib, dev, cfg->intpin); + irq = PCI_ASSIGN_INTERRUPT(bus, dev); if (PCI_INTERRUPT_VALID(irq)) { pci_write_config(dev, PCIR_INTLINE, irq, 1); cfg->intline = irq; @@ -855,7 +857,7 @@ pci_add_child(device_t bus, struct pci_devinfo *dinfo) pcib = device_get_parent(bus); dinfo->cfg.dev = device_add_child(bus, NULL, -1); device_set_ivars(dinfo->cfg.dev, dinfo); - pci_add_resources(pcib, dinfo->cfg.dev); + pci_add_resources(pcib, bus, dinfo->cfg.dev); pci_print_verbose(dinfo); } @@ -1356,8 +1358,7 @@ pci_alloc_resource(device_t dev, device_t child, int type, int *rid, */ if (!PCI_INTERRUPT_VALID(cfg->intline) && (cfg->intpin != 0)) { - cfg->intline = PCIB_ROUTE_INTERRUPT( - device_get_parent(dev), child, cfg->intpin); + cfg->intline = PCI_ASSIGN_INTERRUPT(dev, child); if (PCI_INTERRUPT_VALID(cfg->intline)) { pci_write_config(child, PCIR_INTLINE, cfg->intline, 1); @@ -1479,6 +1480,16 @@ pci_child_pnpinfo_str_method(device_t cbdev, device_t child, char *buf, return (0); } +int +pci_assign_interrupt_method(device_t dev, device_t child) +{ + struct pci_devinfo *dinfo = device_get_ivars(child); + pcicfgregs *cfg = &dinfo->cfg; + + return (PCIB_ROUTE_INTERRUPT(device_get_parent(dev), child, + cfg->intpin)); +} + static int pci_modevent(module_t mod, int what, void *arg) { diff --git a/sys/dev/pci/pci_if.m b/sys/dev/pci/pci_if.m index bd19565..635005d 100644 --- a/sys/dev/pci/pci_if.m +++ b/sys/dev/pci/pci_if.m @@ -77,3 +77,8 @@ METHOD int disable_io { device_t child; int space; }; + +METHOD int assign_interrupt { + device_t dev; + device_t child; +}; diff --git a/sys/dev/pci/pci_private.h b/sys/dev/pci/pci_private.h index f0387d0..fb85e60 100644 --- a/sys/dev/pci/pci_private.h +++ b/sys/dev/pci/pci_private.h @@ -72,4 +72,5 @@ int pci_child_location_str_method(device_t cbdev, device_t child, char *buf, size_t buflen); int pci_child_pnpinfo_str_method(device_t cbdev, device_t child, char *buf, size_t buflen); +int pci_assign_interrupt_method(device_t dev, device_t child); #endif /* _PCI_PRIVATE_H_ */ |