diff options
author | Ilkka Virta <itvirta@iki.fi> | 2009-02-07 01:00:36 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-02-07 01:00:36 -0500 |
commit | 71822faa3bc0af5dbf5e333a2d085f1ed7cd809f (patch) | |
tree | b0ad50f98ee521de666f595ec4d33b430f39a80c | |
parent | 15bde72738f373aa060ececeda8e064e4f924360 (diff) |
sungem: Soft lockup in sungem on Netra AC200 when switching interface up
From: Ilkka Virta <itvirta@iki.fi>
In the lockup situation the driver seems to go off in an eternal storm
of interrupts right after calling request_irq(). It doesn't actually
do anything interesting in the interrupt handler. Since connecting the link
afterwards works, something later in initialization must fix this.
Looking at gem_do_start() and gem_open(), it seems that the only thing
done while opening the device after the request_irq(), is a call to
napi_enable().
I don't know what the ordering requirements are for the
initialization, but I boldly tried to move the napi_enable() call
inside gem_do_start() before the link state is checked and interrupts
subsequently enabled, and it seems to work for me. Doesn't even break
anything too obvious...
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/sungem.c | 8 |
1 files changed, 4 insertions, 4 deletions
diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c index b17efa9cc530..491876341068 100644 --- a/drivers/net/sungem.c +++ b/drivers/net/sungem.c | |||
@@ -2221,6 +2221,8 @@ static int gem_do_start(struct net_device *dev) | |||
2221 | 2221 | ||
2222 | gp->running = 1; | 2222 | gp->running = 1; |
2223 | 2223 | ||
2224 | napi_enable(&gp->napi); | ||
2225 | |||
2224 | if (gp->lstate == link_up) { | 2226 | if (gp->lstate == link_up) { |
2225 | netif_carrier_on(gp->dev); | 2227 | netif_carrier_on(gp->dev); |
2226 | gem_set_link_modes(gp); | 2228 | gem_set_link_modes(gp); |
@@ -2238,6 +2240,8 @@ static int gem_do_start(struct net_device *dev) | |||
2238 | spin_lock_irqsave(&gp->lock, flags); | 2240 | spin_lock_irqsave(&gp->lock, flags); |
2239 | spin_lock(&gp->tx_lock); | 2241 | spin_lock(&gp->tx_lock); |
2240 | 2242 | ||
2243 | napi_disable(&gp->napi); | ||
2244 | |||
2241 | gp->running = 0; | 2245 | gp->running = 0; |
2242 | gem_reset(gp); | 2246 | gem_reset(gp); |
2243 | gem_clean_rings(gp); | 2247 | gem_clean_rings(gp); |
@@ -2338,8 +2342,6 @@ static int gem_open(struct net_device *dev) | |||
2338 | if (!gp->asleep) | 2342 | if (!gp->asleep) |
2339 | rc = gem_do_start(dev); | 2343 | rc = gem_do_start(dev); |
2340 | gp->opened = (rc == 0); | 2344 | gp->opened = (rc == 0); |
2341 | if (gp->opened) | ||
2342 | napi_enable(&gp->napi); | ||
2343 | 2345 | ||
2344 | mutex_unlock(&gp->pm_mutex); | 2346 | mutex_unlock(&gp->pm_mutex); |
2345 | 2347 | ||
@@ -2476,8 +2478,6 @@ static int gem_resume(struct pci_dev *pdev) | |||
2476 | 2478 | ||
2477 | /* Re-attach net device */ | 2479 | /* Re-attach net device */ |
2478 | netif_device_attach(dev); | 2480 | netif_device_attach(dev); |
2479 | |||
2480 | napi_enable(&gp->napi); | ||
2481 | } | 2481 | } |
2482 | 2482 | ||
2483 | spin_lock_irqsave(&gp->lock, flags); | 2483 | spin_lock_irqsave(&gp->lock, flags); |