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;


Reply via email to