diff options
author | scottl <scottl@FreeBSD.org> | 2003-02-19 21:58:34 +0000 |
---|---|---|
committer | scottl <scottl@FreeBSD.org> | 2003-02-19 21:58:34 +0000 |
commit | 6ececd4417e9635c5b55583283f2640c2fb05a6b (patch) | |
tree | 25035399bc17c6c584e99655dd9114daacea575c /sys/dev/aac/aac.c | |
parent | e7c18881a0bf0ba8620d4b0347f9acf5623ff365 (diff) | |
download | FreeBSD-src-6ececd4417e9635c5b55583283f2640c2fb05a6b.zip FreeBSD-src-6ececd4417e9635c5b55583283f2640c2fb05a6b.tar.gz |
Make the aac driver be INTR_MPSAFE. Once the interrupt handler determines
that a command completion happened, all further processing is deferred to
a taskqueue. The taskqueue itself runs implicetely under Giant, but we
already used a taskqueue for the biodone() processing, so this at least
saves the contesting of Giant in the interrupt handler.
Diffstat (limited to 'sys/dev/aac/aac.c')
-rw-r--r-- | sys/dev/aac/aac.c | 48 |
1 files changed, 12 insertions, 36 deletions
diff --git a/sys/dev/aac/aac.c b/sys/dev/aac/aac.c index b25286e..28bb8a0 100644 --- a/sys/dev/aac/aac.c +++ b/sys/dev/aac/aac.c @@ -83,7 +83,6 @@ static int aac_bio_command(struct aac_softc *sc, struct aac_command **cmp); static void aac_bio_complete(struct aac_command *cm); static int aac_wait_command(struct aac_command *cm, int timeout); static void aac_command_thread(struct aac_softc *sc); -static void aac_host_response(struct aac_softc *sc); /* Command Buffer Management */ static void aac_map_command_helper(void *arg, bus_dma_segment_t *segs, @@ -661,7 +660,8 @@ aac_intr(void *arg) /* It's not ok to return here because of races with the previous step */ if (reason & AAC_DB_RESPONSE_READY) - aac_host_response(sc); + /* handle completion processing */ + taskqueue_enqueue(taskqueue_swi, &sc->aac_task_complete); /* controller wants to talk to the log */ if (reason & AAC_DB_PRINTF) { @@ -845,60 +845,36 @@ aac_command_thread(struct aac_softc *sc) } /* - * Handle notification of one or more FIBs completed by the controller + * Process completed commands. */ static void -aac_host_response(struct aac_softc *sc) +aac_complete(void *context, int pending) { + struct aac_softc *sc; struct aac_command *cm; struct aac_fib *fib; u_int32_t fib_size; debug_called(2); + sc = (struct aac_softc *)context; + + /* pull completed commands off the queue */ for (;;) { /* look for completed FIBs on our queue */ if (aac_dequeue_fib(sc, AAC_HOST_NORM_RESP_QUEUE, &fib_size, &fib)) break; /* nothing to do */ - + /* get the command, unmap and queue for later processing */ cm = (struct aac_command *)fib->Header.SenderData; if (cm == NULL) { AAC_PRINT_FIB(sc, fib); - } else { - aac_remove_busy(cm); - aac_unmap_command(cm); /* XXX defer? */ - aac_enqueue_complete(cm); + break; } - } - - /* handle completion processing */ -#if __FreeBSD_version >= 500005 - taskqueue_enqueue(taskqueue_swi, &sc->aac_task_complete); -#else - aac_complete(sc, 0); -#endif -} -/* - * Process completed commands. - */ -static void -aac_complete(void *context, int pending) -{ - struct aac_softc *sc; - struct aac_command *cm; - - debug_called(2); - - sc = (struct aac_softc *)context; - - /* pull completed commands off the queue */ - for (;;) { - cm = aac_dequeue_complete(sc); - if (cm == NULL) - break; + aac_remove_busy(cm); + aac_unmap_command(cm); /* XXX defer? */ cm->cm_flags |= AAC_CMD_COMPLETED; /* is there a completion handler? */ |