aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_els.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_els.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_els.c181
1 files changed, 50 insertions, 131 deletions
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index 886c5f1b11d2..f54e0f7eaee3 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -1754,29 +1754,34 @@ lpfc_cancel_retry_delay_tmo(struct lpfc_vport *vport, struct lpfc_nodelist *nlp)
1754 struct Scsi_Host *shost = lpfc_shost_from_vport(vport); 1754 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1755 struct lpfc_work_evt *evtp; 1755 struct lpfc_work_evt *evtp;
1756 1756
1757 if (!(nlp->nlp_flag & NLP_DELAY_TMO))
1758 return;
1757 spin_lock_irq(shost->host_lock); 1759 spin_lock_irq(shost->host_lock);
1758 nlp->nlp_flag &= ~NLP_DELAY_TMO; 1760 nlp->nlp_flag &= ~NLP_DELAY_TMO;
1759 spin_unlock_irq(shost->host_lock); 1761 spin_unlock_irq(shost->host_lock);
1760 del_timer_sync(&nlp->nlp_delayfunc); 1762 del_timer_sync(&nlp->nlp_delayfunc);
1761 nlp->nlp_last_elscmd = 0; 1763 nlp->nlp_last_elscmd = 0;
1762
1763 if (!list_empty(&nlp->els_retry_evt.evt_listp)) { 1764 if (!list_empty(&nlp->els_retry_evt.evt_listp)) {
1764 list_del_init(&nlp->els_retry_evt.evt_listp); 1765 list_del_init(&nlp->els_retry_evt.evt_listp);
1765 /* Decrement nlp reference count held for the delayed retry */ 1766 /* Decrement nlp reference count held for the delayed retry */
1766 evtp = &nlp->els_retry_evt; 1767 evtp = &nlp->els_retry_evt;
1767 lpfc_nlp_put((struct lpfc_nodelist *)evtp->evt_arg1); 1768 lpfc_nlp_put((struct lpfc_nodelist *)evtp->evt_arg1);
1768 } 1769 }
1769
1770 if (nlp->nlp_flag & NLP_NPR_2B_DISC) { 1770 if (nlp->nlp_flag & NLP_NPR_2B_DISC) {
1771 spin_lock_irq(shost->host_lock); 1771 spin_lock_irq(shost->host_lock);
1772 nlp->nlp_flag &= ~NLP_NPR_2B_DISC; 1772 nlp->nlp_flag &= ~NLP_NPR_2B_DISC;
1773 spin_unlock_irq(shost->host_lock); 1773 spin_unlock_irq(shost->host_lock);
1774 if (vport->num_disc_nodes) { 1774 if (vport->num_disc_nodes) {
1775 /* Check to see if there are more 1775 if (vport->port_state < LPFC_VPORT_READY) {
1776 * PLOGIs to be sent 1776 /* Check if there are more ADISCs to be sent */
1777 */ 1777 lpfc_more_adisc(vport);
1778 lpfc_more_plogi(vport); 1778 if ((vport->num_disc_nodes == 0) &&
1779 1779 (vport->fc_npr_cnt))
1780 lpfc_els_disc_plogi(vport);
1781 } else {
1782 /* Check if there are more PLOGIs to be sent */
1783 lpfc_more_plogi(vport);
1784 }
1780 if (vport->num_disc_nodes == 0) { 1785 if (vport->num_disc_nodes == 0) {
1781 spin_lock_irq(shost->host_lock); 1786 spin_lock_irq(shost->host_lock);
1782 vport->fc_flag &= ~FC_NDISC_ACTIVE; 1787 vport->fc_flag &= ~FC_NDISC_ACTIVE;
@@ -1798,10 +1803,6 @@ lpfc_els_retry_delay(unsigned long ptr)
1798 unsigned long flags; 1803 unsigned long flags;
1799 struct lpfc_work_evt *evtp = &ndlp->els_retry_evt; 1804 struct lpfc_work_evt *evtp = &ndlp->els_retry_evt;
1800 1805
1801 ndlp = (struct lpfc_nodelist *) ptr;
1802 phba = ndlp->vport->phba;
1803 evtp = &ndlp->els_retry_evt;
1804
1805 spin_lock_irqsave(&phba->hbalock, flags); 1806 spin_lock_irqsave(&phba->hbalock, flags);
1806 if (!list_empty(&evtp->evt_listp)) { 1807 if (!list_empty(&evtp->evt_listp)) {
1807 spin_unlock_irqrestore(&phba->hbalock, flags); 1808 spin_unlock_irqrestore(&phba->hbalock, flags);
@@ -1812,11 +1813,11 @@ lpfc_els_retry_delay(unsigned long ptr)
1812 * count until the queued work is done 1813 * count until the queued work is done
1813 */ 1814 */
1814 evtp->evt_arg1 = lpfc_nlp_get(ndlp); 1815 evtp->evt_arg1 = lpfc_nlp_get(ndlp);
1815 evtp->evt = LPFC_EVT_ELS_RETRY; 1816 if (evtp->evt_arg1) {
1816 list_add_tail(&evtp->evt_listp, &phba->work_list); 1817 evtp->evt = LPFC_EVT_ELS_RETRY;
1817 if (phba->work_wait) 1818 list_add_tail(&evtp->evt_listp, &phba->work_list);
1818 lpfc_worker_wake_up(phba); 1819 lpfc_worker_wake_up(phba);
1819 1820 }
1820 spin_unlock_irqrestore(&phba->hbalock, flags); 1821 spin_unlock_irqrestore(&phba->hbalock, flags);
1821 return; 1822 return;
1822} 1823}
@@ -2761,10 +2762,11 @@ lpfc_els_rsp_prli_acc(struct lpfc_vport *vport, struct lpfc_iocbq *oldiocb,
2761 npr = (PRLI *) pcmd; 2762 npr = (PRLI *) pcmd;
2762 vpd = &phba->vpd; 2763 vpd = &phba->vpd;
2763 /* 2764 /*
2764 * If our firmware version is 3.20 or later, 2765 * If the remote port is a target and our firmware version is 3.20 or
2765 * set the following bits for FC-TAPE support. 2766 * later, set the following bits for FC-TAPE support.
2766 */ 2767 */
2767 if (vpd->rev.feaLevelHigh >= 0x02) { 2768 if ((ndlp->nlp_type & NLP_FCP_TARGET) &&
2769 (vpd->rev.feaLevelHigh >= 0x02)) {
2768 npr->ConfmComplAllowed = 1; 2770 npr->ConfmComplAllowed = 1;
2769 npr->Retry = 1; 2771 npr->Retry = 1;
2770 npr->TaskRetryIdReq = 1; 2772 npr->TaskRetryIdReq = 1;
@@ -3056,27 +3058,16 @@ lpfc_rscn_recovery_check(struct lpfc_vport *vport)
3056{ 3058{
3057 struct lpfc_nodelist *ndlp = NULL; 3059 struct lpfc_nodelist *ndlp = NULL;
3058 3060
3059 /* Look at all nodes effected by pending RSCNs and move 3061 /* Move all affected nodes by pending RSCNs to NPR state. */
3060 * them to NPR state.
3061 */
3062
3063 list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) { 3062 list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
3064 if (!NLP_CHK_NODE_ACT(ndlp) || 3063 if (!NLP_CHK_NODE_ACT(ndlp) ||
3065 ndlp->nlp_state == NLP_STE_UNUSED_NODE || 3064 (ndlp->nlp_state == NLP_STE_UNUSED_NODE) ||
3066 lpfc_rscn_payload_check(vport, ndlp->nlp_DID) == 0) 3065 !lpfc_rscn_payload_check(vport, ndlp->nlp_DID))
3067 continue; 3066 continue;
3068
3069 lpfc_disc_state_machine(vport, ndlp, NULL, 3067 lpfc_disc_state_machine(vport, ndlp, NULL,
3070 NLP_EVT_DEVICE_RECOVERY); 3068 NLP_EVT_DEVICE_RECOVERY);
3071 3069 lpfc_cancel_retry_delay_tmo(vport, ndlp);
3072 /*
3073 * Make sure NLP_DELAY_TMO is NOT running after a device
3074 * recovery event.
3075 */
3076 if (ndlp->nlp_flag & NLP_DELAY_TMO)
3077 lpfc_cancel_retry_delay_tmo(vport, ndlp);
3078 } 3070 }
3079
3080 return 0; 3071 return 0;
3081} 3072}
3082 3073
@@ -3781,91 +3772,27 @@ static int
3781lpfc_els_rcv_fan(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, 3772lpfc_els_rcv_fan(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
3782 struct lpfc_nodelist *fan_ndlp) 3773 struct lpfc_nodelist *fan_ndlp)
3783{ 3774{
3784 struct lpfc_dmabuf *pcmd; 3775 struct lpfc_hba *phba = vport->phba;
3785 uint32_t *lp; 3776 uint32_t *lp;
3786 IOCB_t *icmd;
3787 uint32_t cmd, did;
3788 FAN *fp; 3777 FAN *fp;
3789 struct lpfc_nodelist *ndlp, *next_ndlp;
3790 struct lpfc_hba *phba = vport->phba;
3791
3792 /* FAN received */
3793 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
3794 "0265 FAN received\n");
3795 icmd = &cmdiocb->iocb;
3796 did = icmd->un.elsreq64.remoteID;
3797 pcmd = (struct lpfc_dmabuf *)cmdiocb->context2;
3798 lp = (uint32_t *)pcmd->virt;
3799
3800 cmd = *lp++;
3801 fp = (FAN *) lp;
3802 3778
3779 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, "0265 FAN received\n");
3780 lp = (uint32_t *)((struct lpfc_dmabuf *)cmdiocb->context2)->virt;
3781 fp = (FAN *) ++lp;
3803 /* FAN received; Fan does not have a reply sequence */ 3782 /* FAN received; Fan does not have a reply sequence */
3804 3783 if ((vport == phba->pport) &&
3805 if (phba->pport->port_state == LPFC_LOCAL_CFG_LINK) { 3784 (vport->port_state == LPFC_LOCAL_CFG_LINK)) {
3806 if ((memcmp(&phba->fc_fabparam.nodeName, &fp->FnodeName, 3785 if ((memcmp(&phba->fc_fabparam.nodeName, &fp->FnodeName,
3807 sizeof(struct lpfc_name)) != 0) || 3786 sizeof(struct lpfc_name))) ||
3808 (memcmp(&phba->fc_fabparam.portName, &fp->FportName, 3787 (memcmp(&phba->fc_fabparam.portName, &fp->FportName,
3809 sizeof(struct lpfc_name)) != 0)) { 3788 sizeof(struct lpfc_name)))) {
3810 /* 3789 /* This port has switched fabrics. FLOGI is required */
3811 * This node has switched fabrics. FLOGI is required
3812 * Clean up the old rpi's
3813 */
3814
3815 list_for_each_entry_safe(ndlp, next_ndlp,
3816 &vport->fc_nodes, nlp_listp) {
3817 if (!NLP_CHK_NODE_ACT(ndlp))
3818 continue;
3819 if (ndlp->nlp_state != NLP_STE_NPR_NODE)
3820 continue;
3821 if (ndlp->nlp_type & NLP_FABRIC) {
3822 /*
3823 * Clean up old Fabric, Nameserver and
3824 * other NLP_FABRIC logins
3825 */
3826 lpfc_drop_node(vport, ndlp);
3827
3828 } else if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) {
3829 /* Fail outstanding I/O now since this
3830 * device is marked for PLOGI
3831 */
3832 lpfc_unreg_rpi(vport, ndlp);
3833 }
3834 }
3835
3836 lpfc_initial_flogi(vport); 3790 lpfc_initial_flogi(vport);
3837 return 0; 3791 } else {
3838 } 3792 /* FAN verified - skip FLOGI */
3839 /* Discovery not needed, 3793 vport->fc_myDID = vport->fc_prevDID;
3840 * move the nodes to their original state. 3794 lpfc_issue_fabric_reglogin(vport);
3841 */
3842 list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes,
3843 nlp_listp) {
3844 if (!NLP_CHK_NODE_ACT(ndlp))
3845 continue;
3846 if (ndlp->nlp_state != NLP_STE_NPR_NODE)
3847 continue;
3848
3849 switch (ndlp->nlp_prev_state) {
3850 case NLP_STE_UNMAPPED_NODE:
3851 ndlp->nlp_prev_state = NLP_STE_NPR_NODE;
3852 lpfc_nlp_set_state(vport, ndlp,
3853 NLP_STE_UNMAPPED_NODE);
3854 break;
3855
3856 case NLP_STE_MAPPED_NODE:
3857 ndlp->nlp_prev_state = NLP_STE_NPR_NODE;
3858 lpfc_nlp_set_state(vport, ndlp,
3859 NLP_STE_MAPPED_NODE);
3860 break;
3861
3862 default:
3863 break;
3864 }
3865 } 3795 }
3866
3867 /* Start discovery - this should just do CLEAR_LA */
3868 lpfc_disc_start(vport);
3869 } 3796 }
3870 return 0; 3797 return 0;
3871} 3798}
@@ -3875,20 +3802,17 @@ lpfc_els_timeout(unsigned long ptr)
3875{ 3802{
3876 struct lpfc_vport *vport = (struct lpfc_vport *) ptr; 3803 struct lpfc_vport *vport = (struct lpfc_vport *) ptr;
3877 struct lpfc_hba *phba = vport->phba; 3804 struct lpfc_hba *phba = vport->phba;
3805 uint32_t tmo_posted;
3878 unsigned long iflag; 3806 unsigned long iflag;
3879 3807
3880 spin_lock_irqsave(&vport->work_port_lock, iflag); 3808 spin_lock_irqsave(&vport->work_port_lock, iflag);
3881 if ((vport->work_port_events & WORKER_ELS_TMO) == 0) { 3809 tmo_posted = vport->work_port_events & WORKER_ELS_TMO;
3810 if (!tmo_posted)
3882 vport->work_port_events |= WORKER_ELS_TMO; 3811 vport->work_port_events |= WORKER_ELS_TMO;
3883 spin_unlock_irqrestore(&vport->work_port_lock, iflag); 3812 spin_unlock_irqrestore(&vport->work_port_lock, iflag);
3884 3813
3885 spin_lock_irqsave(&phba->hbalock, iflag); 3814 if (!tmo_posted)
3886 if (phba->work_wait) 3815 lpfc_worker_wake_up(phba);
3887 lpfc_worker_wake_up(phba);
3888 spin_unlock_irqrestore(&phba->hbalock, iflag);
3889 }
3890 else
3891 spin_unlock_irqrestore(&vport->work_port_lock, iflag);
3892 return; 3816 return;
3893} 3817}
3894 3818
@@ -3933,9 +3857,6 @@ lpfc_els_timeout_handler(struct lpfc_vport *vport)
3933 els_command == ELS_CMD_FDISC) 3857 els_command == ELS_CMD_FDISC)
3934 continue; 3858 continue;
3935 3859
3936 if (vport != piocb->vport)
3937 continue;
3938
3939 if (piocb->drvrTimeout > 0) { 3860 if (piocb->drvrTimeout > 0) {
3940 if (piocb->drvrTimeout >= timeout) 3861 if (piocb->drvrTimeout >= timeout)
3941 piocb->drvrTimeout -= timeout; 3862 piocb->drvrTimeout -= timeout;
@@ -4089,7 +4010,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
4089 payload = ((struct lpfc_dmabuf *)elsiocb->context2)->virt; 4010 payload = ((struct lpfc_dmabuf *)elsiocb->context2)->virt;
4090 cmd = *payload; 4011 cmd = *payload;
4091 if ((phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) == 0) 4012 if ((phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) == 0)
4092 lpfc_post_buffer(phba, pring, 1, 1); 4013 lpfc_post_buffer(phba, pring, 1);
4093 4014
4094 did = icmd->un.rcvels.remoteID; 4015 did = icmd->un.rcvels.remoteID;
4095 if (icmd->ulpStatus) { 4016 if (icmd->ulpStatus) {
@@ -4398,7 +4319,7 @@ lpfc_els_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
4398 phba->fc_stat.NoRcvBuf++; 4319 phba->fc_stat.NoRcvBuf++;
4399 /* Not enough posted buffers; Try posting more buffers */ 4320 /* Not enough posted buffers; Try posting more buffers */
4400 if (!(phba->sli3_options & LPFC_SLI3_HBQ_ENABLED)) 4321 if (!(phba->sli3_options & LPFC_SLI3_HBQ_ENABLED))
4401 lpfc_post_buffer(phba, pring, 0, 1); 4322 lpfc_post_buffer(phba, pring, 0);
4402 return; 4323 return;
4403 } 4324 }
4404 4325
@@ -4842,18 +4763,16 @@ lpfc_fabric_block_timeout(unsigned long ptr)
4842 struct lpfc_hba *phba = (struct lpfc_hba *) ptr; 4763 struct lpfc_hba *phba = (struct lpfc_hba *) ptr;
4843 unsigned long iflags; 4764 unsigned long iflags;
4844 uint32_t tmo_posted; 4765 uint32_t tmo_posted;
4766
4845 spin_lock_irqsave(&phba->pport->work_port_lock, iflags); 4767 spin_lock_irqsave(&phba->pport->work_port_lock, iflags);
4846 tmo_posted = phba->pport->work_port_events & WORKER_FABRIC_BLOCK_TMO; 4768 tmo_posted = phba->pport->work_port_events & WORKER_FABRIC_BLOCK_TMO;
4847 if (!tmo_posted) 4769 if (!tmo_posted)
4848 phba->pport->work_port_events |= WORKER_FABRIC_BLOCK_TMO; 4770 phba->pport->work_port_events |= WORKER_FABRIC_BLOCK_TMO;
4849 spin_unlock_irqrestore(&phba->pport->work_port_lock, iflags); 4771 spin_unlock_irqrestore(&phba->pport->work_port_lock, iflags);
4850 4772
4851 if (!tmo_posted) { 4773 if (!tmo_posted)
4852 spin_lock_irqsave(&phba->hbalock, iflags); 4774 lpfc_worker_wake_up(phba);
4853 if (phba->work_wait) 4775 return;
4854 lpfc_worker_wake_up(phba);
4855 spin_unlock_irqrestore(&phba->hbalock, iflags);
4856 }
4857} 4776}
4858 4777
4859static void 4778static void