aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_sli.c
diff options
context:
space:
mode:
authorJames Smart <James.Smart@Emulex.Com>2008-04-07 10:15:56 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-04-10 08:52:11 -0400
commit58da1ffb2b1234e9c6c75013a649c659cc38ebd4 (patch)
treef159b38ff5c830e10eb90918ef5b42ae71645daa /drivers/scsi/lpfc/lpfc_sli.c
parentb35c07d00751c3d554dd6e582b661ac2e8ffc162 (diff)
[SCSI] lpfc 8.2.6 : Multiple discovery fixes
Multiple Discovery Fixes: - Fix race on discovery due to link events coinciding with vport_delete. - Use NLP_FABRIC state to filter out switch-based pseudo initiators that reuse the same WWNs. - Correct erroneous setting of DID=0 in lpfc_matchdid() - Correct extra reference count that was in the lookup path for the remoteid from an unsolicited ELS. - Correct double-free bug in els abort path. - Correct FDMI server discovery logic for switch that return a WWN of 0. - Fix bugs in ndlp mgmt when a node changes address - Correct bug that did not delete RSCNs for vports upon link transitions - Fix "0216 Link event during NS query" error which pops up when vports are swapped to different switch ports. - Add sanity checks on ndlp structures - Fix devloss log message to dump WWN correctly - Hold off mgmt commands that were interferring with discovery mailbox cmds - Remove unnecessary FC_ESTABLISH_LINK logic. - Correct some race conditions in the worker thread, resulting in devloss: - Clear the work_port_events field before handling the work port events - Clear the deferred ring event before handling a deferred ring event - Hold the hba lock when waking up the work thread - Send an acc for the rscn even when we aren't going to handle it - Fix locking behavior that was not properly protecting the ACTIVE flag, thus allowing mailbox command order to shift. Signed-off-by: James Smart <james.smart@emulex.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_sli.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c93
1 files changed, 60 insertions, 33 deletions
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index fc0d9501aba6..c71b9a577770 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -2648,7 +2648,6 @@ lpfc_mbox_timeout_handler(struct lpfc_hba *phba)
2648 spin_unlock_irq(&phba->pport->work_port_lock); 2648 spin_unlock_irq(&phba->pport->work_port_lock);
2649 spin_lock_irq(&phba->hbalock); 2649 spin_lock_irq(&phba->hbalock);
2650 phba->link_state = LPFC_LINK_UNKNOWN; 2650 phba->link_state = LPFC_LINK_UNKNOWN;
2651 phba->pport->fc_flag |= FC_ESTABLISH_LINK;
2652 psli->sli_flag &= ~LPFC_SLI2_ACTIVE; 2651 psli->sli_flag &= ~LPFC_SLI2_ACTIVE;
2653 spin_unlock_irq(&phba->hbalock); 2652 spin_unlock_irq(&phba->hbalock);
2654 2653
@@ -2669,8 +2668,7 @@ lpfc_mbox_timeout_handler(struct lpfc_hba *phba)
2669 lpfc_offline_prep(phba); 2668 lpfc_offline_prep(phba);
2670 lpfc_offline(phba); 2669 lpfc_offline(phba);
2671 lpfc_sli_brdrestart(phba); 2670 lpfc_sli_brdrestart(phba);
2672 if (lpfc_online(phba) == 0) /* Initialize the HBA */ 2671 lpfc_online(phba);
2673 mod_timer(&phba->fc_estabtmo, jiffies + HZ * 60);
2674 lpfc_unblock_mgmt_io(phba); 2672 lpfc_unblock_mgmt_io(phba);
2675 return; 2673 return;
2676} 2674}
@@ -2687,28 +2685,41 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag)
2687 unsigned long drvr_flag = 0; 2685 unsigned long drvr_flag = 0;
2688 volatile uint32_t word0, ldata; 2686 volatile uint32_t word0, ldata;
2689 void __iomem *to_slim; 2687 void __iomem *to_slim;
2688 int processing_queue = 0;
2689
2690 spin_lock_irqsave(&phba->hbalock, drvr_flag);
2691 if (!pmbox) {
2692 /* processing mbox queue from intr_handler */
2693 processing_queue = 1;
2694 phba->sli.sli_flag &= ~LPFC_SLI_MBOX_ACTIVE;
2695 pmbox = lpfc_mbox_get(phba);
2696 if (!pmbox) {
2697 spin_unlock_irqrestore(&phba->hbalock, drvr_flag);
2698 return MBX_SUCCESS;
2699 }
2700 }
2690 2701
2691 if (pmbox->mbox_cmpl && pmbox->mbox_cmpl != lpfc_sli_def_mbox_cmpl && 2702 if (pmbox->mbox_cmpl && pmbox->mbox_cmpl != lpfc_sli_def_mbox_cmpl &&
2692 pmbox->mbox_cmpl != lpfc_sli_wake_mbox_wait) { 2703 pmbox->mbox_cmpl != lpfc_sli_wake_mbox_wait) {
2693 if(!pmbox->vport) { 2704 if(!pmbox->vport) {
2705 spin_unlock_irqrestore(&phba->hbalock, drvr_flag);
2694 lpfc_printf_log(phba, KERN_ERR, 2706 lpfc_printf_log(phba, KERN_ERR,
2695 LOG_MBOX | LOG_VPORT, 2707 LOG_MBOX | LOG_VPORT,
2696 "1806 Mbox x%x failed. No vport\n", 2708 "1806 Mbox x%x failed. No vport\n",
2697 pmbox->mb.mbxCommand); 2709 pmbox->mb.mbxCommand);
2698 dump_stack(); 2710 dump_stack();
2699 return MBX_NOT_FINISHED; 2711 goto out_not_finished;
2700 } 2712 }
2701 } 2713 }
2702 2714
2703
2704 /* If the PCI channel is in offline state, do not post mbox. */ 2715 /* If the PCI channel is in offline state, do not post mbox. */
2705 if (unlikely(pci_channel_offline(phba->pcidev))) 2716 if (unlikely(pci_channel_offline(phba->pcidev))) {
2706 return MBX_NOT_FINISHED; 2717 spin_unlock_irqrestore(&phba->hbalock, drvr_flag);
2718 goto out_not_finished;
2719 }
2707 2720
2708 spin_lock_irqsave(&phba->hbalock, drvr_flag);
2709 psli = &phba->sli; 2721 psli = &phba->sli;
2710 2722
2711
2712 mb = &pmbox->mb; 2723 mb = &pmbox->mb;
2713 status = MBX_SUCCESS; 2724 status = MBX_SUCCESS;
2714 2725
@@ -2717,14 +2728,14 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag)
2717 2728
2718 /* Mbox command <mbxCommand> cannot issue */ 2729 /* Mbox command <mbxCommand> cannot issue */
2719 LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag); 2730 LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag);
2720 return MBX_NOT_FINISHED; 2731 goto out_not_finished;
2721 } 2732 }
2722 2733
2723 if (mb->mbxCommand != MBX_KILL_BOARD && flag & MBX_NOWAIT && 2734 if (mb->mbxCommand != MBX_KILL_BOARD && flag & MBX_NOWAIT &&
2724 !(readl(phba->HCregaddr) & HC_MBINT_ENA)) { 2735 !(readl(phba->HCregaddr) & HC_MBINT_ENA)) {
2725 spin_unlock_irqrestore(&phba->hbalock, drvr_flag); 2736 spin_unlock_irqrestore(&phba->hbalock, drvr_flag);
2726 LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag); 2737 LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag);
2727 return MBX_NOT_FINISHED; 2738 goto out_not_finished;
2728 } 2739 }
2729 2740
2730 if (psli->sli_flag & LPFC_SLI_MBOX_ACTIVE) { 2741 if (psli->sli_flag & LPFC_SLI_MBOX_ACTIVE) {
@@ -2738,14 +2749,14 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag)
2738 2749
2739 /* Mbox command <mbxCommand> cannot issue */ 2750 /* Mbox command <mbxCommand> cannot issue */
2740 LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag); 2751 LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag);
2741 return MBX_NOT_FINISHED; 2752 goto out_not_finished;
2742 } 2753 }
2743 2754
2744 if (!(psli->sli_flag & LPFC_SLI2_ACTIVE)) { 2755 if (!(psli->sli_flag & LPFC_SLI2_ACTIVE)) {
2745 spin_unlock_irqrestore(&phba->hbalock, drvr_flag); 2756 spin_unlock_irqrestore(&phba->hbalock, drvr_flag);
2746 /* Mbox command <mbxCommand> cannot issue */ 2757 /* Mbox command <mbxCommand> cannot issue */
2747 LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag); 2758 LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag);
2748 return MBX_NOT_FINISHED; 2759 goto out_not_finished;
2749 } 2760 }
2750 2761
2751 /* Another mailbox command is still being processed, queue this 2762 /* Another mailbox command is still being processed, queue this
@@ -2792,7 +2803,7 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag)
2792 spin_unlock_irqrestore(&phba->hbalock, drvr_flag); 2803 spin_unlock_irqrestore(&phba->hbalock, drvr_flag);
2793 /* Mbox command <mbxCommand> cannot issue */ 2804 /* Mbox command <mbxCommand> cannot issue */
2794 LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag); 2805 LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag);
2795 return MBX_NOT_FINISHED; 2806 goto out_not_finished;
2796 } 2807 }
2797 /* timeout active mbox command */ 2808 /* timeout active mbox command */
2798 mod_timer(&psli->mbox_tmo, (jiffies + 2809 mod_timer(&psli->mbox_tmo, (jiffies +
@@ -2900,7 +2911,7 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag)
2900 psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; 2911 psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE;
2901 spin_unlock_irqrestore(&phba->hbalock, 2912 spin_unlock_irqrestore(&phba->hbalock,
2902 drvr_flag); 2913 drvr_flag);
2903 return MBX_NOT_FINISHED; 2914 goto out_not_finished;
2904 } 2915 }
2905 2916
2906 /* Check if we took a mbox interrupt while we were 2917 /* Check if we took a mbox interrupt while we were
@@ -2967,6 +2978,13 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag)
2967 2978
2968 spin_unlock_irqrestore(&phba->hbalock, drvr_flag); 2979 spin_unlock_irqrestore(&phba->hbalock, drvr_flag);
2969 return status; 2980 return status;
2981
2982out_not_finished:
2983 if (processing_queue) {
2984 pmbox->mb.mbxStatus = MBX_NOT_FINISHED;
2985 lpfc_mbox_cmpl_put(phba, pmbox);
2986 }
2987 return MBX_NOT_FINISHED;
2970} 2988}
2971 2989
2972/* 2990/*
@@ -3613,6 +3631,16 @@ lpfc_sli_abort_els_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
3613 irsp->ulpStatus, irsp->un.ulpWord[4]); 3631 irsp->ulpStatus, irsp->un.ulpWord[4]);
3614 3632
3615 /* 3633 /*
3634 * If the iocb is not found in Firmware queue the iocb
3635 * might have completed already. Do not free it again.
3636 */
3637 if ((irsp->ulpStatus == IOSTAT_LOCAL_REJECT) &&
3638 (irsp->un.ulpWord[4] == IOERR_NO_XRI)) {
3639 spin_unlock_irq(&phba->hbalock);
3640 lpfc_sli_release_iocbq(phba, cmdiocb);
3641 return;
3642 }
3643 /*
3616 * make sure we have the right iocbq before taking it 3644 * make sure we have the right iocbq before taking it
3617 * off the txcmplq and try to call completion routine. 3645 * off the txcmplq and try to call completion routine.
3618 */ 3646 */
@@ -4237,10 +4265,15 @@ lpfc_intr_handler(int irq, void *dev_id)
4237 pmb->context1 = mp; 4265 pmb->context1 = mp;
4238 pmb->context2 = ndlp; 4266 pmb->context2 = ndlp;
4239 pmb->vport = vport; 4267 pmb->vport = vport;
4240 spin_lock(&phba->hbalock); 4268 rc = lpfc_sli_issue_mbox(phba,
4241 phba->sli.sli_flag &= 4269 pmb,
4242 ~LPFC_SLI_MBOX_ACTIVE; 4270 MBX_NOWAIT);
4243 spin_unlock(&phba->hbalock); 4271 if (rc != MBX_BUSY)
4272 lpfc_printf_log(phba,
4273 KERN_ERR,
4274 LOG_MBOX | LOG_SLI,
4275 "0306 rc should have"
4276 "been MBX_BUSY");
4244 goto send_current_mbox; 4277 goto send_current_mbox;
4245 } 4278 }
4246 } 4279 }
@@ -4253,22 +4286,16 @@ lpfc_intr_handler(int irq, void *dev_id)
4253 } 4286 }
4254 if ((work_ha_copy & HA_MBATT) && 4287 if ((work_ha_copy & HA_MBATT) &&
4255 (phba->sli.mbox_active == NULL)) { 4288 (phba->sli.mbox_active == NULL)) {
4256send_next_mbox:
4257 spin_lock(&phba->hbalock);
4258 phba->sli.sli_flag &= ~LPFC_SLI_MBOX_ACTIVE;
4259 pmb = lpfc_mbox_get(phba);
4260 spin_unlock(&phba->hbalock);
4261send_current_mbox: 4289send_current_mbox:
4262 /* Process next mailbox command if there is one */ 4290 /* Process next mailbox command if there is one */
4263 if (pmb != NULL) { 4291 do {
4264 rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT); 4292 rc = lpfc_sli_issue_mbox(phba, NULL,
4265 if (rc == MBX_NOT_FINISHED) { 4293 MBX_NOWAIT);
4266 pmb->mb.mbxStatus = MBX_NOT_FINISHED; 4294 } while (rc == MBX_NOT_FINISHED);
4267 lpfc_mbox_cmpl_put(phba, pmb); 4295 if (rc != MBX_SUCCESS)
4268 goto send_next_mbox; 4296 lpfc_printf_log(phba, KERN_ERR, LOG_MBOX |
4269 } 4297 LOG_SLI, "0349 rc should be "
4270 } 4298 "MBX_SUCCESS");
4271
4272 } 4299 }
4273 4300
4274 spin_lock(&phba->hbalock); 4301 spin_lock(&phba->hbalock);