Skip to content

Commit

Permalink
powerpc/eeh: Make EEH device add/remove more robust
Browse files Browse the repository at this point in the history
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: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
  • Loading branch information
Benjamin Herrenschmidt authored and Paul Mackerras committed Nov 5, 2008
1 parent 8b8da35 commit 57b066f
Showing 1 changed file with 24 additions and 20 deletions.
44 changes: 24 additions & 20 deletions arch/powerpc/platforms/pseries/eeh.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
* Please address comments and feedback to Linas Vepstas <linas@austin.ibm.com>
*/

#undef DEBUG

#include <linux/delay.h>
#include <linux/init.h>
#include <linux/list.h>
Expand Down Expand Up @@ -488,10 +490,8 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
if (!(pdn->eeh_mode & EEH_MODE_SUPPORTED) ||
pdn->eeh_mode & EEH_MODE_NOCHECK) {
ignored_check++;
#ifdef DEBUG
printk ("EEH:ignored check (%x) for %s %s\n",
pdn->eeh_mode, pci_name (dev), dn->full_name);
#endif
pr_debug("EEH: Ignored check (%x) for %s %s\n",
pdn->eeh_mode, pci_name (dev), dn->full_name);
return 0;
}

Expand Down Expand Up @@ -1014,10 +1014,9 @@ static void *early_enable_eeh(struct device_node *dn, void *data)
eeh_subsystem_enabled = 1;
pdn->eeh_mode |= EEH_MODE_SUPPORTED;

#ifdef DEBUG
printk(KERN_DEBUG "EEH: %s: eeh enabled, config=%x pe_config=%x\n",
dn->full_name, pdn->eeh_config_addr, pdn->eeh_pe_config_addr);
#endif
pr_debug("EEH: %s: eeh enabled, config=%x pe_config=%x\n",
dn->full_name, pdn->eeh_config_addr,
pdn->eeh_pe_config_addr);
} else {

/* This device doesn't support EEH, but it may have an
Expand Down Expand Up @@ -1161,13 +1160,17 @@ static void eeh_add_device_late(struct pci_dev *dev)
if (!dev || !eeh_subsystem_enabled)
return;

#ifdef DEBUG
printk(KERN_DEBUG "EEH: adding device %s\n", pci_name(dev));
#endif
pr_debug("EEH: Adding device %s\n", pci_name(dev));

pci_dev_get (dev);
dn = pci_device_to_OF_node(dev);
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;

pci_addr_cache_insert_device(dev);
Expand Down Expand Up @@ -1206,17 +1209,18 @@ static void eeh_remove_device(struct pci_dev *dev)
return;

/* Unregister the device with the EEH/PCI address search system */
#ifdef DEBUG
printk(KERN_DEBUG "EEH: remove device %s\n", pci_name(dev));
#endif
pci_addr_cache_remove_device(dev);
eeh_sysfs_remove_device(dev);
pr_debug("EEH: Removing device %s\n", pci_name(dev));

dn = pci_device_to_OF_node(dev);
if (PCI_DN(dn)->pcidev) {
PCI_DN(dn)->pcidev = NULL;
pci_dev_put (dev);
if (PCI_DN(dn)->pcidev == NULL) {
pr_debug("EEH: Not referenced !\n");
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)
Expand Down

0 comments on commit 57b066f

Please sign in to comment.