Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 8053
b: refs/heads/master
c: 1635317
h: refs/heads/master
i:
  8051: 604f3e7
v: v3
  • Loading branch information
Paul Mackerras committed Sep 9, 2005
1 parent 1d51cee commit b87d2d2
Show file tree
Hide file tree
Showing 20 changed files with 210 additions and 138 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: b28d2582ce8aafe531d909bb9c4dcf29189e786e
refs/heads/master: 1635317facea3094ddf34082cd86797efb1d9f7e
55 changes: 32 additions & 23 deletions trunk/arch/ppc64/kernel/eeh.c
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,7 @@ pci_addr_cache_insert(struct pci_dev *dev, unsigned long alo,
static void __pci_addr_cache_insert_device(struct pci_dev *dev)
{
struct device_node *dn;
struct pci_dn *pdn;
int i;
int inserted = 0;

Expand All @@ -265,8 +266,9 @@ static void __pci_addr_cache_insert_device(struct pci_dev *dev)
}

/* Skip any devices for which EEH is not enabled. */
if (!(dn->eeh_mode & EEH_MODE_SUPPORTED) ||
dn->eeh_mode & EEH_MODE_NOCHECK) {
pdn = dn->data;
if (!(pdn->eeh_mode & EEH_MODE_SUPPORTED) ||
pdn->eeh_mode & EEH_MODE_NOCHECK) {
#ifdef DEBUG
printk(KERN_INFO "PCI: skip building address cache for=%s\n",
pci_name(dev));
Expand Down Expand Up @@ -415,6 +417,7 @@ int eeh_unregister_notifier(struct notifier_block *nb)
static int read_slot_reset_state(struct device_node *dn, int rets[])
{
int token, outputs;
struct pci_dn *pdn = dn->data;

if (ibm_read_slot_reset_state2 != RTAS_UNKNOWN_SERVICE) {
token = ibm_read_slot_reset_state2;
Expand All @@ -424,8 +427,8 @@ static int read_slot_reset_state(struct device_node *dn, int rets[])
outputs = 3;
}

return rtas_call(token, 3, outputs, rets, dn->eeh_config_addr,
BUID_HI(dn->phb->buid), BUID_LO(dn->phb->buid));
return rtas_call(token, 3, outputs, rets, pdn->eeh_config_addr,
BUID_HI(pdn->phb->buid), BUID_LO(pdn->phb->buid));
}

/**
Expand Down Expand Up @@ -534,6 +537,7 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
unsigned long flags;
int rc, reset_state;
struct eeh_event *event;
struct pci_dn *pdn;

__get_cpu_var(total_mmio_ffs)++;

Expand All @@ -542,22 +546,23 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)

if (!dn)
return 0;
pdn = dn->data;

/* Access to IO BARs might get this far and still not want checking. */
if (!(dn->eeh_mode & EEH_MODE_SUPPORTED) ||
dn->eeh_mode & EEH_MODE_NOCHECK) {
if (!pdn->eeh_capable || !(pdn->eeh_mode & EEH_MODE_SUPPORTED) ||
pdn->eeh_mode & EEH_MODE_NOCHECK) {
return 0;
}

if (!dn->eeh_config_addr) {
if (!pdn->eeh_config_addr) {
return 0;
}

/*
* If we already have a pending isolation event for this
* slot, we know it's bad already, we don't need to check...
*/
if (dn->eeh_mode & EEH_MODE_ISOLATED) {
if (pdn->eeh_mode & EEH_MODE_ISOLATED) {
atomic_inc(&eeh_fail_count);
if (atomic_read(&eeh_fail_count) >= EEH_MAX_FAILS) {
/* re-read the slot reset state */
Expand All @@ -582,17 +587,17 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
}

/* prevent repeated reports of this failure */
dn->eeh_mode |= EEH_MODE_ISOLATED;
pdn->eeh_mode |= EEH_MODE_ISOLATED;

reset_state = rets[0];

spin_lock_irqsave(&slot_errbuf_lock, flags);
memset(slot_errbuf, 0, eeh_error_buf_size);

rc = rtas_call(ibm_slot_error_detail,
8, 1, NULL, dn->eeh_config_addr,
BUID_HI(dn->phb->buid),
BUID_LO(dn->phb->buid), NULL, 0,
8, 1, NULL, pdn->eeh_config_addr,
BUID_HI(pdn->phb->buid),
BUID_LO(pdn->phb->buid), NULL, 0,
virt_to_phys(slot_errbuf),
eeh_error_buf_size,
1 /* Temporary Error */);
Expand Down Expand Up @@ -679,8 +684,9 @@ static void *early_enable_eeh(struct device_node *dn, void *data)
u32 *device_id = (u32 *)get_property(dn, "device-id", NULL);
u32 *regs;
int enable;
struct pci_dn *pdn = dn->data;

dn->eeh_mode = 0;
pdn->eeh_mode = 0;

if (status && strcmp(status, "ok") != 0)
return NULL; /* ignore devices with bad status */
Expand All @@ -691,7 +697,7 @@ static void *early_enable_eeh(struct device_node *dn, void *data)

/* There is nothing to check on PCI to ISA bridges */
if (dn->type && !strcmp(dn->type, "isa")) {
dn->eeh_mode |= EEH_MODE_NOCHECK;
pdn->eeh_mode |= EEH_MODE_NOCHECK;
return NULL;
}

Expand All @@ -708,7 +714,7 @@ static void *early_enable_eeh(struct device_node *dn, void *data)
enable = 0;

if (!enable)
dn->eeh_mode |= EEH_MODE_NOCHECK;
pdn->eeh_mode |= EEH_MODE_NOCHECK;

/* Ok... see if this device supports EEH. Some do, some don't,
* and the only way to find out is to check each and every one. */
Expand All @@ -721,19 +727,20 @@ static void *early_enable_eeh(struct device_node *dn, void *data)
EEH_ENABLE);
if (ret == 0) {
eeh_subsystem_enabled = 1;
dn->eeh_mode |= EEH_MODE_SUPPORTED;
dn->eeh_config_addr = regs[0];
pdn->eeh_mode |= EEH_MODE_SUPPORTED;
pdn->eeh_config_addr = regs[0];
#ifdef DEBUG
printk(KERN_DEBUG "EEH: %s: eeh enabled\n", dn->full_name);
#endif
} else {

/* This device doesn't support EEH, but it may have an
* EEH parent, in which case we mark it as supported. */
if (dn->parent && (dn->parent->eeh_mode & EEH_MODE_SUPPORTED)) {
if (dn->parent && dn->parent->data
&& (PCI_DN(dn->parent)->eeh_mode & EEH_MODE_SUPPORTED)) {
/* Parent supports EEH. */
dn->eeh_mode |= EEH_MODE_SUPPORTED;
dn->eeh_config_addr = dn->parent->eeh_config_addr;
pdn->eeh_mode |= EEH_MODE_SUPPORTED;
pdn->eeh_config_addr = PCI_DN(dn->parent)->eeh_config_addr;
return NULL;
}
}
Expand Down Expand Up @@ -790,11 +797,13 @@ void __init eeh_init(void)
for (phb = of_find_node_by_name(NULL, "pci"); phb;
phb = of_find_node_by_name(phb, "pci")) {
unsigned long buid;
struct pci_dn *pci;

buid = get_phb_buid(phb);
if (buid == 0)
if (buid == 0 || phb->data == NULL)
continue;

pci = phb->data;
info.buid_lo = BUID_LO(buid);
info.buid_hi = BUID_HI(buid);
traverse_pci_devices(phb, early_enable_eeh, &info);
Expand Down Expand Up @@ -823,9 +832,9 @@ void eeh_add_device_early(struct device_node *dn)
struct pci_controller *phb;
struct eeh_early_enable_info info;

if (!dn)
if (!dn || !dn->data)
return;
phb = dn->phb;
phb = PCI_DN(dn)->phb;
if (NULL == phb || 0 == phb->buid) {
printk(KERN_WARNING "EEH: Expected buid but found none\n");
return;
Expand Down
3 changes: 2 additions & 1 deletion trunk/arch/ppc64/kernel/iommu.c
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,8 @@ struct iommu_table *iommu_init_table(struct iommu_table *tbl)

void iommu_free_table(struct device_node *dn)
{
struct iommu_table *tbl = dn->iommu_table;
struct pci_dn *pdn = dn->data;
struct iommu_table *tbl = pdn->iommu_table;
unsigned long bitmap_sz, i;
unsigned int order;

Expand Down
4 changes: 2 additions & 2 deletions trunk/arch/ppc64/kernel/maple_pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -447,9 +447,9 @@ void __init maple_pci_init(void)
*/
if (u3_agp) {
struct device_node *np = u3_agp->arch_data;
np->busno = 0xf0;
PCI_DN(np)->busno = 0xf0;
for (np = np->child; np; np = np->sibling)
np->busno = 0xf0;
PCI_DN(np)->busno = 0xf0;
}

/* Tell pci.c to use the common resource allocation mecanism */
Expand Down
Loading

0 comments on commit b87d2d2

Please sign in to comment.