[PATCH 1/8] preliminary changes to OF fixup functions

Nathan Lynch ntl at pobox.com
Thu Mar 10 11:51:37 EST 2005


Preliminary modifications to support using some of the interpret_func
family of functions at runtime.  Changes the mem_start argument to be
passed by reference, and the return type to int for error handling to
be implemented in following patches.

Signed-off-by: Nathan Lynch <ntl at pobox.com>

 prom.c |  135 ++++++++++++++++++++++++++++++++++-------------------------------
 1 files changed, 71 insertions(+), 64 deletions(-)

Index: linux-2.6.11-bk5/arch/ppc64/kernel/prom.c
===================================================================
--- linux-2.6.11-bk5.orig/arch/ppc64/kernel/prom.c	2005-03-09 20:01:32.000000000 +0000
+++ linux-2.6.11-bk5/arch/ppc64/kernel/prom.c	2005-03-09 20:02:15.000000000 +0000
@@ -73,8 +73,8 @@ struct isa_reg_property {
 };
 
 
-typedef unsigned long interpret_func(struct device_node *, unsigned long,
-				     int, int, int);
+typedef int interpret_func(struct device_node *, unsigned long *,
+			   int, int, int);
 
 extern struct rtas_t rtas;
 extern struct lmb lmb;
@@ -255,9 +255,9 @@ static int __devinit map_interrupt(unsig
 	return nintrc;
 }
 
-static unsigned long __init finish_node_interrupts(struct device_node *np,
-						   unsigned long mem_start,
-						   int measure_only)
+static int __init finish_node_interrupts(struct device_node *np,
+					 unsigned long *mem_start,
+					 int measure_only)
 {
 	unsigned int *ints;
 	int intlen, intrcells, intrcount;
@@ -267,14 +267,14 @@ static unsigned long __init finish_node_
 
 	ints = (unsigned int *) get_property(np, "interrupts", &intlen);
 	if (ints == NULL)
-		return mem_start;
+		return 0;
 	intrcells = prom_n_intr_cells(np);
 	intlen /= intrcells * sizeof(unsigned int);
-	np->intrs = (struct interrupt_info *) mem_start;
-	mem_start += intlen * sizeof(struct interrupt_info);
+	np->intrs = (struct interrupt_info *) (*mem_start);
+	(*mem_start) += intlen * sizeof(struct interrupt_info);
 
 	if (measure_only)
-		return mem_start;
+		return 0;
 
 	intrcount = 0;
 	for (i = 0; i < intlen; ++i, ints += intrcells) {
@@ -315,13 +315,13 @@ static unsigned long __init finish_node_
 	}
 	np->n_intrs = intrcount;
 
-	return mem_start;
+	return 0;
 }
 
