aboutsummaryrefslogtreecommitdiffstats
path: root/xen/common/device_tree.c
diff options
context:
space:
mode:
authorDavid Vrabel <david.vrabel@citrix.com>2012-04-02 16:50:44 +0100
committerDavid Vrabel <david.vrabel@citrix.com>2012-04-02 16:50:44 +0100
commitae0a90bd8c2683e53f472854fa89ec3cb74c9ddb (patch)
tree4623b772f659dfb349dd237ab2033dba791eb40a /xen/common/device_tree.c
parent8166f512eaa2b3cb7e263291fc1b55db1b867eb0 (diff)
downloadxen-ae0a90bd8c2683e53f472854fa89ec3cb74c9ddb.tar.gz
xen-ae0a90bd8c2683e53f472854fa89ec3cb74c9ddb.tar.bz2
xen-ae0a90bd8c2683e53f472854fa89ec3cb74c9ddb.zip
device tree: print a warning if a node is nested too deep
Since device_tree_for_each_node() is called before printk() works, a variable is used to switch between using early_printk() and printk(). Signed-off-by: David Vrabel <david.vrabel@citrix.com> Acked-by: Ian Campbell <ian.campbell@citrix.com> Committed-by: Ian Campbell <ian.campbell@citrix.com>
Diffstat (limited to 'xen/common/device_tree.c')
-rw-r--r--xen/common/device_tree.c19
1 files changed, 18 insertions, 1 deletions
diff --git a/xen/common/device_tree.c b/xen/common/device_tree.c
index 8fb6d463c3..04619f4227 100644
--- a/xen/common/device_tree.c
+++ b/xen/common/device_tree.c
@@ -23,6 +23,10 @@
struct dt_early_info __initdata early_info;
void *device_tree_flattened;
+/* Some device tree functions may be called both before and after the
+ console is initialized. */
+static void (*dt_printk)(const char *fmt, ...) = early_printk;
+
bool_t device_tree_node_matches(const void *fdt, int node, const char *match)
{
const char *name;
@@ -90,6 +94,11 @@ u32 device_tree_get_u32(const void *fdt, int node, const char *prop_name)
* @fdt: flat device tree.
* @func: function to call for each node.
* @data: data to pass to @func.
+ *
+ * Any nodes nested at DEVICE_TREE_MAX_DEPTH or deeper are ignored.
+ *
+ * Returns 0 if all nodes were iterated over successfully. If @func
+ * returns a negative value, that value is returned immediately.
*/
int device_tree_for_each_node(const void *fdt,
device_tree_node_func func, void *data)
@@ -104,13 +113,19 @@ int device_tree_for_each_node(const void *fdt,
node >=0 && depth >= 0;
node = fdt_next_node(fdt, node, &depth) )
{
+ const char *name = fdt_get_name(fdt, node, NULL);
+
if ( depth >= DEVICE_TREE_MAX_DEPTH )
+ {
+ dt_printk("Warning: device tree node `%s' is nested too deep\n",
+ name);
continue;
+ }
address_cells[depth] = device_tree_get_u32(fdt, node, "#address-cells");
size_cells[depth] = device_tree_get_u32(fdt, node, "#size-cells");
- ret = func(fdt, node, fdt_get_name(fdt, node, NULL), depth,
+ ret = func(fdt, node, name, depth,
address_cells[depth-1], size_cells[depth-1], data);
if ( ret < 0 )
return ret;
@@ -253,6 +268,8 @@ size_t __init device_tree_early_init(const void *fdt)
device_tree_for_each_node((void *)fdt, early_scan_node, NULL);
early_print_info();
+ dt_printk = printk;
+
return fdt_totalsize(fdt);
}