diff options
| author | dyoung <dyoung@NetBSD.org> | 2009-04-07 22:01:38 +0000 |
|---|---|---|
| committer | dyoung <dyoung@NetBSD.org> | 2009-04-07 22:01:38 +0000 |
| commit | b6889a3f64b36ee5872ae14ef12c8cd796c2175a (patch) | |
| tree | e9836749a8f112854ef1d7a86a29b761c898c7fa /sys | |
| parent | 3afac3e1897a39e6ab80110b905eff79a27a0798 (diff) | |
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.
Diffstat (limited to 'sys')
| -rw-r--r-- | sys/arch/i386/i386/mainbus.c | 185 |
1 files changed, 122 insertions, 63 deletions
diff --git a/sys/arch/i386/i386/mainbus.c b/sys/arch/i386/i386/mainbus.c index a91401b6434..0d141a64250 100644 --- a/sys/arch/i386/i386/mainbus.c +++ b/sys/arch/i386/i386/mainbus.c @@ -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 @@ __KERNEL_RCSID(0, "$NetBSD: mainbus.c,v 1.81 2009/03/14 15:36:07 dsl Exp $"); #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 @@ int mp_verbose = 0; 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 @@ mainbus_match(struct device *parent, struct cfdata *match, void *aux) * 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 @@ mainbus_attach(struct device *parent, struct device *self, void *aux) int mpacpi_active = 0; int numcpus = 0; + sc->sc_dev = self; + aprint_naive("\n"); aprint_normal("\n"); @@ -223,13 +245,13 @@ mainbus_attach(struct device *parent, struct device *self, void *aux) #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 @@ mainbus_attach(struct device *parent, struct device *self, void *aux) 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 @@ mainbus_attach(struct device *parent, struct device *self, void *aux) } #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 @@ mainbus_attach(struct device *parent, struct device *self, void *aux) 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) { |
