From 9fac14e51fbda70a693d9001fd1ab05d3560cc98 Mon Sep 17 00:00:00 2001 From: iwasaki Date: Wed, 17 Sep 2003 08:32:44 +0000 Subject: Add pci_resume() to reestablish interrupt routing after suspend/resume. Especially after hibernation, interrupt routing went back to initial status on some machines. --- sys/dev/acpica/acpi_pci.c | 2 +- sys/dev/pci/pci.c | 34 +++++++++++++++++++++++++++++++++- sys/dev/pci/pci_private.h | 1 + 3 files changed, 35 insertions(+), 2 deletions(-) (limited to 'sys/dev') diff --git a/sys/dev/acpica/acpi_pci.c b/sys/dev/acpica/acpi_pci.c index b8bf11e..85b6b1c 100644 --- a/sys/dev/acpica/acpi_pci.c +++ b/sys/dev/acpica/acpi_pci.c @@ -79,7 +79,7 @@ static device_method_t acpi_pci_methods[] = { DEVMETHOD(device_attach, acpi_pci_attach), DEVMETHOD(device_shutdown, bus_generic_shutdown), DEVMETHOD(device_suspend, bus_generic_suspend), - DEVMETHOD(device_resume, bus_generic_resume), + DEVMETHOD(device_resume, pci_resume), /* Bus interface */ DEVMETHOD(bus_print_child, pci_print_child), diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c index a4e1a54..a7f320e 100644 --- a/sys/dev/pci/pci.c +++ b/sys/dev/pci/pci.c @@ -89,7 +89,7 @@ static device_method_t pci_methods[] = { DEVMETHOD(device_attach, pci_attach), DEVMETHOD(device_shutdown, bus_generic_shutdown), DEVMETHOD(device_suspend, bus_generic_suspend), - DEVMETHOD(device_resume, bus_generic_resume), + DEVMETHOD(device_resume, pci_resume), /* Bus interface */ DEVMETHOD(bus_print_child, pci_print_child), @@ -1509,3 +1509,35 @@ pci_modevent(module_t mod, int what, void *arg) return (0); } + +int +pci_resume(device_t dev) +{ + int numdevs; + int i; + device_t *children; + device_t child; + struct pci_devinfo *dinfo; + pcicfgregs *cfg; + + device_get_children(dev, &children, &numdevs); + + for (i = 0; i < numdevs; i++) { + child = children[i]; + + dinfo = device_get_ivars(child); + cfg = &dinfo->cfg; + if (cfg->intpin > 0 && PCI_INTERRUPT_VALID(cfg->intline)) { + cfg->intline = PCI_ASSIGN_INTERRUPT(dev, child); + if (PCI_INTERRUPT_VALID(cfg->intline)) { + pci_write_config(child, PCIR_INTLINE, + cfg->intline, 1); + } + } + } + + free(children, M_TEMP); + + return (bus_generic_resume(dev)); +} + diff --git a/sys/dev/pci/pci_private.h b/sys/dev/pci/pci_private.h index 3123c61..816106d 100644 --- a/sys/dev/pci/pci_private.h +++ b/sys/dev/pci/pci_private.h @@ -73,4 +73,5 @@ int pci_child_location_str_method(device_t cbdev, device_t child, 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); +int pci_resume(device_t dev); #endif /* _PCI_PRIVATE_H_ */ -- cgit v1.1