summaryrefslogtreecommitdiffstats
path: root/sys/dev/twe
diff options
context:
space:
mode:
authorvkashyap <vkashyap@FreeBSD.org>2004-06-11 18:42:44 +0000
committervkashyap <vkashyap@FreeBSD.org>2004-06-11 18:42:44 +0000
commit570fb9bce13426eefd5a31a086ee8b65f9bc2ebe (patch)
tree1b98d6ea829a05a880753c0117a1573bd8a06846 /sys/dev/twe
parentb75fa8ff5c6ffd5f71c21a674749e607ea6c7f8e (diff)
downloadFreeBSD-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.c10
-rw-r--r--sys/dev/twe/twe_freebsd.c10
-rw-r--r--sys/dev/twe/twevar.h5
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 */
OpenPOWER on IntegriCloud