struct pci_dev;
struct pci_bus;
-struct device_node;
struct pci_dn;
#ifdef CONFIG_EEH
struct eeh_pe *pe; /* Associated PE */
struct list_head list; /* Form link list in the PE */
struct pci_controller *phb; /* Associated PHB */
- struct device_node *dn; /* Associated device node */
struct pci_dn *pdn; /* Associated PCI device node */
struct pci_dev *pdev; /* Associated PCI device */
struct pci_bus *bus; /* PCI bus for partial hotplug */
};
-static inline struct device_node *eeh_dev_to_of_node(struct eeh_dev *edev)
-{
- return edev ? edev->dn : NULL;
-}
-
static inline struct pci_dn *eeh_dev_to_pdn(struct eeh_dev *edev)
{
return edev ? edev->pdn : NULL;
}
#if defined(CONFIG_EEH)
-static inline struct eeh_dev *of_node_to_eeh_dev(struct device_node *dn)
-{
- /*
- * For those OF nodes whose parent isn't PCI bridge, they
- * don't have PCI_DN actually. So we have to skip them for
- * any EEH operations.
- */
- if (!dn || !PCI_DN(dn))
- return NULL;
-
- return PCI_DN(dn)->edev;
-}
-
static inline struct eeh_dev *pdn_to_eeh_dev(struct pci_dn *pdn)
{
return pdn ? pdn->edev : NULL;
}
#else
-#define of_node_to_eeh_dev(x) (NULL)
#define pdn_to_eeh_dev(x) (NULL)
#endif
int ret;
int active_flags = (EEH_STATE_MMIO_ACTIVE | EEH_STATE_DMA_ACTIVE);
unsigned long flags;
- struct device_node *dn;
+ struct pci_dn *pdn;
struct pci_dev *dev;
struct eeh_pe *pe, *parent_pe, *phb_pe;
int rc = 0;
- const char *location;
+ const char *location = NULL;
eeh_stats.total_mmio_ffs++;
eeh_stats.no_dn++;
return 0;
}
- dn = eeh_dev_to_of_node(edev);
dev = eeh_dev_to_pci_dev(edev);
pe = eeh_dev_to_pe(edev);
/* Access to IO BARs might get this far and still not want checking. */
if (!pe) {
eeh_stats.ignored_check++;
- pr_debug("EEH: Ignored check for %s %s\n",
- eeh_pci_name(dev), dn->full_name);
+ pr_debug("EEH: Ignored check for %s\n",
+ eeh_pci_name(dev));
return 0;
}
if (pe->state & EEH_PE_ISOLATED) {
pe->check_count++;
if (pe->check_count % EEH_MAX_FAILS == 0) {
- location = of_get_property(dn, "ibm,loc-code", NULL);
+ pdn = eeh_dev_to_pdn(edev);
+ if (pdn->node)
+ location = of_get_property(pdn->node, "ibm,loc-code", NULL);
printk(KERN_ERR "EEH: %d reads ignored for recovering device at "
"location=%s driver=%s pci addr=%s\n",
- pe->check_count, location,
+ pe->check_count,
+ location ? location : "unknown",
eeh_driver_name(dev), eeh_pci_name(dev));
printk(KERN_ERR "EEH: Might be infinite loop in %s driver\n",
eeh_driver_name(dev));
core_initcall_sync(eeh_init);
/**
- * eeh_add_device_early - Enable EEH for the indicated device_node
+ * eeh_add_device_early - Enable EEH for the indicated device node
* @pdn: PCI device node for which to set up EEH
*
* This routine must be used to perform EEH initialization for PCI
*/
void eeh_add_device_late(struct pci_dev *dev)
{
- struct device_node *dn;
+ struct pci_dn *pdn;
struct eeh_dev *edev;
if (!dev || !eeh_enabled())
pr_debug("EEH: Adding device %s\n", pci_name(dev));
- dn = pci_device_to_OF_node(dev);
- edev = of_node_to_eeh_dev(dn);
+ pdn = pci_get_pdn_by_devfn(dev->bus, dev->devfn);
+ edev = pdn_to_eeh_dev(pdn);
if (edev->pdev == dev) {
pr_debug("EEH: Already referenced !\n");
return;
static void __eeh_addr_cache_insert_dev(struct pci_dev *dev)
{
- struct device_node *dn;
+ struct pci_dn *pdn;
struct eeh_dev *edev;
int i;
- dn = pci_device_to_OF_node(dev);
- if (!dn) {
+ pdn = pci_get_pdn_by_devfn(dev->bus, dev->devfn);
+ if (!pdn) {
pr_warn("PCI: no pci dn found for dev=%s\n",
pci_name(dev));
return;
}
- edev = of_node_to_eeh_dev(dn);
+ edev = pdn_to_eeh_dev(pdn);
if (!edev) {
- pr_warn("PCI: no EEH dev found for dn=%s\n",
- dn->full_name);
+ pr_warn("PCI: no EEH dev found for %s\n",
+ pci_name(dev));
return;
}
/* Skip any devices for which EEH is not enabled. */
if (!edev->pe) {
-#ifdef DEBUG
- pr_info("PCI: skip building address cache for=%s - %s\n",
- pci_name(dev), dn->full_name);
-#endif
+ dev_dbg(&dev->dev, "EEH: Skip building address cache\n");
return;
}
*/
void eeh_addr_cache_build(void)
{
- struct device_node *dn;
+ struct pci_dn *pdn;
struct eeh_dev *edev;
struct pci_dev *dev = NULL;
spin_lock_init(&pci_io_addr_cache_root.piar_lock);
for_each_pci_dev(dev) {
- dn = pci_device_to_OF_node(dev);
- if (!dn)
+ pdn = pci_get_pdn_by_devfn(dev->bus, dev->devfn);
+ if (!pdn)
continue;
- edev = of_node_to_eeh_dev(dn);
+ edev = pdn_to_eeh_dev(pdn);
if (!edev)
continue;
module_put(pdev->driver->driver.owner);
}
-#if 0
-static void print_device_node_tree(struct pci_dn *pdn, int dent)
-{
- int i;
- struct device_node *pc;
-
- if (!pdn)
- return;
- for (i = 0; i < dent; i++)
- printk(" ");
- printk("dn=%s mode=%x \tcfg_addr=%x pe_addr=%x \tfull=%s\n",
- pdn->node->name, pdn->eeh_mode, pdn->eeh_config_addr,
- pdn->eeh_pe_config_addr, pdn->node->full_name);
- dent += 3;
- pc = pdn->node->child;
- while (pc) {
- print_device_node_tree(PCI_DN(pc), dent);
- pc = pc->sibling;
- }
-}
-#endif
-
/**
* eeh_disable_irq - Disable interrupt for the recovering device
* @dev: PCI device
/* Put the edev to PE */
list_add_tail(&edev->list, &pe->edevs);
- pr_debug("EEH: Add %s to Bus PE#%x\n",
- edev->dn->full_name, pe->addr);
-
+ pr_debug("EEH: Add %04x:%02x:%02x.%01x to Bus PE#%x\n",
+ edev->phb->global_number,
+ edev->config_addr >> 8,
+ PCI_SLOT(edev->config_addr & 0xFF),
+ PCI_FUNC(edev->config_addr & 0xFF),
+ pe->addr);
return 0;
} else if (pe && (pe->type & EEH_PE_INVALID)) {
list_add_tail(&edev->list, &pe->edevs);
parent->type &= ~(EEH_PE_INVALID | EEH_PE_KEEP);
parent = parent->parent;
}
- pr_debug("EEH: Add %s to Device PE#%x, Parent PE#%x\n",
- edev->dn->full_name, pe->addr, pe->parent->addr);
+ pr_debug("EEH: Add %04x:%02x:%02x.%01x to Device "
+ "PE#%x, Parent PE#%x\n",
+ edev->phb->global_number,
+ edev->config_addr >> 8,
+ PCI_SLOT(edev->config_addr & 0xFF),
+ PCI_FUNC(edev->config_addr & 0xFF),
+ pe->addr, pe->parent->addr);
return 0;
}
list_add_tail(&pe->child, &parent->child_list);
list_add_tail(&edev->list, &pe->edevs);
edev->pe = pe;
- pr_debug("EEH: Add %s to Device PE#%x, Parent PE#%x\n",
- edev->dn->full_name, pe->addr, pe->parent->addr);
+ pr_debug("EEH: Add %04x:%02x:%02x.%01x to "
+ "Device PE#%x, Parent PE#%x\n",
+ edev->phb->global_number,
+ edev->config_addr >> 8,
+ PCI_SLOT(edev->config_addr & 0xFF),
+ PCI_FUNC(edev->config_addr & 0xFF),
+ pe->addr, pe->parent->addr);
return 0;
}
int cnt;
if (!edev->pe) {
- pr_debug("%s: No PE found for EEH device %s\n",
- __func__, edev->dn->full_name);
+ pr_debug("%s: No PE found for device %04x:%02x:%02x.%01x\n",
+ __func__, edev->phb->global_number,
+ edev->config_addr >> 8,
+ PCI_SLOT(edev->config_addr & 0xFF),
+ PCI_FUNC(edev->config_addr & 0xFF));
return -EEXIST;
}
const __be32 *reg;
int reglen, devfn;
#ifdef CONFIG_EEH
- struct eeh_dev *edev = of_node_to_eeh_dev(dn);
+ struct eeh_dev *edev = pdn_to_eeh_dev(PCI_DN(dn));
#endif
pr_debug(" * %s\n", dn->full_name);
ret = rtas_read_config(pdn, where, size, val);
if (*val == EEH_IO_ERROR_VALUE(size) &&
- eeh_dev_check_failure(of_node_to_eeh_dev(dn)))
+ eeh_dev_check_failure(pdn_to_eeh_dev(pdn)))
return PCIBIOS_DEVICE_NOT_FOUND;
return ret;
static struct device_node *find_pe_dn(struct pci_dev *dev, int *total)
{
struct device_node *dn;
+ struct pci_dn *pdn;
struct eeh_dev *edev;
/* Found our PE and assume 8 at that point. */
return NULL;
/* Get the top level device in the PE */
- edev = of_node_to_eeh_dev(dn);
+ edev = pdn_to_eeh_dev(PCI_DN(dn));
if (edev->pe)
edev = list_first_entry(&edev->pe->edevs, struct eeh_dev, list);
- dn = eeh_dev_to_of_node(edev);
+ pdn = eeh_dev_to_pdn(edev);
+ dn = pdn ? pdn->node : NULL;
if (!dn)
return NULL;