Module Name: src Committed By: jruoho Date: Mon Mar 8 10:53:03 UTC 2010
Modified Files: src/sys/dev/acpi: wmi_acpi.c Log Message: Add a detachment routine. To generate a diff of this commit: cvs rdiff -u -r1.15 -r1.16 src/sys/dev/acpi/wmi_acpi.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/dev/acpi/wmi_acpi.c diff -u src/sys/dev/acpi/wmi_acpi.c:1.15 src/sys/dev/acpi/wmi_acpi.c:1.16 --- src/sys/dev/acpi/wmi_acpi.c:1.15 Fri Mar 5 14:00:17 2010 +++ src/sys/dev/acpi/wmi_acpi.c Mon Mar 8 10:53:03 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: wmi_acpi.c,v 1.15 2010/03/05 14:00:17 jruoho Exp $ */ +/* $NetBSD: wmi_acpi.c,v 1.16 2010/03/08 10:53:03 jruoho Exp $ */ /*- * Copyright (c) 2009, 2010 Jukka Ruohonen <jruoho...@iki.fi> @@ -27,7 +27,7 @@ * SUCH DAMAGE. */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: wmi_acpi.c,v 1.15 2010/03/05 14:00:17 jruoho Exp $"); +__KERNEL_RCSID(0, "$NetBSD: wmi_acpi.c,v 1.16 2010/03/08 10:53:03 jruoho Exp $"); #include <sys/param.h> #include <sys/device.h> @@ -117,6 +117,7 @@ static int acpi_wmi_match(device_t, cfdata_t, void *); static void acpi_wmi_attach(device_t, device_t, void *); +static int acpi_wmi_detach(device_t, int); static int acpi_wmi_print(void *, const char *); static bool acpi_wmi_init(struct acpi_wmi_softc *); static bool acpi_wmi_add(struct acpi_wmi_softc *, ACPI_OBJECT *); @@ -128,8 +129,8 @@ static ACPI_STATUS acpi_wmi_guid_get(struct acpi_wmi_softc *, const char *, struct wmi_t **); -static void acpi_wmi_event_add(struct acpi_wmi_softc *); -static void acpi_wmi_event_del(struct acpi_wmi_softc *); +static ACPI_STATUS acpi_wmi_event_add(struct acpi_wmi_softc *); +static ACPI_STATUS acpi_wmi_event_del(struct acpi_wmi_softc *); static void acpi_wmi_event_handler(ACPI_HANDLE, uint32_t, void *); static bool acpi_wmi_suspend(device_t, const pmf_qual_t *); static bool acpi_wmi_resume(device_t, const pmf_qual_t *); @@ -142,7 +143,7 @@ }; CFATTACH_DECL_NEW(acpiwmi, sizeof(struct acpi_wmi_softc), - acpi_wmi_match, acpi_wmi_attach, NULL, NULL); + acpi_wmi_match, acpi_wmi_attach, acpi_wmi_detach, NULL); static int acpi_wmi_match(device_t parent, cfdata_t match, void *aux) @@ -163,6 +164,8 @@ sc->sc_dev = self; sc->sc_node = aa->aa_node; + + sc->sc_child = NULL; sc->sc_handler = NULL; aprint_naive("\n"); @@ -175,18 +178,34 @@ acpi_wmi_dump(sc); #endif - acpi_wmi_event_add(sc); - - if (pmf_device_register(sc->sc_dev, - acpi_wmi_suspend, acpi_wmi_resume) != true) - aprint_error_dev(self, "failed to register power handler\n"); + (void)acpi_wmi_event_add(sc); + (void)pmf_device_register(self, acpi_wmi_suspend, acpi_wmi_resume); - /* Attach a child device to the pseudo-bus. */ sc->sc_child = config_found_ia(self, "acpiwmibus", NULL, acpi_wmi_print); } static int +acpi_wmi_detach(device_t self, int flags) +{ + struct acpi_wmi_softc *sc = device_private(self); + ACPI_STATUS rv; + + rv = acpi_wmi_event_del(sc); + + if (ACPI_FAILURE(rv)) + return EBUSY; + + if (sc->sc_child != NULL) + (void)config_detach(sc->sc_child, flags); + + acpi_wmi_del(sc); + pmf_device_deregister(self); + + return 0; +} + +static int acpi_wmi_print(void *aux, const char *pnp) { @@ -389,7 +408,7 @@ /* * Adds internal event handler. */ -static void +static ACPI_STATUS acpi_wmi_event_add(struct acpi_wmi_softc *sc) { struct wmi_t *wmi; @@ -401,7 +420,7 @@ if (ACPI_FAILURE(rv)) { aprint_error_dev(sc->sc_dev, "failed to install notify " "handler: %s\n", AcpiFormatException(rv)); - return; + return rv; } /* Enable possible expensive events. */ @@ -422,12 +441,14 @@ "expensive WExx: %s\n", AcpiFormatException(rv)); } } + + return AE_OK; } /* * Removes the internal event handler. */ -static void +static ACPI_STATUS acpi_wmi_event_del(struct acpi_wmi_softc *sc) { struct wmi_t *wmi; @@ -439,7 +460,7 @@ if (ACPI_FAILURE(rv)) { aprint_debug_dev(sc->sc_dev, "failed to remove notify " "handler: %s\n", AcpiFormatException(rv)); - return; + return rv; } SIMPLEQ_FOREACH(wmi, &sc->wmi_head, wmi_link) { @@ -461,6 +482,8 @@ aprint_error_dev(sc->sc_dev, "failed to disable " "expensive WExx: %s\n", AcpiFormatException(rv)); } + + return AE_OK; } /* @@ -512,6 +535,9 @@ { struct acpi_wmi_softc *sc = aux; + if (sc->sc_child == NULL) + return; + if (sc->sc_handler == NULL) return;