Module Name: src Committed By: jruoho Date: Sun Jan 31 11:16:18 UTC 2010
Modified Files: src/sys/dev/acpi: acpi_acad.c Log Message: Simplify and clean: * Semantics. * Remove ACPI_ACAD_DEBUG. * Reduce the amount of error reporting. * Remove the internal bookkeeping flags and variables; instead operate only with a single state variable. * Trust that the notify handler is doing its job; remove the refresh routine from the sensor. * Queue a status check upon resume; we want to know if the status has changed when in suspend (and it is unclear if a notify is sent to us). To generate a diff of this commit: cvs rdiff -u -r1.38 -r1.39 src/sys/dev/acpi/acpi_acad.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/acpi_acad.c diff -u src/sys/dev/acpi/acpi_acad.c:1.38 src/sys/dev/acpi/acpi_acad.c:1.39 --- src/sys/dev/acpi/acpi_acad.c:1.38 Sun Jan 31 07:34:10 2010 +++ src/sys/dev/acpi/acpi_acad.c Sun Jan 31 11:16:18 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: acpi_acad.c,v 1.38 2010/01/31 07:34:10 jruoho Exp $ */ +/* $NetBSD: acpi_acad.c,v 1.39 2010/01/31 11:16:18 jruoho Exp $ */ /* * Copyright 2001 Wasabi Systems, Inc. @@ -35,16 +35,12 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#if 0 -#define ACPI_ACAD_DEBUG -#endif - /* * ACPI AC Adapter driver. */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: acpi_acad.c,v 1.38 2010/01/31 07:34:10 jruoho Exp $"); +__KERNEL_RCSID(0, "$NetBSD: acpi_acad.c,v 1.39 2010/01/31 11:16:18 jruoho Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -57,20 +53,16 @@ #include <dev/sysmon/sysmonvar.h> -#define _COMPONENT ACPI_ACAD_COMPONENT -ACPI_MODULE_NAME ("acpi_acad") +#define _COMPONENT ACPI_ACAD_COMPONENT +ACPI_MODULE_NAME ("acpi_acad") struct acpiacad_softc { - struct acpi_devnode *sc_node; /* our ACPI devnode */ - int sc_flags; /* see below */ - int sc_status; /* status changed/not changed */ - int sc_notifysent; /* notify message sent */ - - struct sysmon_envsys *sc_sme; - struct sysmon_pswitch sc_smpsw; /* our sysmon glue */ - envsys_data_t sc_sensor; - - kmutex_t sc_mtx; + struct acpi_devnode *sc_node; + struct sysmon_envsys *sc_sme; + struct sysmon_pswitch sc_smpsw; + envsys_data_t sc_sensor; + kmutex_t sc_mutex; + int sc_status; }; static const char * const acad_hid[] = { @@ -78,23 +70,13 @@ NULL }; -#define AACAD_F_VERBOSE 0x01 /* verbose events */ -#define AACAD_F_AVAILABLE 0x02 /* information is available */ -#define AACAD_F_STCHANGED 0x04 /* status changed */ - -#define AACAD_SET(sc, f) (void)((sc)->sc_flags |= (f)) -#define AACAD_CLEAR(sc, f) (void)((sc)->sc_flags &= ~(f)) -#define AACAD_ISSET(sc, f) ((sc)->sc_flags & (f)) - -static int acpiacad_match(device_t, cfdata_t, void *); -static void acpiacad_attach(device_t, device_t, void *); -static int acpiacad_detach(device_t, int); -static void acpiacad_get_status(void *); -static void acpiacad_clear_status(struct acpiacad_softc *); -static void acpiacad_notify_handler(ACPI_HANDLE, UINT32, void *); -static void acpiacad_init_envsys(device_t); -static void acpiacad_refresh(struct sysmon_envsys *, envsys_data_t *); -static bool acpiacad_resume(device_t, pmf_qual_t); +static int acpiacad_match(device_t, cfdata_t, void *); +static void acpiacad_attach(device_t, device_t, void *); +static int acpiacad_detach(device_t, int); +static bool acpiacad_resume(device_t, pmf_qual_t); +static void acpiacad_get_status(void *); +static void acpiacad_notify_handler(ACPI_HANDLE, uint32_t, void *); +static void acpiacad_init_envsys(device_t); CFATTACH_DECL_NEW(acpiacad, sizeof(struct acpiacad_softc), acpiacad_match, acpiacad_attach, acpiacad_detach, NULL); @@ -130,36 +112,23 @@ aprint_naive(": ACPI AC Adapter\n"); aprint_normal(": ACPI AC Adapter\n"); + sc->sc_sme = NULL; + sc->sc_status = -1; sc->sc_node = aa->aa_node; - mutex_init(&sc->sc_mtx, MUTEX_DEFAULT, IPL_NONE); + + mutex_init(&sc->sc_mutex, MUTEX_DEFAULT, IPL_NONE); sc->sc_smpsw.smpsw_name = device_xname(self); sc->sc_smpsw.smpsw_type = PSWITCH_TYPE_ACADAPTER; - if (sysmon_pswitch_register(&sc->sc_smpsw) != 0) { - aprint_error_dev(self, "unable to register with sysmon\n"); - return; - } - sc->sc_sme = NULL; - sc->sc_status = -1; + (void)sysmon_pswitch_register(&sc->sc_smpsw); + (void)pmf_device_register(self, NULL, acpiacad_resume); rv = AcpiInstallNotifyHandler(sc->sc_node->ad_handle, ACPI_ALL_NOTIFY, acpiacad_notify_handler, self); - if (ACPI_FAILURE(rv)) { - aprint_error_dev(self, "unable to register DEVICE and SYSTEM " - "NOTIFY handler: %s\n", AcpiFormatException(rv)); - return; - } - -#ifdef ACPI_ACAD_DEBUG - /* Display the current state. */ - sc->sc_flags = AACAD_F_VERBOSE; -#endif - if (!pmf_device_register(self, NULL, acpiacad_resume)) - aprint_error_dev(self, "couldn't establish power handler\n"); - - acpiacad_init_envsys(self); + if (ACPI_SUCCESS(rv)) + acpiacad_init_envsys(self); } /* @@ -179,7 +148,7 @@ if (ACPI_FAILURE(rv)) return EBUSY; - mutex_destroy(&sc->sc_mtx); + mutex_destroy(&sc->sc_mutex); if (sc->sc_sme != NULL) sysmon_envsys_unregister(sc->sc_sme); @@ -193,14 +162,14 @@ /* * acpiacad_resume: * - * Clear status after resuming to fetch new status. + * Queue a new status check. */ static bool acpiacad_resume(device_t dv, pmf_qual_t qual) { - struct acpiacad_softc *sc = device_private(dv); - acpiacad_clear_status(sc); + (void)AcpiOsExecute(OSL_NOTIFY_HANDLER, acpiacad_get_status, dv); + return true; } @@ -217,48 +186,49 @@ ACPI_INTEGER status; ACPI_STATUS rv; + mutex_enter(&sc->sc_mutex); + rv = acpi_eval_integer(sc->sc_node->ad_handle, "_PSR", &status); + if (ACPI_FAILURE(rv)) - return; + goto fail; - mutex_enter(&sc->sc_mtx); - sc->sc_notifysent = 0; - if (sc->sc_status != status) { - sc->sc_status = status; - if (status) - sc->sc_sensor.value_cur = 1; - else - sc->sc_sensor.value_cur = 0; - AACAD_SET(sc, AACAD_F_STCHANGED); + if (status != 0 && status != 1) { + rv = AE_BAD_VALUE; + goto fail; } - sc->sc_sensor.state = ENVSYS_SVALID; - AACAD_SET(sc, AACAD_F_AVAILABLE); - /* - * If status has changed, send the event. - * - * PSWITCH_EVENT_RELEASED : AC offline - * PSWITCH_EVENT_PRESSED : AC online - */ - if (AACAD_ISSET(sc, AACAD_F_STCHANGED)) { - sysmon_pswitch_event(&sc->sc_smpsw, status ? + if (sc->sc_status != status) { + + /* + * If status has changed, send the event: + * + * PSWITCH_EVENT_PRESSED : _PSR = 1 : AC online. + * PSWITCH_EVENT_RELEASED : _PSR = 0 : AC offline. + */ + sysmon_pswitch_event(&sc->sc_smpsw, (status != 0) ? PSWITCH_EVENT_PRESSED : PSWITCH_EVENT_RELEASED); - if (AACAD_ISSET(sc, AACAD_F_VERBOSE)) - aprint_verbose_dev(dv, "AC adapter %sconnected\n", - status == 0 ? "not " : ""); + + aprint_debug_dev(dv, "AC adapter %sconnected\n", + status == 0 ? "not " : ""); } - mutex_exit(&sc->sc_mtx); -} -/* - * Clear status - */ -static void -acpiacad_clear_status(struct acpiacad_softc *sc) -{ + sc->sc_status = status; + sc->sc_sensor.state = ENVSYS_SVALID; + sc->sc_sensor.value_cur = sc->sc_status; + + mutex_exit(&sc->sc_mutex); + + return; + +fail: + sc->sc_status = -1; sc->sc_sensor.state = ENVSYS_SINVALID; - AACAD_CLEAR(sc, AACAD_F_AVAILABLE); - AACAD_CLEAR(sc, AACAD_F_STCHANGED); + + aprint_debug_dev(dv, "failed to evaluate _PSR: %s\n", + AcpiFormatException(rv)); + + mutex_exit(&sc->sc_mutex); } /* @@ -267,11 +237,10 @@ * Callback from ACPI interrupt handler to notify us of an event. */ static void -acpiacad_notify_handler(ACPI_HANDLE handle, UINT32 notify, void *context) +acpiacad_notify_handler(ACPI_HANDLE handle, uint32_t notify, void *context) { + static const int handler = OSL_NOTIFY_HANDLER; device_t dv = context; - struct acpiacad_softc *sc = device_private(dv); - ACPI_STATUS rv; switch (notify) { /* @@ -293,27 +262,11 @@ case ACPI_NOTIFY_DeviceCheck: case ACPI_NOTIFY_PowerSourceStatusChanged: case ACPI_NOTIFY_BatteryInformationChanged: - mutex_enter(&sc->sc_mtx); - acpiacad_clear_status(sc); - mutex_exit(&sc->sc_mtx); - if (sc->sc_status == -1 || !sc->sc_notifysent) { - rv = AcpiOsExecute(OSL_NOTIFY_HANDLER, - acpiacad_get_status, dv); - if (ACPI_FAILURE(rv)) - aprint_error_dev(dv, - "unable to queue status check: %s\n", - AcpiFormatException(rv)); - sc->sc_notifysent = 1; -#ifdef ACPI_ACAD_DEBUG - aprint_debug_dev(dv, "received notify message: 0x%x\n", - notify); -#endif - } + (void)AcpiOsExecute(handler, acpiacad_get_status, dv); break; default: - aprint_error_dev(dv, "received unknown notify message: 0x%x\n", - notify); + aprint_error_dev(dv, "unknown notify 0x%02X\n", notify); } } @@ -323,22 +276,24 @@ struct acpiacad_softc *sc = device_private(dv); sc->sc_sme = sysmon_envsys_create(); - sc->sc_sensor.state = ENVSYS_SVALID; + + sc->sc_sensor.state = ENVSYS_SINVALID; sc->sc_sensor.units = ENVSYS_INDICATOR; - strlcpy(sc->sc_sensor.desc, "connected", sizeof(sc->sc_sensor.desc)); + + (void)strlcpy(sc->sc_sensor.desc, "connected", ENVSYS_DESCLEN); if (sysmon_envsys_sensor_attach(sc->sc_sme, &sc->sc_sensor) != 0) goto fail; sc->sc_sme->sme_name = device_xname(dv); - sc->sc_sme->sme_cookie = dv; - sc->sc_sme->sme_refresh = acpiacad_refresh; sc->sc_sme->sme_class = SME_CLASS_ACADAPTER; - sc->sc_sme->sme_flags = SME_INIT_REFRESH; + sc->sc_sme->sme_flags = SME_DISABLE_REFRESH; if (sysmon_envsys_register(sc->sc_sme) != 0) goto fail; + (void)AcpiOsExecute(OSL_NOTIFY_HANDLER, acpiacad_get_status, dv); + return; fail: @@ -346,13 +301,3 @@ sysmon_envsys_destroy(sc->sc_sme); sc->sc_sme = NULL; } - -static void -acpiacad_refresh(struct sysmon_envsys *sme, envsys_data_t *edata) -{ - device_t dv = sme->sme_cookie; - struct acpiacad_softc *sc = device_private(dv); - - if (!AACAD_ISSET(sc, AACAD_F_AVAILABLE)) - acpiacad_get_status(dv); -}