forked from Minki/linux
[PATCH] ppc64: PCI device-node failure detection
OpenFirmware marks devices as failed in the device-tree when a hardware problem is detected. The kernel needs to fail config reads/writes to prevent a kernel crash when incorrect data is read. This patch validates that the device-node is not marked "fail" when config space reads/writes are attempted. Signed-off-by: Jake Moilanen <moilanen@austin.ibm.com> Signed-off-by: Paul Mackerras <paulus@samba.org>
This commit is contained in:
parent
34153fa3af
commit
293da76b3d
@ -58,6 +58,21 @@ static int config_access_valid(struct device_node *dn, int where)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int of_device_available(struct device_node * dn)
|
||||||
|
{
|
||||||
|
char * status;
|
||||||
|
|
||||||
|
status = get_property(dn, "status", NULL);
|
||||||
|
|
||||||
|
if (!status)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (!strcmp(status, "okay"))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int rtas_read_config(struct device_node *dn, int where, int size, u32 *val)
|
static int rtas_read_config(struct device_node *dn, int where, int size, u32 *val)
|
||||||
{
|
{
|
||||||
int returnval = -1;
|
int returnval = -1;
|
||||||
@ -103,7 +118,7 @@ static int rtas_pci_read_config(struct pci_bus *bus,
|
|||||||
|
|
||||||
/* Search only direct children of the bus */
|
/* Search only direct children of the bus */
|
||||||
for (dn = busdn->child; dn; dn = dn->sibling)
|
for (dn = busdn->child; dn; dn = dn->sibling)
|
||||||
if (dn->devfn == devfn)
|
if (dn->devfn == devfn && of_device_available(dn))
|
||||||
return rtas_read_config(dn, where, size, val);
|
return rtas_read_config(dn, where, size, val);
|
||||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||||
}
|
}
|
||||||
@ -146,7 +161,7 @@ static int rtas_pci_write_config(struct pci_bus *bus,
|
|||||||
|
|
||||||
/* Search only direct children of the bus */
|
/* Search only direct children of the bus */
|
||||||
for (dn = busdn->child; dn; dn = dn->sibling)
|
for (dn = busdn->child; dn; dn = dn->sibling)
|
||||||
if (dn->devfn == devfn)
|
if (dn->devfn == devfn && of_device_available(dn))
|
||||||
return rtas_write_config(dn, where, size, val);
|
return rtas_write_config(dn, where, size, val);
|
||||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user