diff options
author | Krzysztof Halasa <khc@pm.waw.pl> | 2010-12-12 07:06:47 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-12-12 18:03:00 -0500 |
commit | eaff9453d3e2b63969af93e9d42a85e803060121 (patch) | |
tree | f27368d0796494cc8d8469e2f387cb2d43f4b209 /drivers/net/wan | |
parent | 9f5449611c9d6d7bdcae8020a197d8b4d9b6443c (diff) |
WAN: Fix a TX IRQ causing BUG() in PC300 and PCI200SYN drivers.
We must not wake the TX queue without free TX descriptors.
sca_xmit() expects at least one free descriptor and BUGs otherwise.
Problem reported and fix tested by Bernie Innocenti and Ward Vandewege.
Signed-off-by: Krzysztof HaĆasa <khc@pm.waw.pl>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/wan')
-rw-r--r-- | drivers/net/wan/hd64572.c | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/drivers/net/wan/hd64572.c b/drivers/net/wan/hd64572.c index ea476cbd38b5..e305274f83fb 100644 --- a/drivers/net/wan/hd64572.c +++ b/drivers/net/wan/hd64572.c | |||
@@ -293,6 +293,7 @@ static inline void sca_tx_done(port_t *port) | |||
293 | struct net_device *dev = port->netdev; | 293 | struct net_device *dev = port->netdev; |
294 | card_t* card = port->card; | 294 | card_t* card = port->card; |
295 | u8 stat; | 295 | u8 stat; |
296 | unsigned count = 0; | ||
296 | 297 | ||
297 | spin_lock(&port->lock); | 298 | spin_lock(&port->lock); |
298 | 299 | ||
@@ -316,10 +317,12 @@ static inline void sca_tx_done(port_t *port) | |||
316 | dev->stats.tx_bytes += readw(&desc->len); | 317 | dev->stats.tx_bytes += readw(&desc->len); |
317 | } | 318 | } |
318 | writeb(0, &desc->stat); /* Free descriptor */ | 319 | writeb(0, &desc->stat); /* Free descriptor */ |
320 | count++; | ||
319 | port->txlast = (port->txlast + 1) % card->tx_ring_buffers; | 321 | port->txlast = (port->txlast + 1) % card->tx_ring_buffers; |
320 | } | 322 | } |
321 | 323 | ||
322 | netif_wake_queue(dev); | 324 | if (count) |
325 | netif_wake_queue(dev); | ||
323 | spin_unlock(&port->lock); | 326 | spin_unlock(&port->lock); |
324 | } | 327 | } |
325 | 328 | ||