If you look at the for-loop in ciss_cmd() you can see that there are
really two loops. One for SCSI_NOSLEEP with delay(9), the other with
tsleep(9). The two paths basically don't interact, they merely happen
to share the loop.
If we pull the if-else out of the loop and give each clause its own
for-loop the logic is a bit easier to follow.
Each loop then needs its own copy of
error = ciss_done(ccb1);
if (ccb1 == ccb)
return (error);
but that's a minor concession.
With the loop split it should be more obvious that we can remove the
ticks from the tsleep(9) path without breaking the other path.
Ken: I think this is better than what I sent you before.
ok?
Index: ic/ciss.c
===================================================================
RCS file: /cvs/src/sys/dev/ic/ciss.c,v
retrieving revision 1.76
diff -u -p -r1.76 ciss.c
--- ic/ciss.c 20 Jan 2020 07:28:03 -0000 1.76
+++ ic/ciss.c 22 Jan 2020 02:34:19 -0000
@@ -532,8 +532,9 @@ ciss_cmd(struct ciss_ccb *ccb, int flags
tohz = tvtohz(&tv);
if (tohz == 0)
tohz = 1;
- for (i *= 100, etick = tick + tohz; i--; ) {
- if (!(wait & SCSI_NOSLEEP)) {
+
+ if (!(wait & SCSI_NOSLEEP)) {
+ for (etick = tick + tohz;;) {
ccb->ccb_state = CISS_CCB_POLL;
CISS_DPRINTF(CISS_D_CMD, ("tsleep(%d) ", tohz));
if (tsleep(ccb, PRIBIO + 1, "ciss_cmd",
@@ -548,7 +549,13 @@ ciss_cmd(struct ciss_ccb *ccb, int flags
continue;
}
ccb1 = ccb;
- } else {
+
+ error = ciss_done(ccb1);
+ if (ccb1 == ccb)
+ return (error);
+ }
+ } else {
+ for (i *= 100; i--;) {
DELAY(10);
if (!(bus_space_read_4(sc->iot, sc->ioh,
@@ -588,11 +595,11 @@ ciss_cmd(struct ciss_ccb *ccb, int flags
ccb1 = sc->ccbs + (id >> 2) * sc->ccblen;
ccb1->ccb_cmd.id = htole32(id);
ccb1->ccb_cmd.id_hi = htole32(0);
- }
- error = ciss_done(ccb1);
- if (ccb1 == ccb)
- return (error);
+ error = ciss_done(ccb1);
+ if (ccb1 == ccb)
+ return (error);
+ }
}
/* if never got a chance to be done above... */