On Sat, 2010-01-23 at 23:10 +, Ben Hutchings wrote:
On Sat, 2010-01-23 at 22:23 +0100, Piotr Skólski wrote:
ifup eth0:
ifup: interface eth0 already configured
dhclient:
There is already a pid file /var/run/dhclient.pid with pid 1298
killed old client process, removed PID file
Internet Systems Consortium DHCP Client V3.1.3
Copyright 2004-2009 Internet Systems Consortium.
All rights reserved.
For info, please visit https://www.isc.org/software/dhcp/
SIOCSIFFLAGS: Invalid argument
SIOCSIFFLAGS: Invalid argument
[...]
It looks like this error comes from the interrupt allocation code. The
IRQ probing code in 3c503 has been wrong for a long time but somehow
managed to work. Now it will fail.
If you know which IRQ the hardware is using, please try running:
rmmod 3c503
modprobe 3c503 irq=n
(substitute the proper number for 'n').
I will continue investigating whether the IRQ probing code can be fixed.
I believe the attached patch will fix this bug, but I have no way of
testing it myself.
You can build a new kernel package with this patch by running:
apt-get source linux-2.6
cd linux-2.6-2.6.32
bash debian/bin/test-patches -f 486 -s none
../0001-3c503-Fix-IRQ-probing.patch
Note, you may be told that you need to install additional packages.
I suggest you do this on a faster machine, if possible.
Ben.
--
Ben Hutchings
Any smoothly functioning technology is indistinguishable from a rigged demo.
From e6a0d3756123f7ad6c95732032c452bea2c25c22 Mon Sep 17 00:00:00 2001
From: Ben Hutchings b...@decadent.org.uk
Date: Sun, 24 Jan 2010 00:24:27 +
Subject: [PATCH] 3c503: Fix IRQ probing
The driver attempts to probe for the correct IRQ automatically using
probe_irq_{on,off}(). However, it is allow configuring of the IRQ, so
there is really no 'correct' IRQ. It attempts to test whether the IRQ
is available by calling request_irq() with a null handler, but that now
returns -EINVAL. There was a second bug that meant it ignored all
errors except -EBUSY, so it would 'succeed' despite this.
Commit ab08999d6029bb2c79c16be5405d63d2bedbdfea 'WARNING: some
request_irq() failures ignored in el2_open()' fixed the second bug,
exposing the first.
This patch:
1. Replaces the use of probe_irq_{on,off}() with a real interrupt handler
2. Adds a delay before checking the interrupt-seen flag
3. Disables interrupts on all failure paths
4. Distinguishes error codes from the second request_irq() call,
consistently with the first
---
drivers/net/3c503.c | 41 ++---
1 files changed, 30 insertions(+), 11 deletions(-)
diff --git a/drivers/net/3c503.c b/drivers/net/3c503.c
index c71e12d..9fb3a0b 100644
--- a/drivers/net/3c503.c
+++ b/drivers/net/3c503.c
@@ -380,6 +380,12 @@ out:
return retval;
}
+static irqreturn_t el2_probe_interrupt(int irq, void *seen)
+{
+ *(bool *)seen = true;
+ return IRQ_HANDLED;
+}
+
static int
el2_open(struct net_device *dev)
{
@@ -391,22 +397,35 @@ el2_open(struct net_device *dev)
outb(EGACFR_NORM, E33G_GACFR); /* Enable RAM and interrupts. */
do {
- retval = request_irq(*irqp, NULL, 0, bogus, dev);
- if (retval = 0) {
+ bool seen;
+
+ retval = request_irq(*irqp, el2_probe_interrupt, 0,
+ dev-name, seen);
+ if (retval == -EBUSY)
+ continue;
+ if (retval 0)
+ goto err_disable;
+
/* Twinkle the interrupt, and check if it's seen. */
- unsigned long cookie = probe_irq_on();
+ seen = false;
+ smp_wmb();
outb_p(0x04 ((*irqp == 9) ? 2 : *irqp), E33G_IDCFR);
outb_p(0x00, E33G_IDCFR);
- if (*irqp == probe_irq_off(cookie) /* It's a good IRQ line! */
- ((retval = request_irq(dev-irq = *irqp,
- eip_interrupt, 0, dev-name, dev)) == 0))
- break;
- } else {
- if (retval != -EBUSY)
- return retval;
- }
+ msleep(1);
+ free_irq(*irqp, el2_probe_interrupt);
+ if (!seen)
+ continue;
+
+ retval = request_irq(dev-irq = *irqp, eip_interrupt, 0,
+ dev-name, dev);
+ if (retval == -EBUSY)
+ continue;
+ if (retval 0)
+ goto err_disable;
} while (*++irqp);
+
if (*irqp == 0) {
+ err_disable:
outb(EGACFR_IRQOFF, E33G_GACFR); /* disable interrupts. */
return -EAGAIN;
}
--
1.6.6
signature.asc
Description: This is a digitally signed message part