Module Name:    src
Committed By:   dyoung
Date:           Tue Apr  7 22:01:39 UTC 2009

Modified Files:
        src/sys/arch/i386/i386: mainbus.c

Log Message:
Let us re-attach acpi0, ipmi0, pnpbios0, and mca0 at mainbus0.

Extract code from mainbus_attach() to create a rescan hook,
mainbus_rescan().  Call mainbus_rescan(, "acpibus"/"ipmibus"/..., ) from
mainbus_attach() in the precise places where we used to attach acpi0,
ipmi0, pnpbios0, and mca0.  This allows, for example, ipmi0 to detach
and re-attach:

# drvctl -d ipmi0
ipmi0: detached
# drvctl -r -a ipmibus mainbus0
ipmi0 at mainbus0
#

Future work will let us detach & re-attach CPUs and the ISA/PCI/EISA
buses at mainbus0.


To generate a diff of this commit:
cvs rdiff -u -r1.81 -r1.82 src/sys/arch/i386/i386/mainbus.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/i386/i386/mainbus.c
diff -u src/sys/arch/i386/i386/mainbus.c:1.81 src/sys/arch/i386/i386/mainbus.c:1.82
--- src/sys/arch/i386/i386/mainbus.c:1.81	Sat Mar 14 15:36:07 2009
+++ src/sys/arch/i386/i386/mainbus.c	Tue Apr  7 22:01:38 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: mainbus.c,v 1.81 2009/03/14 15:36:07 dsl Exp $	*/
+/*	$NetBSD: mainbus.c,v 1.82 2009/04/07 22:01:38 dyoung Exp $	*/
 
 /*
  * Copyright (c) 1996 Christopher G. Demetriou.  All rights reserved.
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: mainbus.c,v 1.81 2009/03/14 15:36:07 dsl Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mainbus.c,v 1.82 2009/04/07 22:01:38 dyoung Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -95,11 +95,24 @@
 #endif
 
 void	mainbus_childdetached(device_t, device_t);
-int	mainbus_match(struct device *, struct cfdata *, void *);
-void	mainbus_attach(struct device *, struct device *, void *);
+int	mainbus_match(device_t, cfdata_t, void *);
+void	mainbus_attach(device_t, device_t, void *);
+void	mainbus_attach(device_t, device_t, void *);
+
+static int	mainbus_rescan(device_t, const char *, const int *);
+
+struct mainbus_softc {
+	device_t	sc_acpi;
+	device_t	sc_dev;
+	device_t	sc_ipmi;
+	device_t	sc_mca;
+	device_t	sc_pnpbios;
+	bool		sc_acpi_present;
+};
 
-CFATTACH_DECL2_NEW(mainbus, 0,
-    mainbus_match, mainbus_attach, NULL, NULL, NULL, mainbus_childdetached);
+CFATTACH_DECL2_NEW(mainbus, sizeof(struct mainbus_softc),
+    mainbus_match, mainbus_attach, NULL, NULL, mainbus_rescan,
+    mainbus_childdetached);
 
 int	mainbus_print(void *, const char *);
 
@@ -163,14 +176,23 @@
 void
 mainbus_childdetached(device_t self, device_t child)
 {
-	/* mainbus holds no pointers to its children, so this is ok */
+	struct mainbus_softc *sc = device_private(self);
+
+	if (sc->sc_acpi == child)
+		sc->sc_acpi = NULL;
+	if (sc->sc_ipmi == child)
+		sc->sc_ipmi = NULL;
+	if (sc->sc_mca == child)
+		sc->sc_mca = NULL;
+	if (sc->sc_pnpbios == child)
+		sc->sc_pnpbios = NULL;
 }
 
 /*
  * Probe for the mainbus; always succeeds.
  */
 int
