diff options
author | vkashyap <vkashyap@FreeBSD.org> | 2004-06-11 18:42:44 +0000 |
---|---|---|
committer | vkashyap <vkashyap@FreeBSD.org> | 2004-06-11 18:42:44 +0000 |
commit | 570fb9bce13426eefd5a31a086ee8b65f9bc2ebe (patch) | |
tree | 1b98d6ea829a05a880753c0117a1573bd8a06846 /sys/dev/twe | |
parent | b75fa8ff5c6ffd5f71c21a674749e607ea6c7f8e (diff) | |
download | FreeBSD-src-570fb9bce13426eefd5a31a086ee8b65f9bc2ebe.zip FreeBSD-src-570fb9bce13426eefd5a31a086ee8b65f9bc2ebe.tar.gz |
Fix for a problem seen only on 6xxx series controllers, where-in the
driver tries to submit the same request repeatedly, on finding the
controller cmd queue to be full.
Submitted by:ps, vkashyap
Reviewed by:re
Approved by:re
Diffstat (limited to 'sys/dev/twe')
-rw-r--r-- | sys/dev/twe/twe.c | 10 | ||||
-rw-r--r-- | sys/dev/twe/twe_freebsd.c | 10 | ||||
-rw-r--r-- | sys/dev/twe/twevar.h | 5 |
3 files changed, 17 insertions, 8 deletions
diff --git a/sys/dev/twe/twe.c b/sys/dev/twe/twe.c index e935c89..340dab9 100644 --- a/sys/dev/twe/twe.c +++ b/sys/dev/twe/twe.c @@ -384,7 +384,7 @@ twe_startio(struct twe_softc *sc) debug_called(4); - if (sc->twe_state & TWE_STATE_FRZN) + if (sc->twe_state & (TWE_STATE_CTLR_BUSY | TWE_STATE_FRZN)) return; /* spin until something prevents us from doing any work */ @@ -435,6 +435,8 @@ twe_startio(struct twe_softc *sc) error = twe_map_request(tr); if (error != 0) { + if (error == EBUSY) + break; tr->tr_status = TWE_CMD_ERROR; if (tr->tr_private != NULL) { bp = (twe_bio *)(tr->tr_private); @@ -762,7 +764,7 @@ twe_get_param(struct twe_softc *sc, int table_id, int param_id, size_t param_siz } else { tr->tr_complete = func; error = twe_map_request(tr); - if (error == 0) + if ((error == 0) || (error == EBUSY)) return(func); } @@ -931,7 +933,8 @@ twe_immediate_request(struct twe_request *tr) tr->tr_flags |= TWE_CMD_IMMEDIATE; tr->tr_status = TWE_CMD_BUSY; if ((error = twe_map_request(tr)) != 0) - return(error); + if (error != EBUSY) + return(error); while (tr->tr_status == TWE_CMD_BUSY){ twe_done(tr->tr_sc); } @@ -1131,6 +1134,7 @@ twe_done(struct twe_softc *sc) /* move to completed queue */ twe_remove_busy(tr); twe_enqueue_complete(tr); + sc->twe_state &= ~TWE_STATE_CTLR_BUSY; } else { break; /* no response ready */ } diff --git a/sys/dev/twe/twe_freebsd.c b/sys/dev/twe/twe_freebsd.c index 0f04532..2415ca5 100644 --- a/sys/dev/twe/twe_freebsd.c +++ b/sys/dev/twe/twe_freebsd.c @@ -1014,8 +1014,10 @@ twe_setup_data_dmamap(void *arg, bus_dma_segment_t *segs, int nsegments, int err } } - if (twe_start(tr) == EBUSY) + if (twe_start(tr) == EBUSY) { + tr->tr_sc->twe_state |= TWE_STATE_CTLR_BUSY; twe_requeue_ready(tr); + } } static void @@ -1037,8 +1039,10 @@ twe_map_request(struct twe_request *tr) debug_called(4); - if (sc->twe_state & TWE_STATE_FRZN) + if (sc->twe_state & (TWE_STATE_CTLR_BUSY | TWE_STATE_FRZN)) { + twe_requeue_ready(tr); return (EBUSY); + } bus_dmamap_sync(sc->twe_cmd_dmat, sc->twe_cmdmap, BUS_DMASYNC_PREWRITE); @@ -1079,8 +1083,8 @@ twe_map_request(struct twe_request *tr) } } else if ((error = twe_start(tr)) == EBUSY) { + sc->twe_state |= TWE_STATE_CTLR_BUSY; twe_requeue_ready(tr); - error = 0; } return(error); diff --git a/sys/dev/twe/twevar.h b/sys/dev/twe/twevar.h index 393846b..90391ad 100644 --- a/sys/dev/twe/twevar.h +++ b/sys/dev/twe/twevar.h @@ -27,7 +27,7 @@ * $FreeBSD$ */ -#define TWE_DRIVER_VERSION_STRING "1.50.01.001" +#define TWE_DRIVER_VERSION_STRING "1.50.01.002" #ifdef TWE_DEBUG #define debug(level, fmt, args...) \ @@ -131,7 +131,8 @@ struct twe_softc #define TWE_STATE_SHUTDOWN (1<<1) /* controller is shut down */ #define TWE_STATE_OPEN (1<<2) /* control device is open */ #define TWE_STATE_SUSPEND (1<<3) /* controller is suspended */ -#define TWE_STATE_FRZN (1<<4) +#define TWE_STATE_FRZN (1<<4) /* got EINPROGRESS */ +#define TWE_STATE_CTLR_BUSY (1<<5) /* controller cmd queue full */ int twe_host_id; struct twe_qstat twe_qstat[TWEQ_COUNT]; /* queue statistics */ |