aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_els.c
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 /drivers/scsi/lpfc/lpfc_els.c
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>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_els.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_els.c52
1 files changed, 46 insertions, 6 deletions
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.