summaryrefslogtreecommitdiffstats
path: root/sys/dev/aac/aac.c
diff options
context:
space:
mode:
authorscottl <scottl@FreeBSD.org>2003-02-19 21:58:34 +0000
committerscottl <scottl@FreeBSD.org>2003-02-19 21:58:34 +0000
commit6ececd4417e9635c5b55583283f2640c2fb05a6b (patch)
tree25035399bc17c6c584e99655dd9114daacea575c /sys/dev/aac/aac.c
parente7c18881a0bf0ba8620d4b0347f9acf5623ff365 (diff)
downloadFreeBSD-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.c48
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? */
OpenPOWER on IntegriCloud