aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Smart <james.smart@emulex.com>2011-02-16 12:39:35 -0500
committerJames Bottomley <James.Bottomley@suse.de>2011-02-18 13:45:21 -0500
commit1151e3ec15c32021a8a12a123459ab5e41692898 (patch)
tree57cf6cf10dbd7e77654958987ca0f840311fcf2d
parentfedd3b7b93302c7789bd3eeb190653cfb0fe7645 (diff)
[SCSI] lpfc 8.3.21: RRQ Implementation fixes
RRQ Implementation fixes - Added checks to prevent a call to findnode_did in clr_active_rrq - Added the del_sync_timer call for the rrq_tmr to the stop_hba_timers routine. - Added a check in __lpfc_set_active_rrq for the driver unloading to prevent adding an rrq when the driver is being removed. - Add code to scsi_iocb_cmpl to check for the remote stop and add the rrq. - Added the same check to els retry. - Added code to compare the source did in the els rrq to the vports did and chose the right exchange ID. - Initialize the start_cmd pointer to indicate when we have looped through all of the scsi buffers. - Remove the need for the lock around the clearing of the active bit in the rrq. - Added code to clean the els and fcp xri aborted list and remove the all of the RRQs for a deleted vport. Signed-off-by: Alex Iannicelli <alex.iannicelli@emulex.com> Signed-off-by: James Smart <james.smart@emulex.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
-rw-r--r--drivers/scsi/lpfc/lpfc_crtn.h2
-rw-r--r--drivers/scsi/lpfc/lpfc_els.c52
-rw-r--r--drivers/scsi/lpfc/lpfc_hbadisc.c6
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c13
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.c77
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c191
-rw-r--r--drivers/scsi/lpfc/lpfc_sli4.h2
7 files changed, 205 insertions, 138 deletions
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h
index 5b4513792a8..34fbc1820c4 100644
--- a/drivers/scsi/lpfc/lpfc_crtn.h
+++ b/drivers/scsi/lpfc/lpfc_crtn.h
@@ -423,6 +423,6 @@ int lpfc_send_rrq(struct lpfc_hba *, struct lpfc_node_rrq *);
423int lpfc_set_rrq_active(struct lpfc_hba *, struct lpfc_nodelist *, 423int lpfc_set_rrq_active(struct lpfc_hba *, struct lpfc_nodelist *,
424 uint16_t, uint16_t, uint16_t); 424 uint16_t, uint16_t, uint16_t);
425void lpfc_cleanup_wt_rrqs(struct lpfc_hba *); 425void lpfc_cleanup_wt_rrqs(struct lpfc_hba *);
426void lpfc_cleanup_vports_rrqs(struct lpfc_vport *); 426void lpfc_cleanup_vports_rrqs(struct lpfc_vport *, struct lpfc_nodelist *);
427struct lpfc_node_rrq *lpfc_get_active_rrq(struct lpfc_vport *, uint16_t, 427struct lpfc_node_rrq *lpfc_get_active_rrq(struct lpfc_vport *, uint16_t,
428 uint32_t); 428 uint32_t);
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index 58e1a55d97f..c6d01f63f55 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -2816,9 +2816,17 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
2816 2816
2817 switch (irsp->ulpStatus) { 2817 switch (irsp->ulpStatus) {
2818 case IOSTAT_FCP_RSP_ERROR: 2818 case IOSTAT_FCP_RSP_ERROR:
2819 break;
2819 case IOSTAT_REMOTE_STOP: 2820 case IOSTAT_REMOTE_STOP:
2821 if (phba->sli_rev == LPFC_SLI_REV4) {
2822 /* This IO was aborted by the target, we don't
2823 * know the rxid and because we did not send the
2824 * ABTS we cannot generate and RRQ.
2825 */
2826 lpfc_set_rrq_active(phba, ndlp,
2827 cmdiocb->sli4_xritag, 0, 0);
2828 }
2820 break; 2829 break;
2821
2822 case IOSTAT_LOCAL_REJECT: 2830 case IOSTAT_LOCAL_REJECT:
2823 switch ((irsp->un.ulpWord[4] & 0xff)) { 2831 switch ((irsp->un.ulpWord[4] & 0xff)) {
2824 case IOERR_LOOP_OPEN_FAILURE: 2832 case IOERR_LOOP_OPEN_FAILURE:
@@ -4014,28 +4022,34 @@ lpfc_els_clear_rrq(struct lpfc_vport *vport,
4014 uint8_t *pcmd; 4022 uint8_t *pcmd;
4015 struct RRQ *rrq; 4023 struct RRQ *rrq;
4016 uint16_t rxid; 4024 uint16_t rxid;
4025 uint16_t xri;
4017 struct lpfc_node_rrq *prrq; 4026 struct lpfc_node_rrq *prrq;
4018 4027
4019 4028
4020 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) iocb->context2)->virt); 4029 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) iocb->context2)->virt);
4021 pcmd += sizeof(uint32_t); 4030 pcmd += sizeof(uint32_t);
4022 rrq = (struct RRQ *)pcmd; 4031 rrq = (struct RRQ *)pcmd;
4023 rxid = bf_get(rrq_oxid, rrq); 4032 rrq->rrq_exchg = be32_to_cpu(rrq->rrq_exchg);
4033 rxid = be16_to_cpu(bf_get(rrq_rxid, rrq));
4024 4034
4025 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, 4035 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
4026 "2883 Clear RRQ for SID:x%x OXID:x%x RXID:x%x" 4036 "2883 Clear RRQ for SID:x%x OXID:x%x RXID:x%x"
4027 " x%x x%x\n", 4037 " x%x x%x\n",
4028 bf_get(rrq_did, rrq), 4038 be32_to_cpu(bf_get(rrq_did, rrq)),
4029 bf_get(rrq_oxid, rrq), 4039 be16_to_cpu(bf_get(rrq_oxid, rrq)),
4030 rxid, 4040 rxid,
4031 iocb->iotag, iocb->iocb.ulpContext); 4041 iocb->iotag, iocb->iocb.ulpContext);
4032 4042
4033 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP, 4043 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP,
4034 "Clear RRQ: did:x%x flg:x%x exchg:x%.08x", 4044 "Clear RRQ: did:x%x flg:x%x exchg:x%.08x",
4035 ndlp->nlp_DID, ndlp->nlp_flag, rrq->rrq_exchg); 4045 ndlp->nlp_DID, ndlp->nlp_flag, rrq->rrq_exchg);
4036 prrq = lpfc_get_active_rrq(vport, rxid, ndlp->nlp_DID); 4046 if (vport->fc_myDID == be32_to_cpu(bf_get(rrq_did, rrq)))
4047 xri = be16_to_cpu(bf_get(rrq_oxid, rrq));
4048 else
4049 xri = rxid;
4050 prrq = lpfc_get_active_rrq(vport, xri, ndlp->nlp_DID);
4037 if (prrq) 4051 if (prrq)
4038 lpfc_clr_rrq_active(phba, rxid, prrq); 4052 lpfc_clr_rrq_active(phba, xri, prrq);
4039 return; 4053 return;
4040} 4054}
4041 4055
@@ -7583,6 +7597,32 @@ void lpfc_fabric_abort_hba(struct lpfc_hba *phba)
7583} 7597}
7584 7598
7585/** 7599/**
7600 * lpfc_sli4_vport_delete_els_xri_aborted -Remove all ndlp references for vport
7601 * @vport: pointer to lpfc vport data structure.
7602 *
7603 * This routine is invoked by the vport cleanup for deletions and the cleanup
7604 * for an ndlp on removal.
7605 **/
7606void
7607lpfc_sli4_vport_delete_els_xri_aborted(struct lpfc_vport *vport)
7608{
7609 struct lpfc_hba *phba = vport->phba;
7610 struct lpfc_sglq *sglq_entry = NULL, *sglq_next = NULL;
7611 unsigned long iflag = 0;
7612
7613 spin_lock_irqsave(&phba->hbalock, iflag);
7614 spin_lock(&phba->sli4_hba.abts_sgl_list_lock);
7615 list_for_each_entry_safe(sglq_entry, sglq_next,
7616 &phba->sli4_hba.lpfc_abts_els_sgl_list, list) {
7617 if (sglq_entry->ndlp && sglq_entry->ndlp->vport == vport)
7618 sglq_entry->ndlp = NULL;
7619 }
7620 spin_unlock(&phba->sli4_hba.abts_sgl_list_lock);
7621 spin_unlock_irqrestore(&phba->hbalock, iflag);
7622 return;
7623}
7624
7625/**
7586 * lpfc_sli4_els_xri_aborted - Slow-path process of els xri abort 7626 * lpfc_sli4_els_xri_aborted - Slow-path process of els xri abort
7587 * @phba: pointer to lpfc hba data structure. 7627 * @phba: pointer to lpfc hba data structure.
7588 * @axri: pointer to the els xri abort wcqe structure. 7628 * @axri: pointer to the els xri abort wcqe structure.
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index 1f9c7f19c31..63300be2e45 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -3160,7 +3160,7 @@ lpfc_mbx_cmpl_unreg_vpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
3160 spin_unlock_irq(shost->host_lock); 3160 spin_unlock_irq(shost->host_lock);
3161 vport->unreg_vpi_cmpl = VPORT_OK; 3161 vport->unreg_vpi_cmpl = VPORT_OK;
3162 mempool_free(pmb, phba->mbox_mem_pool); 3162 mempool_free(pmb, phba->mbox_mem_pool);
3163 lpfc_cleanup_vports_rrqs(vport); 3163 lpfc_cleanup_vports_rrqs(vport, NULL);
3164 /* 3164 /*
3165 * This shost reference might have been taken at the beginning of 3165 * This shost reference might have been taken at the beginning of
3166 * lpfc_vport_delete() 3166 * lpfc_vport_delete()
@@ -3900,6 +3900,8 @@ lpfc_drop_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
3900 if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) 3900 if (ndlp->nlp_state == NLP_STE_UNUSED_NODE)
3901 return; 3901 return;
3902 lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNUSED_NODE); 3902 lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNUSED_NODE);
3903 if (vport->phba->sli_rev == LPFC_SLI_REV4)
3904 lpfc_cleanup_vports_rrqs(vport, ndlp);
3903 lpfc_nlp_put(ndlp); 3905 lpfc_nlp_put(ndlp);
3904 return; 3906 return;
3905} 3907}
@@ -4289,7 +4291,7 @@ lpfc_cleanup_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
4289 4291
4290 list_del_init(&ndlp->els_retry_evt.evt_listp); 4292 list_del_init(&ndlp->els_retry_evt.evt_listp);
4291 list_del_init(&ndlp->dev_loss_evt.evt_listp); 4293 list_del_init(&ndlp->dev_loss_evt.evt_listp);
4292 4294 lpfc_cleanup_vports_rrqs(vport, ndlp);
4293 lpfc_unreg_rpi(vport, ndlp); 4295 lpfc_unreg_rpi(vport, ndlp);
4294 4296
4295 return 0; 4297 return 0;
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 0b5f76caa6e..32cd138f654 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -945,17 +945,13 @@ static void
945lpfc_rrq_timeout(unsigned long ptr) 945lpfc_rrq_timeout(unsigned long ptr)
946{ 946{
947 struct lpfc_hba *phba; 947 struct lpfc_hba *phba;
948 uint32_t tmo_posted;
949 unsigned long iflag; 948 unsigned long iflag;
950 949
951 phba = (struct lpfc_hba *)ptr; 950 phba = (struct lpfc_hba *)ptr;
952 spin_lock_irqsave(&phba->pport->work_port_lock, iflag); 951 spin_lock_irqsave(&phba->pport->work_port_lock, iflag);
953 tmo_posted = phba->hba_flag & HBA_RRQ_ACTIVE; 952 phba->hba_flag |= HBA_RRQ_ACTIVE;
954 if (!tmo_posted)
955 phba->hba_flag |= HBA_RRQ_ACTIVE;
956 spin_unlock_irqrestore(&phba->pport->work_port_lock, iflag); 953 spin_unlock_irqrestore(&phba->pport->work_port_lock, iflag);
957 if (!tmo_posted) 954 lpfc_worker_wake_up(phba);
958 lpfc_worker_wake_up(phba);
959} 955}
960 956
961/** 957/**
@@ -2280,6 +2276,7 @@ lpfc_cleanup(struct lpfc_vport *vport)
2280 /* Wait for any activity on ndlps to settle */ 2276 /* Wait for any activity on ndlps to settle */
2281 msleep(10); 2277 msleep(10);
2282 } 2278 }
2279 lpfc_cleanup_vports_rrqs(vport, NULL);
2283} 2280}
2284 2281
2285/** 2282/**
@@ -2355,6 +2352,10 @@ lpfc_stop_hba_timers(struct lpfc_hba *phba)
2355 del_timer_sync(&phba->fabric_block_timer); 2352 del_timer_sync(&phba->fabric_block_timer);
2356 del_timer_sync(&phba->eratt_poll); 2353 del_timer_sync(&phba->eratt_poll);
2357 del_timer_sync(&phba->hb_tmofunc); 2354 del_timer_sync(&phba->hb_tmofunc);
2355 if (phba->sli_rev == LPFC_SLI_REV4) {
2356 del_timer_sync(&phba->rrq_tmr);
2357 phba->hba_flag &= ~HBA_RRQ_ACTIVE;
2358 }
2358 phba->hb_outstanding = 0; 2359 phba->hb_outstanding = 0;
2359 2360
2360 switch (phba->pci_dev_grp) { 2361 switch (phba->pci_dev_grp) {
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:
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index ed8f048dfb5..b85c40e3bf5 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -535,15 +535,35 @@ __lpfc_set_rrq_active(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp,
535 uint16_t adj_xri; 535 uint16_t adj_xri;
536 struct lpfc_node_rrq *rrq; 536 struct lpfc_node_rrq *rrq;
537 int empty; 537 int empty;
538 uint32_t did = 0;
539
540
541 if (!ndlp)
542 return -EINVAL;
543
544 if (!phba->cfg_enable_rrq)
545 return -EINVAL;
546
547 if (phba->pport->load_flag & FC_UNLOADING) {
548 phba->hba_flag &= ~HBA_RRQ_ACTIVE;
549 goto out;
550 }
551 did = ndlp->nlp_DID;
538 552
539 /* 553 /*
540 * set the active bit even if there is no mem available. 554 * set the active bit even if there is no mem available.
541 */ 555 */
542 adj_xri = xritag - phba->sli4_hba.max_cfg_param.xri_base; 556 adj_xri = xritag - phba->sli4_hba.max_cfg_param.xri_base;
543 if (!ndlp) 557
544 return -EINVAL; 558 if (NLP_CHK_FREE_REQ(ndlp))
559 goto out;
560
561 if (ndlp->vport && (ndlp->vport->load_flag & FC_UNLOADING))
562 goto out;
563
545 if (test_and_set_bit(adj_xri, ndlp->active_rrqs.xri_bitmap)) 564 if (test_and_set_bit(adj_xri, ndlp->active_rrqs.xri_bitmap))
546 return -EINVAL; 565 goto out;
566
547 rrq = mempool_alloc(phba->rrq_pool, GFP_KERNEL); 567 rrq = mempool_alloc(phba->rrq_pool, GFP_KERNEL);
548 if (rrq) { 568 if (rrq) {
549 rrq->send_rrq = send_rrq; 569 rrq->send_rrq = send_rrq;
@@ -554,14 +574,7 @@ __lpfc_set_rrq_active(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp,
554 rrq->vport = ndlp->vport; 574 rrq->vport = ndlp->vport;
555 rrq->rxid = rxid; 575 rrq->rxid = rxid;
556 empty = list_empty(&phba->active_rrq_list); 576 empty = list_empty(&phba->active_rrq_list);
557 if (phba->cfg_enable_rrq && send_rrq) 577 rrq->send_rrq = send_rrq;
558 /*
559 * We need the xri before we can add this to the
560 * phba active rrq list.
561 */
562 rrq->send_rrq = send_rrq;
563 else
564 rrq->send_rrq = 0;
565 list_add_tail(&rrq->list, &phba->active_rrq_list); 578 list_add_tail(&rrq->list, &phba->active_rrq_list);
566 if (!(phba->hba_flag & HBA_RRQ_ACTIVE)) { 579 if (!(phba->hba_flag & HBA_RRQ_ACTIVE)) {
567 phba->hba_flag |= HBA_RRQ_ACTIVE; 580 phba->hba_flag |= HBA_RRQ_ACTIVE;
@@ -570,40 +583,49 @@ __lpfc_set_rrq_active(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp,
570 } 583 }
571 return 0; 584 return 0;
572 } 585 }
573 return -ENOMEM; 586out:
587 lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
588 "2921 Can't set rrq active xri:0x%x rxid:0x%x"
589 " DID:0x%x Send:%d\n",
590 xritag, rxid, did, send_rrq);
591 return -EINVAL;
574} 592}
575 593
576/** 594/**
577 * __lpfc_clr_rrq_active - Clears RRQ active bit in xri_bitmap. 595 * lpfc_clr_rrq_active - Clears RRQ active bit in xri_bitmap.
578 * @phba: Pointer to HBA context object. 596 * @phba: Pointer to HBA context object.
579 * @xritag: xri used in this exchange. 597 * @xritag: xri used in this exchange.
580 * @rrq: The RRQ to be cleared. 598 * @rrq: The RRQ to be cleared.
581 * 599 *
582 * This function is called with hbalock held. This function
583 **/ 600 **/
584static void 601void
585__lpfc_clr_rrq_active(struct lpfc_hba *phba, 602lpfc_clr_rrq_active(struct lpfc_hba *phba,
586 uint16_t xritag, 603 uint16_t xritag,
587 struct lpfc_node_rrq *rrq) 604 struct lpfc_node_rrq *rrq)
588{ 605{
589 uint16_t adj_xri; 606 uint16_t adj_xri;
590 struct lpfc_nodelist *ndlp; 607 struct lpfc_nodelist *ndlp = NULL;
591 608
592 ndlp = lpfc_findnode_did(rrq->vport, rrq->nlp_DID); 609 if ((rrq->vport) && NLP_CHK_NODE_ACT(rrq->ndlp))
610 ndlp = lpfc_findnode_did(rrq->vport, rrq->nlp_DID);
593 611
594 /* The target DID could have been swapped (cable swap) 612 /* The target DID could have been swapped (cable swap)
595 * we should use the ndlp from the findnode if it is 613 * we should use the ndlp from the findnode if it is
596 * available. 614 * available.
597 */ 615 */
598 if (!ndlp) 616 if ((!ndlp) && rrq->ndlp)
599 ndlp = rrq->ndlp; 617 ndlp = rrq->ndlp;
600 618
619 if (!ndlp)
620 goto out;
621
601 adj_xri = xritag - phba->sli4_hba.max_cfg_param.xri_base; 622 adj_xri = xritag - phba->sli4_hba.max_cfg_param.xri_base;
602 if (test_and_clear_bit(adj_xri, ndlp->active_rrqs.xri_bitmap)) { 623 if (test_and_clear_bit(adj_xri, ndlp->active_rrqs.xri_bitmap)) {
603 rrq->send_rrq = 0; 624 rrq->send_rrq = 0;
604 rrq->xritag = 0; 625 rrq->xritag = 0;
605 rrq->rrq_stop_time = 0; 626 rrq->rrq_stop_time = 0;
606 } 627 }
628out:
607 mempool_free(rrq, phba->rrq_pool); 629 mempool_free(rrq, phba->rrq_pool);
608} 630}
609 631
@@ -628,34 +650,34 @@ lpfc_handle_rrq_active(struct lpfc_hba *phba)
628 struct lpfc_node_rrq *nextrrq; 650 struct lpfc_node_rrq *nextrrq;
629 unsigned long next_time; 651 unsigned long next_time;
630 unsigned long iflags; 652 unsigned long iflags;
653 LIST_HEAD(send_rrq);
631 654
632 spin_lock_irqsave(&phba->hbalock, iflags); 655 spin_lock_irqsave(&phba->hbalock, iflags);
633 phba->hba_flag &= ~HBA_RRQ_ACTIVE; 656 phba->hba_flag &= ~HBA_RRQ_ACTIVE;
634 next_time = jiffies + HZ * (phba->fc_ratov + 1); 657 next_time = jiffies + HZ * (phba->fc_ratov + 1);
635 list_for_each_entry_safe(rrq, nextrrq, 658 list_for_each_entry_safe(rrq, nextrrq,
636 &phba->active_rrq_list, list) { 659 &phba->active_rrq_list, list) {
637 if (time_after(jiffies, rrq->rrq_stop_time)) { 660 if (time_after(jiffies, rrq->rrq_stop_time))
638 list_del(&rrq->list); 661 list_move(&rrq->list, &send_rrq);
639 if (!rrq->send_rrq) 662 else if (time_before(rrq->rrq_stop_time, next_time))
640 /* this call will free the rrq */
641 __lpfc_clr_rrq_active(phba, rrq->xritag, rrq);
642 else {
643 /* if we send the rrq then the completion handler
644 * will clear the bit in the xribitmap.
645 */
646 spin_unlock_irqrestore(&phba->hbalock, iflags);
647 if (lpfc_send_rrq(phba, rrq)) {
648 lpfc_clr_rrq_active(phba, rrq->xritag,
649 rrq);
650 }
651 spin_lock_irqsave(&phba->hbalock, iflags);
652 }
653 } else if (time_before(rrq->rrq_stop_time, next_time))
654 next_time = rrq->rrq_stop_time; 663 next_time = rrq->rrq_stop_time;
655 } 664 }
656 spin_unlock_irqrestore(&phba->hbalock, iflags); 665 spin_unlock_irqrestore(&phba->hbalock, iflags);
657 if (!list_empty(&phba->active_rrq_list)) 666 if (!list_empty(&phba->active_rrq_list))
658 mod_timer(&phba->rrq_tmr, next_time); 667 mod_timer(&phba->rrq_tmr, next_time);
668 list_for_each_entry_safe(rrq, nextrrq, &send_rrq, list) {
669 list_del(&rrq->list);
670 if (!rrq->send_rrq)
671 /* this call will free the rrq */
672 lpfc_clr_rrq_active(phba, rrq->xritag, rrq);
673 else if (lpfc_send_rrq(phba, rrq)) {
674 /* if we send the rrq then the completion handler
675 * will clear the bit in the xribitmap.
676 */
677 lpfc_clr_rrq_active(phba, rrq->xritag,
678 rrq);
679 }
680 }
659} 681}
660 682
661/** 683/**
@@ -693,29 +715,37 @@ lpfc_get_active_rrq(struct lpfc_vport *vport, uint16_t xri, uint32_t did)
693/** 715/**
694 * lpfc_cleanup_vports_rrqs - Remove and clear the active RRQ for this vport. 716 * lpfc_cleanup_vports_rrqs - Remove and clear the active RRQ for this vport.
695 * @vport: Pointer to vport context object. 717 * @vport: Pointer to vport context object.
696 * 718 * @ndlp: Pointer to the lpfc_node_list structure.
697 * Remove all active RRQs for this vport from the phba->active_rrq_list and 719 * If ndlp is NULL Remove all active RRQs for this vport from the
698 * clear the rrq. 720 * phba->active_rrq_list and clear the rrq.
721 * If ndlp is not NULL then only remove rrqs for this vport & this ndlp.
699 **/ 722 **/
700void 723void
701lpfc_cleanup_vports_rrqs(struct lpfc_vport *vport) 724lpfc_cleanup_vports_rrqs(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
702 725
703{ 726{
704 struct lpfc_hba *phba = vport->phba; 727 struct lpfc_hba *phba = vport->phba;
705 struct lpfc_node_rrq *rrq; 728 struct lpfc_node_rrq *rrq;
706 struct lpfc_node_rrq *nextrrq; 729 struct lpfc_node_rrq *nextrrq;
707 unsigned long iflags; 730 unsigned long iflags;
731 LIST_HEAD(rrq_list);
708 732
709 if (phba->sli_rev != LPFC_SLI_REV4) 733 if (phba->sli_rev != LPFC_SLI_REV4)
710 return; 734 return;
711 spin_lock_irqsave(&phba->hbalock, iflags); 735 if (!ndlp) {
712 list_for_each_entry_safe(rrq, nextrrq, &phba->active_rrq_list, list) { 736 lpfc_sli4_vport_delete_els_xri_aborted(vport);
713 if (rrq->vport == vport) { 737 lpfc_sli4_vport_delete_fcp_xri_aborted(vport);
714 list_del(&rrq->list);
715 __lpfc_clr_rrq_active(phba, rrq->xritag, rrq);
716 }
717 } 738 }
739 spin_lock_irqsave(&phba->hbalock, iflags);
740 list_for_each_entry_safe(rrq, nextrrq, &phba->active_rrq_list, list)
741 if ((rrq->vport == vport) && (!ndlp || rrq->ndlp == ndlp))
742 list_move(&rrq->list, &rrq_list);
718 spin_unlock_irqrestore(&phba->hbalock, iflags); 743 spin_unlock_irqrestore(&phba->hbalock, iflags);
744
745 list_for_each_entry_safe(rrq, nextrrq, &rrq_list, list) {
746 list_del(&rrq->list);
747 lpfc_clr_rrq_active(phba, rrq->xritag, rrq);
748 }
719} 749}
720 750
721/** 751/**
@@ -733,24 +763,27 @@ lpfc_cleanup_wt_rrqs(struct lpfc_hba *phba)
733 struct lpfc_node_rrq *nextrrq; 763 struct lpfc_node_rrq *nextrrq;
734 unsigned long next_time; 764 unsigned long next_time;
735 unsigned long iflags; 765 unsigned long iflags;
766 LIST_HEAD(rrq_list);
736 767
737 if (phba->sli_rev != LPFC_SLI_REV4) 768 if (phba->sli_rev != LPFC_SLI_REV4)
738 return; 769 return;
739 spin_lock_irqsave(&phba->hbalock, iflags); 770 spin_lock_irqsave(&phba->hbalock, iflags);
740 phba->hba_flag &= ~HBA_RRQ_ACTIVE; 771 phba->hba_flag &= ~HBA_RRQ_ACTIVE;
741 next_time = jiffies + HZ * (phba->fc_ratov * 2); 772 next_time = jiffies + HZ * (phba->fc_ratov * 2);
742 list_for_each_entry_safe(rrq, nextrrq, &phba->active_rrq_list, list) { 773 list_splice_init(&phba->active_rrq_list, &rrq_list);
774 spin_unlock_irqrestore(&phba->hbalock, iflags);
775
776 list_for_each_entry_safe(rrq, nextrrq, &rrq_list, list) {
743 list_del(&rrq->list); 777 list_del(&rrq->list);
744 __lpfc_clr_rrq_active(phba, rrq->xritag, rrq); 778 lpfc_clr_rrq_active(phba, rrq->xritag, rrq);
745 } 779 }
746 spin_unlock_irqrestore(&phba->hbalock, iflags);
747 if (!list_empty(&phba->active_rrq_list)) 780 if (!list_empty(&phba->active_rrq_list))
748 mod_timer(&phba->rrq_tmr, next_time); 781 mod_timer(&phba->rrq_tmr, next_time);
749} 782}
750 783
751 784
752/** 785/**
753 * __lpfc_test_rrq_active - Test RRQ bit in xri_bitmap. 786 * lpfc_test_rrq_active - Test RRQ bit in xri_bitmap.
754 * @phba: Pointer to HBA context object. 787 * @phba: Pointer to HBA context object.
755 * @ndlp: Targets nodelist pointer for this exchange. 788 * @ndlp: Targets nodelist pointer for this exchange.
756 * @xritag the xri in the bitmap to test. 789 * @xritag the xri in the bitmap to test.
@@ -759,8 +792,8 @@ lpfc_cleanup_wt_rrqs(struct lpfc_hba *phba)
759 * returns 0 = rrq not active for this xri 792 * returns 0 = rrq not active for this xri
760 * 1 = rrq is valid for this xri. 793 * 1 = rrq is valid for this xri.
761 **/ 794 **/
762static int 795int
763__lpfc_test_rrq_active(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, 796lpfc_test_rrq_active(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp,
764 uint16_t xritag) 797 uint16_t xritag)
765{ 798{
766 uint16_t adj_xri; 799 uint16_t adj_xri;
@@ -803,52 +836,6 @@ lpfc_set_rrq_active(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp,
803} 836}
804 837
805/** 838/**
806 * lpfc_clr_rrq_active - Clears RRQ active bit in xri_bitmap.
807 * @phba: Pointer to HBA context object.
808 * @xritag: xri used in this exchange.
809 * @rrq: The RRQ to be cleared.
810 *
811 * This function is takes the hbalock.
812 **/
813void
814lpfc_clr_rrq_active(struct lpfc_hba *phba,
815 uint16_t xritag,
816 struct lpfc_node_rrq *rrq)
817{
818 unsigned long iflags;
819
820 spin_lock_irqsave(&phba->hbalock, iflags);
821 __lpfc_clr_rrq_active(phba, xritag, rrq);
822 spin_unlock_irqrestore(&phba->hbalock, iflags);
823 return;
824}
825
826
827
828/**
829 * lpfc_test_rrq_active - Test RRQ bit in xri_bitmap.
830 * @phba: Pointer to HBA context object.
831 * @ndlp: Targets nodelist pointer for this exchange.
832 * @xritag the xri in the bitmap to test.
833 *
834 * This function takes the hbalock.
835 * returns 0 = rrq not active for this xri
836 * 1 = rrq is valid for this xri.
837 **/
838int
839lpfc_test_rrq_active(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp,
840 uint16_t xritag)
841{
842 int ret;
843 unsigned long iflags;
844
845 spin_lock_irqsave(&phba->hbalock, iflags);
846 ret = __lpfc_test_rrq_active(phba, ndlp, xritag);
847 spin_unlock_irqrestore(&phba->hbalock, iflags);
848 return ret;
849}
850
851/**
852 * __lpfc_sli_get_sglq - Allocates an iocb object from sgl pool 839 * __lpfc_sli_get_sglq - Allocates an iocb object from sgl pool
853 * @phba: Pointer to HBA context object. 840 * @phba: Pointer to HBA context object.
854 * @piocb: Pointer to the iocbq. 841 * @piocb: Pointer to the iocbq.
@@ -885,7 +872,7 @@ __lpfc_sli_get_sglq(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq)
885 return NULL; 872 return NULL;
886 adj_xri = sglq->sli4_xritag - 873 adj_xri = sglq->sli4_xritag -
887 phba->sli4_hba.max_cfg_param.xri_base; 874 phba->sli4_hba.max_cfg_param.xri_base;
888 if (__lpfc_test_rrq_active(phba, ndlp, sglq->sli4_xritag)) { 875 if (lpfc_test_rrq_active(phba, ndlp, sglq->sli4_xritag)) {
889 /* This xri has an rrq outstanding for this DID. 876 /* This xri has an rrq outstanding for this DID.
890 * put it back in the list and get another xri. 877 * put it back in the list and get another xri.
891 */ 878 */
diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h
index aea4aa01227..435a09d331e 100644
--- a/drivers/scsi/lpfc/lpfc_sli4.h
+++ b/drivers/scsi/lpfc/lpfc_sli4.h
@@ -566,6 +566,8 @@ void lpfc_sli4_fcp_xri_aborted(struct lpfc_hba *,
566 struct sli4_wcqe_xri_aborted *); 566 struct sli4_wcqe_xri_aborted *);
567void lpfc_sli4_els_xri_aborted(struct lpfc_hba *, 567void lpfc_sli4_els_xri_aborted(struct lpfc_hba *,
568 struct sli4_wcqe_xri_aborted *); 568 struct sli4_wcqe_xri_aborted *);
569void lpfc_sli4_vport_delete_els_xri_aborted(struct lpfc_vport *);
570void lpfc_sli4_vport_delete_fcp_xri_aborted(struct lpfc_vport *);
569int lpfc_sli4_brdreset(struct lpfc_hba *); 571int lpfc_sli4_brdreset(struct lpfc_hba *);
570int lpfc_sli4_add_fcf_record(struct lpfc_hba *, struct fcf_record *); 572int lpfc_sli4_add_fcf_record(struct lpfc_hba *, struct fcf_record *);
571void lpfc_sli_remove_dflt_fcf(struct lpfc_hba *); 573void lpfc_sli_remove_dflt_fcf(struct lpfc_hba *);