aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJayamohan Kallickal <jayamohan.kallickal@emulex.com>2014-01-29 02:16:39 -0500
committerJames Bottomley <JBottomley@Parallels.com>2014-03-15 13:19:10 -0400
commit1957aa7f62462dc888dfc9a94373b27f936f2e10 (patch)
treedc059ae34b917d20a1525d8304085f46635e6a3a
parent8e616a5ee6e389f855a9fa0ab57194b4b049d9c8 (diff)
[SCSI] be2iscsi: Fix handling timed out MBX completion from FW
When an MBX command timeout happens,the resources associated with the MBX command were freed. If FW were to give the response to host after the timeout value set by driver then driver crashes as the MBX Cmd resources were already freed. This patch fixes this issue by maintaing a state flag for each of the MBX command posted/timedout/completed. Signed-off-by: John Soni Jose <sony.john-n@emulex.com> Signed-off-by: Jayamohan Kallickal <jayamohan.kallickal@emulex.com> Reviewed-by: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
-rw-r--r--drivers/scsi/be2iscsi/be.h10
-rw-r--r--drivers/scsi/be2iscsi/be_cmds.c90
-rw-r--r--drivers/scsi/be2iscsi/be_cmds.h3
-rw-r--r--drivers/scsi/be2iscsi/be_iscsi.c10
-rw-r--r--drivers/scsi/be2iscsi/be_main.c27
-rw-r--r--drivers/scsi/be2iscsi/be_mgmt.c22
6 files changed, 117 insertions, 45 deletions
diff --git a/drivers/scsi/be2iscsi/be.h b/drivers/scsi/be2iscsi/be.h
index 2e28f6c419fe..23c73fe42648 100644
--- a/drivers/scsi/be2iscsi/be.h
+++ b/drivers/scsi/be2iscsi/be.h
@@ -98,6 +98,14 @@ struct be_mcc_obj {
98 struct be_queue_info cq; 98 struct be_queue_info cq;
99}; 99};
100 100
101struct beiscsi_mcc_tag_state {
102#define MCC_TAG_STATE_COMPLETED 0x00
103#define MCC_TAG_STATE_RUNNING 0x01
104#define MCC_TAG_STATE_TIMEOUT 0x02
105 uint8_t tag_state;
106 struct be_dma_mem tag_mem_state;
107};
108
101struct be_ctrl_info { 109struct be_ctrl_info {
102 u8 __iomem *csr; 110 u8 __iomem *csr;
103 u8 __iomem *db; /* Door Bell */ 111 u8 __iomem *db; /* Door Bell */
@@ -122,6 +130,8 @@ struct be_ctrl_info {
122 unsigned short mcc_alloc_index; 130 unsigned short mcc_alloc_index;
123 unsigned short mcc_free_index; 131 unsigned short mcc_free_index;
124 unsigned int mcc_tag_available; 132 unsigned int mcc_tag_available;
133
134 struct beiscsi_mcc_tag_state ptag_state[MAX_MCC_CMD + 1];
125}; 135};
126 136
127#include "be_cmds.h" 137#include "be_cmds.h"
diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index 3338391b64de..b14949a71eda 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -138,7 +138,7 @@ unsigned int alloc_mcc_tag(struct beiscsi_hba *phba)
138 * @phba: Driver private structure 138 * @phba: Driver private structure
139 * @tag: Tag for the MBX Command 139 * @tag: Tag for the MBX Command
140 * @wrb: the WRB used for the MBX Command 140 * @wrb: the WRB used for the MBX Command
141 * @cmd_hdr: IOCTL Hdr for the MBX Cmd 141 * @mbx_cmd_mem: ptr to memory allocated for MBX Cmd
142 * 142 *
143 * Waits for MBX completion with the passed TAG. 143 * Waits for MBX completion with the passed TAG.
144 * 144 *
@@ -148,21 +148,26 @@ unsigned int alloc_mcc_tag(struct beiscsi_hba *phba)
148 **/ 148 **/
149int beiscsi_mccq_compl(struct beiscsi_hba *phba, 149int beiscsi_mccq_compl(struct beiscsi_hba *phba,
150 uint32_t tag, struct be_mcc_wrb **wrb, 150 uint32_t tag, struct be_mcc_wrb **wrb,
151 void *cmd_hdr) 151 struct be_dma_mem *mbx_cmd_mem)
152{ 152{
153 int rc = 0; 153 int rc = 0;
154 uint32_t mcc_tag_response; 154 uint32_t mcc_tag_response;
155 uint16_t status = 0, addl_status = 0, wrb_num = 0; 155 uint16_t status = 0, addl_status = 0, wrb_num = 0;
156 struct be_mcc_wrb *temp_wrb; 156 struct be_mcc_wrb *temp_wrb;
157 struct be_cmd_req_hdr *ioctl_hdr; 157 struct be_cmd_req_hdr *mbx_hdr;
158 struct be_cmd_resp_hdr *ioctl_resp_hdr; 158 struct be_cmd_resp_hdr *mbx_resp_hdr;
159 struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q; 159 struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
160 160
161 if (beiscsi_error(phba)) { 161 if (beiscsi_error(phba)) {
162 free_mcc_tag(&phba->ctrl, tag); 162 free_mcc_tag(&phba->ctrl, tag);
163 return -EIO; 163 return -EPERM;
164 } 164 }
165 165
166 /* Set MBX Tag state to Active */
167 spin_lock(&phba->ctrl.mbox_lock);
168 phba->ctrl.ptag_state[tag].tag_state = MCC_TAG_STATE_RUNNING;
169 spin_unlock(&phba->ctrl.mbox_lock);
170
166 /* wait for the mccq completion */ 171 /* wait for the mccq completion */
167 rc = wait_event_interruptible_timeout( 172 rc = wait_event_interruptible_timeout(
168 phba->ctrl.mcc_wait[tag], 173 phba->ctrl.mcc_wait[tag],
@@ -171,56 +176,71 @@ int beiscsi_mccq_compl(struct beiscsi_hba *phba,
171 BEISCSI_HOST_MBX_TIMEOUT)); 176 BEISCSI_HOST_MBX_TIMEOUT));
172 177
173 if (rc <= 0) { 178 if (rc <= 0) {
179 struct be_dma_mem *tag_mem;
180 /* Set MBX Tag state to timeout */
181 spin_lock(&phba->ctrl.mbox_lock);
182 phba->ctrl.ptag_state[tag].tag_state = MCC_TAG_STATE_TIMEOUT;
183 spin_unlock(&phba->ctrl.mbox_lock);
184
185 /* Store resource addr to be freed later */
186 tag_mem = &phba->ctrl.ptag_state[tag].tag_mem_state;
187 if (mbx_cmd_mem) {
188 tag_mem->size = mbx_cmd_mem->size;
189 tag_mem->va = mbx_cmd_mem->va;
190 tag_mem->dma = mbx_cmd_mem->dma;
191 } else
192 tag_mem->size = 0;
193
174 beiscsi_log(phba, KERN_ERR, 194 beiscsi_log(phba, KERN_ERR,
175 BEISCSI_LOG_INIT | BEISCSI_LOG_EH | 195 BEISCSI_LOG_INIT | BEISCSI_LOG_EH |
176 BEISCSI_LOG_CONFIG, 196 BEISCSI_LOG_CONFIG,
177 "BC_%d : MBX Cmd Completion timed out\n"); 197 "BC_%d : MBX Cmd Completion timed out\n");
178 rc = -EBUSY; 198 return -EBUSY;
179 199 } else {
180 /* decrement the mccq used count */
181 atomic_dec(&phba->ctrl.mcc_obj.q.used);
182
183 goto release_mcc_tag;
184 } else
185 rc = 0; 200 rc = 0;
201 /* Set MBX Tag state to completed */
202 spin_lock(&phba->ctrl.mbox_lock);
203 phba->ctrl.ptag_state[tag].tag_state = MCC_TAG_STATE_COMPLETED;
204 spin_unlock(&phba->ctrl.mbox_lock);
205 }
186 206
187 mcc_tag_response = phba->ctrl.mcc_numtag[tag]; 207 mcc_tag_response = phba->ctrl.mcc_numtag[tag];
188 status = (mcc_tag_response & CQE_STATUS_MASK); 208 status = (mcc_tag_response & CQE_STATUS_MASK);
189 addl_status = ((mcc_tag_response & CQE_STATUS_ADDL_MASK) >> 209 addl_status = ((mcc_tag_response & CQE_STATUS_ADDL_MASK) >>
190 CQE_STATUS_ADDL_SHIFT); 210 CQE_STATUS_ADDL_SHIFT);
191 211
192 if (cmd_hdr) { 212 if (mbx_cmd_mem) {
193 ioctl_hdr = (struct be_cmd_req_hdr *)cmd_hdr; 213 mbx_hdr = (struct be_cmd_req_hdr *)mbx_cmd_mem->va;
194 } else { 214 } else {
195 wrb_num = (mcc_tag_response & CQE_STATUS_WRB_MASK) >> 215 wrb_num = (mcc_tag_response & CQE_STATUS_WRB_MASK) >>
196 CQE_STATUS_WRB_SHIFT; 216 CQE_STATUS_WRB_SHIFT;
197 temp_wrb = (struct be_mcc_wrb *)queue_get_wrb(mccq, wrb_num); 217 temp_wrb = (struct be_mcc_wrb *)queue_get_wrb(mccq, wrb_num);
198 ioctl_hdr = embedded_payload(temp_wrb); 218 mbx_hdr = embedded_payload(temp_wrb);
199 219
200 if (wrb) 220 if (wrb)
201 *wrb = temp_wrb; 221 *wrb = temp_wrb;
202 } 222 }
203 223
204 if (status || addl_status) { 224 if (status || addl_status) {
205 beiscsi_log(phba, KERN_ERR, 225 beiscsi_log(phba, KERN_WARNING,
206 BEISCSI_LOG_INIT | BEISCSI_LOG_EH | 226 BEISCSI_LOG_INIT | BEISCSI_LOG_EH |
207 BEISCSI_LOG_CONFIG, 227 BEISCSI_LOG_CONFIG,
208 "BC_%d : MBX Cmd Failed for " 228 "BC_%d : MBX Cmd Failed for "
209 "Subsys : %d Opcode : %d with " 229 "Subsys : %d Opcode : %d with "
210 "Status : %d and Extd_Status : %d\n", 230 "Status : %d and Extd_Status : %d\n",
211 ioctl_hdr->subsystem, 231 mbx_hdr->subsystem,
212 ioctl_hdr->opcode, 232 mbx_hdr->opcode,
213 status, addl_status); 233 status, addl_status);
214 234
215 if (status == MCC_STATUS_INSUFFICIENT_BUFFER) { 235 if (status == MCC_STATUS_INSUFFICIENT_BUFFER) {
216 ioctl_resp_hdr = (struct be_cmd_resp_hdr *) ioctl_hdr; 236 mbx_resp_hdr = (struct be_cmd_resp_hdr *) mbx_hdr;
217 beiscsi_log(phba, KERN_WARNING, 237 beiscsi_log(phba, KERN_WARNING,
218 BEISCSI_LOG_INIT | BEISCSI_LOG_EH | 238 BEISCSI_LOG_INIT | BEISCSI_LOG_EH |
219 BEISCSI_LOG_CONFIG, 239 BEISCSI_LOG_CONFIG,
220 "BC_%d : Insufficent Buffer Error " 240 "BC_%d : Insufficent Buffer Error "
221 "Resp_Len : %d Actual_Resp_Len : %d\n", 241 "Resp_Len : %d Actual_Resp_Len : %d\n",
222 ioctl_resp_hdr->response_length, 242 mbx_resp_hdr->response_length,
223 ioctl_resp_hdr->actual_resp_len); 243 mbx_resp_hdr->actual_resp_len);
224 244
225 rc = -EAGAIN; 245 rc = -EAGAIN;
226 goto release_mcc_tag; 246 goto release_mcc_tag;
@@ -319,6 +339,7 @@ static int be_mcc_compl_process(struct be_ctrl_info *ctrl,
319int be_mcc_compl_process_isr(struct be_ctrl_info *ctrl, 339int be_mcc_compl_process_isr(struct be_ctrl_info *ctrl,
320 struct be_mcc_compl *compl) 340 struct be_mcc_compl *compl)
321{ 341{
342 struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev);
322 u16 compl_status, extd_status; 343 u16 compl_status, extd_status;
323 unsigned short tag; 344 unsigned short tag;
324 345
@@ -338,7 +359,32 @@ int be_mcc_compl_process_isr(struct be_ctrl_info *ctrl,
338 ctrl->mcc_numtag[tag] |= (compl->tag0 & 0x00FF0000); 359 ctrl->mcc_numtag[tag] |= (compl->tag0 & 0x00FF0000);
339 ctrl->mcc_numtag[tag] |= (extd_status & 0x000000FF) << 8; 360 ctrl->mcc_numtag[tag] |= (extd_status & 0x000000FF) << 8;
340 ctrl->mcc_numtag[tag] |= (compl_status & 0x000000FF); 361 ctrl->mcc_numtag[tag] |= (compl_status & 0x000000FF);
341 wake_up_interruptible(&ctrl->mcc_wait[tag]); 362
363 if (ctrl->ptag_state[tag].tag_state == MCC_TAG_STATE_RUNNING) {
364 wake_up_interruptible(&ctrl->mcc_wait[tag]);
365 } else if (ctrl->ptag_state[tag].tag_state == MCC_TAG_STATE_TIMEOUT) {
366 struct be_dma_mem *tag_mem;
367 tag_mem = &ctrl->ptag_state[tag].tag_mem_state;
368
369 beiscsi_log(phba, KERN_WARNING,
370 BEISCSI_LOG_MBOX | BEISCSI_LOG_INIT |
371 BEISCSI_LOG_CONFIG,
372 "BC_%d : MBX Completion for timeout Command "
373 "from FW\n");
374 /* Check if memory needs to be freed */
375 if (tag_mem->size)
376 pci_free_consistent(ctrl->pdev, tag_mem->size,
377 tag_mem->va, tag_mem->dma);
378
379 /* Change tag state */
380 spin_lock(&phba->ctrl.mbox_lock);
381 ctrl->ptag_state[tag].tag_state = MCC_TAG_STATE_COMPLETED;
382 spin_unlock(&phba->ctrl.mbox_lock);
383
384 /* Free MCC Tag */
385 free_mcc_tag(ctrl, tag);
386 }
387
342 return 0; 388 return 0;
343} 389}
344 390
diff --git a/drivers/scsi/be2iscsi/be_cmds.h b/drivers/scsi/be2iscsi/be_cmds.h
index 627ebbe0172c..770b6c8bcad8 100644
--- a/drivers/scsi/be2iscsi/be_cmds.h
+++ b/drivers/scsi/be2iscsi/be_cmds.h
@@ -709,7 +709,8 @@ unsigned int be_cmd_get_port_speed(struct beiscsi_hba *phba);
709void free_mcc_tag(struct be_ctrl_info *ctrl, unsigned int tag); 709void free_mcc_tag(struct be_ctrl_info *ctrl, unsigned int tag);
710 710
711int beiscsi_mccq_compl(struct beiscsi_hba *phba, 711int beiscsi_mccq_compl(struct beiscsi_hba *phba,
712 uint32_t tag, struct be_mcc_wrb **wrb, void *cmd_va); 712 uint32_t tag, struct be_mcc_wrb **wrb,
713 struct be_dma_mem *mbx_cmd_mem);
713/*ISCSI Functuions */ 714/*ISCSI Functuions */
714int be_cmd_fw_initialize(struct be_ctrl_info *ctrl); 715int be_cmd_fw_initialize(struct be_ctrl_info *ctrl);
715int be_cmd_fw_uninit(struct be_ctrl_info *ctrl); 716int be_cmd_fw_uninit(struct be_ctrl_info *ctrl);
diff --git a/drivers/scsi/be2iscsi/be_iscsi.c b/drivers/scsi/be2iscsi/be_iscsi.c
index 889066d9d6fb..bdd0f05a3342 100644
--- a/drivers/scsi/be2iscsi/be_iscsi.c
+++ b/drivers/scsi/be2iscsi/be_iscsi.c
@@ -1153,16 +1153,18 @@ static int beiscsi_open_conn(struct iscsi_endpoint *ep,
1153 return -EAGAIN; 1153 return -EAGAIN;
1154 } 1154 }
1155 1155
1156 ret = beiscsi_mccq_compl(phba, tag, NULL, nonemb_cmd.va); 1156 ret = beiscsi_mccq_compl(phba, tag, NULL, &nonemb_cmd);
1157 if (ret) { 1157 if (ret) {
1158 beiscsi_log(phba, KERN_ERR, 1158 beiscsi_log(phba, KERN_ERR,
1159 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX, 1159 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
1160 "BS_%d : mgmt_open_connection Failed"); 1160 "BS_%d : mgmt_open_connection Failed");
1161 1161
1162 pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size, 1162 if (ret != -EBUSY)
1163 nonemb_cmd.va, nonemb_cmd.dma); 1163 pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
1164 nonemb_cmd.va, nonemb_cmd.dma);
1165
1164 beiscsi_free_ep(beiscsi_ep); 1166 beiscsi_free_ep(beiscsi_ep);
1165 return -EBUSY; 1167 return ret;
1166 } 1168 }
1167 1169
1168 ptcpcnct_out = (struct tcp_connect_and_offload_out *)nonemb_cmd.va; 1170 ptcpcnct_out = (struct tcp_connect_and_offload_out *)nonemb_cmd.va;
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index 5642a9b250c2..c8f90cef728d 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -228,6 +228,7 @@ static int beiscsi_eh_abort(struct scsi_cmnd *sc)
228 struct invalidate_command_table *inv_tbl; 228 struct invalidate_command_table *inv_tbl;
229 struct be_dma_mem nonemb_cmd; 229 struct be_dma_mem nonemb_cmd;
230 unsigned int cid, tag, num_invalidate; 230 unsigned int cid, tag, num_invalidate;
231 int rc;
231 232
232 cls_session = starget_to_session(scsi_target(sc->device)); 233 cls_session = starget_to_session(scsi_target(sc->device));
233 session = cls_session->dd_data; 234 session = cls_session->dd_data;
@@ -285,9 +286,11 @@ static int beiscsi_eh_abort(struct scsi_cmnd *sc)
285 return FAILED; 286 return FAILED;
286 } 287 }
287 288
288 beiscsi_mccq_compl(phba, tag, NULL, nonemb_cmd.va); 289 rc = beiscsi_mccq_compl(phba, tag, NULL, &nonemb_cmd);
289 pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size, 290 if (rc != -EBUSY)
290 nonemb_cmd.va, nonemb_cmd.dma); 291 pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
292 nonemb_cmd.va, nonemb_cmd.dma);
293
291 return iscsi_eh_abort(sc); 294 return iscsi_eh_abort(sc);
292} 295}
293 296
@@ -303,6 +306,7 @@ static int beiscsi_eh_device_reset(struct scsi_cmnd *sc)
303 struct invalidate_command_table *inv_tbl; 306 struct invalidate_command_table *inv_tbl;
304 struct be_dma_mem nonemb_cmd; 307 struct be_dma_mem nonemb_cmd;
305 unsigned int cid, tag, i, num_invalidate; 308 unsigned int cid, tag, i, num_invalidate;
309 int rc;
306 310
307 /* invalidate iocbs */ 311 /* invalidate iocbs */
308 cls_session = starget_to_session(scsi_target(sc->device)); 312 cls_session = starget_to_session(scsi_target(sc->device));
@@ -363,9 +367,10 @@ static int beiscsi_eh_device_reset(struct scsi_cmnd *sc)
363 return FAILED; 367 return FAILED;
364 } 368 }
365 369
366 beiscsi_mccq_compl(phba, tag, NULL, nonemb_cmd.va); 370 rc = beiscsi_mccq_compl(phba, tag, NULL, &nonemb_cmd);
367 pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size, 371 if (rc != -EBUSY)
368 nonemb_cmd.va, nonemb_cmd.dma); 372 pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
373 nonemb_cmd.va, nonemb_cmd.dma);
369 return iscsi_eh_device_reset(sc); 374 return iscsi_eh_device_reset(sc);
370} 375}
371 376
@@ -4360,12 +4365,16 @@ static int beiscsi_get_boot_info(struct beiscsi_hba *phba)
4360 goto boot_freemem; 4365 goto boot_freemem;
4361 } 4366 }
4362 4367
4363 ret = beiscsi_mccq_compl(phba, tag, NULL, nonemb_cmd.va); 4368 ret = beiscsi_mccq_compl(phba, tag, NULL, &nonemb_cmd);
4364 if (ret) { 4369 if (ret) {
4365 beiscsi_log(phba, KERN_ERR, 4370 beiscsi_log(phba, KERN_ERR,
4366 BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG, 4371 BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
4367 "BM_%d : beiscsi_get_session_info Failed"); 4372 "BM_%d : beiscsi_get_session_info Failed");
4368 goto boot_freemem; 4373
4374 if (ret != -EBUSY)
4375 goto boot_freemem;
4376 else
4377 return ret;
4369 } 4378 }
4370 4379
4371 session_resp = nonemb_cmd.va ; 4380 session_resp = nonemb_cmd.va ;
@@ -5594,6 +5603,8 @@ static int beiscsi_dev_probe(struct pci_dev *pcidev,
5594 phba->ctrl.mcc_tag[i] = i + 1; 5603 phba->ctrl.mcc_tag[i] = i + 1;
5595 phba->ctrl.mcc_numtag[i + 1] = 0; 5604 phba->ctrl.mcc_numtag[i + 1] = 0;
5596 phba->ctrl.mcc_tag_available++; 5605 phba->ctrl.mcc_tag_available++;
5606 memset(&phba->ctrl.ptag_state[i].tag_mem_state, 0,
5607 sizeof(struct beiscsi_mcc_tag_state));
5597 } 5608 }
5598 5609
5599 phba->ctrl.mcc_alloc_index = phba->ctrl.mcc_free_index = 0; 5610 phba->ctrl.mcc_alloc_index = phba->ctrl.mcc_free_index = 0;
diff --git a/drivers/scsi/be2iscsi/be_mgmt.c b/drivers/scsi/be2iscsi/be_mgmt.c
index b2fcac78feaa..088bdf752cfa 100644
--- a/drivers/scsi/be2iscsi/be_mgmt.c
+++ b/drivers/scsi/be2iscsi/be_mgmt.c
@@ -828,22 +828,25 @@ static int mgmt_exec_nonemb_cmd(struct beiscsi_hba *phba,
828 be_mcc_notify(phba); 828 be_mcc_notify(phba);
829 spin_unlock(&ctrl->mbox_lock); 829 spin_unlock(&ctrl->mbox_lock);
830 830
831 rc = beiscsi_mccq_compl(phba, tag, NULL, nonemb_cmd->va); 831 rc = beiscsi_mccq_compl(phba, tag, NULL, nonemb_cmd);
832
833 if (resp_buf)
834 memcpy(resp_buf, nonemb_cmd->va, resp_buf_len);
835
832 if (rc) { 836 if (rc) {
833 /* Check if the IOCTL needs to be re-issued */ 837 /* Check if the MBX Cmd needs to be re-issued */
834 if (rc == -EAGAIN) 838 if (rc == -EAGAIN)
835 return rc; 839 return rc;
836 840
837 beiscsi_log(phba, KERN_ERR, 841 beiscsi_log(phba, KERN_WARNING,
838 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX, 842 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
839 "BG_%d : mgmt_exec_nonemb_cmd Failed status\n"); 843 "BG_%d : mgmt_exec_nonemb_cmd Failed status\n");
840 844
841 goto free_cmd; 845 if (rc != -EBUSY)
846 goto free_cmd;
847 else
848 return rc;
842 } 849 }
843
844 if (resp_buf)
845 memcpy(resp_buf, nonemb_cmd->va, resp_buf_len);
846
847free_cmd: 850free_cmd:
848 pci_free_consistent(ctrl->pdev, nonemb_cmd->size, 851 pci_free_consistent(ctrl->pdev, nonemb_cmd->size,
849 nonemb_cmd->va, nonemb_cmd->dma); 852 nonemb_cmd->va, nonemb_cmd->dma);
@@ -1348,7 +1351,6 @@ int mgmt_set_vlan(struct beiscsi_hba *phba,
1348{ 1351{
1349 int rc; 1352 int rc;
1350 unsigned int tag; 1353 unsigned int tag;
1351 struct be_mcc_wrb *wrb = NULL;
1352 1354
1353 tag = be_cmd_set_vlan(phba, vlan_tag); 1355 tag = be_cmd_set_vlan(phba, vlan_tag);
1354 if (!tag) { 1356 if (!tag) {
@@ -1358,7 +1360,7 @@ int mgmt_set_vlan(struct beiscsi_hba *phba,
1358 return -EBUSY; 1360 return -EBUSY;
1359 } 1361 }
1360 1362
1361 rc = beiscsi_mccq_compl(phba, tag, &wrb, NULL); 1363 rc = beiscsi_mccq_compl(phba, tag, NULL, NULL);
1362 if (rc) { 1364 if (rc) {
1363 beiscsi_log(phba, KERN_ERR, 1365 beiscsi_log(phba, KERN_ERR,
1364 (BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX), 1366 (BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX),