From 79ff2e1a25b342d4c81ef87ee4fe2dfa7b061640 Mon Sep 17 00:00:00 2001 From: Miod Vallat Date: Mon, 24 Aug 2009 22:43:11 +0000 Subject: 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! --- sys/arch/sgi/sgi/autoconf.c | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) (limited to 'sys/arch/sgi') 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; } -- cgit v1.2.3