[parisc-linux-cvs] Legacy inventory cleanups & Asp sound fixes

Matthew Wilcox willy@ldl.fc.hp.com
Thu, 30 Aug 2001 10:53:59 -0600


 * Put an appropriate copyright & licence on the file.
 * the 715old stuff is bogus.  I've tried a 715/50 & a 715/75.
 * sanitise the comments, and move them outofline.
 * remove some unnecessary duplicate checks from do_legacy_inventory.
 * factor common code from do_legacy_inventory into legacy_create_device.
 * Remove setting of stype altogether -- it wasn't getting used anywhere.
 * Fill in dev->parent for subdevices of Asp -- harmony now finds an irq
   on Asp-based machines.

Index: arch/parisc/kernel/inventory.c
===================================================================
RCS file: /home/cvs/parisc/linux/arch/parisc/kernel/inventory.c,v
retrieving revision 1.32
diff -u -p -r1.32 inventory.c
--- arch/parisc/kernel/inventory.c	2001/08/14 16:54:52	1.32
+++ arch/parisc/kernel/inventory.c	2001/08/30 16:44:51
@@ -1,5 +1,17 @@
-/* Copyright (c) 1999 The Puffin Group */
-/* Written by David Kennedy and Alex deVries */
+/*
+ * inventory.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * Copyright (c) 1999 The Puffin Group (David Kennedy and Alex deVries)
+ * Copyright (c) 2001 Matthew Wilcox for Hewlett-Packard
+ *
+ * We query PDC for devices it knows about, and do an architected buswalk
+ * in order to find devices it won't tell us about.
+ */
 
 #include <linux/types.h>
 #include <linux/kernel.h>
