Module Name: src Committed By: pgoyette Date: Fri Mar 19 01:16:45 UTC 2010
Modified Files: src/sys/dev/sysmon: sysmon_envsys_events.c sysmon_envsysvar.h Log Message: Separate event delivery from polling and limit evaluation in sme_events_worker(). Provide a wrapper that can be called from sensor drivers' interrupt routines to find and deliver a specific event. XXX Actually updating sensor drivers (and their parent devices) to XXX have interrupts is a future enhancement. This is simply an XXX enabler. To generate a diff of this commit: cvs rdiff -u -r1.85 -r1.86 src/sys/dev/sysmon/sysmon_envsys_events.c cvs rdiff -u -r1.32 -r1.33 src/sys/dev/sysmon/sysmon_envsysvar.h 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/sysmon/sysmon_envsys_events.c diff -u src/sys/dev/sysmon/sysmon_envsys_events.c:1.85 src/sys/dev/sysmon/sysmon_envsys_events.c:1.86 --- src/sys/dev/sysmon/sysmon_envsys_events.c:1.85 Thu Feb 18 12:30:53 2010 +++ src/sys/dev/sysmon/sysmon_envsys_events.c Fri Mar 19 01:16:44 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: sysmon_envsys_events.c,v 1.85 2010/02/18 12:30:53 pgoyette Exp $ */ +/* $NetBSD: sysmon_envsys_events.c,v 1.86 2010/03/19 01:16:44 pgoyette Exp $ */ /*- * Copyright (c) 2007, 2008 Juan Romero Pardines. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: sysmon_envsys_events.c,v 1.85 2010/02/18 12:30:53 pgoyette Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sysmon_envsys_events.c,v 1.86 2010/03/19 01:16:44 pgoyette Exp $"); #include <sys/param.h> #include <sys/types.h> @@ -578,19 +578,15 @@ void sme_events_worker(struct work *wk, void *arg) { - const struct sme_description_table *sdt = NULL; - const struct sme_sensor_event *sse = sme_sensor_event; sme_event_t *see = (void *)wk; struct sysmon_envsys *sme = see->see_sme; envsys_data_t *edata = see->see_edata; - int i, state = 0; KASSERT(wk == &see->see_wk); KASSERT(sme != NULL || edata != NULL); mutex_enter(&sme->sme_mtx); - if ((see->see_flags & SEE_EVENT_WORKING) == 0) - see->see_flags |= SEE_EVENT_WORKING; + see->see_flags |= SEE_EVENT_WORKING; /* * sme_events_check marks the sensors to make us refresh them here. * Don't refresh if the driver uses its own method for refreshing. @@ -612,7 +608,6 @@ if (edata->state == ENVSYS_SINVALID) goto out; - switch (see->see_type) { /* * For range limits, if the driver claims responsibility for * limit/range checking, just user driver-supplied status. @@ -620,30 +615,74 @@ * relinquish responsibility for ALL limits if there is even * one limit that it cannot handle! */ + if ((see->see_type == PENVSYS_EVENT_LIMITS || + see->see_type == PENVSYS_EVENT_CAPACITY) && + (edata->upropset & PROP_DRIVER_LIMITS) == 0) { + if ((edata->upropset & (PROP_CRITMIN | PROP_BATTCAP)) && + (edata->value_cur < edata->limits.sel_critmin)) + edata->state = ENVSYS_SCRITUNDER; + else if ((edata->upropset & (PROP_WARNMIN | PROP_BATTWARN)) && + (edata->value_cur < edata->limits.sel_warnmin)) + edata->state = ENVSYS_SWARNUNDER; + else if ((edata->upropset & (PROP_CRITMAX | PROP_BATTMAX)) && + (edata->value_cur > edata->limits.sel_critmax)) + edata->state = ENVSYS_SCRITOVER; + else if ((edata->upropset & (PROP_WARNMAX | PROP_BATTHIGH)) && + (edata->value_cur > edata->limits.sel_warnmax)) + edata->state = ENVSYS_SWARNOVER; + else + edata->state = ENVSYS_SVALID; + } + sme_deliver_event(see); + +out: + see->see_flags &= ~SEE_EVENT_WORKING; + cv_broadcast(&sme->sme_condvar); + mutex_exit(&sme->sme_mtx); +} + +/* + * sme_deliver_typed_event + * + * + Find the monitor event of a particular type for a given sensor + * on a device and deliver the event if one is required. + */ +void +sme_deliver_typed_event(struct sysmon_envsys *sme, envsys_data_t *edata, + int ev_type) +{ + sme_event_t *see; + + mutex_enter(&sme->sme_mtx); + LIST_FOREACH(see, &sme->sme_events_list, see_list) { + if (edata != see->see_edata || + see->see_type != ev_type) + continue; + sme_deliver_event(see); + break; + } + mutex_exit(&sme->sme_mtx); +} + +/* + * sme_deliver_event: + * + * + If new sensor state requires it, send an event to powerd + * + * Must be called with the device's sysmon mutex held + * see->see_sme->sme_mtx + */ +void +sme_deliver_event(sme_event_t *see) +{ + envsys_data_t *edata = see->see_edata; + const struct sme_description_table *sdt = NULL; + const struct sme_sensor_event *sse = sme_sensor_event; + int i, state = 0; + + switch (see->see_type) { case PENVSYS_EVENT_LIMITS: case PENVSYS_EVENT_CAPACITY: -#define __EXCEED_LIM(valid, lim, rel) \ - ((edata->upropset & (valid)) && \ - (edata->value_cur rel (edata->limits.lim))) - - if ((edata->upropset & PROP_DRIVER_LIMITS) == 0) { - if __EXCEED_LIM(PROP_CRITMIN | PROP_BATTCAP, - sel_critmin, <) - edata->state = ENVSYS_SCRITUNDER; - else if __EXCEED_LIM(PROP_WARNMIN | PROP_BATTWARN, - sel_warnmin, <) - edata->state = ENVSYS_SWARNUNDER; - else if __EXCEED_LIM(PROP_CRITMAX | PROP_BATTMAX, - sel_critmax, >) - edata->state = ENVSYS_SCRITOVER; - else if __EXCEED_LIM(PROP_WARNMAX | PROP_BATTHIGH, - sel_warnmax, >) - edata->state = ENVSYS_SWARNOVER; - else - edata->state = ENVSYS_SVALID; - } -#undef __EXCEED_LIM - /* * Send event if state has changed */ @@ -763,7 +802,7 @@ * Stop the callout and send the 'low-power' event. */ sysmon_low_power = true; - callout_stop(&sme->sme_callout); + callout_stop(&see->see_sme->sme_callout); pes.pes_type = PENVSYS_TYPE_BATTERY; sysmon_penvsys_event(&pes, PENVSYS_EVENT_LOW_POWER); } @@ -771,11 +810,6 @@ default: panic("%s: invalid event type %d", __func__, see->see_type); } - -out: - see->see_flags &= ~SEE_EVENT_WORKING; - cv_broadcast(&sme->sme_condvar); - mutex_exit(&sme->sme_mtx); } /* Index: src/sys/dev/sysmon/sysmon_envsysvar.h diff -u src/sys/dev/sysmon/sysmon_envsysvar.h:1.32 src/sys/dev/sysmon/sysmon_envsysvar.h:1.33 --- src/sys/dev/sysmon/sysmon_envsysvar.h:1.32 Sun Mar 14 18:03:15 2010 +++ src/sys/dev/sysmon/sysmon_envsysvar.h Fri Mar 19 01:16:44 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: sysmon_envsysvar.h,v 1.32 2010/03/14 18:03:15 pgoyette Exp $ */ +/* $NetBSD: sysmon_envsysvar.h,v 1.33 2010/03/19 01:16:44 pgoyette Exp $ */ /*- * Copyright (c) 2007, 2008 Juan Romero Pardines. @@ -129,7 +129,9 @@ int sme_events_init(struct sysmon_envsys *); void sme_events_destroy(struct sysmon_envsys *); void sme_events_check(void *); -void sme_events_worker(struct work *, void *); +void sme_events_worker(struct work *, void *); +void sme_deliver_event(sme_event_t *); +void sme_deliver_typed_event(struct sysmon_envsys *, envsys_data_t *, int); /* * common functions to create/update objects in a dictionary.