From: mpi Date: Thu, 30 Apr 2015 10:00:50 +0000 (+0000) Subject: Instead of using a single flat array for all sensors, put all the X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=3d645ebb7575e2dd2a2dfd951ffc9c1712d33920;p=openbsd Instead of using a single flat array for all sensors, put all the children of a sensor in a separate structure. Children sensors should only be probbed if their parent is active. This make the dependency tree explicit and will reduce the number of I/O. From David Higgs. --- diff --git a/sys/dev/usb/upd.c b/sys/dev/usb/upd.c index 428b2c28cc9..93b06e9e8d1 100644 --- a/sys/dev/usb/upd.c +++ b/sys/dev/usb/upd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: upd.c,v 1.17 2015/04/27 09:14:45 mpi Exp $ */ +/* $OpenBSD: upd.c,v 1.18 2015/04/30 10:00:50 mpi Exp $ */ /* * Copyright (c) 2014 Andre de Oliveira @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -46,9 +47,11 @@ struct upd_usage_entry { uint8_t usage_id; enum sensor_type senstype; char *usage_name; /* sensor string */ + int nchildren; + struct upd_usage_entry *children; }; -static struct upd_usage_entry upd_usage_table[] = { +static struct upd_usage_entry upd_usage_batdep[] = { { HUP_BATTERY, HUB_REL_STATEOF_CHARGE, SENSOR_PERCENT, "RelativeStateOfCharge" }, { HUP_BATTERY, HUB_ABS_STATEOF_CHARGE, @@ -61,25 +64,32 @@ static struct upd_usage_entry upd_usage_table[] = { SENSOR_INDICATOR, "Charging" }, { HUP_BATTERY, HUB_DISCHARGING, SENSOR_INDICATOR, "Discharging" }, + { HUP_BATTERY, HUB_ATRATE_TIMETOFULL, + SENSOR_TIMEDELTA, "AtRateTimeToFull" } +}; +static struct upd_usage_entry upd_usage_roots[] = { { HUP_BATTERY, HUB_BATTERY_PRESENT, - SENSOR_INDICATOR, "BatteryPresent" }, + SENSOR_INDICATOR, "BatteryPresent", + nitems(upd_usage_batdep), upd_usage_batdep }, { HUP_POWER, HUP_SHUTDOWN_IMMINENT, SENSOR_INDICATOR, "ShutdownImminent" }, { HUP_BATTERY, HUB_AC_PRESENT, - SENSOR_INDICATOR, "ACPresent" }, - { HUP_BATTERY, HUB_ATRATE_TIMETOFULL, - SENSOR_TIMEDELTA, "AtRateTimeToFull" } + SENSOR_INDICATOR, "ACPresent" } }; +#define UPD_MAX_SENSORS (nitems(upd_usage_batdep) + nitems(upd_usage_roots)) struct upd_report { size_t size; int enabled; }; +SLIST_HEAD(upd_sensor_head, upd_sensor); struct upd_sensor { - struct ksensor ksensor; - struct hid_item hitem; - int attached; + struct ksensor ksensor; + struct hid_item hitem; + int attached; + struct upd_sensor_head children; + SLIST_ENTRY(upd_sensor) dep_next; }; struct upd_softc { @@ -92,10 +102,13 @@ struct upd_softc { struct sensor_task *sc_sensortask; struct upd_report *sc_reports; struct upd_sensor *sc_sensors; + struct upd_sensor_head sc_root_sensors; }; int upd_match(struct device *, void *, void *); void upd_attach(struct device *, struct device *, void *); +void upd_attach_sensor_tree(struct upd_softc *, void *, int, int, + struct upd_usage_entry *, struct upd_sensor_head *); int upd_detach(struct device *, int); void upd_refresh(void *); @@ -134,13 +147,11 @@ upd_match(struct device *parent, void *match, void *aux) DPRINTF(("upd: vendor=0x%04x, product=0x%04x\n", uha->uaa->vendor, uha->uaa->product)); - /* - * look for at least one sensor of our table - */ + /* need at least one sensor from root of tree */ uhidev_get_report_desc(uha->parent, &desc, &size); - for (i = 0; i < nitems(upd_usage_table); i++) + for (i = 0; i < nitems(upd_usage_roots); i++) if (upd_lookup_usage_entry(desc, size, - upd_usage_table + i, &item)) { + upd_usage_roots + i, &item)) { ret = UMATCH_VENDOR_PRODUCT; break; } @@ -153,9 +164,6 @@ upd_attach(struct device *parent, struct device *self, void *aux) { struct upd_softc *sc = (struct upd_softc *)self; struct uhidev_attach_arg *uha = (struct uhidev_attach_arg *)aux; - struct hid_item item; - struct upd_usage_entry *entry; - struct upd_sensor *sensor; int size; int i; void *desc; @@ -164,6 +172,7 @@ upd_attach(struct device *parent, struct device *self, void *aux) sc->sc_hdev.sc_parent = uha->parent; sc->sc_reports = NULL; sc->sc_sensors = NULL; + SLIST_INIT(&sc->sc_root_sensors); strlcpy(sc->sc_sensordev.xname, DEVNAME(sc), sizeof(sc->sc_sensordev.xname)); @@ -174,13 +183,41 @@ upd_attach(struct device *parent, struct device *self, void *aux) sc->sc_reports = mallocarray(sc->sc_max_repid, sizeof(struct upd_report), M_USBDEV, M_WAITOK | M_ZERO); - sc->sc_sensors = mallocarray(nitems(upd_usage_table), + sc->sc_sensors = mallocarray(UPD_MAX_SENSORS, sizeof(struct upd_sensor), M_USBDEV, M_WAITOK | M_ZERO); - sc->sc_num_sensors = 0; + for (i = 0; i < UPD_MAX_SENSORS; i++) + SLIST_INIT(&sc->sc_sensors[i].children); + sc->sc_num_sensors = 0; uhidev_get_report_desc(uha->parent, &desc, &size); - for (i = 0; i < nitems(upd_usage_table); i++) { - entry = &upd_usage_table[i]; + upd_attach_sensor_tree(sc, desc, size, nitems(upd_usage_roots), + upd_usage_roots, &sc->sc_root_sensors); + DPRINTF(("upd: sc_num_sensors=%d\n", sc->sc_num_sensors)); + + sc->sc_sensortask = sensor_task_register(sc, upd_refresh, 6); + if (sc->sc_sensortask == NULL) { + printf(", unable to register update task\n"); + return; + } + sensordev_install(&sc->sc_sensordev); + + printf("\n"); + + DPRINTF(("upd_attach: complete\n")); +} + +void +upd_attach_sensor_tree(struct upd_softc *sc, void *desc, int size, + int nentries, struct upd_usage_entry *entries, + struct upd_sensor_head *queue) +{ + struct hid_item item; + struct upd_usage_entry *entry; + struct upd_sensor *sensor; + int i; + + for (i = 0; i < nentries; i++) { + entry = entries + i; if (!upd_lookup_usage_entry(desc, size, entry, &item)) continue; @@ -200,27 +237,18 @@ upd_attach(struct device *parent, struct device *self, void *aux) sensor->ksensor.value = 0; sensor_attach(&sc->sc_sensordev, &sensor->ksensor); sensor->attached = 1; + SLIST_INSERT_HEAD(queue, sensor, dep_next); sc->sc_num_sensors++; + upd_attach_sensor_tree(sc, desc, size, entry->nchildren, + entry->children, &sensor->children); + if (sc->sc_reports[item.report_ID].enabled) continue; - sc->sc_reports[item.report_ID].size = hid_report_size(desc, size, item.kind, item.report_ID); sc->sc_reports[item.report_ID].enabled = 1; } - DPRINTF(("upd: sc_num_sensors=%d\n", sc->sc_num_sensors)); - - sc->sc_sensortask = sensor_task_register(sc, upd_refresh, 6); - if (sc->sc_sensortask == NULL) { - printf(", unable to register update task\n"); - return; - } - sensordev_install(&sc->sc_sensordev); - - printf("\n"); - - DPRINTF(("upd_attach: complete\n")); } int