-mainbus_match(struct device *parent, struct cfdata *match, void *aux)
+mainbus_match(device_t parent, cfdata_t match, void *aux)
 {
 
 	return 1;
@@ -180,12 +202,10 @@
  * Attach the mainbus.
  */
 void
-mainbus_attach(struct device *parent, struct device *self, void *aux)
+mainbus_attach(device_t parent, device_t self, void *aux)
 {
+	struct mainbus_softc *sc = device_private(self);
 	union mainbus_attach_args mba;
-#if NACPI > 0
-	int acpi_present = 0;
-#endif
 #ifdef MPBIOS
 	int mpbios_present = 0;
 #endif
@@ -195,6 +215,8 @@
 	int mpacpi_active = 0;
 	int numcpus = 0;
 
+	sc->sc_dev = self;
+
 	aprint_naive("\n");
 	aprint_normal("\n");
 
@@ -223,13 +245,13 @@
 
 #if NACPI > 0
 	if ((boothowto & RB_MD2) == 0 && acpi_check(self, "acpibus"))
-		acpi_present = acpi_probe();
+		sc->sc_acpi_present = acpi_probe() != 0;
 	/*
 	 * First, see if the MADT contains CPUs, and possibly I/O APICs.
 	 * Building the interrupt routing structures can only
 	 * be done later (via a callback).
 	 */
-	if (acpi_present)
+	if (sc->sc_acpi_present)
 		mpacpi_active = mpacpi_scan_apics(self, &numcpus);
 #endif
 
@@ -259,46 +281,12 @@
 	    self);
 #endif
 
-#if NACPI > 0
-	if (acpi_present) {
-		mba.mba_acpi.aa_iot = X86_BUS_SPACE_IO;
-		mba.mba_acpi.aa_memt = X86_BUS_SPACE_MEM;
-		mba.mba_acpi.aa_pc = NULL;
-		mba.mba_acpi.aa_pciflags =
-		    PCI_FLAGS_IO_ENABLED | PCI_FLAGS_MEM_ENABLED |
-		    PCI_FLAGS_MRL_OKAY | PCI_FLAGS_MRM_OKAY |
-		    PCI_FLAGS_MWI_OKAY;
-		mba.mba_acpi.aa_ic = &x86_isa_chipset;
-		config_found_ia(self, "acpibus", &mba.mba_acpi, 0);
-#if 0 /* XXXJRT not yet */
-		if (acpi_active) {
-			/*
-			 * ACPI already did all the work for us, there
-			 * is nothing more for us to do.
-			 */
-			return;
-		}
-#endif
-	}
-#endif
+	mainbus_rescan(self, "acpibus", NULL);
 
-#if NPNPBIOS > 0
-#if NACPI > 0
-	if (acpi_active == 0)
-#endif
-	if (pnpbios_probe()) {
-		mba.mba_paa.paa_ic = &x86_isa_chipset;
-		config_found_ia(self, "pnpbiosbus", &mba.mba_paa, 0);
-	}
-#endif
+	mainbus_rescan(self, "pnpbiosbus", NULL);
+
+	mainbus_rescan(self, "ipmibus", NULL);
 
-#if NIPMI > 0
-	memset(&mba.mba_ipmi, 0, sizeof(mba.mba_ipmi));
-	mba.mba_ipmi.iaa_iot = X86_BUS_SPACE_IO;
-	mba.mba_ipmi.iaa_memt = X86_BUS_SPACE_MEM;
-	if (ipmi_probe(&mba.mba_ipmi))
-		config_found_ia(self, "ipmibus", &mba.mba_ipmi, 0);
-#endif
 	/*
 	 * XXX Note also that the presence of a PCI bus should
 	 * XXX _always_ be checked, and if present the bus should be
@@ -333,17 +321,7 @@
 	}
 #endif
 
-#if NMCA > 0
-	/* Note: MCA bus probe is done in i386/machdep.c */
-	if (MCA_system) {
-		mba.mba_mba.mba_iot = X86_BUS_SPACE_IO;
-		mba.mba_mba.mba_memt = X86_BUS_SPACE_MEM;
-		mba.mba_mba.mba_dmat = &mca_bus_dma_tag;
-		mba.mba_mba.mba_mc = NULL;
-		mba.mba_mba.mba_bus = 0;
-		config_found_ia(self, "mcabus", &mba.mba_mba, mcabusprint);
-	}
-#endif
+	mainbus_rescan(self, "mcabus", NULL);
 
 	if (memcmp(ISA_HOLE_VADDR(EISA_ID_PADDR), EISA_ID, EISA_ID_LEN) == 0 &&
 	    eisa_has_been_seen == 0) {
@@ -372,6 +350,87 @@
 		aprint_error_dev(self, "couldn't establish power handler\n");
 }
 
+/* XXX share this with sys/arch/i386/pci/elan520.c */
+static bool
+ifattr_match(const char *snull, const char *t)
+{
+	return (snull == NULL) || strcmp(snull, t) == 0;
+}
+
+/* scan for new children */
+static int
+mainbus_rescan(device_t self, const char *ifattr, const int *locators)
+{
+	struct mainbus_softc *sc = device_private(self);
+	union mainbus_attach_args mba;
+
+	if (ifattr_match(ifattr, "acpibus") && sc->sc_acpi == NULL &&
+	    sc->sc_acpi_present) {
+#if NACPI > 0
+		mba.mba_acpi.aa_iot = X86_BUS_SPACE_IO;
+		mba.mba_acpi.aa_memt = X86_BUS_SPACE_MEM;
+		mba.mba_acpi.aa_pc = NULL;
+		mba.mba_acpi.aa_pciflags =
+		    PCI_FLAGS_IO_ENABLED | PCI_FLAGS_MEM_ENABLED |
+		    PCI_FLAGS_MRL_OKAY | PCI_FLAGS_MRM_OKAY |
+		    PCI_FLAGS_MWI_OKAY;
+		mba.mba_acpi.aa_ic = &x86_isa_chipset;
+		sc->sc_acpi =
+		    config_found_ia(self, "acpibus", &mba.mba_acpi, 0);
+#if 0 /* XXXJRT not yet */
+		if (acpi_active) {
+			/*
+			 * ACPI already did all the work for us, there
+			 * is nothing more for us to do.
+			 */
+			return;
+		}
+#endif
+#endif
+	}
+
+	if (ifattr_match(ifattr, "pnpbiosbus") && sc->sc_pnpbios == NULL) {
+#if NPNPBIOS > 0
+#if NACPI > 0
+		if (acpi_active == 0)
+#endif
+		if (pnpbios_probe()) {
+			mba.mba_paa.paa_ic = &x86_isa_chipset;
+			sc->sc_pnpbios = config_found_ia(self, "pnpbiosbus",
+			    &mba.mba_paa, 0);
+		}
+#endif
+	}
+
+	if (ifattr_match(ifattr, "ipmibus") && sc->sc_ipmi == NULL) {
+#if NIPMI > 0
+		memset(&mba.mba_ipmi, 0, sizeof(mba.mba_ipmi));
+		mba.mba_ipmi.iaa_iot = X86_BUS_SPACE_IO;
+		mba.mba_ipmi.iaa_memt = X86_BUS_SPACE_MEM;
+		if (ipmi_probe(&mba.mba_ipmi)) {
+			sc->sc_ipmi =
+			    config_found_ia(self, "ipmibus", &mba.mba_ipmi, 0);
+		}
+#endif
+	}
+
+	if (ifattr_match(ifattr, "mcabus") && sc->sc_mca == NULL) {
+#if NMCA > 0
+	/* Note: MCA bus probe is done in i386/machdep.c */
+		if (MCA_system) {
+			mba.mba_mba.mba_iot = X86_BUS_SPACE_IO;
+			mba.mba_mba.mba_memt = X86_BUS_SPACE_MEM;
+			mba.mba_mba.mba_dmat = &mca_bus_dma_tag;
+			mba.mba_mba.mba_mc = NULL;
+			mba.mba_mba.mba_bus = 0;
+			sc->sc_mca = config_found_ia(self, "mcabus",
+			    &mba.mba_mba, mcabusprint);
+		}
+#endif
+	}
+	return 0;
+}
+
 int
 mainbus_print(void *aux, const char *pnp)
 {

Reply via email to