This is the final patch in the series. Utilize the pending flags and report callback for their intended purpose - to process async behavior.
Apply splusb() to ensure report callbacks can't fire before their data structures have been properly updated. This only needs to happen in upd_refresh(); all other calls to upd_request_children() are from a report callback. --david --- a/upd.c +++ b/upd.c @@ -99,6 +99,7 @@ struct upd_softc { struct uhidev sc_hdev; int sc_num_sensors; u_int sc_max_repid; + char sc_buf[256]; /* sensor framework */ struct ksensordev sc_sensordev; @@ -290,27 +291,12 @@ void upd_refresh(void *arg) { struct upd_softc *sc = arg; - struct upd_report *report; - uint8_t buf[256]; - int repid, actlen, done; + int s; - /* request root sensors */ + /* request root sensors, do not let async handlers fire yet */ + s = splusb(); upd_request_children(sc, &sc->sc_root_sensors, 1); - - /* repeat until all reports queried */ - do { - done = 1; - for (repid = 0; repid < sc->sc_max_repid; repid++) { - report = &sc->sc_reports[repid]; - if (!report->pending) - continue; - memset(buf, 0x0, sizeof(buf)); - actlen = uhidev_get_report(sc->sc_hdev.sc_parent, - UHID_FEATURE_REPORT, repid, buf, report->size); - upd_update_report_cb(sc, repid, buf, actlen); - done = 0; - } - } while (!done); + splx(s); } void @@ -336,7 +322,14 @@ upd_request_children(struct upd_softc *s } else if (report->pending) /* already requested */ sensor->pending = 1; - else { + else if (uhidev_get_report_async(sc->sc_hdev.sc_parent, + UHID_FEATURE_REPORT, repid, sc->sc_buf, + report->size, sc, upd_update_report_cb) < 0) { + DPRINTF(("%s: %s request of repid %d failed\n", + DEVNAME(sc), sensor->ksensor.desc, repid)); + sensor->pending = 1; + upd_update_report_cb(sc, repid, NULL, -1); + } else { DPRINTF(("%s: %s requests repid %d\n", DEVNAME(sc), sensor->ksensor.desc, repid)); sensor->pending = 1;