diff options
author | Somnath Kotur <somnath.kotur@emulex.com> | 2011-04-20 23:18:12 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-04-25 15:13:47 -0400 |
commit | fe2a70eefa18a3e419dd9a23e16af14258b7cc20 (patch) | |
tree | c86cf20f94ef175ff83bd7ae4d3c9ee648826662 /drivers/net/benet | |
parent | 3aba891dde3842d89ad022237b99c1ed308040b0 (diff) |
be2net: Fixed a bug in be_cmd_get_regs().
Same WRB entry was being reused over different iterations of a
loop while issuing non-embedded IOCTL requests.Fixed couple of minor bugs
in this path as well.
Re-factored code to alloc/free memory for DMA outside of loop
Signed-off-by: Somnath Kotur <somnath.kotur@emulex.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/benet')
-rw-r--r-- | drivers/net/benet/be_cmds.c | 53 |
1 files changed, 28 insertions, 25 deletions
diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index af8cf3d7c1e3..0fc06d363806 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c | |||
@@ -1214,8 +1214,8 @@ int be_cmd_get_reg_len(struct be_adapter *adapter, u32 *log_size) | |||
1214 | if (!status) { | 1214 | if (!status) { |
1215 | struct be_cmd_resp_get_fat *resp = embedded_payload(wrb); | 1215 | struct be_cmd_resp_get_fat *resp = embedded_payload(wrb); |
1216 | if (log_size && resp->log_size) | 1216 | if (log_size && resp->log_size) |
1217 | *log_size = le32_to_cpu(resp->log_size - | 1217 | *log_size = le32_to_cpu(resp->log_size) - |
1218 | sizeof(u32)); | 1218 | sizeof(u32); |
1219 | } | 1219 | } |
1220 | err: | 1220 | err: |
1221 | spin_unlock_bh(&adapter->mcc_lock); | 1221 | spin_unlock_bh(&adapter->mcc_lock); |
@@ -1228,7 +1228,8 @@ void be_cmd_get_regs(struct be_adapter *adapter, u32 buf_len, void *buf) | |||
1228 | struct be_mcc_wrb *wrb; | 1228 | struct be_mcc_wrb *wrb; |
1229 | struct be_cmd_req_get_fat *req; | 1229 | struct be_cmd_req_get_fat *req; |
1230 | struct be_sge *sge; | 1230 | struct be_sge *sge; |
1231 | u32 offset = 0, total_size, buf_size, log_offset = sizeof(u32); | 1231 | u32 offset = 0, total_size, buf_size, |
1232 | log_offset = sizeof(u32), payload_len; | ||
1232 | int status; | 1233 | int status; |
1233 | 1234 | ||
1234 | if (buf_len == 0) | 1235 | if (buf_len == 0) |
@@ -1236,37 +1237,39 @@ void be_cmd_get_regs(struct be_adapter *adapter, u32 buf_len, void *buf) | |||
1236 | 1237 | ||
1237 | total_size = buf_len; | 1238 | total_size = buf_len; |
1238 | 1239 | ||
1240 | get_fat_cmd.size = sizeof(struct be_cmd_req_get_fat) + 60*1024; | ||
1241 | get_fat_cmd.va = pci_alloc_consistent(adapter->pdev, | ||
1242 | get_fat_cmd.size, | ||
1243 | &get_fat_cmd.dma); | ||
1244 | if (!get_fat_cmd.va) { | ||
1245 | status = -ENOMEM; | ||
1246 | dev_err(&adapter->pdev->dev, | ||
1247 | "Memory allocation failure while retrieving FAT data\n"); | ||
1248 | return; | ||
1249 | } | ||
1250 | |||
1239 | spin_lock_bh(&adapter->mcc_lock); | 1251 | spin_lock_bh(&adapter->mcc_lock); |
1240 | 1252 | ||
1241 | wrb = wrb_from_mccq(adapter); | ||
1242 | if (!wrb) { | ||
1243 | status = -EBUSY; | ||
1244 | goto err; | ||
1245 | } | ||
1246 | while (total_size) { | 1253 | while (total_size) { |
1247 | buf_size = min(total_size, (u32)60*1024); | 1254 | buf_size = min(total_size, (u32)60*1024); |
1248 | total_size -= buf_size; | 1255 | total_size -= buf_size; |
1249 | 1256 | ||
1250 | get_fat_cmd.size = sizeof(struct be_cmd_req_get_fat) + buf_size; | 1257 | wrb = wrb_from_mccq(adapter); |
1251 | get_fat_cmd.va = pci_alloc_consistent(adapter->pdev, | 1258 | if (!wrb) { |
1252 | get_fat_cmd.size, | 1259 | status = -EBUSY; |
1253 | &get_fat_cmd.dma); | ||
1254 | if (!get_fat_cmd.va) { | ||
1255 | status = -ENOMEM; | ||
1256 | dev_err(&adapter->pdev->dev, | ||
1257 | "Memory allocation failure while retrieving FAT data\n"); | ||
1258 | goto err; | 1260 | goto err; |
1259 | } | 1261 | } |
1260 | req = get_fat_cmd.va; | 1262 | req = get_fat_cmd.va; |
1261 | sge = nonembedded_sgl(wrb); | 1263 | sge = nonembedded_sgl(wrb); |
1262 | 1264 | ||
1263 | be_wrb_hdr_prepare(wrb, get_fat_cmd.size, false, 1, | 1265 | payload_len = sizeof(struct be_cmd_req_get_fat) + buf_size; |
1266 | be_wrb_hdr_prepare(wrb, payload_len, false, 1, | ||
1264 | OPCODE_COMMON_MANAGE_FAT); | 1267 | OPCODE_COMMON_MANAGE_FAT); |
1265 | 1268 | ||
1266 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, | 1269 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, |
1267 | OPCODE_COMMON_MANAGE_FAT, get_fat_cmd.size); | 1270 | OPCODE_COMMON_MANAGE_FAT, payload_len); |
1268 | 1271 | ||
1269 | sge->pa_hi = cpu_to_le32(upper_32_bits(get_fat_cmd.size)); | 1272 | sge->pa_hi = cpu_to_le32(upper_32_bits(get_fat_cmd.dma)); |
1270 | sge->pa_lo = cpu_to_le32(get_fat_cmd.dma & 0xFFFFFFFF); | 1273 | sge->pa_lo = cpu_to_le32(get_fat_cmd.dma & 0xFFFFFFFF); |
1271 | sge->len = cpu_to_le32(get_fat_cmd.size); | 1274 | sge->len = cpu_to_le32(get_fat_cmd.size); |
1272 | 1275 | ||
@@ -1281,17 +1284,17 @@ void be_cmd_get_regs(struct be_adapter *adapter, u32 buf_len, void *buf) | |||
1281 | memcpy(buf + offset, | 1284 | memcpy(buf + offset, |
1282 | resp->data_buffer, | 1285 | resp->data_buffer, |
1283 | resp->read_log_length); | 1286 | resp->read_log_length); |
1284 | } | 1287 | } else { |
1285 | pci_free_consistent(adapter->pdev, get_fat_cmd.size, | ||
1286 | get_fat_cmd.va, | ||
1287 | get_fat_cmd.dma); | ||
1288 | if (status) | ||
1289 | dev_err(&adapter->pdev->dev, "FAT Table Retrieve error\n"); | 1288 | dev_err(&adapter->pdev->dev, "FAT Table Retrieve error\n"); |
1290 | 1289 | goto err; | |
1290 | } | ||
1291 | offset += buf_size; | 1291 | offset += buf_size; |
1292 | log_offset += buf_size; | 1292 | log_offset += buf_size; |
1293 | } | 1293 | } |
1294 | err: | 1294 | err: |
1295 | pci_free_consistent(adapter->pdev, get_fat_cmd.size, | ||
1296 | get_fat_cmd.va, | ||
1297 | get_fat_cmd.dma); | ||
1295 | spin_unlock_bh(&adapter->mcc_lock); | 1298 | spin_unlock_bh(&adapter->mcc_lock); |
1296 | } | 1299 | } |
1297 | 1300 | ||