@@ -393,179 +405,64 @@ static void do_system_map_memconfig(void
 
 /* All of the older legacy box (32 bit only) code goes here */
 
-/* The following checks to see if the system is a 715/old.  This might
-** sound a bit unusual, but there are some workarounds required for these
-** machines.  These machines are the 715/33, 715/50 and 715/75. 
-**
-** This function returns 1 if we are a 715/old, and 0 if we're not. 
-*/
-static int check_if_715old(void)
+static struct parisc_device *legacy_create_device(struct pdc_memory_map *r_addr,
+		struct pdc_module_path *module_path)
 {
-	/* We trust that the CPU HVersion returned by PDC is correct.
-	**
-	** Machine             CPU_HVERSION real life verification
-	**
-	** Scorpio (715/50):        0x310           Yes
-	** Scorpio Jr.(715/33)      0x311           Yes
-	** Strider-50 (715S/50)     0x312           No
-	** Strider-33 (715S/33)     0x313           No
-	** Trailways-50 (715T/50)   0x314           No
-	** Trailways-33 (715T/33)   0x315           No
-	** Scorpio Sr.(715/75)      0x316           Yes
-	**
-	*/
-
-	if (CPU_HVERSION >= 0x310 && CPU_HVERSION <=0x316)
-		return 1;
+	struct parisc_device *hp_dev;
+	int status = pdc_mem_map_hpa(r_addr, module_path);
+	if (status != PDC_RET_OK)
+		return NULL;
+
+	hp_dev = alloc_pa_dev(r_addr->hpa);
+	if (hp_dev == NULL)
+		return NULL;
 
-	return 0;
+	register_pa_dev(hp_dev);
+	return hp_dev;
 }
 
+/**
+ * do_legacy_inventory
+ *
+ * Before PDC_SYSTEM_MAP was invented, the PDC_MEM_MAP call was used.
+ * To use it, we initialise the mod_path.bc to 0xff and try all values of
+ * mod to get the HPA for the top-level devices.  Bus adapters may have
+ * 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 i, mod, num = 0;
-	int status;
-	unsigned int hw_type;
-	unsigned int func;
-	unsigned long bytecnt;
-	struct pdc_module_path module_path;
-	struct pdc_memory_map r_addr;
-	u8 iodc_data[32 * sizeof(long)];
-
-	/* This is undocumented at the time of writing, but basically 
-	** we're setting up mod_path so that bc[0..4]=0xff, and step
-	** through mod to get the "Path Structure for GSC Modules".  If
-	** it works, use the returned HPA and determine the hardware type.  
-	*/
-
-	memset(module_path.bc, 0xff, sizeof(module_path.bc));
-
+	int mod, num = 0;
 	for (mod = 0; mod < 16; mod++) {
-		char *stype = NULL;
-		
+		struct parisc_device *dev;
+		struct pdc_module_path module_path;
+		struct pdc_memory_map r_addr;
+		unsigned int func;
+
+		memset(module_path.bc, 0xff, sizeof(module_path.bc));
 		module_path.mod = mod;
-		
-		status = pdc_mem_map_hpa(&r_addr, &module_path);
-		if (status != PDC_RET_OK)
-			continue;
-		
-		/* On 715/old systems, pdc_iodc_read() seems to fail 
-		** and simply hang the system when querying the onboard
-		** graphics cards, which are at location 0xf800000.  Because
-		** of this, I'm going to skip them.  We might have to rewrite
-		** an exception to this so it ends up in the inventory table.
-		** In any case, this is where the hook is.
-		*/
-		if (r_addr.hpa == 0xf8000000 && check_if_715old()) {
-			printk(KERN_ERR "Using Alex's odd 715/old exception, "
-				"onboard graphics won't be inventoried!\n");
+		dev = legacy_create_device(&r_addr, &module_path);
+		if (!dev)
 			continue;
-		}
+		num++;
 
-		status = pdc_iodc_read(&bytecnt, (void *)r_addr.hpa, 0,
-				       &iodc_data, 32);
-		if (status != PDC_RET_OK)
+		if (dev->id.hw_type != HPHW_BA)
 			continue;
-
-		hw_type = iodc_data[3] & 0x1f;
-		switch (hw_type) {
-		case HPHW_NPROC:
-			stype = "Processor";
-			break;	/* 0 */
-		case HPHW_MEMORY:
-			stype = "Memory";
-			break;	/* 1 */
-		case HPHW_B_DMA:
-			stype = "Type B DMA";
-			break;	/* 2 */
-		case HPHW_A_DMA:
-			stype = "Type A DMA";
-			break;	/* 4 */
-		case HPHW_A_DIRECT:
-			stype = "Type A Direct";
-			break;	/* 5 */
-		case HPHW_BCPORT:
-			stype = "Bus Converter Port";
-			break;	/* 7 */
-		case HPHW_CONSOLE:
-			stype = "Console";
-			break;	/* 9 */
-		case HPHW_FIO:
-			stype = "Foreign I/O (Graphics)";
-			break;	/* 10 */
-		case HPHW_BA:
-			stype = "Bus Adapter";
-			break;	/* 11 */
-		case HPHW_IOA:
-			stype = "I/O Adapter";
-			break;	/* 12 */
-		case HPHW_BRIDGE:
-			stype = "Bridge";
-			break;	/* 13 */
-		case HPHW_FABRIC:
-			stype = "Fabric";
-			break;	/* 14 */
-		case HPHW_FAULTY:
-			stype = "Faulty HW";
-			break;	/* 31 */
-		case HPHW_OTHER:	/* 42 */
-		default:
-			printk(KERN_WARNING "Don't know this hw_type: %d\n", hw_type);
-			break;
-		} /* switch() */
 
-		/* This is kluged. But don't want to replicate code for
-		** most of the above cases.
-		*/
-		if (stype) {
-			struct parisc_device *hp_dev;
-
-			status = pdc_mem_map_hpa(&r_addr, &module_path);
-			if (status == PDC_RET_OK
-			    && (hp_dev = alloc_pa_dev(r_addr.hpa))) {
-				
-				register_pa_dev(hp_dev);
-				++num;
-			}
-
-			if (hw_type == HPHW_BA) {
-				/* Now, we're checking for devices for each
-				** module.  I seem to think that the
-				** modules in question are Lasi (2), 2nd Lasi (6)
-				** Wax (5).  To do this, set bc[5]=0, and set
-				** bc[4] to the module, and step through the
-				** functions. 
-				*/
-
-				for (i = 0; i < 4; i++) {
-					module_path.bc[i] = 0xff;
-				}
-
-				module_path.bc[4] = mod;
-				for (func = 0; func < 16; func++) {
-					module_path.mod = func;
-					module_path.bc[5] = 0;
-
-					status = pdc_mem_map_hpa(&r_addr,
-								 &module_path);
-					if (status != PDC_RET_OK)
-						continue;
-
-					hp_dev = alloc_pa_dev(r_addr.hpa);
-					if (hp_dev) {
-						register_pa_dev(hp_dev);
-						++num;
-					}
-				}
-
-			} /* hw_type == HPHW_BA */
-
-			/* reset module_path.bc[] */
-			memset(module_path.bc, 0xff,
-			       sizeof(module_path.bc));
+		memset(module_path.bc, 0xff, 4);
+		module_path.bc[4] = mod;
 
-		}  /* if (stype) */
-	} /* for() */
+		for (func = 0; func < 16; func++) {
+			struct parisc_device *child;
+			module_path.bc[5] = 0;
+			module_path.mod = func;
+			child = legacy_create_device(&r_addr, &module_path);
+			if (!child)
+				continue;
+			num++;
+			child->parent = dev;
+		}
+	}
 
 	return num;
 }
Index: drivers/gsc/busdevice.c
===================================================================
RCS file: /home/cvs/parisc/linux/drivers/gsc/busdevice.c,v
retrieving revision 1.24
diff -u -p -r1.24 busdevice.c
--- drivers/gsc/busdevice.c	2001/08/14 16:54:54	1.24
+++ drivers/gsc/busdevice.c	2001/08/30 16:44:51
@@ -51,7 +51,12 @@ int busdevice_alloc_irq(struct parisc_de
 {
 	struct busdevice *busdev = busdev_list;
 	int	irq;
+	int hpa = dev->hpa;
 
+	if (dev->parent) {
+		hpa = dev->parent->hpa;
+	}
+
 	if (!busdev) {
 		printk(KERN_ERR "%s(0x%p): No LASI/ASP/WAX found in system yet !\n",
 			__FUNCTION__, dev);
@@ -62,7 +67,7 @@ int busdevice_alloc_irq(struct parisc_de
 	/* deller: Changed to test only the 3 highest nibbles of the
 	    address-range, since ASP uses hpa of 0xf080yyyy, but devices are 
 	    at adress 0xf082yyyy ! */
-	while (busdev && ((busdev->hpa & ~0xfffff) != (dev->hpa & ~0xfffff))) {
+	while (busdev && ((busdev->hpa & ~0xfffff) != (hpa & ~0xfffff))) {
 		busdev = busdev->next;
 	}