Wed Oct 27 10:42:13 2010 UTC ()
Get and parse root-device.


(kiyohara)
diff -r1.22 -r1.23 src/sys/arch/bebox/bebox/autoconf.c

cvs diff -r1.22 -r1.23 src/sys/arch/bebox/bebox/autoconf.c (expand / switch to context diff)
--- src/sys/arch/bebox/bebox/autoconf.c 2009/03/18 10:22:26 1.22
+++ src/sys/arch/bebox/bebox/autoconf.c 2010/10/27 10:42:12 1.23
@@ -1,4 +1,4 @@
-/*	$NetBSD: autoconf.c,v 1.22 2009/03/18 10:22:26 cegger Exp $	*/
+/*	$NetBSD: autoconf.c,v 1.23 2010/10/27 10:42:12 kiyohara Exp $	*/
 
 /*-
  * Copyright (c) 1990 The Regents of the University of California.
@@ -37,18 +37,19 @@
 /*
  * Setup the system to run on the current machine.
  *
- * Configure() is called at boot time and initializes the vba 
+ * Configure() is called at boot time and initializes the vba
  * device tables and the memory controller monitoring.  Available
  * devices are determined (from possibilities mentioned in ioconf.c),
  * and the drivers are initialized.
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.22 2009/03/18 10:22:26 cegger Exp $");
+__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.23 2010/10/27 10:42:12 kiyohara Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/buf.h>
+#include <sys/disk.h>
 #include <sys/disklabel.h>
 #include <sys/conf.h>
 #include <sys/reboot.h>
@@ -61,13 +62,21 @@
 #include <dev/pci/pcireg.h>
 #include <dev/pci/pcivar.h>
 #endif
+#include <dev/ata/atareg.h>
+#include <dev/ata/atavar.h>
+#include <dev/ata/wdvar.h>
+#include <dev/scsipi/sdvar.h>
 
+#include <machine/bootinfo.h>
 #include <machine/pte.h>
 #include <machine/intr.h>
 
 void genppc_cpu_configure(void);
 static void findroot(void);
 
+static int bus, target, lun, drive;
+static const char *name = NULL;
+
 /*
  * Determine i/o configuration for a machine.
  */
@@ -76,16 +85,17 @@
 cpu_configure(void)
 {
 
+	findroot();
+
 	if (config_rootfound("mainbus", NULL) == NULL)
 		panic("configure: mainbus not configured");
-	
+
 	genppc_cpu_configure();
 }
 
 void
 cpu_rootconf(void)
 {
-	findroot();
 
 	aprint_normal("boot device: %s\n",
 	    booted_device ? booted_device->dv_xname : "<unknown>");
@@ -93,39 +103,82 @@
 	setroot(booted_device, booted_partition);
 }
 
-u_long	bootdev = 0;		/* should be dev_t, but not until 32 bits */
-
 /*
  * Attempt to find the device from which we were booted.
  * If we can do so, and not instructed not to do so,
  * change rootdev to correspond to the load device.
  */
-void
+static void
 findroot(void)
 {
-	int unit, part;
-	device_t dv;
-	const char *name;
+	struct btinfo_rootdevice *rdev;
+	int part;
+	char *p;
 
-	if ((bootdev & B_MAGICMASK) != (u_long)B_DEVMAGIC)
+	rdev = (struct btinfo_rootdevice *)lookup_bootinfo(BTINFO_ROOTDEVICE);
+	if (rdev == NULL)
 		return;
-	
-	name = devsw_blk2name((bootdev >> B_TYPESHIFT) & B_TYPEMASK);
-	if (name == NULL)
+	p = rdev->rootdevice;
+	if (strncmp(p, "/dev/disk/", 10) != 0)
+		/* unknwon device... */
 		return;
-	
-	part = (bootdev >> B_PARTITIONSHIFT) & B_PARTITIONMASK;
-	unit = (bootdev >> B_UNITSHIFT) & B_UNITMASK;
+	p += 10;
+	if (strncmp(p, "scsi/", 5) == 0) {
+		name = "sd";
+		p += 5;
 
-	if ((dv = device_find_by_driver_unit(name, unit)) != NULL) {
-		booted_device = dv;
-		booted_partition = part;
-	}
+		bus = 0;
+		while (isdigit(*p))
+			bus = bus * 10 + (*p++) - '0';
+		if (*p++ != '/')
+			return;
+		target = 0;
+		while (isdigit(*p))
+			target = target * 10 + (*p++) - '0';
+		if (*p++ != '/')
+			return;
+		lun = 0;
+		while (isdigit(*p))
+			lun = lun * 10 + (*p++) - '0';
+	} else if (strncmp(p, "ide/", 4) == 0) {
+		name = "wd";
+		p += 4;
+
+		bus = 0;
+		while (isdigit(*p))
+			bus = bus * 10 + (*p++) - '0';
+		if (*p++ != '/')
+			return;
+		if (strncmp(p, "master/0", 8) == 0) {
+			drive = 0;
+			p += 8;
+		} else if (strncmp(p, "slave/0", 7) == 0) {
+			drive = 1;
+			p += 7;
+		} else
+			return;
+	} else if (strcmp(p, "floppy") == 0)
+		return;
+	else
+		/* unknwon disk... */
+		return;
+
+	if (*p != '_' || !isdigit(*(p + 1)))
+		return;
+	p++;
+	part = 0;
+	while (isdigit(*p))
+		part = part * 10 + (*p++) - '0';
+	if (p != '\0')
+		return;
+
+	booted_partition = part;
 }
 
 void
-device_register(struct device *dev, void *aux)
+device_register(device_t dev, void *aux)
 {
+	device_t bdev, cdev;
 
 #if NPCI > 0
 	if (device_is_a(dev, "genfb") &&
@@ -149,13 +202,48 @@
 	    device_is_a(device_parent(dev), "pci")) {
 		prop_dictionary_t dict = device_properties(dev);
 		struct pci_attach_args *pa = aux;
-		int bus, device;
+		int pbus, device;
 
-		pci_decompose_tag(pa->pa_pc, pa->pa_tag, &bus, &device, NULL);
-		if (bus == 0 && device == 12)
+		pci_decompose_tag(pa->pa_pc, pa->pa_tag, &pbus, &device, NULL);
+		if (pbus == 0 && device == 12)
 			/* Internal SCSI uses PCI clock as SCSI clock */
 			prop_dictionary_set_bool(dict, "use_pciclock", 1);
 	}
 #endif
+
+	if (booted_device != NULL)
+		return;
+	/*
+	 * Check boot device.
+	 * It is sd/wd connected by the onboard controller to be supported.
+	 */
+	if (device_is_a(dev, "sd") && strcmp(name, "sd") == 0) {
+		struct scsipibus_attach_args *sa = aux;
+
+		bdev = device_parent(dev);
+		if (!device_is_a(bdev, "scsibus"))
+			return;
+		cdev = device_parent(bdev);
+		if (!device_is_a(cdev, "siop"))
+			return;
+
+		if (sa->sa_periph->periph_target == target &&
+		    sa->sa_periph->periph_lun == lun)
+			booted_device = dev;
+	} else if (device_is_a(dev, "wd") && strcmp(name, "wd") == 0) {
+		struct ata_device *adev = aux;
+
+		bdev = device_parent(dev);
+		if (!device_is_a(bdev, "atabus"))
+			return;
+		cdev = device_parent(bdev);
+		if (!device_is_a(cdev, "wdc"))
+			return;
+		if (!device_is_a(device_parent(cdev), "isa"))
+			return;
+
+		if (adev->adev_drv_data->drive == drive)
+			booted_device = dev;
+	}
 }