Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/ic Untangle the poll/wait/timeout code in ciss_cmd()...
details: https://anonhg.NetBSD.org/src/rev/ca8305ad378e
branches: trunk
changeset: 336713:ca8305ad378e
user: christos <christos%NetBSD.org@localhost>
date: Thu Mar 12 18:53:22 2015 +0000
description:
Untangle the poll/wait/timeout code in ciss_cmd() Tested on a DL-360.
diffstat:
sys/dev/ic/ciss.c | 178 ++++++++++++++++++++++++++++++-----------------------
1 files changed, 101 insertions(+), 77 deletions(-)
diffs (220 lines):
diff -r 57e2b7398bf4 -r ca8305ad378e sys/dev/ic/ciss.c
--- a/sys/dev/ic/ciss.c Thu Mar 12 15:33:10 2015 +0000
+++ b/sys/dev/ic/ciss.c Thu Mar 12 18:53:22 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ciss.c,v 1.33 2015/03/12 15:33:10 christos Exp $ */
+/* $NetBSD: ciss.c,v 1.34 2015/03/12 18:53:22 christos Exp $ */
/* $OpenBSD: ciss.c,v 1.68 2013/05/30 16:15:02 deraadt Exp $ */
/*
@@ -19,7 +19,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ciss.c,v 1.33 2015/03/12 15:33:10 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ciss.c,v 1.34 2015/03/12 18:53:22 christos Exp $");
#include "bio.h"
@@ -437,6 +437,97 @@
minphys(bp);
}
+static struct ciss_ccb *
+ciss_poll1(struct ciss_softc *sc)
+{
+ struct ciss_ccb *ccb;
+ uint32_t id;
+
+ if (!(bus_space_read_4(sc->sc_iot, sc->sc_ioh, CISS_ISR) & sc->iem)) {
+ CISS_DPRINTF(CISS_D_CMD, ("N"));
+ return NULL;
+ }
+
+ if (sc->cfg.methods & CISS_METH_FIFO64) {
+ if (bus_space_read_4(sc->sc_iot, sc->sc_ioh, CISS_OUTQ64_HI) ==
+ 0xffffffff) {
+ CISS_DPRINTF(CISS_D_CMD, ("Q"));
+ return NULL;
+ }
+ id = bus_space_read_4(sc->sc_iot, sc->sc_ioh, CISS_OUTQ64_LO);
+ } else if (sc->cfg.methods & CISS_METH_FIFO64_RRO) {
+ id = bus_space_read_4(sc->sc_iot, sc->sc_ioh, CISS_OUTQ64_LO);
+ if (id == 0xffffffff) {
+ CISS_DPRINTF(CISS_D_CMD, ("Q"));
+ return NULL;
+ }
+ (void)bus_space_read_4(sc->sc_iot, sc->sc_ioh, CISS_OUTQ64_HI);
+ } else {
+ id = bus_space_read_4(sc->sc_iot, sc->sc_ioh, CISS_OUTQ);
+ if (id == 0xffffffff) {
+ CISS_DPRINTF(CISS_D_CMD, ("Q"));
+ return NULL;
+ }
+ }
+
+ CISS_DPRINTF(CISS_D_CMD, ("got=0x%x ", id));
+ ccb = (struct ciss_ccb *) ((char *)sc->ccbs + (id >> 2) * sc->ccblen);
+ ccb->ccb_cmd.id = htole32(id);
+ ccb->ccb_cmd.id_hi = htole32(0);
+ return ccb;
+}
+
+static int
+ciss_poll(struct ciss_softc *sc, struct ciss_ccb *ccb, int ms)
+{
+ struct ciss_ccb *ccb1;
+
+ ms /= 10;
+
+ while (ms-- > 0) {
+ DELAY(10);
+ ccb1 = ciss_poll1(sc);
+ if (ccb1 == NULL)
+ continue;
+ ciss_done(ccb1);
+ if (ccb1 == ccb)
+ return 0;
+ }
+
+ return ETIMEDOUT;
+}
+
+static int
+ciss_wait(struct ciss_softc *sc, struct ciss_ccb *ccb, int ms)
+{
+ int tohz, etick;
+
+ tohz = mstohz(ms);
+ if (tohz == 0)
+ tohz = 1;
+ etick = tick + tohz;
+
+ for (;;) {
+ ccb->ccb_state = CISS_CCB_POLL;
+ CISS_DPRINTF(CISS_D_CMD, ("cv_timedwait(%d) ", tohz));
+ mutex_enter(&sc->sc_mutex);
+ if (cv_timedwait(&sc->sc_condvar, &sc->sc_mutex, tohz)
+ == EWOULDBLOCK) {
+ mutex_exit(&sc->sc_mutex);
+ return EWOULDBLOCK;
+ }
+ mutex_exit(&sc->sc_mutex);
+ if (ccb->ccb_state == CISS_CCB_ONQ) {
+ ciss_done(ccb);
+ return 0;
+ }
+ tohz = etick - tick;
+ if (tohz <= 0)
+ return EWOULDBLOCK;
+ CISS_DPRINTF(CISS_D_CMD, ("T"));
+ }
+}
+
/*
* submit a command and optionally wait for completition.
* wait arg abuses XS_CTL_POLL|XS_CTL_NOSLEEP flags to request
@@ -448,11 +539,9 @@
{
struct ciss_softc *sc = ccb->ccb_sc;
struct ciss_cmd *cmd = &ccb->ccb_cmd;
- struct ciss_ccb *ccb1;
bus_dmamap_t dmap = ccb->ccb_dmamap;
- u_int32_t id;
u_int64_t addr;
- int i, tohz, error = 0;
+ int i, error = 0;
if (ccb->ccb_state != CISS_CCB_READY) {
printf("%s: ccb %d not ready state=0x%x\n", device_xname(sc->sc_dev),
@@ -527,83 +616,18 @@
ccb->ccb_cmdpa);
if (wait & XS_CTL_POLL) {
- int etick;
+ int ms;
CISS_DPRINTF(CISS_D_CMD, ("waiting "));
- i = ccb->ccb_xs? ccb->ccb_xs->timeout : 60000;
- tohz = (i / 1000) * hz + (i % 1000) * (hz / 1000);
- if (tohz == 0)
- tohz = 1;
- for (i *= 100, etick = tick + tohz; i--; ) {
- if (!(wait & XS_CTL_NOSLEEP)) {
- ccb->ccb_state = CISS_CCB_POLL;
- CISS_DPRINTF(CISS_D_CMD, ("cv_timedwait(%d) ", tohz));
- mutex_enter(&sc->sc_mutex);
- if (cv_timedwait(&sc->sc_condvar,
- &sc->sc_mutex, tohz) == EWOULDBLOCK) {
- mutex_exit(&sc->sc_mutex);
- break;
- }
- mutex_exit(&sc->sc_mutex);
- if (ccb->ccb_state != CISS_CCB_ONQ) {
- tohz = etick - tick;
- if (tohz <= 0)
- break;
- CISS_DPRINTF(CISS_D_CMD, ("T"));
- continue;
- }
- ccb1 = ccb;
- } else {
- DELAY(10);
-
- if (!(bus_space_read_4(sc->sc_iot, sc->sc_ioh,
- CISS_ISR) & sc->iem)) {
- CISS_DPRINTF(CISS_D_CMD, ("N"));
- continue;
- }
-
- if (sc->cfg.methods & CISS_METH_FIFO64) {
- if (bus_space_read_4(sc->sc_iot,
- sc->sc_ioh,
- CISS_OUTQ64_HI) == 0xffffffff) {
- CISS_DPRINTF(CISS_D_CMD, ("Q"));
- continue;
- }
- id = bus_space_read_4(sc->sc_iot,
- sc->sc_ioh, CISS_OUTQ64_LO);
- } else if (sc->cfg.methods &
- CISS_METH_FIFO64_RRO) {
- id = bus_space_read_4(sc->sc_iot,
- sc->sc_ioh, CISS_OUTQ64_LO);
- if (id == 0xffffffff) {
- CISS_DPRINTF(CISS_D_CMD, ("Q"));
- continue;
- }
- (void)bus_space_read_4(sc->sc_iot,
- sc->sc_ioh, CISS_OUTQ64_HI);
- } else {
- id = bus_space_read_4(sc->sc_iot,
- sc->sc_ioh, CISS_OUTQ);
- if (id == 0xffffffff) {
- CISS_DPRINTF(CISS_D_CMD, ("Q"));
- continue;
- }
- }
-
- CISS_DPRINTF(CISS_D_CMD, ("got=0x%x ", id));
- ccb1 = (struct ciss_ccb *)
- ((char *)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)
- break;
- }
+ ms = ccb->ccb_xs ? ccb->ccb_xs->timeout : 60000;
+ if (wait & XS_CTL_NOSLEEP)
+ error = ciss_poll(sc, ccb, ms);
+ else
+ error = ciss_wait(sc, ccb, ms);
/* if never got a chance to be done above... */
if (ccb->ccb_state != CISS_CCB_FREE) {
+ KASSERT(error);
ccb->ccb_err.cmd_stat = CISS_ERR_TMO;
error = ciss_done(ccb);
}
Home |
Main Index |
Thread Index |
Old Index