aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_bsg.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_bsg.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_bsg.c90
1 files changed, 72 insertions, 18 deletions
diff --git a/drivers/scsi/lpfc/lpfc_bsg.c b/drivers/scsi/lpfc/lpfc_bsg.c
index 79c13c3263f1..b92aec989d60 100644
--- a/drivers/scsi/lpfc/lpfc_bsg.c
+++ b/drivers/scsi/lpfc/lpfc_bsg.c
@@ -317,6 +317,11 @@ lpfc_bsg_send_mgmt_cmd_cmp(struct lpfc_hba *phba,
317 } 317 }
318 spin_unlock_irqrestore(&phba->ct_ev_lock, flags); 318 spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
319 319
320 /* Close the timeout handler abort window */
321 spin_lock_irqsave(&phba->hbalock, flags);
322 cmdiocbq->iocb_flag &= ~LPFC_IO_CMD_OUTSTANDING;
323 spin_unlock_irqrestore(&phba->hbalock, flags);
324
320 iocb = &dd_data->context_un.iocb; 325 iocb = &dd_data->context_un.iocb;
321 ndlp = iocb->ndlp; 326 ndlp = iocb->ndlp;
322 rmp = iocb->rmp; 327 rmp = iocb->rmp;
@@ -387,6 +392,7 @@ lpfc_bsg_send_mgmt_cmd(struct fc_bsg_job *job)
387 int request_nseg; 392 int request_nseg;
388 int reply_nseg; 393 int reply_nseg;
389 struct bsg_job_data *dd_data; 394 struct bsg_job_data *dd_data;
395 unsigned long flags;
390 uint32_t creg_val; 396 uint32_t creg_val;
391 int rc = 0; 397 int rc = 0;
392 int iocb_stat; 398 int iocb_stat;
@@ -501,14 +507,24 @@ lpfc_bsg_send_mgmt_cmd(struct fc_bsg_job *job)
501 } 507 }
502 508
503 iocb_stat = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, cmdiocbq, 0); 509 iocb_stat = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, cmdiocbq, 0);
504 if (iocb_stat == IOCB_SUCCESS) 510
511 if (iocb_stat == IOCB_SUCCESS) {
512 spin_lock_irqsave(&phba->hbalock, flags);
513 /* make sure the I/O had not been completed yet */
514 if (cmdiocbq->iocb_flag & LPFC_IO_LIBDFC) {
515 /* open up abort window to timeout handler */
516 cmdiocbq->iocb_flag |= LPFC_IO_CMD_OUTSTANDING;
517 }
518 spin_unlock_irqrestore(&phba->hbalock, flags);
505 return 0; /* done for now */ 519 return 0; /* done for now */
506 else if (iocb_stat == IOCB_BUSY) 520 } else if (iocb_stat == IOCB_BUSY) {
507 rc = -EAGAIN; 521 rc = -EAGAIN;
508 else 522 } else {
509 rc = -EIO; 523 rc = -EIO;
524 }
510 525
511 /* iocb failed so cleanup */ 526 /* iocb failed so cleanup */
527 job->dd_data = NULL;
512 528
513free_rmp: 529free_rmp:
514 lpfc_free_bsg_buffers(phba, rmp); 530 lpfc_free_bsg_buffers(phba, rmp);
@@ -577,6 +593,11 @@ lpfc_bsg_rport_els_cmp(struct lpfc_hba *phba,
577 } 593 }
578 spin_unlock_irqrestore(&phba->ct_ev_lock, flags); 594 spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
579 595
596 /* Close the timeout handler abort window */
597 spin_lock_irqsave(&phba->hbalock, flags);
598 cmdiocbq->iocb_flag &= ~LPFC_IO_CMD_OUTSTANDING;
599 spin_unlock_irqrestore(&phba->hbalock, flags);
600
580 rsp = &rspiocbq->iocb; 601 rsp = &rspiocbq->iocb;
581 pcmd = (struct lpfc_dmabuf *)cmdiocbq->context2; 602 pcmd = (struct lpfc_dmabuf *)cmdiocbq->context2;
582 prsp = (struct lpfc_dmabuf *)pcmd->list.next; 603 prsp = (struct lpfc_dmabuf *)pcmd->list.next;
@@ -639,6 +660,7 @@ lpfc_bsg_rport_els(struct fc_bsg_job *job)
639 struct lpfc_iocbq *cmdiocbq; 660 struct lpfc_iocbq *cmdiocbq;
640 uint16_t rpi = 0; 661 uint16_t rpi = 0;
641 struct bsg_job_data *dd_data; 662 struct bsg_job_data *dd_data;
663 unsigned long flags;
642 uint32_t creg_val; 664 uint32_t creg_val;
643 int rc = 0; 665 int rc = 0;
644 666
@@ -721,15 +743,25 @@ lpfc_bsg_rport_els(struct fc_bsg_job *job)
721 743
722 rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, cmdiocbq, 0); 744 rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, cmdiocbq, 0);
723 745
724 if (rc == IOCB_SUCCESS) 746 if (rc == IOCB_SUCCESS) {
747 spin_lock_irqsave(&phba->hbalock, flags);
748 /* make sure the I/O had not been completed/released */
749 if (cmdiocbq->iocb_flag & LPFC_IO_LIBDFC) {
750 /* open up abort window to timeout handler */
751 cmdiocbq->iocb_flag |= LPFC_IO_CMD_OUTSTANDING;
752 }
753 spin_unlock_irqrestore(&phba->hbalock, flags);
725 return 0; /* done for now */ 754 return 0; /* done for now */
726 else if (rc == IOCB_BUSY) 755 } else if (rc == IOCB_BUSY) {
727 rc = -EAGAIN; 756 rc = -EAGAIN;
728 else 757 } else {
729 rc = -EIO; 758 rc = -EIO;
759 }
730 760
731linkdown_err: 761 /* iocb failed so cleanup */
762 job->dd_data = NULL;
732 763
764linkdown_err:
733 cmdiocbq->context1 = ndlp; 765 cmdiocbq->context1 = ndlp;
734 lpfc_els_free_iocb(phba, cmdiocbq); 766 lpfc_els_free_iocb(phba, cmdiocbq);
735 767
@@ -1249,7 +1281,7 @@ lpfc_bsg_hba_get_event(struct fc_bsg_job *job)
1249 struct lpfc_hba *phba = vport->phba; 1281 struct lpfc_hba *phba = vport->phba;
1250 struct get_ct_event *event_req; 1282 struct get_ct_event *event_req;
1251 struct get_ct_event_reply *event_reply; 1283 struct get_ct_event_reply *event_reply;
1252 struct lpfc_bsg_event *evt; 1284 struct lpfc_bsg_event *evt, *evt_next;
1253 struct event_data *evt_dat = NULL; 1285 struct event_data *evt_dat = NULL;
1254 unsigned long flags; 1286 unsigned long flags;
1255 uint32_t rc = 0; 1287 uint32_t rc = 0;
@@ -1269,7 +1301,7 @@ lpfc_bsg_hba_get_event(struct fc_bsg_job *job)
1269 event_reply = (struct get_ct_event_reply *) 1301 event_reply = (struct get_ct_event_reply *)
1270 job->reply->reply_data.vendor_reply.vendor_rsp; 1302 job->reply->reply_data.vendor_reply.vendor_rsp;
1271 spin_lock_irqsave(&phba->ct_ev_lock, flags); 1303 spin_lock_irqsave(&phba->ct_ev_lock, flags);
1272 list_for_each_entry(evt, &phba->ct_ev_waiters, node) { 1304 list_for_each_entry_safe(evt, evt_next, &phba->ct_ev_waiters, node) {
1273 if (evt->reg_id == event_req->ev_reg_id) { 1305 if (evt->reg_id == event_req->ev_reg_id) {
1274 if (list_empty(&evt->events_to_get)) 1306 if (list_empty(&evt->events_to_get))
1275 break; 1307 break;
@@ -1370,6 +1402,11 @@ lpfc_issue_ct_rsp_cmp(struct lpfc_hba *phba,
1370 } 1402 }
1371 spin_unlock_irqrestore(&phba->ct_ev_lock, flags); 1403 spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
1372 1404
1405 /* Close the timeout handler abort window */
1406 spin_lock_irqsave(&phba->hbalock, flags);
1407 cmdiocbq->iocb_flag &= ~LPFC_IO_CMD_OUTSTANDING;
1408 spin_unlock_irqrestore(&phba->hbalock, flags);
1409
1373 ndlp = dd_data->context_un.iocb.ndlp; 1410 ndlp = dd_data->context_un.iocb.ndlp;
1374 cmp = cmdiocbq->context2; 1411 cmp = cmdiocbq->context2;
1375 bmp = cmdiocbq->context3; 1412 bmp = cmdiocbq->context3;
@@ -1433,6 +1470,7 @@ lpfc_issue_ct_rsp(struct lpfc_hba *phba, struct fc_bsg_job *job, uint32_t tag,
1433 int rc = 0; 1470 int rc = 0;
1434 struct lpfc_nodelist *ndlp = NULL; 1471 struct lpfc_nodelist *ndlp = NULL;
1435 struct bsg_job_data *dd_data; 1472 struct bsg_job_data *dd_data;
1473 unsigned long flags;
1436 uint32_t creg_val; 1474 uint32_t creg_val;
1437 1475
1438 /* allocate our bsg tracking structure */ 1476 /* allocate our bsg tracking structure */
@@ -1542,8 +1580,19 @@ lpfc_issue_ct_rsp(struct lpfc_hba *phba, struct fc_bsg_job *job, uint32_t tag,
1542 1580
1543 rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, ctiocb, 0); 1581 rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, ctiocb, 0);
1544 1582
1545 if (rc == IOCB_SUCCESS) 1583 if (rc == IOCB_SUCCESS) {
1584 spin_lock_irqsave(&phba->hbalock, flags);
1585 /* make sure the I/O had not been completed/released */
1586 if (ctiocb->iocb_flag & LPFC_IO_LIBDFC) {
1587 /* open up abort window to timeout handler */
1588 ctiocb->iocb_flag |= LPFC_IO_CMD_OUTSTANDING;
1589 }
1590 spin_unlock_irqrestore(&phba->hbalock, flags);
1546 return 0; /* done for now */ 1591 return 0; /* done for now */
1592 }
1593
1594 /* iocb failed so cleanup */
1595 job->dd_data = NULL;
1547 1596
1548issue_ct_rsp_exit: 1597issue_ct_rsp_exit:
1549 lpfc_sli_release_iocbq(phba, ctiocb); 1598 lpfc_sli_release_iocbq(phba, ctiocb);
@@ -5284,9 +5333,15 @@ lpfc_bsg_timeout(struct fc_bsg_job *job)
5284 * remove it from the txq queue and call cancel iocbs. 5333 * remove it from the txq queue and call cancel iocbs.
5285 * Otherwise, call abort iotag 5334 * Otherwise, call abort iotag
5286 */ 5335 */
5287
5288 cmdiocb = dd_data->context_un.iocb.cmdiocbq; 5336 cmdiocb = dd_data->context_un.iocb.cmdiocbq;
5289 spin_lock_irq(&phba->hbalock); 5337 spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
5338
5339 spin_lock_irqsave(&phba->hbalock, flags);
5340 /* make sure the I/O abort window is still open */
5341 if (!(cmdiocb->iocb_flag & LPFC_IO_CMD_OUTSTANDING)) {
5342 spin_unlock_irqrestore(&phba->hbalock, flags);
5343 return -EAGAIN;
5344 }
5290 list_for_each_entry_safe(check_iocb, next_iocb, &pring->txq, 5345 list_for_each_entry_safe(check_iocb, next_iocb, &pring->txq,
5291 list) { 5346 list) {
5292 if (check_iocb == cmdiocb) { 5347 if (check_iocb == cmdiocb) {
@@ -5296,8 +5351,7 @@ lpfc_bsg_timeout(struct fc_bsg_job *job)
5296 } 5351 }
5297 if (list_empty(&completions)) 5352 if (list_empty(&completions))
5298 lpfc_sli_issue_abort_iotag(phba, pring, cmdiocb); 5353 lpfc_sli_issue_abort_iotag(phba, pring, cmdiocb);
5299 spin_unlock_irq(&phba->hbalock); 5354 spin_unlock_irqrestore(&phba->hbalock, flags);
5300 spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
5301 if (!list_empty(&completions)) { 5355 if (!list_empty(&completions)) {
5302 lpfc_sli_cancel_iocbs(phba, &completions, 5356 lpfc_sli_cancel_iocbs(phba, &completions,
5303 IOSTAT_LOCAL_REJECT, 5357 IOSTAT_LOCAL_REJECT,
@@ -5321,9 +5375,10 @@ lpfc_bsg_timeout(struct fc_bsg_job *job)
5321 * remove it from the txq queue and call cancel iocbs. 5375 * remove it from the txq queue and call cancel iocbs.
5322 * Otherwise, call abort iotag. 5376 * Otherwise, call abort iotag.
5323 */ 5377 */
5324
5325 cmdiocb = dd_data->context_un.menlo.cmdiocbq; 5378 cmdiocb = dd_data->context_un.menlo.cmdiocbq;
5326 spin_lock_irq(&phba->hbalock); 5379 spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
5380
5381 spin_lock_irqsave(&phba->hbalock, flags);
5327 list_for_each_entry_safe(check_iocb, next_iocb, &pring->txq, 5382 list_for_each_entry_safe(check_iocb, next_iocb, &pring->txq,
5328 list) { 5383 list) {
5329 if (check_iocb == cmdiocb) { 5384 if (check_iocb == cmdiocb) {
@@ -5333,8 +5388,7 @@ lpfc_bsg_timeout(struct fc_bsg_job *job)
5333 } 5388 }
5334 if (list_empty(&completions)) 5389 if (list_empty(&completions))
5335 lpfc_sli_issue_abort_iotag(phba, pring, cmdiocb); 5390 lpfc_sli_issue_abort_iotag(phba, pring, cmdiocb);
5336 spin_unlock_irq(&phba->hbalock); 5391 spin_unlock_irqrestore(&phba->hbalock, flags);
5337 spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
5338 if (!list_empty(&completions)) { 5392 if (!list_empty(&completions)) {
5339 lpfc_sli_cancel_iocbs(phba, &completions, 5393 lpfc_sli_cancel_iocbs(phba, &completions,
5340 IOSTAT_LOCAL_REJECT, 5394 IOSTAT_LOCAL_REJECT,