diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2009-08-24 22:43:11 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2009-08-24 22:43:11 +0000 |
commit | 79ff2e1a25b342d4c81ef87ee4fe2dfa7b061640 (patch) | |
tree | 1e609a6e3669756e7443b3a2df2ebcf34255e743 /sys/arch/sgi | |
parent | d62a69783717cebfc1059fc4fdc6db825779f4d4 (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.c | 31 |
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; } |