you cant test a variable and then sleep on it without blocking
interrupts, cos a completion could change the variables state between
those two actions.

could anyone test setting a hotspare on ami(4) while doing io?

dlg

Index: ami.c
===================================================================
RCS file: /cvs/src/sys/dev/ic/ami.c,v
retrieving revision 1.204
diff -u -p ami.c
--- ami.c       20 May 2010 00:55:17 -0000      1.204
+++ ami.c       31 May 2010 12:42:47 -0000
@@ -186,11 +186,8 @@ ami_remove_runq(struct ami_ccb *ccb)
        splassert(IPL_BIO);
 
        TAILQ_REMOVE(&ccb->ccb_sc->sc_ccb_runq, ccb, ccb_link);
-       if (TAILQ_EMPTY(&ccb->ccb_sc->sc_ccb_runq)) {
-               ccb->ccb_sc->sc_drained = 1;
-               if (ccb->ccb_sc->sc_drainio)
-                       wakeup(ccb->ccb_sc);
-       }
+       if (ccb->ccb_sc->sc_drainio && TAILQ_EMPTY(&ccb->ccb_sc->sc_ccb_runq))
+               wakeup(ccb->ccb_sc);
 }
 
 void
@@ -198,7 +195,6 @@ ami_insert_runq(struct ami_ccb *ccb)
 {
        splassert(IPL_BIO);
 
-       ccb->ccb_sc->sc_drained = 0;
        TAILQ_INSERT_TAIL(&ccb->ccb_sc->sc_ccb_runq, ccb, ccb_link);
 }
 
@@ -539,7 +535,6 @@ ami_attach(struct ami_softc *sc)
                /* error already printed */
                goto free_mbox;
        }
-       sc->sc_drained = 1;
 
        /* hack for hp netraid version encoding */
        if ('A' <= sc->sc_fwver[2] && sc->sc_fwver[2] <= 'Z' &&
@@ -1016,7 +1011,6 @@ ami_runqueue(struct ami_softc *sc)
 
        while ((ccb = TAILQ_FIRST(&sc->sc_ccb_preq)) != NULL) {
                if (sc->sc_exec(sc, &ccb->ccb_cmd) != 0) {
-                       /* this is now raceable too with other incoming io */
                        timeout_add(&sc->sc_run_tmo, 1);
                        break;
                }
@@ -1895,10 +1889,8 @@ ami_mgmt(struct ami_softc *sc, u_int8_t opcode, u_int8
                        goto err;
                }
                ccb->ccb_done = ami_done_ioctl;
-       } else {
+       } else
                ccb = sc->sc_mgmtccb;
-               ccb->ccb_done = ami_done_dummy;
-       }
 
        if (size) {
                if ((am = ami_allocmem(sc, size)) == NULL) {
@@ -1930,22 +1922,29 @@ ami_mgmt(struct ami_softc *sc, u_int8_t opcode, u_int8
 
        if (opcode != AMI_CHSTATE) {
                ami_start(sc, ccb);
+               s = splbio();
                while (ccb->ccb_state != AMI_CCB_READY)
                        tsleep(ccb, PRIBIO,"ami_mgmt", 0);
+               splx(s);
        } else {
                /* change state must be run with id 0xfe and MUST be polled */
+               s = splbio();
                sc->sc_drainio = 1;
-               while (sc->sc_drained != 1)
+               while (!TAILQ_EMPTY(&sc->sc_ccb_runq)) {
                        if (tsleep(sc, PRIBIO, "ami_mgmt_drain", hz * 60) ==
                            EWOULDBLOCK) {
                                printf("%s: drain io timeout\n", DEVNAME(sc));
                                ccb->ccb_flags |= AMI_CCB_F_ERR;
                                goto restartio;
                        }
-               ami_poll(sc, ccb);
+               }
+
+               error = sc->sc_poll(sc, &ccb->ccb_cmd);
+               if (error == -1)
+                       ccb->ccb_flags |= AMI_CCB_F_ERR;
+
 restartio:
                /* restart io */
-               s = splbio();
                sc->sc_drainio = 0;
                ami_runqueue(sc);
                splx(s);
@@ -1966,7 +1965,6 @@ memerr:
        } else {
                ccb->ccb_flags = 0;
                ccb->ccb_state = AMI_CCB_FREE;
-               ccb->ccb_done = NULL;
        }
 
 err:
Index: amivar.h
===================================================================
RCS file: /cvs/src/sys/dev/ic/amivar.h,v
retrieving revision 1.54
diff -u -p amivar.h
--- amivar.h    28 Oct 2008 11:43:10 -0000      1.54
+++ amivar.h    31 May 2010 12:42:47 -0000
@@ -149,7 +149,6 @@ struct ami_softc {
        char                    sc_plist[AMI_BIG_MAX_PDRIVES];
 
        struct ami_ccb          *sc_mgmtccb;
-       int                     sc_drained;
        int                     sc_drainio;
        u_int8_t                sc_drvinscnt;
 };

Reply via email to