-static unsigned long __init interpret_pci_props(struct device_node *np,
-						unsigned long mem_start,
-						int naddrc, int nsizec,
-						int measure_only)
+static int __init interpret_pci_props(struct device_node *np,
+				      unsigned long *mem_start,
+				      int naddrc, int nsizec,
+				      int measure_only)
 {
 	struct address_range *adr;
 	struct pci_reg_property *pci_addrs;
@@ -331,7 +331,7 @@ static unsigned long __init interpret_pc
 		get_property(np, "assigned-addresses", &l);
 	if (pci_addrs != 0 && l >= sizeof(struct pci_reg_property)) {
 		i = 0;
-		adr = (struct address_range *) mem_start;
+		adr = (struct address_range *) (*mem_start);
 		while ((l -= sizeof(struct pci_reg_property)) >= 0) {
 			if (!measure_only) {
 				adr[i].space = pci_addrs[i].addr.a_hi;
@@ -343,15 +343,15 @@ static unsigned long __init interpret_pc
 		}
 		np->addrs = adr;
 		np->n_addrs = i;
-		mem_start += i * sizeof(struct address_range);
+		(*mem_start) += i * sizeof(struct address_range);
 	}
-	return mem_start;
+	return 0;
 }
 
-static unsigned long __init interpret_dbdma_props(struct device_node *np,
-						  unsigned long mem_start,
-						  int naddrc, int nsizec,
-						  int measure_only)
+static int __init interpret_dbdma_props(struct device_node *np,
+					unsigned long *mem_start,
+					int naddrc, int nsizec,
+					int measure_only)
 {
 	struct reg_property32 *rp;
 	struct address_range *adr;
@@ -372,7 +372,7 @@ static unsigned long __init interpret_db
 	rp = (struct reg_property32 *) get_property(np, "reg", &l);
 	if (rp != 0 && l >= sizeof(struct reg_property32)) {
 		i = 0;
-		adr = (struct address_range *) mem_start;
+		adr = (struct address_range *) (*mem_start);
 		while ((l -= sizeof(struct reg_property32)) >= 0) {
 			if (!measure_only) {
 				adr[i].space = 2;
@@ -383,16 +383,16 @@ static unsigned long __init interpret_db
 		}
 		np->addrs = adr;
 		np->n_addrs = i;
-		mem_start += i * sizeof(struct address_range);
+		(*mem_start) += i * sizeof(struct address_range);
 	}
 
-	return mem_start;
+	return 0;
 }
 
-static unsigned long __init interpret_macio_props(struct device_node *np,
-						  unsigned long mem_start,
-						  int naddrc, int nsizec,
-						  int measure_only)
+static int __init interpret_macio_props(struct device_node *np,
+					unsigned long *mem_start,
+					int naddrc, int nsizec,
+					int measure_only)
 {
 	struct reg_property32 *rp;
 	struct address_range *adr;
@@ -413,7 +413,7 @@ static unsigned long __init interpret_ma
 	rp = (struct reg_property32 *) get_property(np, "reg", &l);
 	if (rp != 0 && l >= sizeof(struct reg_property32)) {
 		i = 0;
-		adr = (struct address_range *) mem_start;
+		adr = (struct address_range *) (*mem_start);
 		while ((l -= sizeof(struct reg_property32)) >= 0) {
 			if (!measure_only) {
 				adr[i].space = 2;
@@ -424,16 +424,16 @@ static unsigned long __init interpret_ma
 		}
 		np->addrs = adr;
 		np->n_addrs = i;
-		mem_start += i * sizeof(struct address_range);
+		(*mem_start) += i * sizeof(struct address_range);
 	}
 
-	return mem_start;
+	return 0;
 }
 
-static unsigned long __init interpret_isa_props(struct device_node *np,
-						unsigned long mem_start,
-						int naddrc, int nsizec,
-						int measure_only)
+static int __init interpret_isa_props(struct device_node *np,
+				      unsigned long *mem_start,
+				      int naddrc, int nsizec,
+				      int measure_only)
 {
 	struct isa_reg_property *rp;
 	struct address_range *adr;
@@ -442,7 +442,7 @@ static unsigned long __init interpret_is
 	rp = (struct isa_reg_property *) get_property(np, "reg", &l);
 	if (rp != 0 && l >= sizeof(struct isa_reg_property)) {
 		i = 0;
-		adr = (struct address_range *) mem_start;
+		adr = (struct address_range *) (*mem_start);
 		while ((l -= sizeof(struct isa_reg_property)) >= 0) {
 			if (!measure_only) {
 				adr[i].space = rp[i].space;
@@ -453,16 +453,16 @@ static unsigned long __init interpret_is
 		}
 		np->addrs = adr;
 		np->n_addrs = i;
-		mem_start += i * sizeof(struct address_range);
+		(*mem_start) += i * sizeof(struct address_range);
 	}
 
-	return mem_start;
+	return 0;
 }
 
-static unsigned long __init interpret_root_props(struct device_node *np,
-						 unsigned long mem_start,
-						 int naddrc, int nsizec,
-						 int measure_only)
+static int __init interpret_root_props(struct device_node *np,
+				       unsigned long *mem_start,
+				       int naddrc, int nsizec,
+				       int measure_only)
 {
 	struct address_range *adr;
 	int i, l;
@@ -472,7 +472,7 @@ static unsigned long __init interpret_ro
 	rp = (unsigned int *) get_property(np, "reg", &l);
 	if (rp != 0 && l >= rpsize) {
 		i = 0;
-		adr = (struct address_range *) mem_start;
+		adr = (struct address_range *) (*mem_start);
 		while ((l -= rpsize) >= 0) {
 			if (!measure_only) {
 				adr[i].space = 0;
@@ -484,26 +484,30 @@ static unsigned long __init interpret_ro
 		}
 		np->addrs = adr;
 		np->n_addrs = i;
-		mem_start += i * sizeof(struct address_range);
+		(*mem_start) += i * sizeof(struct address_range);
 	}
 
-	return mem_start;
+	return 0;
 }
 
-static unsigned long __init finish_node(struct device_node *np,
-					unsigned long mem_start,
-					interpret_func *ifunc,
-					int naddrc, int nsizec,
-					int measure_only)
+static int __init finish_node(struct device_node *np,
+			      unsigned long *mem_start,
+			      interpret_func *ifunc,
+			      int naddrc, int nsizec,
+			      int measure_only)
 {
 	struct device_node *child;
-	int *ip;
+	int *ip, rc = 0;
 
 	/* get the device addresses and interrupts */
 	if (ifunc != NULL)
-		mem_start = ifunc(np, mem_start, naddrc, nsizec, measure_only);
+		rc = ifunc(np, mem_start, naddrc, nsizec, measure_only);
+	if (rc)
+		goto out;
 
-	mem_start = finish_node_interrupts(np, mem_start, measure_only);
+	rc = finish_node_interrupts(np, mem_start, measure_only);
+	if (rc)
+		goto out;
 
 	/* Look for #address-cells and #size-cells properties. */
 	ip = (int *) get_property(np, "#address-cells", NULL);
@@ -539,11 +543,14 @@ static unsigned long __init finish_node(
 		       || !strcmp(np->type, "media-bay"))))
 		ifunc = NULL;
 
-	for (child = np->child; child != NULL; child = child->sibling)
-		mem_start = finish_node(child, mem_start, ifunc,
-					naddrc, nsizec, measure_only);
-
-	return mem_start;
+	for (child = np->child; child != NULL; child = child->sibling) {
+		rc = finish_node(child, mem_start, ifunc,
+				 naddrc, nsizec, measure_only);
+		if (rc)
+			goto out;
+	}
+out:
+	return rc;
 }
 
 /**
@@ -555,7 +562,7 @@ static unsigned long __init finish_node(
  */
 void __init finish_device_tree(void)
 {
-	unsigned long mem, size;
+	unsigned long start, end, size = 0;
 
 	DBG(" -> finish_device_tree\n");
 
@@ -568,11 +575,11 @@ void __init finish_device_tree(void)
 	virt_irq_init();
 
 	/* Finish device-tree (pre-parsing some properties etc...) */
-	size = finish_node(allnodes, 0, NULL, 0, 0, 1);
-	mem = (unsigned long)abs_to_virt(lmb_alloc(size, 128));
-	if (finish_node(allnodes, mem, NULL, 0, 0, 0) != mem + size)
-		BUG();
-
+	finish_node(allnodes, &size, NULL, 0, 0, 1);
+	end = start = (unsigned long)abs_to_virt(lmb_alloc(size, 128));
+	finish_node(allnodes, &end, NULL, 0, 0, 0);
+	BUG_ON(end != start + size);
+		
 	DBG(" <- finish_device_tree\n");
 }
 



More information about the Linuxppc64-dev mailing list