aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/be2iscsi/be_cmds.c
diff options
context:
space:
mode:
authorJitendra Bhivare <jitendra.bhivare@broadcom.com>2016-08-19 05:50:12 -0400
committerMartin K. Petersen <martin.petersen@oracle.com>2016-08-23 22:42:43 -0400
commit50a4b824be9e4a01f3b87790865e26b1546fcbb8 (patch)
treea677875c94ddad99dd6a1274bbd21a83ffc7c683 /drivers/scsi/be2iscsi/be_cmds.c
parent9122e991cebb90a7225109ed7627950f485c5f58 (diff)
scsi: be2iscsi: Fix to make boot discovery non-blocking
Boot work involves: 1. Find and fetch configured boot session and its handle. 2. Attempt to open the session if its not. 3. Get the session details for boot kset creation. 4. Logout of that session owned by FW. 5. Create boot kset for session details. All these actions were done in blocking call with retries in global wq. Other works in wq suffered if the IOCTLs stalled or timed out. This change moves all the boot work to make it non-blocking. The work queued in global wq just issues the IOCTL depending on the action to be taken and mcc wq schedules work depending on status of the IOCTL. Initial boot_work is started on link and ASYNC event. The other code changes move all boot related functions in one place and follow naming conventions. Signed-off-by: Jitendra Bhivare <jitendra.bhivare@broadcom.com> Reviewed-by: Hannes Reinecke <hare@suse.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/be2iscsi/be_cmds.c')
-rw-r--r--drivers/scsi/be2iscsi/be_cmds.c161
1 files changed, 96 insertions, 65 deletions
diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index f16de6cf2678..27d10cee0c40 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -84,6 +84,7 @@ struct be_mcc_wrb *alloc_mcc_wrb(struct beiscsi_hba *phba,
84 phba->ctrl.mcc_tag[phba->ctrl.mcc_alloc_index] = 0; 84 phba->ctrl.mcc_tag[phba->ctrl.mcc_alloc_index] = 0;
85 phba->ctrl.mcc_tag_status[tag] = 0; 85 phba->ctrl.mcc_tag_status[tag] = 0;
86 phba->ctrl.ptag_state[tag].tag_state = 0; 86 phba->ctrl.ptag_state[tag].tag_state = 0;
87 phba->ctrl.ptag_state[tag].cbfn = NULL;
87 phba->ctrl.mcc_tag_available--; 88 phba->ctrl.mcc_tag_available--;
88 if (phba->ctrl.mcc_alloc_index == (MAX_MCC_CMD - 1)) 89 if (phba->ctrl.mcc_alloc_index == (MAX_MCC_CMD - 1))
89 phba->ctrl.mcc_alloc_index = 0; 90 phba->ctrl.mcc_alloc_index = 0;
@@ -128,6 +129,70 @@ void beiscsi_fail_session(struct iscsi_cls_session *cls_session)
128} 129}
129 130
130/* 131/*
132 * beiscsi_mcc_compl_status - Return the status of MCC completion
133 * @phba: Driver private structure
134 * @tag: Tag for the MBX Command
135 * @wrb: the WRB used for the MBX Command
136 * @mbx_cmd_mem: ptr to memory allocated for MBX Cmd
137 *
138 * return
139 * Success: 0
140 * Failure: Non-Zero
141 */
142int __beiscsi_mcc_compl_status(struct beiscsi_hba *phba,
143 unsigned int tag,
144 struct be_mcc_wrb **wrb,
145 struct be_dma_mem *mbx_cmd_mem)
146{
147 struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
148 uint16_t status = 0, addl_status = 0, wrb_num = 0;
149 struct be_cmd_resp_hdr *mbx_resp_hdr;
150 struct be_cmd_req_hdr *mbx_hdr;
151 struct be_mcc_wrb *temp_wrb;
152 uint32_t mcc_tag_status;
153 int rc = 0;
154
155 mcc_tag_status = phba->ctrl.mcc_tag_status[tag];
156 status = (mcc_tag_status & CQE_STATUS_MASK);
157 addl_status = ((mcc_tag_status & CQE_STATUS_ADDL_MASK) >>
158 CQE_STATUS_ADDL_SHIFT);
159
160 if (mbx_cmd_mem) {
161 mbx_hdr = (struct be_cmd_req_hdr *)mbx_cmd_mem->va;
162 } else {
163 wrb_num = (mcc_tag_status & CQE_STATUS_WRB_MASK) >>
164 CQE_STATUS_WRB_SHIFT;
165 temp_wrb = (struct be_mcc_wrb *)queue_get_wrb(mccq, wrb_num);
166 mbx_hdr = embedded_payload(temp_wrb);
167
168 if (wrb)
169 *wrb = temp_wrb;
170 }
171
172 if (status || addl_status) {
173 beiscsi_log(phba, KERN_WARNING,
174 BEISCSI_LOG_INIT | BEISCSI_LOG_EH |
175 BEISCSI_LOG_CONFIG,
176 "BC_%d : MBX Cmd Failed for Subsys : %d Opcode : %d with Status : %d and Extd_Status : %d\n",
177 mbx_hdr->subsystem, mbx_hdr->opcode,
178 status, addl_status);
179 rc = -EIO;
180 if (status == MCC_STATUS_INSUFFICIENT_BUFFER) {
181 mbx_resp_hdr = (struct be_cmd_resp_hdr *)mbx_hdr;
182 beiscsi_log(phba, KERN_WARNING,
183 BEISCSI_LOG_INIT | BEISCSI_LOG_EH |
184 BEISCSI_LOG_CONFIG,
185 "BC_%d : Insufficient Buffer Error Resp_Len : %d Actual_Resp_Len : %d\n",
186 mbx_resp_hdr->response_length,
187 mbx_resp_hdr->actual_resp_len);
188 rc = -EAGAIN;
189 }
190 }
191
192 return rc;
193}
194
195/*
131 * beiscsi_mccq_compl_wait()- Process completion in MCC CQ 196 * beiscsi_mccq_compl_wait()- Process completion in MCC CQ
132 * @phba: Driver private structure 197 * @phba: Driver private structure
133 * @tag: Tag for the MBX Command 198 * @tag: Tag for the MBX Command
@@ -141,16 +206,11 @@ void beiscsi_fail_session(struct iscsi_cls_session *cls_session)
141 * Failure: Non-Zero 206 * Failure: Non-Zero
142 **/ 207 **/
143int beiscsi_mccq_compl_wait(struct beiscsi_hba *phba, 208int beiscsi_mccq_compl_wait(struct beiscsi_hba *phba,
144 uint32_t tag, struct be_mcc_wrb **wrb, 209 unsigned int tag,
210 struct be_mcc_wrb **wrb,
145 struct be_dma_mem *mbx_cmd_mem) 211 struct be_dma_mem *mbx_cmd_mem)
146{ 212{
147 int rc = 0; 213 int rc = 0;
148 uint32_t mcc_tag_status;
149 uint16_t status = 0, addl_status = 0, wrb_num = 0;
150 struct be_mcc_wrb *temp_wrb;
151 struct be_cmd_req_hdr *mbx_hdr;
152 struct be_cmd_resp_hdr *mbx_resp_hdr;
153 struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
154 214
155 if (beiscsi_hba_in_error(phba)) { 215 if (beiscsi_hba_in_error(phba)) {
156 clear_bit(MCC_TAG_STATE_RUNNING, 216 clear_bit(MCC_TAG_STATE_RUNNING,
@@ -159,11 +219,11 @@ int beiscsi_mccq_compl_wait(struct beiscsi_hba *phba,
159 } 219 }
160 220
161 /* wait for the mccq completion */ 221 /* wait for the mccq completion */
162 rc = wait_event_interruptible_timeout( 222 rc = wait_event_interruptible_timeout(phba->ctrl.mcc_wait[tag],
163 phba->ctrl.mcc_wait[tag], 223 phba->ctrl.mcc_tag_status[tag],
164 phba->ctrl.mcc_tag_status[tag], 224 msecs_to_jiffies(
165 msecs_to_jiffies( 225 BEISCSI_HOST_MBX_TIMEOUT));
166 BEISCSI_HOST_MBX_TIMEOUT)); 226
167 /** 227 /**
168 * If MBOX cmd timeout expired, tag and resource allocated 228 * If MBOX cmd timeout expired, tag and resource allocated
169 * for cmd is not freed until FW returns completion. 229 * for cmd is not freed until FW returns completion.
@@ -197,47 +257,7 @@ int beiscsi_mccq_compl_wait(struct beiscsi_hba *phba,
197 return -EBUSY; 257 return -EBUSY;
198 } 258 }
199 259
200 rc = 0; 260 rc = __beiscsi_mcc_compl_status(phba, tag, wrb, mbx_cmd_mem);
201 mcc_tag_status = phba->ctrl.mcc_tag_status[tag];
202 status = (mcc_tag_status & CQE_STATUS_MASK);
203 addl_status = ((mcc_tag_status & CQE_STATUS_ADDL_MASK) >>
204 CQE_STATUS_ADDL_SHIFT);
205
206 if (mbx_cmd_mem) {
207 mbx_hdr = (struct be_cmd_req_hdr *)mbx_cmd_mem->va;
208 } else {
209 wrb_num = (mcc_tag_status & CQE_STATUS_WRB_MASK) >>
210 CQE_STATUS_WRB_SHIFT;
211 temp_wrb = (struct be_mcc_wrb *)queue_get_wrb(mccq, wrb_num);
212 mbx_hdr = embedded_payload(temp_wrb);
213
214 if (wrb)
215 *wrb = temp_wrb;
216 }
217
218 if (status || addl_status) {
219 beiscsi_log(phba, KERN_WARNING,
220 BEISCSI_LOG_INIT | BEISCSI_LOG_EH |
221 BEISCSI_LOG_CONFIG,
222 "BC_%d : MBX Cmd Failed for "
223 "Subsys : %d Opcode : %d with "
224 "Status : %d and Extd_Status : %d\n",
225 mbx_hdr->subsystem,
226 mbx_hdr->opcode,
227 status, addl_status);
228 rc = -EIO;
229 if (status == MCC_STATUS_INSUFFICIENT_BUFFER) {
230 mbx_resp_hdr = (struct be_cmd_resp_hdr *) mbx_hdr;
231 beiscsi_log(phba, KERN_WARNING,
232 BEISCSI_LOG_INIT | BEISCSI_LOG_EH |
233 BEISCSI_LOG_CONFIG,
234 "BC_%d : Insufficient Buffer Error "
235 "Resp_Len : %d Actual_Resp_Len : %d\n",
236 mbx_resp_hdr->response_length,
237 mbx_resp_hdr->actual_resp_len);
238 rc = -EAGAIN;
239 }
240 }
241 261
242 free_mcc_wrb(&phba->ctrl, tag); 262 free_mcc_wrb(&phba->ctrl, tag);
243 return rc; 263 return rc;
@@ -318,11 +338,9 @@ static void beiscsi_process_async_link(struct beiscsi_hba *phba,
318 * This has been newly introduced in SKH-R Firmware 10.0.338.45. 338 * This has been newly introduced in SKH-R Firmware 10.0.338.45.
319 **/ 339 **/
320 if (evt->port_link_status & BE_ASYNC_LINK_UP_MASK) { 340 if (evt->port_link_status & BE_ASYNC_LINK_UP_MASK) {
321 phba->get_boot = BE_GET_BOOT_RETRIES; 341 set_bit(BEISCSI_HBA_LINK_UP, &phba->state);
322 /* first this needs to be visible to worker thread */ 342 if (test_bit(BEISCSI_HBA_BOOT_FOUND, &phba->state))
323 wmb(); 343 beiscsi_start_boot_work(phba, BE_BOOT_INVALID_SHANDLE);
324 set_bit(BEISCSI_HBA_LINK_UP | BEISCSI_HBA_BOOT_FOUND,
325 &phba->state);
326 __beiscsi_log(phba, KERN_ERR, 344 __beiscsi_log(phba, KERN_ERR,
327 "BC_%d : Link Up on Port %d tag 0x%x\n", 345 "BC_%d : Link Up on Port %d tag 0x%x\n",
328 evt->physical_port, evt->event_tag); 346 evt->physical_port, evt->event_tag);
@@ -412,10 +430,8 @@ void beiscsi_process_async_event(struct beiscsi_hba *phba,
412 beiscsi_process_async_link(phba, compl); 430 beiscsi_process_async_link(phba, compl);
413 break; 431 break;
414 case ASYNC_EVENT_CODE_ISCSI: 432 case ASYNC_EVENT_CODE_ISCSI:
415 phba->get_boot = BE_GET_BOOT_RETRIES; 433 if (test_bit(BEISCSI_HBA_BOOT_FOUND, &phba->state))
416 /* first this needs to be visible to worker thread */ 434 beiscsi_start_boot_work(phba, BE_BOOT_INVALID_SHANDLE);
417 wmb();
418 set_bit(BEISCSI_HBA_BOOT_FOUND, &phba->state);
419 sev = KERN_ERR; 435 sev = KERN_ERR;
420 break; 436 break;
421 case ASYNC_EVENT_CODE_SLI: 437 case ASYNC_EVENT_CODE_SLI:
@@ -451,6 +467,9 @@ int beiscsi_process_mcc_compl(struct be_ctrl_info *ctrl,
451 return 0; 467 return 0;
452 } 468 }
453 469
470 /* end MCC with this tag */
471 clear_bit(MCC_TAG_STATE_RUNNING, &ctrl->ptag_state[tag].tag_state);
472
454 if (test_bit(MCC_TAG_STATE_TIMEOUT, &ctrl->ptag_state[tag].tag_state)) { 473 if (test_bit(MCC_TAG_STATE_TIMEOUT, &ctrl->ptag_state[tag].tag_state)) {
455 beiscsi_log(phba, KERN_WARNING, 474 beiscsi_log(phba, KERN_WARNING,
456 BEISCSI_LOG_MBOX | BEISCSI_LOG_INIT | 475 BEISCSI_LOG_MBOX | BEISCSI_LOG_INIT |
@@ -461,9 +480,11 @@ int beiscsi_process_mcc_compl(struct be_ctrl_info *ctrl,
461 * Only for non-embedded cmd, PCI resource is allocated. 480 * Only for non-embedded cmd, PCI resource is allocated.
462 **/ 481 **/
463 tag_mem = &ctrl->ptag_state[tag].tag_mem_state; 482 tag_mem = &ctrl->ptag_state[tag].tag_mem_state;
464 if (tag_mem->size) 483 if (tag_mem->size) {
465 pci_free_consistent(ctrl->pdev, tag_mem->size, 484 pci_free_consistent(ctrl->pdev, tag_mem->size,
466 tag_mem->va, tag_mem->dma); 485 tag_mem->va, tag_mem->dma);
486 tag_mem->size = 0;
487 }
467 free_mcc_wrb(ctrl, tag); 488 free_mcc_wrb(ctrl, tag);
468 return 0; 489 return 0;
469 } 490 }
@@ -482,8 +503,18 @@ int beiscsi_process_mcc_compl(struct be_ctrl_info *ctrl,
482 CQE_STATUS_ADDL_MASK; 503 CQE_STATUS_ADDL_MASK;
483 ctrl->mcc_tag_status[tag] |= (compl_status & CQE_STATUS_MASK); 504 ctrl->mcc_tag_status[tag] |= (compl_status & CQE_STATUS_MASK);
484 505
485 /* write ordering forced in wake_up_interruptible */ 506 if (test_bit(MCC_TAG_STATE_ASYNC, &ctrl->ptag_state[tag].tag_state)) {
486 clear_bit(MCC_TAG_STATE_RUNNING, &ctrl->ptag_state[tag].tag_state); 507 if (ctrl->ptag_state[tag].cbfn)
508 ctrl->ptag_state[tag].cbfn(phba, tag);
509 else
510 beiscsi_log(phba, KERN_ERR,
511 BEISCSI_LOG_MBOX | BEISCSI_LOG_INIT |
512 BEISCSI_LOG_CONFIG,
513 "BC_%d : MBX ASYNC command with no callback\n");
514 free_mcc_wrb(ctrl, tag);
515 return 0;
516 }
517
487 wake_up_interruptible(&ctrl->mcc_wait[tag]); 518 wake_up_interruptible(&ctrl->mcc_wait[tag]);
488 return 0; 519 return 0;
489} 520}