diff options
| author | NeilBrown <neilb@suse.de> | 2010-08-10 10:02:33 +1000 |
|---|---|---|
| committer | NeilBrown <neilb@suse.de> | 2010-08-10 10:02:33 +1000 |
| commit | fd8aa2c1811bf60ccb2d5de0579c6f62aec1772d (patch) | |
| tree | 311567d03758afc3a93b4273fe172836e89bb01d /drivers/net/82596.c | |
| parent | 6e17b0276452912cb13445e5ea552b599984675f (diff) | |
| parent | 2144381da478cc4aa3a29ee29b0c5e6ddaaced14 (diff) | |
| download | linux-next-fd8aa2c1811bf60ccb2d5de0579c6f62aec1772d.tar.gz linux-next-fd8aa2c1811bf60ccb2d5de0579c6f62aec1772d.zip | |
Merge git://git.infradead.org/users/dwmw2/libraid-2.6 into for-linus
Diffstat (limited to 'drivers/net/82596.c')
| -rw-r--r-- | drivers/net/82596.c | 64 |
1 files changed, 44 insertions, 20 deletions
diff --git a/drivers/net/82596.c b/drivers/net/82596.c index dd8dc15556cb..e2c9c5b949f9 100644 --- a/drivers/net/82596.c +++ b/drivers/net/82596.c @@ -525,7 +525,21 @@ static irqreturn_t i596_error(int irq, void *dev_id) } #endif -static inline void init_rx_bufs(struct net_device *dev) +static inline void remove_rx_bufs(struct net_device *dev) +{ + struct i596_private *lp = dev->ml_priv; + struct i596_rbd *rbd; + int i; + + for (i = 0, rbd = lp->rbds; i < rx_ring_size; i++, rbd++) { + if (rbd->skb == NULL) + break; + dev_kfree_skb(rbd->skb); + rbd->skb = NULL; + } +} + +static inline int init_rx_bufs(struct net_device *dev) { struct i596_private *lp = dev->ml_priv; int i; @@ -537,8 +551,11 @@ static inline void init_rx_bufs(struct net_device *dev) for (i = 0, rbd = lp->rbds; i < rx_ring_size; i++, rbd++) { struct sk_buff *skb = dev_alloc_skb(PKT_BUF_SZ); - if (skb == NULL) - panic("82596: alloc_skb() failed"); + if (skb == NULL) { + remove_rx_bufs(dev); + return -ENOMEM; + } + skb->dev = dev; rbd->v_next = rbd+1; rbd->b_next = WSWAPrbd(virt_to_bus(rbd+1)); @@ -574,19 +591,8 @@ static inline void init_rx_bufs(struct net_device *dev) rfd->v_next = lp->rfds; rfd->b_next = WSWAPrfd(virt_to_bus(lp->rfds)); rfd->cmd = CMD_EOL|CMD_FLEX; -} -static inline void remove_rx_bufs(struct net_device *dev) -{ - struct i596_private *lp = dev->ml_priv; - struct i596_rbd *rbd; - int i; - - for (i = 0, rbd = lp->rbds; i < rx_ring_size; i++, rbd++) { - if (rbd->skb == NULL) - break; - dev_kfree_skb(rbd->skb); - } + return 0; } @@ -1009,20 +1015,35 @@ static int i596_open(struct net_device *dev) } #ifdef ENABLE_MVME16x_NET if (MACH_IS_MVME16x) { - if (request_irq(0x56, i596_error, 0, "i82596_error", dev)) - return -EAGAIN; + if (request_irq(0x56, i596_error, 0, "i82596_error", dev)) { + res = -EAGAIN; + goto err_irq_dev; + } } #endif - init_rx_bufs(dev); + res = init_rx_bufs(dev); + if (res) + goto err_irq_56; netif_start_queue(dev); - /* Initialize the 82596 memory */ if (init_i596_mem(dev)) { res = -EAGAIN; - free_irq(dev->irq, dev); + goto err_queue; } + return 0; + +err_queue: + netif_stop_queue(dev); + remove_rx_bufs(dev); +err_irq_56: +#ifdef ENABLE_MVME16x_NET + free_irq(0x56, dev); +err_irq_dev: +#endif + free_irq(dev->irq, dev); + return res; } @@ -1488,6 +1509,9 @@ static int i596_close(struct net_device *dev) } #endif +#ifdef ENABLE_MVME16x_NET + free_irq(0x56, dev); +#endif free_irq(dev->irq, dev); remove_rx_bufs(dev); |
