aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_scsi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_scsi.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.c77
1 files changed, 56 insertions, 21 deletions
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index af5498d735e..d482dfc951f 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -609,6 +609,32 @@ lpfc_new_scsi_buf_s3(struct lpfc_vport *vport, int num_to_alloc)
609} 609}
610 610
611/** 611/**
612 * lpfc_sli4_vport_delete_fcp_xri_aborted -Remove all ndlp references for vport
613 * @vport: pointer to lpfc vport data structure.
614 *
615 * This routine is invoked by the vport cleanup for deletions and the cleanup
616 * for an ndlp on removal.
617 **/
618void
619lpfc_sli4_vport_delete_fcp_xri_aborted(struct lpfc_vport *vport)
620{
621 struct lpfc_hba *phba = vport->phba;
622 struct lpfc_scsi_buf *psb, *next_psb;
623 unsigned long iflag = 0;
624
625 spin_lock_irqsave(&phba->hbalock, iflag);
626 spin_lock(&phba->sli4_hba.abts_scsi_buf_list_lock);
627 list_for_each_entry_safe(psb, next_psb,
628 &phba->sli4_hba.lpfc_abts_scsi_buf_list, list) {
629 if (psb->rdata && psb->rdata->pnode
630 && psb->rdata->pnode->vport == vport)
631 psb->rdata = NULL;
632 }
633 spin_unlock(&phba->sli4_hba.abts_scsi_buf_list_lock);
634 spin_unlock_irqrestore(&phba->hbalock, iflag);
635}
636
637/**
612 * lpfc_sli4_fcp_xri_aborted - Fast-path process of fcp xri abort 638 * lpfc_sli4_fcp_xri_aborted - Fast-path process of fcp xri abort
613 * @phba: pointer to lpfc hba data structure. 639 * @phba: pointer to lpfc hba data structure.
614 * @axri: pointer to the fcp xri abort wcqe structure. 640 * @axri: pointer to the fcp xri abort wcqe structure.
@@ -640,7 +666,11 @@ lpfc_sli4_fcp_xri_aborted(struct lpfc_hba *phba,
640 psb->status = IOSTAT_SUCCESS; 666 psb->status = IOSTAT_SUCCESS;
641 spin_unlock( 667 spin_unlock(
642 &phba->sli4_hba.abts_scsi_buf_list_lock); 668 &phba->sli4_hba.abts_scsi_buf_list_lock);
643 ndlp = psb->rdata->pnode; 669 if (psb->rdata && psb->rdata->pnode)
670 ndlp = psb->rdata->pnode;
671 else
672 ndlp = NULL;
673
644 rrq_empty = list_empty(&phba->active_rrq_list); 674 rrq_empty = list_empty(&phba->active_rrq_list);
645 spin_unlock_irqrestore(&phba->hbalock, iflag); 675 spin_unlock_irqrestore(&phba->hbalock, iflag);
646 if (ndlp) 676 if (ndlp)
@@ -964,36 +994,29 @@ lpfc_get_scsi_buf_s3(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
964static struct lpfc_scsi_buf* 994static struct lpfc_scsi_buf*
965lpfc_get_scsi_buf_s4(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) 995lpfc_get_scsi_buf_s4(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
966{ 996{
967 struct lpfc_scsi_buf *lpfc_cmd = NULL; 997 struct lpfc_scsi_buf *lpfc_cmd ;
968 struct lpfc_scsi_buf *start_lpfc_cmd = NULL;
969 struct list_head *scsi_buf_list = &phba->lpfc_scsi_buf_list;
970 unsigned long iflag = 0; 998 unsigned long iflag = 0;
971 int found = 0; 999 int found = 0;
972 1000
973 spin_lock_irqsave(&phba->scsi_buf_list_lock, iflag); 1001 spin_lock_irqsave(&phba->scsi_buf_list_lock, iflag);
974 list_remove_head(scsi_buf_list, lpfc_cmd, struct lpfc_scsi_buf, list); 1002 list_for_each_entry(lpfc_cmd, &phba->lpfc_scsi_buf_list,
975 spin_unlock_irqrestore(&phba->scsi_buf_list_lock, iflag); 1003 list) {
976 while (!found && lpfc_cmd) {
977 if (lpfc_test_rrq_active(phba, ndlp, 1004 if (lpfc_test_rrq_active(phba, ndlp,
978 lpfc_cmd->cur_iocbq.sli4_xritag)) { 1005 lpfc_cmd->cur_iocbq.sli4_xritag))
979 lpfc_release_scsi_buf_s4(phba, lpfc_cmd); 1006 continue;
980 spin_lock_irqsave(&phba->scsi_buf_list_lock, iflag); 1007 list_del(&lpfc_cmd->list);
981 list_remove_head(scsi_buf_list, lpfc_cmd,
982 struct lpfc_scsi_buf, list);
983 spin_unlock_irqrestore(&phba->scsi_buf_list_lock,
984 iflag);
985 if (lpfc_cmd == start_lpfc_cmd) {
986 lpfc_cmd = NULL;
987 break;
988 } else
989 continue;
990 }
991 found = 1; 1008 found = 1;
992 lpfc_cmd->seg_cnt = 0; 1009 lpfc_cmd->seg_cnt = 0;
993 lpfc_cmd->nonsg_phys = 0; 1010 lpfc_cmd->nonsg_phys = 0;
994 lpfc_cmd->prot_seg_cnt = 0; 1011 lpfc_cmd->prot_seg_cnt = 0;
1012 break;
995 } 1013 }
996 return lpfc_cmd; 1014 spin_unlock_irqrestore(&phba->scsi_buf_list_lock,
1015 iflag);
1016 if (!found)
1017 return NULL;
1018 else
1019 return lpfc_cmd;
997} 1020}
998/** 1021/**
999 * lpfc_get_scsi_buf - Get a scsi buffer from lpfc_scsi_buf_list of the HBA 1022 * lpfc_get_scsi_buf - Get a scsi buffer from lpfc_scsi_buf_list of the HBA
@@ -2484,6 +2507,7 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
2484 lpfc_worker_wake_up(phba); 2507 lpfc_worker_wake_up(phba);
2485 break; 2508 break;
2486 case IOSTAT_LOCAL_REJECT: 2509 case IOSTAT_LOCAL_REJECT:
2510 case IOSTAT_REMOTE_STOP:
2487 if (lpfc_cmd->result == IOERR_INVALID_RPI || 2511 if (lpfc_cmd->result == IOERR_INVALID_RPI ||
2488 lpfc_cmd->result == IOERR_NO_RESOURCES || 2512 lpfc_cmd->result == IOERR_NO_RESOURCES ||
2489 lpfc_cmd->result == IOERR_ABORT_REQUESTED || 2513 lpfc_cmd->result == IOERR_ABORT_REQUESTED ||
@@ -2510,6 +2534,17 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
2510 "on unprotected cmd\n"); 2534 "on unprotected cmd\n");
2511 } 2535 }
2512 } 2536 }
2537 if ((lpfc_cmd->status == IOSTAT_REMOTE_STOP)
2538 && (phba->sli_rev == LPFC_SLI_REV4)
2539 && (pnode && NLP_CHK_NODE_ACT(pnode))) {
2540 /* This IO was aborted by the target, we don't
2541 * know the rxid and because we did not send the
2542 * ABTS we cannot generate and RRQ.
2543 */
2544 lpfc_set_rrq_active(phba, pnode,
2545 lpfc_cmd->cur_iocbq.sli4_xritag,
2546 0, 0);
2547 }
2513 2548
2514 /* else: fall through */ 2549 /* else: fall through */
2515 default: 2550 default: