summaryrefslogtreecommitdiff
path: root/sys/arch/sgi
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2009-08-24 22:43:11 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2009-08-24 22:43:11 +0000
commit79ff2e1a25b342d4c81ef87ee4fe2dfa7b061640 (patch)
tree1e609a6e3669756e7443b3a2df2ebcf34255e743 /sys/arch/sgi
parentd62a69783717cebfc1059fc4fdc6db825779f4d4 (diff)
On O2, the bootpath may omit the pci(0) component and start with scsi(); in
that case, fake the pci(0) part in order to match correctly the onboard scsi controller. While there, make sure device_register() returns early for devices attached to root; without both these changes, an O2 lacking pci(0) in its bootpath would dereference a NULL pointer when softraid would attach. Problem found the hard way by Jukka Taimisto (jtaimisto, iki dot fi), thanks for the report!
Diffstat (limited to 'sys/arch/sgi')
-rw-r--r--sys/arch/sgi/sgi/autoconf.c31
1 files changed, 27 insertions, 4 deletions
diff --git a/sys/arch/sgi/sgi/autoconf.c b/sys/arch/sgi/sgi/autoconf.c
index 7d132f5a91a..dea21684613 100644
--- a/sys/arch/sgi/sgi/autoconf.c
+++ b/sys/arch/sgi/sgi/autoconf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: autoconf.c,v 1.21 2009/06/13 21:48:03 miod Exp $ */
+/* $OpenBSD: autoconf.c,v 1.22 2009/08/24 22:43:10 miod Exp $ */
/*
* Copyright (c) 2009 Miodrag Vallat.
*
@@ -260,6 +260,7 @@ device_register(struct device *dev, void *aux)
{
static struct device *lastparent = NULL;
static struct device *pciparent = NULL;
+ static int component_pos = 0;
struct device *parent = dev->dv_parent;
struct cfdata *cf = dev->dv_cfdata;
@@ -268,6 +269,9 @@ device_register(struct device *dev, void *aux)
const char *component;
int unit;
+ if (parent == NULL)
+ return; /* one of the @root devices */
+
if (bootdv != NULL)
return;
@@ -347,9 +351,27 @@ device_register(struct device *dev, void *aux)
}
#endif
- if (strcmp(cd->cd_name, "scsibus") == 0 &&
- parent == lastparent)
- goto found_advance;
+ if (strcmp(cd->cd_name, "scsibus") == 0) {
+ if (parent == lastparent)
+ goto found_advance;
+
+#if defined(TGT_O2)
+ /*
+ * On O2, the pci(0) component may be omitted from
+ * the bootpath, in which case we fake the missing
+ * pci(0) component.
+ */
+ if (sys_config.system_type == SGI_O2 &&
+ component_pos == 0) {
+ if (parent->dv_parent != NULL &&
+ strcmp(parent->dv_parent->dv_cfdata->cf_driver->cd_name,
+ "pci") == 0) {
+ pciparent = parent->dv_parent;
+ goto found_advance;
+ }
+ }
+#endif
+ }
if (parent == lastparent) {
if (parent == pciparent) {
@@ -392,6 +414,7 @@ device_register(struct device *dev, void *aux)
found_advance:
bootpath_next();
+ component_pos++;
found:
lastparent = dev;
}