Subject: port-next68k/17157: boot device is always set to xe0
To: None <gnats-bugs@gnats.netbsd.org>
From: None <chris@Pin.LU>
List: netbsd-bugs
Date: 06/03/2002 19:51:19
>Number:         17157
>Category:       port-next68k
>Synopsis:       boot device is always set to xe0
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    port-next68k-maintainer
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon Jun 03 11:32:00 PDT 2002
>Closed-Date:
>Last-Modified:
>Originator:     Christian Limpach
>Release:        current
>Organization:
	
>Environment:
	
sys/arch/next68k/dev/if_xe.c rev. 1.5
sys/arch/next68k/next68k/autoconf.c rev. 1.7

>Description:
	The boot device is always set to the network device xe0.

>How-To-Repeat:
	Boot from sd0. (this will be possible soon...)

>Fix:
	The included patch sets the boot device according to the information
	available from the rom monitor.  The rom monitor has different names
	for some of the devices, these are mapped to the corresponding
	devices in the kernel.

Index: dev/if_xe.c
===================================================================
RCS file: /cvs/netbsd/syssrc/sys/arch/next68k/dev/if_xe.c,v
retrieving revision 1.5
retrieving revision 1.5.1724.2
diff -u -r1.5 -r1.5.1724.2
--- dev/if_xe.c	31 Mar 2001 06:56:54 -0000	1.5
+++ dev/if_xe.c	2 Jun 2002 21:17:21 -0000	1.5.1724.2
@@ -161,8 +161,6 @@
   INTR_ENABLE(NEXT_I_ENETX);
   isrlink_autovec(xe_rint, sc, NEXT_I_IPL(NEXT_I_ENETR), 1);
   INTR_ENABLE(NEXT_I_ENETR);
-
-  booted_device = &(sc->sc_dev);
 }
 
 
Index: next68k/autoconf.c
===================================================================
RCS file: /cvs/netbsd/syssrc/sys/arch/next68k/next68k/autoconf.c,v
retrieving revision 1.7
retrieving revision 1.7.1724.1
diff -u -r1.7 -r1.7.1724.1
--- next68k/autoconf.c	17 Sep 1999 20:04:44 -0000	1.7
+++ next68k/autoconf.c	2 Jun 2002 21:14:41 -0000	1.7.1724.1
@@ -66,6 +66,7 @@
 #include <machine/pte.h>
 
 #include <next68k/next68k/isr.h>
+#include <next68k/next68k/nextrom.h>
 
 struct device *booted_device;	/* boot device */
 
@@ -73,6 +74,10 @@
 int  mainbus_match __P((struct device *, struct cfdata *, void *));
 int  mainbus_print __P((void *, const char *));
 
+static struct device *getdevunit __P((char *, int));
+static int devidentparse __P((const char *, int *, int *, int *));
+static int atoi __P((const char *));
+
 struct mainbus_softc {
 	struct device sc_dev;
 };
@@ -93,6 +98,16 @@
 	NULL
 };
 
+struct device_equiv {
+	char *alias;
+	char *real;
+};
+static struct device_equiv device_equiv[] = {
+	{ "en", "xe" },
+	{ "tp", "xe" },
+};
+static int ndevice_equivs = (sizeof(device_equiv)/sizeof(device_equiv[0]));
+
 int
 mainbus_match(parent, cf, args)
 	struct device *parent;
@@ -162,18 +177,23 @@
 void
 cpu_rootconf()
 {
-
+	int count, lun, part;
+	
+	count = lun = part = 0;
+
+	devidentparse (rom_boot_info, &count, &lun, &part);
+	booted_device = getdevunit (rom_boot_dev, count);
+	
 	printf("boot device: %s\n",
 		(booted_device) ? booted_device->dv_xname : "<unknown>");
 
-	setroot(booted_device, 0);
+	setroot(booted_device, part);
 }
 
-#if 0 /* @@@ Does anything use this? Is it a required interface? */
 /*
  * find a device matching "name" and unit number
  */
-struct device *
+static struct device *
 getdevunit(name, unit)
 	char *name;
 	int unit;
@@ -181,6 +201,11 @@
 	struct device *dev = alldevs.tqh_first;
 	char num[10], fullname[16];
 	int lunit;
+	int i;
+
+	for (i = 0; i < ndevice_equivs; i++)
+		if (device_equiv->alias && strcmp (name, device_equiv->alias) == 0)
+			name = device_equiv->real;
 
 	/* compute length of name and decimal expansion of unit number */
 	sprintf(num, "%d", unit);
@@ -198,4 +223,65 @@
 	return dev;
 }
 
-#endif
+/*
+ * Parse a device ident.
+ *
+ * Format:
+ *   (count, lun, part)
+ */
+static int
+devidentparse(spec, count, lun, part)
+	const char *spec;
+	int *count; 
+	int *lun;
+	int *part;
+{
+	int i;
+	const char *args[3];
+
+	if (*spec == '(') {
+		/* tokenize device ident */
+		args[0] = ++spec;
+		for (i = 1; *spec && *spec != ')' && i<3; spec++) {
+			if (*spec == ',')
+				args[i++] = ++spec;
+		}
+		if (*spec != ')')
+			goto baddev;
+	
+		switch(i) {
+		case 3:
+			*count  = atoi(args[0]);
+			*lun  = atoi(args[1]);
+			*part  = atoi(args[2]);
+			break;
+		case 2:
+			*lun  = atoi(args[0]);
+			*part  = atoi(args[1]);
+			break;
+		case 1:
+			*part  = atoi(args[0]);
+			break;
+		case 0:
+			break;
+		}
+	}
+	else
+		goto baddev;
+    
+	return 0;
+    
+ baddev:
+	return ENXIO;
+}
+
+static int
+atoi(s)
+	const char *s;
+{
+	int val = 0;
+	
+	while(isdigit(*s))
+		val = val * 10 + (*s++ - '0');
+	return val;
+}
>Release-Note:
>Audit-Trail:
>Unformatted: