Commit 293da76b authored by Jake Moilanen's avatar Jake Moilanen Committed by Paul Mackerras

[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: default avatarJake Moilanen <moilanen@austin.ibm.com>
Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
parent 34153fa3
...@@ -58,6 +58,21 @@ static int config_access_valid(struct device_node *dn, int where) ...@@ -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, ...@@ -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, ...@@ -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;
} }
......
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