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 <[EMAIL PROTECTED]>
Signed-off-by: Sreenivasa Honnur <[EMAIL PROTECTED]>
Signed-off-by: Ramkrishna Vepa <[EMAIL PROTECTED]>
---
diff -Nurp patch_8/drivers/net/s2io.c patch_9/drivers/net/s2io.c
--- patch_8/drivers/net/s2io.c  2007-11-20 23:31:57.000000000 +0530
+++ patch_9/drivers/net/s2io.c  2007-11-20 23:13:24.000000000 +0530
@@ -84,7 +84,7 @@
 #include "s2io.h"
 #include "s2io-regs.h"
 
-#define DRV_VERSION "2.0.26.8"
+#define DRV_VERSION "2.0.26.9"
 
 /* S2io Driver name & version. */
 static char s2io_driver_name[] = "Neterion";
@@ -1118,7 +1118,7 @@ static int init_nic(struct s2io_nic *nic
        /* to set the swapper controle on the card */
        if(s2io_set_swapper(nic)) {
                DBG_PRINT(ERR_DBG,"ERROR: Setting Swapper failed\n");
-               return -1;
+               return -EIO;
        }
 
        /*
@@ -1540,7 +1540,7 @@ static int init_nic(struct s2io_nic *nic
                        DBG_PRINT(ERR_DBG, "%s: failed rts ds steering",
                                dev->name);
                        DBG_PRINT(ERR_DBG, "set on codepoint %d\n", i);
-                       return FAILURE;
+                       return -ENODEV;
                }
        }
 
@@ -1607,7 +1607,7 @@ static int init_nic(struct s2io_nic *nic
                if (time > 10) {
                        DBG_PRINT(ERR_DBG, "%s: TTI init Failed\n",
                                  dev->name);
-                       return -1;
+                       return -ENODEV;
                }
                msleep(50);
                time++;
@@ -1660,7 +1660,7 @@ static int init_nic(struct s2io_nic *nic
                        if (time > 10) {
                                DBG_PRINT(ERR_DBG, "%s: RTI init Failed\n",
                                          dev->name);
-                               return -1;
+                               return -ENODEV;
                        }
                        time++;
                        msleep(50);
@@ -3946,6 +3946,12 @@ static int s2io_close(struct net_device 
 {
        struct s2io_nic *sp = dev->priv;
 
+       /* Return if the device is already closed               *
+       *  Can happen when s2io_card_up failed in change_mtu    *
+       */
+       if (!is_s2io_card_up(sp))
+               return 0;
+
        netif_stop_queue(dev);
        napi_disable(&sp->napi);
        /* Reset card, kill tasklet and free Tx and Rx buffers. */
@@ -6373,6 +6379,7 @@ static int s2io_ioctl(struct net_device 
 static int s2io_change_mtu(struct net_device *dev, int new_mtu)
 {
        struct s2io_nic *sp = dev->priv;
+       int ret = 0;
 
        if ((new_mtu < MIN_MTU) || (new_mtu > S2IO_JUMBO_SIZE)) {
                DBG_PRINT(ERR_DBG, "%s: MTU size is invalid.\n",
@@ -6384,9 +6391,11 @@ static int s2io_change_mtu(struct net_de
        if (netif_running(dev)) {
                s2io_card_down(sp);
                netif_stop_queue(dev);
-               if (s2io_card_up(sp)) {
+               ret = s2io_card_up(sp);
+               if (ret) {
                        DBG_PRINT(ERR_DBG, "%s: Device bring up failed\n",
                                  __FUNCTION__);
+                       return ret;
                }
                if (netif_queue_stopped(dev))
                        netif_wake_queue(dev);
@@ -6397,7 +6406,7 @@ static int s2io_change_mtu(struct net_de
                writeq(vBIT(val64, 2, 14), &bar0->rmac_max_pyld_len);
        }
 
-       return 0;
+       return ret;
 }
 
 /**
@@ -6795,6 +6804,9 @@ static void do_s2io_card_down(struct s2i
        unsigned long flags;
        register u64 val64 = 0;
 
+       if (!is_s2io_card_up(sp))
+               return;
+
        del_timer_sync(&sp->alarm_timer);
        /* If s2io_set_link task is executing, wait till it completes. */
        while (test_and_set_bit(__S2IO_STATE_LINK_TASK, &(sp->state))) {
@@ -6868,11 +6880,13 @@ static int s2io_card_up(struct s2io_nic 
        u16 interruptible;
 
        /* Initialize the H/W I/O registers */
-       if (init_nic(sp) != 0) {
+       ret = init_nic(sp);
+       if (ret != 0) {
                DBG_PRINT(ERR_DBG, "%s: H/W initialization failed\n",
                          dev->name);
-               s2io_reset(sp);
-               return -ENODEV;
+               if (ret != -EIO)
+                       s2io_reset(sp);
+               return ret;
        }
 
        /*

-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to