Commit 57b066ff authored by Benjamin Herrenschmidt's avatar Benjamin Herrenschmidt Committed by Paul Mackerras

powerpc/eeh: Make EEH device add/remove more robust

To properly fix PCI hotplug, it's useful to be able to make the fixup
passes on all devices whether they were just hot plugged or already
there.

The EEH code however used to not be very friendly with calling
eeh_add_device_late() multiple time, and not very rebust in the way it
generally tests whether a device is in the expected state vs. the EEH
code.

This improves it, along with cleaning up a couple of debug printk's.
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
parent 8b8da358
...@@ -21,6 +21,8 @@ ...@@ -21,6 +21,8 @@
* Please address comments and feedback to Linas Vepstas <linas@austin.ibm.com> * Please address comments and feedback to Linas Vepstas <linas@austin.ibm.com>
*/ */
#undef DEBUG
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/list.h> #include <linux/list.h>
...@@ -488,10 +490,8 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev) ...@@ -488,10 +490,8 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
if (!(pdn->eeh_mode & EEH_MODE_SUPPORTED) || if (!(pdn->eeh_mode & EEH_MODE_SUPPORTED) ||
pdn->eeh_mode & EEH_MODE_NOCHECK) { pdn->eeh_mode & EEH_MODE_NOCHECK) {
ignored_check++; ignored_check++;
#ifdef DEBUG pr_debug("EEH: Ignored check (%x) for %s %s\n",
printk ("EEH:ignored check (%x) for %s %s\n", pdn->eeh_mode, pci_name (dev), dn->full_name);
pdn->eeh_mode, pci_name (dev), dn->full_name);
#endif
return 0; return 0;
} }
...@@ -1014,10 +1014,9 @@ static void *early_enable_eeh(struct device_node *dn, void *data) ...@@ -1014,10 +1014,9 @@ static void *early_enable_eeh(struct device_node *dn, void *data)
eeh_subsystem_enabled = 1; eeh_subsystem_enabled = 1;
pdn->eeh_mode |= EEH_MODE_SUPPORTED; pdn->eeh_mode |= EEH_MODE_SUPPORTED;
#ifdef DEBUG pr_debug("EEH: %s: eeh enabled, config=%x pe_config=%x\n",
printk(KERN_DEBUG "EEH: %s: eeh enabled, config=%x pe_config=%x\n", dn->full_name, pdn->eeh_config_addr,
dn->full_name, pdn->eeh_config_addr, pdn->eeh_pe_config_addr); pdn->eeh_pe_config_addr);
#endif
} else { } else {
/* This device doesn't support EEH, but it may have an /* This device doesn't support EEH, but it may have an
...@@ -1161,13 +1160,17 @@ static void eeh_add_device_late(struct pci_dev *dev) ...@@ -1161,13 +1160,17 @@ static void eeh_add_device_late(struct pci_dev *dev)
if (!dev || !eeh_subsystem_enabled) if (!dev || !eeh_subsystem_enabled)
return; return;
#ifdef DEBUG pr_debug("EEH: Adding device %s\n", pci_name(dev));
printk(KERN_DEBUG "EEH: adding device %s\n", pci_name(dev));
#endif
pci_dev_get (dev);
dn = pci_device_to_OF_node(dev); dn = pci_device_to_OF_node(dev);
pdn = PCI_DN(dn); pdn = PCI_DN(dn);
if (pdn->pcidev == dev) {
pr_debug("EEH: Already referenced !\n");
return;
}
WARN_ON(pdn->pcidev);
pci_dev_get (dev);
pdn->pcidev = dev; pdn->pcidev = dev;
pci_addr_cache_insert_device(dev); pci_addr_cache_insert_device(dev);
...@@ -1206,17 +1209,18 @@ static void eeh_remove_device(struct pci_dev *dev) ...@@ -1206,17 +1209,18 @@ static void eeh_remove_device(struct pci_dev *dev)
return; return;
/* Unregister the device with the EEH/PCI address search system */ /* Unregister the device with the EEH/PCI address search system */
#ifdef DEBUG pr_debug("EEH: Removing device %s\n", pci_name(dev));
printk(KERN_DEBUG "EEH: remove device %s\n", pci_name(dev));
#endif
pci_addr_cache_remove_device(dev);
eeh_sysfs_remove_device(dev);
dn = pci_device_to_OF_node(dev); dn = pci_device_to_OF_node(dev);
if (PCI_DN(dn)->pcidev) { if (PCI_DN(dn)->pcidev == NULL) {
PCI_DN(dn)->pcidev = NULL; pr_debug("EEH: Not referenced !\n");
pci_dev_put (dev); return;
} }
PCI_DN(dn)->pcidev = NULL;
pci_dev_put (dev);
pci_addr_cache_remove_device(dev);
eeh_sysfs_remove_device(dev);
} }
void eeh_remove_bus_device(struct pci_dev *dev) void eeh_remove_bus_device(struct pci_dev *dev)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment