qlge: Fix queueing of firmware handler in ISR.
authorRon Mercer <ron.mercer@qlogic.com>
Mon, 5 Oct 2009 11:46:48 +0000 (11:46 +0000)
committerDavid S. Miller <davem@davemloft.net>
Wed, 7 Oct 2009 00:33:36 +0000 (17:33 -0700)
Check that we are not already polling firmware events before we queue the
firmware event worker, then disable firmware interrupts.
Otherwise we can queue the same event multiple times.

Signed-off-by: Ron Mercer <ron.mercer@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/qlge/qlge_main.c

index 3d0efea32111bd15ce5f66a0eaec7ce20ae56408..c21eda03fa5a7ff3c016d6400edc5d6f50f445ff 100644 (file)
@@ -2001,15 +2001,17 @@ static irqreturn_t qlge_isr(int irq, void *dev_id)
        /*
         * Check MPI processor activity.
         */
-       if (var & STS_PI) {
+       if ((var & STS_PI) &&
+               (ql_read32(qdev, INTR_MASK) & INTR_MASK_PI)) {
                /*
                 * We've got an async event or mailbox completion.
                 * Handle it and clear the source of the interrupt.
                 */
                QPRINTK(qdev, INTR, ERR, "Got MPI processor interrupt.\n");
                ql_disable_completion_interrupt(qdev, intr_context->intr);
-               queue_delayed_work_on(smp_processor_id(), qdev->workqueue,
-                                     &qdev->mpi_work, 0);
+               ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16));
+               queue_delayed_work_on(smp_processor_id(),
+                               qdev->workqueue, &qdev->mpi_work, 0);
                work_done++;
        }