[parisc-linux] [PATCH] Additional Address cleanup

Ryan Bradetich rbradetich@uswest.net
Fri, 21 Sep 2001 10:48:38 -0600


--Nq2Wo0NMKNjxTN9z
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Hello parisc-linux hackers,

I have a small patch which allows the additional addresses to
be allocated dynamically instead of a static array.  The patch
itself is pretty simple, but I made one simplification that
I wanted to run by the experts before committing the patch.

The simplification I made was to remove the HPA from index
0 of the addr[] in the parisc_device.  I feel this is redundant
since the device already records the HPA with the hpa field.
By not including the HPA, it also saves a kmalloc on every
parisc device to store the HPA, and an additional kfree/kmalloc
when the device actually has additional addresses to store.

Currently, the only device that is using the additional
addresses is the STI driver, and it blindly reads from
addr[1] for the location of a graphics card.  Nothing else
besides the adding/printing of the additional addresses
every uses the addr field in the parisc device.

So can I safely remove the HPA from addr[0] as I've done with
the attached patch?  Or will I break future device support
if the HPA is not present?

Thanks,

- Ryan

P.S. I have tested this patch on C200+ with serial console,
712/100 with STI console, and compiled it at 64-bit.

--Nq2Wo0NMKNjxTN9z
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="addr.patch"

? addr.diff
? arch/parisc/kernel/Makefile.iotree
? arch/parisc/kernel/drivers.c.iotree
? arch/parisc/kernel/inventory.c.iotree
? arch/parisc/kernel/iotree.c
Index: arch/parisc/kernel/drivers.c
===================================================================
RCS file: /home/cvs/parisc/linux/arch/parisc/kernel/drivers.c,v
retrieving revision 1.24
diff -u -p -r1.24 drivers.c
--- arch/parisc/kernel/drivers.c	2001/09/18 01:14:18	1.24
+++ arch/parisc/kernel/drivers.c	2001/09/21 16:21:46
@@ -174,30 +174,6 @@ int get_num_pa_dev(void)
 	return i;
 }
 
-/**
- * add_pa_dev_addr - Add an additional address to the list of addresses of a HP device
- * @hp_device: the PA-RISC device structure
- * @addr: the address to be added
- */
-int add_pa_dev_addr(struct parisc_device *hp_device, unsigned long addr)
-{
-	if (!hp_device || !addr)
-	    return 0;
-
-	if (hp_device->num_addrs >= MAX_ADD_ADDRS) {
-	    printk(KERN_ERR "%s: Too many additional addresses. "
-			"Increase the value of MAX_ADD_ADDRS in harware.h !\n",
-			__FUNCTION__ );
-	    return 0;
-	}
-
-	hp_device->addr[hp_device->num_addrs] = addr;
-	hp_device->num_addrs++;
-
-	return hp_device->num_addrs;
-}
-
-
 struct parisc_device *alloc_pa_dev(unsigned long hpa)
 {
 	int i, status;
@@ -243,13 +219,9 @@ struct parisc_device *alloc_pa_dev(unsig
 		strncpy(dev->name, name, sizeof(dev->name)-1);
 	}
 
-	/* add the hpa of this module as the first additional address */
-	add_pa_dev_addr(dev, hpa);
-
 	num_devices++;
 
 	write_unlock(&pa_lock);
-
 	return dev;
 }
 
Index: arch/parisc/kernel/inventory.c
===================================================================
RCS file: /home/cvs/parisc/linux/arch/parisc/kernel/inventory.c,v
retrieving revision 1.35
diff -u -p -r1.35 inventory.c
--- arch/parisc/kernel/inventory.c	2001/09/18 16:12:08	1.35
+++ arch/parisc/kernel/inventory.c	2001/09/21 16:21:46
@@ -15,6 +15,8 @@
 
 #include <linux/types.h>
 #include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/mm.h>
 #include <asm/hardware.h>
 #include <asm/io.h>
@@ -30,7 +32,7 @@
 
 int pdc_type = PDC_TYPE_ILLEGAL;
 
