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)
{