diff options
author | David S. Miller <davem@sunset.davemloft.net> | 2007-05-10 03:53:29 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-05-10 03:53:29 -0400 |
commit | aa5242e78f8667ba771e4c0d44bf45871abceb7e (patch) | |
tree | 75ec694e3347e7634a01227c0e431617df07153e /arch/sparc64/kernel/prom.c | |
parent | 7cc5c8559c62289d027812bfdd4eb6a28c5769b6 (diff) |
[SPARC64]: Fix recursion in PROM tree building.
Use iteration for scanning of PROM node siblings.
Based upon a patch by Greg Onufer, who found this bug.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc64/kernel/prom.c')
-rw-r--r-- | arch/sparc64/kernel/prom.c | 19 |
1 files changed, 15 insertions, 4 deletions
diff --git a/arch/sparc64/kernel/prom.c b/arch/sparc64/kernel/prom.c index c54d4d8af014..b7976b14d0ba 100644 --- a/arch/sparc64/kernel/prom.c +++ b/arch/sparc64/kernel/prom.c | |||
@@ -1636,10 +1636,21 @@ static struct device_node * __init create_node(phandle node, struct device_node | |||
1636 | 1636 | ||
1637 | static struct device_node * __init build_tree(struct device_node *parent, phandle node, struct device_node ***nextp) | 1637 | static struct device_node * __init build_tree(struct device_node *parent, phandle node, struct device_node ***nextp) |
1638 | { | 1638 | { |
1639 | struct device_node *ret = NULL, *prev_sibling = NULL; | ||
1639 | struct device_node *dp; | 1640 | struct device_node *dp; |
1640 | 1641 | ||
1641 | dp = create_node(node, parent); | 1642 | while (1) { |
1642 | if (dp) { | 1643 | dp = create_node(node, parent); |
1644 | if (!dp) | ||
1645 | break; | ||
1646 | |||
1647 | if (prev_sibling) | ||
1648 | prev_sibling->sibling = dp; | ||
1649 | |||
1650 | if (!ret) | ||
1651 | ret = dp; | ||
1652 | prev_sibling = dp; | ||
1653 | |||
1643 | *(*nextp) = dp; | 1654 | *(*nextp) = dp; |
1644 | *nextp = &dp->allnext; | 1655 | *nextp = &dp->allnext; |
1645 | 1656 | ||
@@ -1648,10 +1659,10 @@ static struct device_node * __init build_tree(struct device_node *parent, phandl | |||
1648 | 1659 | ||
1649 | dp->child = build_tree(dp, prom_getchild(node), nextp); | 1660 | dp->child = build_tree(dp, prom_getchild(node), nextp); |
1650 | 1661 | ||
1651 | dp->sibling = build_tree(parent, prom_getsibling(node), nextp); | 1662 | node = prom_getsibling(node); |
1652 | } | 1663 | } |
1653 | 1664 | ||
1654 | return dp; | 1665 | return ret; |
1655 | } | 1666 | } |
1656 | 1667 | ||
1657 | void __init prom_build_devicetree(void) | 1668 | void __init prom_build_devicetree(void) |