aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicolas Pitre <nico@cam.org>2005-11-17 14:02:48 -0500
committerJeff Garzik <jgarzik@pobox.com>2005-11-18 13:10:30 -0500
commit5d0571d915f3e281f151df9a18a6a0be5a57c4b0 (patch)
tree731e8546c3a663208b8d8ad429dd86a9b49a2a1c
parentfc71fe40d2bedcc57d3406bf2050481f8b3441b6 (diff)
[PATCH] smc91x: fix one source of spurious interrupts
Not only SMC_ACK_INT(IM_TX_EMPTY_INT) in in smc_hardware_send_pkt) appears to be unnecessary (tested with an SMC91C94 and SMC91C111), but it seems to trigger spurious interrupts on some machines as well. Removed. While at it, let's log any remaining spurious interrupts if any (and clean usage of the max IRQ loop count value). Signed-off-by: Nicolas Pitre <nico@cam.org> Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
-rw-r--r--drivers/net/smc91x.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c
index c91e2e81f131..1021108e9a25 100644
--- a/drivers/net/smc91x.c
+++ b/drivers/net/smc91x.c
@@ -155,6 +155,12 @@ MODULE_LICENSE("GPL");
155#define MEMORY_WAIT_TIME 16 155#define MEMORY_WAIT_TIME 16
156 156
157/* 157/*
158 * The maximum number of processing loops allowed for each call to the
159 * IRQ handler.
160 */
161#define MAX_IRQ_LOOPS 8
162
163/*
158 * This selects whether TX packets are sent one by one to the SMC91x internal 164 * This selects whether TX packets are sent one by one to the SMC91x internal
159 * memory and throttled until transmission completes. This may prevent 165 * memory and throttled until transmission completes. This may prevent
160 * RX overruns a litle by keeping much of the memory free for RX packets 166 * RX overruns a litle by keeping much of the memory free for RX packets
@@ -684,7 +690,6 @@ static void smc_hardware_send_pkt(unsigned long data)
684 690
685 /* queue the packet for TX */ 691 /* queue the packet for TX */
686 SMC_SET_MMU_CMD(MC_ENQUEUE); 692 SMC_SET_MMU_CMD(MC_ENQUEUE);
687 SMC_ACK_INT(IM_TX_EMPTY_INT);
688 smc_special_unlock(&lp->lock); 693 smc_special_unlock(&lp->lock);
689 694
690 dev->trans_start = jiffies; 695 dev->trans_start = jiffies;
@@ -1305,7 +1310,7 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
1305 SMC_SET_INT_MASK(0); 1310 SMC_SET_INT_MASK(0);
1306 1311
1307 /* set a timeout value, so I don't stay here forever */ 1312 /* set a timeout value, so I don't stay here forever */
1308 timeout = 8; 1313 timeout = MAX_IRQ_LOOPS;
1309 1314
1310 do { 1315 do {
1311 status = SMC_GET_INT(); 1316 status = SMC_GET_INT();
@@ -1372,10 +1377,13 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
1372 /* restore register states */ 1377 /* restore register states */
1373 SMC_SET_PTR(saved_pointer); 1378 SMC_SET_PTR(saved_pointer);
1374 SMC_SET_INT_MASK(mask); 1379 SMC_SET_INT_MASK(mask);
1375
1376 spin_unlock(&lp->lock); 1380 spin_unlock(&lp->lock);
1377 1381
1378 DBG(3, "%s: Interrupt done (%d loops)\n", dev->name, 8-timeout); 1382 if (timeout == MAX_IRQ_LOOPS)
1383 PRINTK("%s: spurious interrupt (mask = 0x%02x)\n",
1384 dev->name, mask);
1385 DBG(3, "%s: Interrupt done (%d loops)\n",
1386 dev->name, MAX_IRQ_LOOPS - timeout);
1379 1387
1380 /* 1388 /*
1381 * We return IRQ_HANDLED unconditionally here even if there was 1389 * We return IRQ_HANDLED unconditionally here even if there was