summaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@osdl.org>2005-12-14 15:47:46 -0800
committerJeff Garzik <jgarzik@pobox.com>2005-12-24 09:36:05 -0500
commit7731a4ea1bbb7c9336bcdec8ef4050cf08a35268 (patch)
tree2aa5dbad868dbaa1bd60972abcd9dcb9ac66fdba /drivers/net
parente8df8554605f014765732605667145c0824a12b7 (diff)
downloadlinux-7731a4ea1bbb7c9336bcdec8ef4050cf08a35268.tar.bz2
[PATCH] skge: handle out of memory on MTU size changes
Changing the MTU size causes the receiver to have to reallocate buffers. If this allocation fails, then we need to return an error, and take the device offline. It can then be brought back up or reconfigured for a smaller MTU. Signed-off-by: Stephen Hemminger <shemminger@osdl.org> Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/skge.c22
1 files changed, 16 insertions, 6 deletions
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index 14bf4cc5b07b..96b661b1f6c0 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -2192,6 +2192,7 @@ static int skge_up(struct net_device *dev)
kfree(skge->rx_ring.start);
free_pci_mem:
pci_free_consistent(hw->pdev, skge->mem_size, skge->mem, skge->dma);
+ skge->mem = NULL;
return err;
}
@@ -2202,6 +2203,9 @@ static int skge_down(struct net_device *dev)
struct skge_hw *hw = skge->hw;
int port = skge->port;
+ if (skge->mem == NULL)
+ return 0;
+
if (netif_msg_ifdown(skge))
printk(KERN_INFO PFX "%s: disabling interface\n", dev->name);
@@ -2258,6 +2262,7 @@ static int skge_down(struct net_device *dev)
kfree(skge->rx_ring.start);
kfree(skge->tx_ring.start);
pci_free_consistent(hw->pdev, skge->mem_size, skge->mem, skge->dma);
+ skge->mem = NULL;
return 0;
}
@@ -2418,18 +2423,23 @@ static void skge_tx_timeout(struct net_device *dev)
static int skge_change_mtu(struct net_device *dev, int new_mtu)
{
- int err = 0;
- int running = netif_running(dev);
+ int err;
if (new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU)
return -EINVAL;
+ if (!netif_running(dev)) {
+ dev->mtu = new_mtu;
+ return 0;
+ }
+
+ skge_down(dev);
- if (running)
- skge_down(dev);
dev->mtu = new_mtu;
- if (running)
- skge_up(dev);
+
+ err = skge_up(dev);
+ if (err)
+ dev_close(dev);
return err;
}