|
@@ -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;
|