summaryrefslogtreecommitdiffstats
path: root/sys/dev/aac
diff options
context:
space:
mode:
authorscottl <scottl@FreeBSD.org>2004-02-07 10:30:22 +0000
committerscottl <scottl@FreeBSD.org>2004-02-07 10:30:22 +0000
commitcb43214a58384d696bfbaf96212f199d82642c3f (patch)
tree46a5516a907890ed9d26cea5cd4d8f8d28e7eeee /sys/dev/aac
parent8a8d62e1aa2a0ccc074fcac23309b8e4f7599516 (diff)
downloadFreeBSD-src-cb43214a58384d696bfbaf96212f199d82642c3f.zip
FreeBSD-src-cb43214a58384d696bfbaf96212f199d82642c3f.tar.gz
If a command has to be deferred because there are no more resources for it
on the card, unmap it first. This allows it to be picked up properly when the queue gets kicked again. This was the root problem for the lost command (i.e. stuck in getblk/vinvalb) problem. While here, panic if commands don't map correctly instead of just silently ignoring the problem and dropping command. Also slow down the dynamic allocation of new commands. It should be safe to go back into the aac waters. Thanks to everyone who suffered through this and provided good feedback.
Diffstat (limited to 'sys/dev/aac')
-rw-r--r--sys/dev/aac/aac.c20
1 files changed, 11 insertions, 9 deletions
diff --git a/sys/dev/aac/aac.c b/sys/dev/aac/aac.c
index b799808..7be607b 100644
--- a/sys/dev/aac/aac.c
+++ b/sys/dev/aac/aac.c
@@ -676,12 +676,12 @@ aac_startio(struct aac_softc *sc)
if (cm == NULL)
break;
- /* try to give the command to the controller */
- if (aac_map_command(cm) == EBUSY) {
- /* put it on the ready queue for later */
- aac_requeue_ready(cm);
- break;
- }
+ /*
+ * Try to give the command to the controller. Any error is
+ * catastrophic since it means that bus_dmamap_load() failed.
+ */
+ if (aac_map_command(cm) != 0)
+ panic("aac: error mapping command %p\n", cm);
}
}
@@ -702,7 +702,7 @@ aac_map_command(struct aac_command *cm)
/* don't map more than once */
if (cm->cm_flags & AAC_CMD_MAPPED)
- return (0);
+ panic("aac: command %p already mapped", cm);
if (cm->cm_datalen != 0) {
error = bus_dmamap_load(sc->aac_buffer_dmat, cm->cm_datamap,
@@ -747,10 +747,10 @@ aac_command_thread(struct aac_softc *sc)
* will grab Giant, and would result in an LOR.
*/
if ((sc->aifflags & AAC_AIFFLAGS_ALLOCFIBS) != 0) {
- sc->aifflags &= ~AAC_AIFFLAGS_ALLOCFIBS;
AAC_LOCK_RELEASE(&sc->aac_io_lock);
aac_alloc_commands(sc);
AAC_LOCK_ACQUIRE(&sc->aac_io_lock);
+ sc->aifflags &= ~AAC_AIFFLAGS_ALLOCFIBS;
aac_startio(sc);
}
@@ -1289,8 +1289,10 @@ aac_map_command_sg(void *arg, bus_dma_segment_t *segs, int nseg, int error)
cm->cm_flags |= AAC_CMD_MAPPED;
/* put the FIB on the outbound queue */
- if (aac_enqueue_fib(sc, cm->cm_queue, cm) == EBUSY)
+ if (aac_enqueue_fib(sc, cm->cm_queue, cm) == EBUSY) {
+ aac_unmap_command(cm);
aac_requeue_ready(cm);
+ }
return;
}
OpenPOWER on IntegriCloud