cxgb4: Dynamically allocate memory in t4_memory_rw() and get_vpd_params()
authorVipul Pandya <vipul@chelsio.com>
Wed, 3 Oct 2012 03:22:32 +0000 (03:22 +0000)
committerDavid S. Miller <davem@davemloft.net>
Wed, 3 Oct 2012 20:34:15 +0000 (16:34 -0400)
This patch changes memory allocation to reduce stack footprint

Signed-off-by: Jay Hernandez <jay@chelsio.com>
Signed-off-by: Vipul Pandya <vipul@chelsio.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/chelsio/cxgb4/t4_hw.c

index 35b81d8b59e90707fdb37518f76300871b5fd627..137a24438d9c76532d691158913a9066d38146f0 100644 (file)
@@ -408,7 +408,8 @@ static int t4_memory_rw(struct adapter *adap, int mtype, u32 addr, u32 len,
                        __be32 *buf, int dir)
 {
        u32 pos, start, end, offset, memoffset;
-       int ret;
+       int ret = 0;
+       __be32 *data;
 
        /*
         * Argument sanity checks ...
@@ -416,6 +417,10 @@ static int t4_memory_rw(struct adapter *adap, int mtype, u32 addr, u32 len,
        if ((addr & 0x3) || (len & 0x3))
                return -EINVAL;
 
+       data = vmalloc(MEMWIN0_APERTURE/sizeof(__be32));
+       if (!data)
+               return -ENOMEM;
+
        /*
         * Offset into the region of memory which is being accessed
         * MEM_EDC0 = 0
@@ -438,7 +443,6 @@ static int t4_memory_rw(struct adapter *adap, int mtype, u32 addr, u32 len,
        offset = (addr - start)/sizeof(__be32);
 
        for (pos = start; pos < end; pos += MEMWIN0_APERTURE, offset = 0) {
-               __be32 data[MEMWIN0_APERTURE/sizeof(__be32)];
 
                /*
                 * If we're writing, copy the data from the caller's memory
@@ -452,7 +456,7 @@ static int t4_memory_rw(struct adapter *adap, int mtype, u32 addr, u32 len,
                        if (offset || len < MEMWIN0_APERTURE) {
                                ret = t4_mem_win_rw(adap, pos, data, 1);
                                if (ret)
-                                       return ret;
+                                       break;
                        }
                        while (offset < (MEMWIN0_APERTURE/sizeof(__be32)) &&
                               len > 0) {
@@ -466,7 +470,7 @@ static int t4_memory_rw(struct adapter *adap, int mtype, u32 addr, u32 len,
                 */
                ret = t4_mem_win_rw(adap, pos, data, dir);
                if (ret)
-                       return ret;
+                       break;
 
                /*
                 * If we're reading, copy the data into the caller's memory
@@ -480,7 +484,8 @@ static int t4_memory_rw(struct adapter *adap, int mtype, u32 addr, u32 len,
                        }
        }
 
-       return 0;
+       vfree(data);
+       return ret;
 }
 
 int t4_memory_write(struct adapter *adap, int mtype, u32 addr, u32 len,
@@ -519,16 +524,21 @@ int get_vpd_params(struct adapter *adapter, struct vpd_params *p)
        u32 cclk_param, cclk_val;
        int i, ret;
        int ec, sn;
-       u8 vpd[VPD_LEN], csum;
+       u8 *vpd, csum;
        unsigned int vpdr_len, kw_offset, id_len;
 
-       ret = pci_read_vpd(adapter->pdev, VPD_BASE, sizeof(vpd), vpd);
+       vpd = vmalloc(VPD_LEN);
+       if (!vpd)
+               return -ENOMEM;
+
+       ret = pci_read_vpd(adapter->pdev, VPD_BASE, VPD_LEN, vpd);
        if (ret < 0)
-               return ret;
+               goto out;
 
        if (vpd[0] != PCI_VPD_LRDT_ID_STRING) {
                dev_err(adapter->pdev_dev, "missing VPD ID string\n");
-               return -EINVAL;
+               ret = -EINVAL;
+               goto out;
        }
 
        id_len = pci_vpd_lrdt_size(vpd);
@@ -538,21 +548,24 @@ int get_vpd_params(struct adapter *adapter, struct vpd_params *p)
        i = pci_vpd_find_tag(vpd, 0, VPD_LEN, PCI_VPD_LRDT_RO_DATA);
        if (i < 0) {
                dev_err(adapter->pdev_dev, "missing VPD-R section\n");
-               return -EINVAL;
+               ret = -EINVAL;
+               goto out;
        }
 
        vpdr_len = pci_vpd_lrdt_size(&vpd[i]);
        kw_offset = i + PCI_VPD_LRDT_TAG_SIZE;
        if (vpdr_len + kw_offset > VPD_LEN) {
                dev_err(adapter->pdev_dev, "bad VPD-R length %u\n", vpdr_len);
-               return -EINVAL;
+               ret = -EINVAL;
+               goto out;
        }
 
 #define FIND_VPD_KW(var, name) do { \
        var = pci_vpd_find_info_keyword(vpd, kw_offset, vpdr_len, name); \
        if (var < 0) { \
                dev_err(adapter->pdev_dev, "missing VPD keyword " name "\n"); \
-               return -EINVAL; \
+               ret = -EINVAL; \
+               goto out; \
        } \
        var += PCI_VPD_INFO_FLD_HDR_SIZE; \
 } while (0)
@@ -564,7 +577,8 @@ int get_vpd_params(struct adapter *adapter, struct vpd_params *p)
        if (csum) {
                dev_err(adapter->pdev_dev,
                        "corrupted VPD EEPROM, actual csum %u\n", csum);
-               return -EINVAL;
+               ret = -EINVAL;
+               goto out;
        }
 
        FIND_VPD_KW(ec, "EC");
@@ -587,6 +601,9 @@ int get_vpd_params(struct adapter *adapter, struct vpd_params *p)
                      FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DEV_CCLK));
        ret = t4_query_params(adapter, adapter->mbox, 0, 0,
                              1, &cclk_param, &cclk_val);
+
+out:
+       vfree(vpd);
        if (ret)
                return ret;
        p->cclk = cclk_val;