summaryrefslogtreecommitdiffstats
path: root/sys/dev
diff options
context:
space:
mode:
authortmm <tmm@FreeBSD.org>2003-07-01 14:08:33 +0000
committertmm <tmm@FreeBSD.org>2003-07-01 14:08:33 +0000
commite8331fe2626d7026214cc367d516271b160e1eb0 (patch)
treeb5480064abfcffaff06714c0eb461a58c67df3b6 /sys/dev
parent18ac6e463e26994f023ddbddfd54825f2a1c7a92 (diff)
downloadFreeBSD-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.c1
-rw-r--r--sys/dev/cardbus/cardbus.c1
-rw-r--r--sys/dev/pci/pci.c23
-rw-r--r--sys/dev/pci/pci_if.m5
-rw-r--r--sys/dev/pci/pci_private.h1
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_ */
OpenPOWER on IntegriCloud