diff options
author | Jayamohan Kallickal <jayamohank@serverengines.com> | 2010-07-21 18:57:47 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2010-07-28 10:05:37 -0400 |
commit | 3cbb7a74a76e45f5e410367259844e8266fba6ec (patch) | |
tree | 0fecd55bd62d80961a0dd7c3fba3523fe8ab5e93 /drivers/scsi/be2iscsi/be_mgmt.c | |
parent | 0aa094331b19e54f928e2ac083285ff68d91c69b (diff) |
[SCSI] be2iscsi: Fix for premature buffer free
This patch fixes a bug where the buffer was being freed as soon as
submission to HW is done.
Signed-off-by: Jayamohan Kallickal <jayamohank@serverengines.com>
Reviewed-by: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/be2iscsi/be_mgmt.c')
-rw-r--r-- | drivers/scsi/be2iscsi/be_mgmt.c | 45 |
1 files changed, 21 insertions, 24 deletions
diff --git a/drivers/scsi/be2iscsi/be_mgmt.c b/drivers/scsi/be2iscsi/be_mgmt.c index 3036d9ee7902..3f3fab91a7d1 100644 --- a/drivers/scsi/be2iscsi/be_mgmt.c +++ b/drivers/scsi/be2iscsi/be_mgmt.c | |||
@@ -50,7 +50,7 @@ int mgmt_get_fw_config(struct be_ctrl_info *ctrl, | |||
50 | pfw_cfg->ulp[0].sq_count; | 50 | pfw_cfg->ulp[0].sq_count; |
51 | if (phba->fw_config.iscsi_cid_count > (BE2_MAX_SESSIONS / 2)) { | 51 | if (phba->fw_config.iscsi_cid_count > (BE2_MAX_SESSIONS / 2)) { |
52 | SE_DEBUG(DBG_LVL_8, | 52 | SE_DEBUG(DBG_LVL_8, |
53 | "FW reported MAX CXNS as %d \t" | 53 | "FW reported MAX CXNS as %d\t" |
54 | "Max Supported = %d.\n", | 54 | "Max Supported = %d.\n", |
55 | phba->fw_config.iscsi_cid_count, | 55 | phba->fw_config.iscsi_cid_count, |
56 | BE2_MAX_SESSIONS); | 56 | BE2_MAX_SESSIONS); |
@@ -145,9 +145,10 @@ int mgmt_epfw_cleanup(struct beiscsi_hba *phba, unsigned short chute) | |||
145 | 145 | ||
146 | unsigned int mgmt_invalidate_icds(struct beiscsi_hba *phba, | 146 | unsigned int mgmt_invalidate_icds(struct beiscsi_hba *phba, |
147 | struct invalidate_command_table *inv_tbl, | 147 | struct invalidate_command_table *inv_tbl, |
148 | unsigned int num_invalidate, unsigned int cid) | 148 | unsigned int num_invalidate, unsigned int cid, |
149 | struct be_dma_mem *nonemb_cmd) | ||
150 | |||
149 | { | 151 | { |
150 | struct be_dma_mem nonemb_cmd; | ||
151 | struct be_ctrl_info *ctrl = &phba->ctrl; | 152 | struct be_ctrl_info *ctrl = &phba->ctrl; |
152 | struct be_mcc_wrb *wrb; | 153 | struct be_mcc_wrb *wrb; |
153 | struct be_sge *sge; | 154 | struct be_sge *sge; |
@@ -161,18 +162,7 @@ unsigned int mgmt_invalidate_icds(struct beiscsi_hba *phba, | |||
161 | return tag; | 162 | return tag; |
162 | } | 163 | } |
163 | 164 | ||
164 | nonemb_cmd.va = pci_alloc_consistent(ctrl->pdev, | 165 | req = nonemb_cmd->va; |
165 | sizeof(struct invalidate_commands_params_in), | ||
166 | &nonemb_cmd.dma); | ||
167 | if (nonemb_cmd.va == NULL) { | ||
168 | SE_DEBUG(DBG_LVL_1, | ||
169 | "Failed to alloc memory for mgmt_invalidate_icds\n"); | ||
170 | spin_unlock(&ctrl->mbox_lock); | ||
171 | free_mcc_tag(&phba->ctrl, tag); | ||
172 | return 0; | ||
173 | } | ||
174 | nonemb_cmd.size = sizeof(struct invalidate_commands_params_in); | ||
175 | req = nonemb_cmd.va; | ||
176 | memset(req, 0, sizeof(*req)); | 166 | memset(req, 0, sizeof(*req)); |
177 | wrb = wrb_from_mccq(phba); | 167 | wrb = wrb_from_mccq(phba); |
178 | sge = nonembedded_sgl(wrb); | 168 | sge = nonembedded_sgl(wrb); |
@@ -190,15 +180,12 @@ unsigned int mgmt_invalidate_icds(struct beiscsi_hba *phba, | |||
190 | req->icd_count++; | 180 | req->icd_count++; |
191 | inv_tbl++; | 181 | inv_tbl++; |
192 | } | 182 | } |
193 | sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd.dma)); | 183 | sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma)); |
194 | sge->pa_lo = cpu_to_le32(nonemb_cmd.dma & 0xFFFFFFFF); | 184 | sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF); |
195 | sge->len = cpu_to_le32(nonemb_cmd.size); | 185 | sge->len = cpu_to_le32(nonemb_cmd->size); |
196 | 186 | ||
197 | be_mcc_notify(phba); | 187 | be_mcc_notify(phba); |
198 | spin_unlock(&ctrl->mbox_lock); | 188 | spin_unlock(&ctrl->mbox_lock); |
199 | if (nonemb_cmd.va) | ||
200 | pci_free_consistent(ctrl->pdev, nonemb_cmd.size, | ||
201 | nonemb_cmd.va, nonemb_cmd.dma); | ||
202 | return tag; | 189 | return tag; |
203 | } | 190 | } |
204 | 191 | ||
@@ -269,7 +256,9 @@ unsigned int mgmt_upload_connection(struct beiscsi_hba *phba, | |||
269 | 256 | ||
270 | int mgmt_open_connection(struct beiscsi_hba *phba, | 257 | int mgmt_open_connection(struct beiscsi_hba *phba, |
271 | struct sockaddr *dst_addr, | 258 | struct sockaddr *dst_addr, |
272 | struct beiscsi_endpoint *beiscsi_ep) | 259 | struct beiscsi_endpoint *beiscsi_ep, |
260 | struct be_dma_mem *nonemb_cmd) | ||
261 | |||
273 | { | 262 | { |
274 | struct hwi_controller *phwi_ctrlr; | 263 | struct hwi_controller *phwi_ctrlr; |
275 | struct hwi_context_memory *phwi_context; | 264 | struct hwi_context_memory *phwi_context; |
@@ -285,6 +274,7 @@ int mgmt_open_connection(struct beiscsi_hba *phba, | |||
285 | unsigned int tag = 0; | 274 | unsigned int tag = 0; |
286 | unsigned int i; | 275 | unsigned int i; |
287 | unsigned short cid = beiscsi_ep->ep_cid; | 276 | unsigned short cid = beiscsi_ep->ep_cid; |
277 | struct be_sge *sge; | ||
288 | 278 | ||
289 | phwi_ctrlr = phba->phwi_ctrlr; | 279 | phwi_ctrlr = phba->phwi_ctrlr; |
290 | phwi_context = phwi_ctrlr->phwi_ctxt; | 280 | phwi_context = phwi_ctrlr->phwi_ctxt; |
@@ -300,10 +290,14 @@ int mgmt_open_connection(struct beiscsi_hba *phba, | |||
300 | return tag; | 290 | return tag; |
301 | } | 291 | } |
302 | wrb = wrb_from_mccq(phba); | 292 | wrb = wrb_from_mccq(phba); |
303 | req = embedded_payload(wrb); | 293 | memset(wrb, 0, sizeof(*wrb)); |
294 | sge = nonembedded_sgl(wrb); | ||
295 | |||
296 | req = nonemb_cmd->va; | ||
297 | memset(req, 0, sizeof(*req)); | ||
304 | wrb->tag0 |= tag; | 298 | wrb->tag0 |= tag; |
305 | 299 | ||
306 | be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); | 300 | be_wrb_hdr_prepare(wrb, sizeof(*req), true, 1); |
307 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI, | 301 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI, |
308 | OPCODE_COMMON_ISCSI_TCP_CONNECT_AND_OFFLOAD, | 302 | OPCODE_COMMON_ISCSI_TCP_CONNECT_AND_OFFLOAD, |
309 | sizeof(*req)); | 303 | sizeof(*req)); |
@@ -347,6 +341,9 @@ int mgmt_open_connection(struct beiscsi_hba *phba, | |||
347 | req->do_offload = 1; | 341 | req->do_offload = 1; |
348 | req->dataout_template_pa.lo = ptemplate_address->lo; | 342 | req->dataout_template_pa.lo = ptemplate_address->lo; |
349 | req->dataout_template_pa.hi = ptemplate_address->hi; | 343 | req->dataout_template_pa.hi = ptemplate_address->hi; |
344 | sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma)); | ||
345 | sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF); | ||
346 | sge->len = cpu_to_le32(nonemb_cmd->size); | ||
350 | be_mcc_notify(phba); | 347 | be_mcc_notify(phba); |
351 | spin_unlock(&ctrl->mbox_lock); | 348 | spin_unlock(&ctrl->mbox_lock); |
352 | return tag; | 349 | return tag; |