-void setup_pdc(void)
+void __init setup_pdc(void)
 {
 	long status;
 	unsigned int bus_id;
@@ -108,9 +110,9 @@ void setup_pdc(void)
 
 #define PDC_PAGE_ADJ_SHIFT (PAGE_SHIFT - 12) /* pdc pages are always 4k */
 
-static void set_pmem_entry(physmem_range_t *pmem_ptr,
-			   unsigned long start,
-			   unsigned long pages4k)
+static void __init
+set_pmem_entry(physmem_range_t *pmem_ptr, unsigned long start,
+	       unsigned long pages4k)
 {
 	/* Rather than aligning and potentially throwing away
 	 * memory, we'll assume that any ranges are already
@@ -129,7 +131,7 @@ static void set_pmem_entry(physmem_range
 	pmem_ptr->pages = (pages4k >> PDC_PAGE_ADJ_SHIFT);
 }
 
-void do_pagezero_memconfig(void)
+void __init do_pagezero_memconfig(void)
 {
 	unsigned long npages;
 
@@ -168,7 +170,8 @@ void do_pagezero_memconfig(void)
 **
 */
 
-static int pat_query_module(ulong pcell_loc, ulong mod_index)
+static int __init 
+pat_query_module(ulong pcell_loc, ulong mod_index)
 {
 	pdc_pat_cell_mod_maddr_block_t pa_pdc_cell;
 	pdc_pat_cell_mod_maddr_block_t io_pdc_cell;
@@ -272,7 +275,7 @@ static int pat_query_module(ulong pcell_
 
 #define PAT_MAX_RANGES (4 * MAX_PHYSMEM_RANGES)
 
-static void do_pat_memconfig(void)
+static void __init do_pat_memconfig(void)
 {
 	unsigned long actual_len;
 	struct pdc_pat_pd_addr_map_entry mem_table[PAT_MAX_RANGES+1];
@@ -338,7 +341,7 @@ static void do_pat_memconfig(void)
 	}
 }
 
-static int do_pat_inventory(void)
+static int __init do_pat_inventory(void)
 {
 	int status;
 	ulong mod_index = 0;
@@ -367,7 +370,7 @@ static int do_pat_inventory(void)
 
 /* We only look for extended memory ranges on a 64 bit capable box */
 
-static void do_system_map_memconfig(void)
+static void __init do_system_map_memconfig(void)
 {
 	struct pdc_memory_table_raddr r_addr;
 	struct pdc_memory_table mem_table[MAX_PHYSMEM_RANGES];
@@ -416,8 +419,9 @@ static void do_system_map_memconfig(void
 
 /* All of the older legacy box (32 bit only) code goes here */
 
-static struct parisc_device *legacy_create_device(struct pdc_memory_map *r_addr,
-		struct pdc_module_path *module_path)
+static struct parisc_device * __init 
+legacy_create_device(struct pdc_memory_map *r_addr,
+		     struct pdc_module_path *module_path)
 {
 	struct parisc_device *dev;
 	int status = pdc_mem_map_hpa(r_addr, module_path);
@@ -441,7 +445,7 @@ static struct parisc_device *legacy_crea
  * sub-devices which are discovered by setting bc[5] to 0 and bc[4] to the
  * module, then trying all possible functions.
  */
-int do_legacy_inventory(void)
+int __init do_legacy_inventory(void)
 {
 	int mod, num = 0;
 	for (mod = 0; mod < 16; mod++) {
@@ -509,13 +513,56 @@ int do_native_bus_walk(unsigned long hpa
 	return num;
 }
 
-static int do_system_map_inventory(void)
+/**
+ * add_system_map_addresses - Add additional addresses to the parisc device.
+ * @dev: The parisce device.
+ * @num_addrs: Then number of addresses to add;
+ * @module_instance: The system_map module instance.
+ *
+ * This function adds any additional addresses reported by the system_map
+ * firmware to the parisc device.
+ */
+static __init void
+add_system_map_addresses(struct parisc_device *dev, int num_addrs, 
+			 int module_instance)
+{
+	int i;
+	long status;
+	struct pdc_system_map_addr_info addr_result;
+
+	dev->addr = kmalloc(sizeof(unsigned long), num_addrs);
+	if(!dev->addr) {
+		printk(KERN_ERR "%s %s(): memory allocation failure\n",
+		       __FILE__, __FUNCTION__);
+		return;
+	}
+
+	for(i = 0; i < num_addrs; ++i) {
+		status = pdc_system_map_find_addrs(&addr_result, 
+						   module_instance, i);
+		if(PDC_RET_OK == status) {
+			dev->addr[dev->num_addrs] = (unsigned long)addr_result.mod_addr;
+			dev->num_addrs++;
+		} else {
+			printk(KERN_WARNING 
+			       "Bad PDC_FIND_ADDRESS status return (%ld) for index %d\n",
+			       status, i);
+		}
+	}
+}
+
+/**
+ * do_system_map_inventory - Retrieve firmware devices via SYSTEM_MAP.
+ *
+ * This function attempts to retrieve and register all the devices firmware
+ * knows about via the SYSTEM_MAP PDC call.
+ */
+static int __init do_system_map_inventory(void)
 {
-	int i, j, num;
+	int i, num;
 	long status;
 	struct parisc_device *dev;
 	struct pdc_system_map_mod_info module_result;
-	struct pdc_system_map_addr_info addr_result;
 	struct pdc_module_path module_path;
 
 	/* So the idea here is to simply try one SYSTEM_MAP call.  If 
@@ -528,41 +575,31 @@ static int do_system_map_inventory(void)
 	num = 0;
 	for (i = 0; status != PDC_RET_NE_PROC && status != PDC_RET_NE_MOD; ++i) {
 
-		status = pdc_system_map_find_mods(&module_result, &module_path, i);
+		status = pdc_system_map_find_mods(&module_result, 
+						  &module_path, i);
 		if (status != PDC_RET_OK)
 			continue;
 		
-		dev = alloc_pa_dev((unsigned long) module_result.mod_addr);
-		if (!dev)
+		dev = alloc_pa_dev((unsigned long)module_result.mod_addr);
+		if(!dev)
 			continue;
 		
 		register_parisc_device(dev);
 		++num;
 
 		/* if available, get the additional addresses for a module */
-		if (!module_result.add_addrs)
+		if(!module_result.add_addrs)
 			continue;
 
-		for (j = 1; j <= module_result.add_addrs; ++j) {
-			status = pdc_system_map_find_addrs(&addr_result, i, j);
-			if (status == PDC_RET_OK) {
-				add_pa_dev_addr(dev, (unsigned long)
-						addr_result.mod_addr);
-			} else {
-				printk(KERN_WARNING 
-					"Bad PDC_FIND_ADDRESS status return (%ld) for index %d\n",
-					status, j);
-				status = PDC_RET_OK;	/* reset status for outer loop */
-			}
-		}
-	} /* end of main loop */
+		add_system_map_addresses(dev, module_result.add_addrs, i);
+	}
 
 	/* Walk the system bus */
 	num += do_native_bus_walk(FPA);
 	return num;
 }
 
-void do_memory_inventory(void)
+void __init do_memory_inventory(void)
 {
 	switch (pdc_type) {
 
@@ -589,7 +626,7 @@ void do_memory_inventory(void)
 	}
 }
 
-void do_device_inventory(void)
+void __init do_device_inventory(void)
 {
 	int num;
 
Index: drivers/video/sti/sticore.c
===================================================================
RCS file: /home/cvs/parisc/linux/drivers/video/sti/sticore.c,v
retrieving revision 1.22
diff -u -p -r1.22 sticore.c
--- drivers/video/sti/sticore.c	2001/08/22 13:23:47	1.22
+++ drivers/video/sti/sticore.c	2001/09/21 16:21:51
@@ -833,7 +833,11 @@ out_err:
  */
 static int __init sticore_pa_init(struct parisc_device *dev)
 {
-	unsigned long rom = dev->addr[1];
+	unsigned long rom;
+
+	if(dev->num_addrs) {
+		rom = dev->addr[0];
+	}
 	if (!rom) {
 		rom = PAGE0->proc_sti;
 	}
Index: include/asm-parisc/hardware.h
===================================================================
RCS file: /home/cvs/parisc/linux/include/asm-parisc/hardware.h,v
retrieving revision 1.21
diff -u -p -r1.21 hardware.h
--- include/asm-parisc/hardware.h	2001/09/18 01:14:19	1.21
+++ include/asm-parisc/hardware.h	2001/09/21 16:21:52
@@ -21,9 +21,6 @@ struct hp_hardware {
 	const char	name[80];	/* The hardware description */
 };
 
-
-#define MAX_ADD_ADDRS	5	/* 5 additional address ranges should be sufficient */
-
 struct parisc_device {
 	unsigned long	hpa;		/* Hard Physical Address */
 	struct parisc_device_id id;
@@ -33,8 +30,8 @@ struct parisc_device {
 	struct parisc_driver *driver;	/* Driver for this device */
 	char name[80];			/* The hardware description */
 
-	unsigned int	num_addrs;	/* some devices have additional address ranges, */
-	unsigned long	addr[MAX_ADD_ADDRS]; /* which will be stored here */
+	unsigned int	num_addrs;	/* some devices have additional address ranges. */
+	unsigned long	*addr;          /* which will be stored here */
  
 #ifdef __LP64__
 	/* parms for pdc_pat_cell_module() call */
@@ -100,7 +97,6 @@ extern enum cpu_type parisc_get_cpu_type
 /* drivers.c: */
 extern struct parisc_device *alloc_pa_dev(unsigned long hpa);
 extern int register_parisc_device(struct parisc_device *dev);
-extern int add_pa_dev_addr(struct parisc_device *dev, unsigned long addr);
 extern int get_num_pa_dev(void);
 extern void print_pa_devices(int start_index, int num_indexes);
 extern int register_parisc_driver(struct parisc_driver *driver);

--Nq2Wo0NMKNjxTN9z--