diff options
author | James Smart <James.Smart@Emulex.Com> | 2008-04-07 10:15:56 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-04-10 08:52:11 -0400 |
commit | 58da1ffb2b1234e9c6c75013a649c659cc38ebd4 (patch) | |
tree | f159b38ff5c830e10eb90918ef5b42ae71645daa /drivers/scsi/lpfc/lpfc_sli.c | |
parent | b35c07d00751c3d554dd6e582b661ac2e8ffc162 (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.c | 93 |
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 | |||
2982 | out_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)) { |
4256 | send_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); | ||
4261 | send_current_mbox: | 4289 | send_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); |