diff options
author | Sreenivasa Honnur <Sreenivasa.Honnur@neterion.com> | 2007-11-30 01:46:08 -0500 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2007-12-01 16:32:28 -0500 |
commit | 9f74ffdebf3f81cb69e6c90026c6cff89e57c262 (patch) | |
tree | e9d61113cd5d5431a4d69da6fa3510f548cc021e /drivers/net/s2io.c | |
parent | 85b161a826f1954e9605deb3e6faa4be4d285a34 (diff) |
S2io: Fixed the case when the card initialization fails on mtu change
Fix the case when the card initialization fails on a mtu change and then
close is called (due to ifdown), which frees non existent rx buffers.
- Returning appropriate error codes in init_nic function.
- In s2io_close function s2io_card_down is called only when device is up.
- In s2io_change_mtu function return value of s2io_card_up function
is checked and returned if it failed.
Signed-off-by: Surjit Reang <surjit.reang@neterion.com>
Signed-off-by: Sreenivasa Honnur <sreenivasa.honnur@neterion.com>
Signed-off-by: Ramkrishna Vepa <ram.vepa@neterion.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net/s2io.c')
-rw-r--r-- | drivers/net/s2io.c | 32 |
1 files changed, 23 insertions, 9 deletions
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 632666706247..d5113dd712c2 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c | |||
@@ -1081,7 +1081,7 @@ static int init_nic(struct s2io_nic *nic) | |||
1081 | /* to set the swapper controle on the card */ | 1081 | /* to set the swapper controle on the card */ |
1082 | if(s2io_set_swapper(nic)) { | 1082 | if(s2io_set_swapper(nic)) { |
1083 | DBG_PRINT(ERR_DBG,"ERROR: Setting Swapper failed\n"); | 1083 | DBG_PRINT(ERR_DBG,"ERROR: Setting Swapper failed\n"); |
1084 | return -1; | 1084 | return -EIO; |
1085 | } | 1085 | } |
1086 | 1086 | ||
1087 | /* | 1087 | /* |
@@ -1503,7 +1503,7 @@ static int init_nic(struct s2io_nic *nic) | |||
1503 | DBG_PRINT(ERR_DBG, "%s: failed rts ds steering", | 1503 | DBG_PRINT(ERR_DBG, "%s: failed rts ds steering", |
1504 | dev->name); | 1504 | dev->name); |
1505 | DBG_PRINT(ERR_DBG, "set on codepoint %d\n", i); | 1505 | DBG_PRINT(ERR_DBG, "set on codepoint %d\n", i); |
1506 | return FAILURE; | 1506 | return -ENODEV; |
1507 | } | 1507 | } |
1508 | } | 1508 | } |
1509 | 1509 | ||
@@ -1570,7 +1570,7 @@ static int init_nic(struct s2io_nic *nic) | |||
1570 | if (time > 10) { | 1570 | if (time > 10) { |
1571 | DBG_PRINT(ERR_DBG, "%s: TTI init Failed\n", | 1571 | DBG_PRINT(ERR_DBG, "%s: TTI init Failed\n", |
1572 | dev->name); | 1572 | dev->name); |
1573 | return -1; | 1573 | return -ENODEV; |
1574 | } | 1574 | } |
1575 | msleep(50); | 1575 | msleep(50); |
1576 | time++; | 1576 | time++; |
@@ -1623,7 +1623,7 @@ static int init_nic(struct s2io_nic *nic) | |||
1623 | if (time > 10) { | 1623 | if (time > 10) { |
1624 | DBG_PRINT(ERR_DBG, "%s: RTI init Failed\n", | 1624 | DBG_PRINT(ERR_DBG, "%s: RTI init Failed\n", |
1625 | dev->name); | 1625 | dev->name); |
1626 | return -1; | 1626 | return -ENODEV; |
1627 | } | 1627 | } |
1628 | time++; | 1628 | time++; |
1629 | msleep(50); | 1629 | msleep(50); |
@@ -3914,6 +3914,12 @@ static int s2io_close(struct net_device *dev) | |||
3914 | { | 3914 | { |
3915 | struct s2io_nic *sp = dev->priv; | 3915 | struct s2io_nic *sp = dev->priv; |
3916 | 3916 | ||
3917 | /* Return if the device is already closed * | ||
3918 | * Can happen when s2io_card_up failed in change_mtu * | ||
3919 | */ | ||
3920 | if (!is_s2io_card_up(sp)) | ||
3921 | return 0; | ||
3922 | |||
3917 | netif_stop_queue(dev); | 3923 | netif_stop_queue(dev); |
3918 | napi_disable(&sp->napi); | 3924 | napi_disable(&sp->napi); |
3919 | /* Reset card, kill tasklet and free Tx and Rx buffers. */ | 3925 | /* Reset card, kill tasklet and free Tx and Rx buffers. */ |
@@ -6355,6 +6361,7 @@ static int s2io_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) | |||
6355 | static int s2io_change_mtu(struct net_device *dev, int new_mtu) | 6361 | static int s2io_change_mtu(struct net_device *dev, int new_mtu) |
6356 | { | 6362 | { |
6357 | struct s2io_nic *sp = dev->priv; | 6363 | struct s2io_nic *sp = dev->priv; |
6364 | int ret = 0; | ||
6358 | 6365 | ||
6359 | if ((new_mtu < MIN_MTU) || (new_mtu > S2IO_JUMBO_SIZE)) { | 6366 | if ((new_mtu < MIN_MTU) || (new_mtu > S2IO_JUMBO_SIZE)) { |
6360 | DBG_PRINT(ERR_DBG, "%s: MTU size is invalid.\n", | 6367 | DBG_PRINT(ERR_DBG, "%s: MTU size is invalid.\n", |
@@ -6366,9 +6373,11 @@ static int s2io_change_mtu(struct net_device *dev, int new_mtu) | |||
6366 | if (netif_running(dev)) { | 6373 | if (netif_running(dev)) { |
6367 | s2io_card_down(sp); | 6374 | s2io_card_down(sp); |
6368 | netif_stop_queue(dev); | 6375 | netif_stop_queue(dev); |
6369 | if (s2io_card_up(sp)) { | 6376 | ret = s2io_card_up(sp); |
6377 | if (ret) { | ||
6370 | DBG_PRINT(ERR_DBG, "%s: Device bring up failed\n", | 6378 | DBG_PRINT(ERR_DBG, "%s: Device bring up failed\n", |
6371 | __FUNCTION__); | 6379 | __FUNCTION__); |
6380 | return ret; | ||
6372 | } | 6381 | } |
6373 | if (netif_queue_stopped(dev)) | 6382 | if (netif_queue_stopped(dev)) |
6374 | netif_wake_queue(dev); | 6383 | netif_wake_queue(dev); |
@@ -6379,7 +6388,7 @@ static int s2io_change_mtu(struct net_device *dev, int new_mtu) | |||
6379 | writeq(vBIT(val64, 2, 14), &bar0->rmac_max_pyld_len); | 6388 | writeq(vBIT(val64, 2, 14), &bar0->rmac_max_pyld_len); |
6380 | } | 6389 | } |
6381 | 6390 | ||
6382 | return 0; | 6391 | return ret; |
6383 | } | 6392 | } |
6384 | 6393 | ||
6385 | /** | 6394 | /** |
@@ -6777,6 +6786,9 @@ static void do_s2io_card_down(struct s2io_nic * sp, int do_io) | |||
6777 | unsigned long flags; | 6786 | unsigned long flags; |
6778 | register u64 val64 = 0; | 6787 | register u64 val64 = 0; |
6779 | 6788 | ||
6789 | if (!is_s2io_card_up(sp)) | ||
6790 | return; | ||
6791 | |||
6780 | del_timer_sync(&sp->alarm_timer); | 6792 | del_timer_sync(&sp->alarm_timer); |
6781 | /* If s2io_set_link task is executing, wait till it completes. */ | 6793 | /* If s2io_set_link task is executing, wait till it completes. */ |
6782 | while (test_and_set_bit(__S2IO_STATE_LINK_TASK, &(sp->state))) { | 6794 | while (test_and_set_bit(__S2IO_STATE_LINK_TASK, &(sp->state))) { |
@@ -6850,11 +6862,13 @@ static int s2io_card_up(struct s2io_nic * sp) | |||
6850 | u16 interruptible; | 6862 | u16 interruptible; |
6851 | 6863 | ||
6852 | /* Initialize the H/W I/O registers */ | 6864 | /* Initialize the H/W I/O registers */ |
6853 | if (init_nic(sp) != 0) { | 6865 | ret = init_nic(sp); |
6866 | if (ret != 0) { | ||
6854 | DBG_PRINT(ERR_DBG, "%s: H/W initialization failed\n", | 6867 | DBG_PRINT(ERR_DBG, "%s: H/W initialization failed\n", |
6855 | dev->name); | 6868 | dev->name); |
6856 | s2io_reset(sp); | 6869 | if (ret != -EIO) |
6857 | return -ENODEV; | 6870 | s2io_reset(sp); |
6871 | return ret; | ||
6858 | } | 6872 | } |
6859 | 6873 | ||
6860 | /* | 6874 | /* |