diff options
author | James Smart <James.Smart@Emulex.Com> | 2008-01-11 01:52:54 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-01-23 12:29:22 -0500 |
commit | 0937282036d9ae798e02c9c69a8b2ef044048855 (patch) | |
tree | 55c8ef65c9c55e74e8985b58396516b3d3b925ad /drivers/scsi/lpfc/lpfc_sli.c | |
parent | 13815c8344a238c204e4f4339b22dc4833c6df0f (diff) |
[SCSI] lpfc 8.2.4 : Miscellaneous Fixes
Miscellaneous Fixes:
- Fix a couple of sparse complaints
- Reset the FCP recovery flag when the node is not a FCP2 device.
- Speed up offline prep delays
- Fixed a memory leak in lpfc_mem_alloc failure path
- Fixed external loopback test.
- Fixed error code returned from the driver when HBA is over heated.
- Correct Max NPIV vport to limits read from adapter
- Add missing locks around fc_flag and FC_NEEDS_REG_VPI
- Add missing hba ids for device identification
- Added support for SET_VARIABLE and MBX_WRITE_WWN mailbox commands
- Changed all temperature event messages from warning to error
- Fix reporting of link speed when link is down
- Added support for MBX_WRITE_WWN mailbox command
- Change del_timer_sync() in ISR to del_timer() in interrupt handler
- Correct instances of beXX_to_cpu() that should be cpu_to_beXX()
- Perform target flush before releasing node references on module unload
- Avoid bogus devloss_tmo messages when driver unloads
- Fix panic when HBA generates ERATT interupt
- Fix mbox race condition and a workaround on back-to-back mailbox commands
- Force NPIV off for pt2pt mode between 2 NPorts
- Stop worker thread before removing fc_host.
- Fix up discovery timeout error case due to missing clear_la
- Tighten mailbox polling code to speed up detection of fast completions
- Only allow DUMP_MEMORY if adapter offline due to overtemp errors
- Added extended error information to the log messages in chip init.
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 | 156 |
1 files changed, 90 insertions, 66 deletions
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 46d529d6ac6b..5a2cb484e137 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c | |||
@@ -716,7 +716,7 @@ lpfc_sli_chk_mbx_command(uint8_t mbxCommand) | |||
716 | case MBX_DEL_LD_ENTRY: | 716 | case MBX_DEL_LD_ENTRY: |
717 | case MBX_RUN_PROGRAM: | 717 | case MBX_RUN_PROGRAM: |
718 | case MBX_SET_MASK: | 718 | case MBX_SET_MASK: |
719 | case MBX_SET_SLIM: | 719 | case MBX_SET_VARIABLE: |
720 | case MBX_UNREG_D_ID: | 720 | case MBX_UNREG_D_ID: |
721 | case MBX_KILL_BOARD: | 721 | case MBX_KILL_BOARD: |
722 | case MBX_CONFIG_FARP: | 722 | case MBX_CONFIG_FARP: |
@@ -728,7 +728,7 @@ lpfc_sli_chk_mbx_command(uint8_t mbxCommand) | |||
728 | case MBX_READ_RPI64: | 728 | case MBX_READ_RPI64: |
729 | case MBX_REG_LOGIN64: | 729 | case MBX_REG_LOGIN64: |
730 | case MBX_READ_LA64: | 730 | case MBX_READ_LA64: |
731 | case MBX_FLASH_WR_ULA: | 731 | case MBX_WRITE_WWN: |
732 | case MBX_SET_DEBUG: | 732 | case MBX_SET_DEBUG: |
733 | case MBX_LOAD_EXP_ROM: | 733 | case MBX_LOAD_EXP_ROM: |
734 | case MBX_ASYNCEVT_ENABLE: | 734 | case MBX_ASYNCEVT_ENABLE: |
@@ -2182,7 +2182,10 @@ lpfc_sli_chipset_init(struct lpfc_hba *phba) | |||
2182 | <status> */ | 2182 | <status> */ |
2183 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 2183 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
2184 | "0436 Adapter failed to init, " | 2184 | "0436 Adapter failed to init, " |
2185 | "timeout, status reg x%x\n", status); | 2185 | "timeout, status reg x%x, " |
2186 | "FW Data: A8 x%x AC x%x\n", status, | ||
2187 | readl(phba->MBslimaddr + 0xa8), | ||
2188 | readl(phba->MBslimaddr + 0xac)); | ||
2186 | phba->link_state = LPFC_HBA_ERROR; | 2189 | phba->link_state = LPFC_HBA_ERROR; |
2187 | return -ETIMEDOUT; | 2190 | return -ETIMEDOUT; |
2188 | } | 2191 | } |
@@ -2194,7 +2197,10 @@ lpfc_sli_chipset_init(struct lpfc_hba *phba) | |||
2194 | <status> */ | 2197 | <status> */ |
2195 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 2198 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
2196 | "0437 Adapter failed to init, " | 2199 | "0437 Adapter failed to init, " |
2197 | "chipset, status reg x%x\n", status); | 2200 | "chipset, status reg x%x, " |
2201 | "FW Data: A8 x%x AC x%x\n", status, | ||
2202 | readl(phba->MBslimaddr + 0xa8), | ||
2203 | readl(phba->MBslimaddr + 0xac)); | ||
2198 | phba->link_state = LPFC_HBA_ERROR; | 2204 | phba->link_state = LPFC_HBA_ERROR; |
2199 | return -EIO; | 2205 | return -EIO; |
2200 | } | 2206 | } |
@@ -2222,7 +2228,10 @@ lpfc_sli_chipset_init(struct lpfc_hba *phba) | |||
2222 | /* Adapter failed to init, chipset, status reg <status> */ | 2228 | /* Adapter failed to init, chipset, status reg <status> */ |
2223 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 2229 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
2224 | "0438 Adapter failed to init, chipset, " | 2230 | "0438 Adapter failed to init, chipset, " |
2225 | "status reg x%x\n", status); | 2231 | "status reg x%x, " |
2232 | "FW Data: A8 x%x AC x%x\n", status, | ||
2233 | readl(phba->MBslimaddr + 0xa8), | ||
2234 | readl(phba->MBslimaddr + 0xac)); | ||
2226 | phba->link_state = LPFC_HBA_ERROR; | 2235 | phba->link_state = LPFC_HBA_ERROR; |
2227 | return -EIO; | 2236 | return -EIO; |
2228 | } | 2237 | } |
@@ -2581,6 +2590,7 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag) | |||
2581 | uint32_t status, evtctr; | 2590 | uint32_t status, evtctr; |
2582 | uint32_t ha_copy; | 2591 | uint32_t ha_copy; |
2583 | int i; | 2592 | int i; |
2593 | unsigned long timeout; | ||
2584 | unsigned long drvr_flag = 0; | 2594 | unsigned long drvr_flag = 0; |
2585 | volatile uint32_t word0, ldata; | 2595 | volatile uint32_t word0, ldata; |
2586 | void __iomem *to_slim; | 2596 | void __iomem *to_slim; |
@@ -2756,18 +2766,24 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag) | |||
2756 | } | 2766 | } |
2757 | 2767 | ||
2758 | wmb(); | 2768 | wmb(); |
2759 | /* interrupt board to doit right away */ | ||
2760 | writel(CA_MBATT, phba->CAregaddr); | ||
2761 | readl(phba->CAregaddr); /* flush */ | ||
2762 | 2769 | ||
2763 | switch (flag) { | 2770 | switch (flag) { |
2764 | case MBX_NOWAIT: | 2771 | case MBX_NOWAIT: |
2765 | /* Don't wait for it to finish, just return */ | 2772 | /* Set up reference to mailbox command */ |
2766 | psli->mbox_active = pmbox; | 2773 | psli->mbox_active = pmbox; |
2774 | /* Interrupt board to do it */ | ||
2775 | writel(CA_MBATT, phba->CAregaddr); | ||
2776 | readl(phba->CAregaddr); /* flush */ | ||
2777 | /* Don't wait for it to finish, just return */ | ||
2767 | break; | 2778 | break; |
2768 | 2779 | ||
2769 | case MBX_POLL: | 2780 | case MBX_POLL: |
2781 | /* Set up null reference to mailbox command */ | ||
2770 | psli->mbox_active = NULL; | 2782 | psli->mbox_active = NULL; |
2783 | /* Interrupt board to do it */ | ||
2784 | writel(CA_MBATT, phba->CAregaddr); | ||
2785 | readl(phba->CAregaddr); /* flush */ | ||
2786 | |||
2771 | if (psli->sli_flag & LPFC_SLI2_ACTIVE) { | 2787 | if (psli->sli_flag & LPFC_SLI2_ACTIVE) { |
2772 | /* First read mbox status word */ | 2788 | /* First read mbox status word */ |
2773 | word0 = *((volatile uint32_t *)&phba->slim2p->mbx); | 2789 | word0 = *((volatile uint32_t *)&phba->slim2p->mbx); |
@@ -2779,15 +2795,15 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag) | |||
2779 | 2795 | ||
2780 | /* Read the HBA Host Attention Register */ | 2796 | /* Read the HBA Host Attention Register */ |
2781 | ha_copy = readl(phba->HAregaddr); | 2797 | ha_copy = readl(phba->HAregaddr); |
2782 | 2798 | timeout = msecs_to_jiffies(lpfc_mbox_tmo_val(phba, | |
2783 | i = lpfc_mbox_tmo_val(phba, mb->mbxCommand); | 2799 | mb->mbxCommand) * |
2784 | i *= 1000; /* Convert to ms */ | 2800 | 1000) + jiffies; |
2785 | 2801 | i = 0; | |
2786 | /* Wait for command to complete */ | 2802 | /* Wait for command to complete */ |
2787 | while (((word0 & OWN_CHIP) == OWN_CHIP) || | 2803 | while (((word0 & OWN_CHIP) == OWN_CHIP) || |
2788 | (!(ha_copy & HA_MBATT) && | 2804 | (!(ha_copy & HA_MBATT) && |
2789 | (phba->link_state > LPFC_WARM_START))) { | 2805 | (phba->link_state > LPFC_WARM_START))) { |
2790 | if (i-- <= 0) { | 2806 | if (time_after(jiffies, timeout)) { |
2791 | psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; | 2807 | psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; |
2792 | spin_unlock_irqrestore(&phba->hbalock, | 2808 | spin_unlock_irqrestore(&phba->hbalock, |
2793 | drvr_flag); | 2809 | drvr_flag); |
@@ -2800,12 +2816,12 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag) | |||
2800 | && (evtctr != psli->slistat.mbox_event)) | 2816 | && (evtctr != psli->slistat.mbox_event)) |
2801 | break; | 2817 | break; |
2802 | 2818 | ||
2803 | spin_unlock_irqrestore(&phba->hbalock, | 2819 | if (i++ > 10) { |
2804 | drvr_flag); | 2820 | spin_unlock_irqrestore(&phba->hbalock, |
2805 | 2821 | drvr_flag); | |
2806 | msleep(1); | 2822 | msleep(1); |
2807 | 2823 | spin_lock_irqsave(&phba->hbalock, drvr_flag); | |
2808 | spin_lock_irqsave(&phba->hbalock, drvr_flag); | 2824 | } |
2809 | 2825 | ||
2810 | if (psli->sli_flag & LPFC_SLI2_ACTIVE) { | 2826 | if (psli->sli_flag & LPFC_SLI2_ACTIVE) { |
2811 | /* First copy command data */ | 2827 | /* First copy command data */ |
@@ -3065,7 +3081,7 @@ lpfc_sli_async_event_handler(struct lpfc_hba * phba, | |||
3065 | if (evt_code == ASYNC_TEMP_WARN) { | 3081 | if (evt_code == ASYNC_TEMP_WARN) { |
3066 | temp_event_data.event_code = LPFC_THRESHOLD_TEMP; | 3082 | temp_event_data.event_code = LPFC_THRESHOLD_TEMP; |
3067 | lpfc_printf_log(phba, | 3083 | lpfc_printf_log(phba, |
3068 | KERN_WARNING, | 3084 | KERN_ERR, |
3069 | LOG_TEMP, | 3085 | LOG_TEMP, |
3070 | "0347 Adapter is very hot, please take " | 3086 | "0347 Adapter is very hot, please take " |
3071 | "corrective action. temperature : %d Celsius\n", | 3087 | "corrective action. temperature : %d Celsius\n", |
@@ -3074,7 +3090,7 @@ lpfc_sli_async_event_handler(struct lpfc_hba * phba, | |||
3074 | if (evt_code == ASYNC_TEMP_SAFE) { | 3090 | if (evt_code == ASYNC_TEMP_SAFE) { |
3075 | temp_event_data.event_code = LPFC_NORMAL_TEMP; | 3091 | temp_event_data.event_code = LPFC_NORMAL_TEMP; |
3076 | lpfc_printf_log(phba, | 3092 | lpfc_printf_log(phba, |
3077 | KERN_INFO, | 3093 | KERN_ERR, |
3078 | LOG_TEMP, | 3094 | LOG_TEMP, |
3079 | "0340 Adapter temperature is OK now. " | 3095 | "0340 Adapter temperature is OK now. " |
3080 | "temperature : %d Celsius\n", | 3096 | "temperature : %d Celsius\n", |
@@ -4047,7 +4063,6 @@ lpfc_intr_handler(int irq, void *dev_id) | |||
4047 | } | 4063 | } |
4048 | 4064 | ||
4049 | if (work_ha_copy & HA_ERATT) { | 4065 | if (work_ha_copy & HA_ERATT) { |
4050 | phba->link_state = LPFC_HBA_ERROR; | ||
4051 | /* | 4066 | /* |
4052 | * There was a link/board error. Read the | 4067 | * There was a link/board error. Read the |
4053 | * status register to retrieve the error event | 4068 | * status register to retrieve the error event |
@@ -4079,7 +4094,7 @@ lpfc_intr_handler(int irq, void *dev_id) | |||
4079 | * Stray Mailbox Interrupt, mbxCommand <cmd> | 4094 | * Stray Mailbox Interrupt, mbxCommand <cmd> |
4080 | * mbxStatus <status> | 4095 | * mbxStatus <status> |
4081 | */ | 4096 | */ |
4082 | lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX | | 4097 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | |
4083 | LOG_SLI, | 4098 | LOG_SLI, |
4084 | "(%d):0304 Stray Mailbox " | 4099 | "(%d):0304 Stray Mailbox " |
4085 | "Interrupt mbxCommand x%x " | 4100 | "Interrupt mbxCommand x%x " |
@@ -4087,51 +4102,60 @@ lpfc_intr_handler(int irq, void *dev_id) | |||
4087 | (vport ? vport->vpi : 0), | 4102 | (vport ? vport->vpi : 0), |
4088 | pmbox->mbxCommand, | 4103 | pmbox->mbxCommand, |
4089 | pmbox->mbxStatus); | 4104 | pmbox->mbxStatus); |
4090 | } | 4105 | /* clear mailbox attention bit */ |
4091 | phba->last_completion_time = jiffies; | 4106 | work_ha_copy &= ~HA_MBATT; |
4092 | del_timer_sync(&phba->sli.mbox_tmo); | 4107 | } else { |
4093 | 4108 | phba->last_completion_time = jiffies; | |
4094 | phba->sli.mbox_active = NULL; | 4109 | del_timer(&phba->sli.mbox_tmo); |
4095 | if (pmb->mbox_cmpl) { | ||
4096 | lpfc_sli_pcimem_bcopy(mbox, pmbox, | ||
4097 | MAILBOX_CMD_SIZE); | ||
4098 | } | ||
4099 | if (pmb->mbox_flag & LPFC_MBX_IMED_UNREG) { | ||
4100 | pmb->mbox_flag &= ~LPFC_MBX_IMED_UNREG; | ||
4101 | 4110 | ||
4102 | lpfc_debugfs_disc_trc(vport, | 4111 | phba->sli.mbox_active = NULL; |
4103 | LPFC_DISC_TRC_MBOX_VPORT, | 4112 | if (pmb->mbox_cmpl) { |
4104 | "MBOX dflt rpi: : status:x%x rpi:x%x", | 4113 | lpfc_sli_pcimem_bcopy(mbox, pmbox, |
4105 | (uint32_t)pmbox->mbxStatus, | 4114 | MAILBOX_CMD_SIZE); |
4106 | pmbox->un.varWords[0], 0); | 4115 | } |
4107 | 4116 | if (pmb->mbox_flag & LPFC_MBX_IMED_UNREG) { | |
4108 | if ( !pmbox->mbxStatus) { | 4117 | pmb->mbox_flag &= ~LPFC_MBX_IMED_UNREG; |
4109 | mp = (struct lpfc_dmabuf *) | 4118 | |
4110 | (pmb->context1); | 4119 | lpfc_debugfs_disc_trc(vport, |
4111 | ndlp = (struct lpfc_nodelist *) | 4120 | LPFC_DISC_TRC_MBOX_VPORT, |
4112 | pmb->context2; | 4121 | "MBOX dflt rpi: : " |
4113 | 4122 | "status:x%x rpi:x%x", | |
4114 | /* Reg_LOGIN of dflt RPI was successful. | 4123 | (uint32_t)pmbox->mbxStatus, |
4115 | * new lets get rid of the RPI using the | 4124 | pmbox->un.varWords[0], 0); |
4116 | * same mbox buffer. | 4125 | |
4117 | */ | 4126 | if (!pmbox->mbxStatus) { |
4118 | lpfc_unreg_login(phba, vport->vpi, | 4127 | mp = (struct lpfc_dmabuf *) |
4119 | pmbox->un.varWords[0], pmb); | 4128 | (pmb->context1); |
4120 | pmb->mbox_cmpl = lpfc_mbx_cmpl_dflt_rpi; | 4129 | ndlp = (struct lpfc_nodelist *) |
4121 | pmb->context1 = mp; | 4130 | pmb->context2; |
4122 | pmb->context2 = ndlp; | 4131 | |
4123 | pmb->vport = vport; | 4132 | /* Reg_LOGIN of dflt RPI was |
4124 | spin_lock(&phba->hbalock); | 4133 | * successful. new lets get |
4125 | phba->sli.sli_flag &= | 4134 | * rid of the RPI using the |
4126 | ~LPFC_SLI_MBOX_ACTIVE; | 4135 | * same mbox buffer. |
4127 | spin_unlock(&phba->hbalock); | 4136 | */ |
4128 | goto send_current_mbox; | 4137 | lpfc_unreg_login(phba, |
4138 | vport->vpi, | ||
4139 | pmbox->un.varWords[0], | ||
4140 | pmb); | ||
4141 | pmb->mbox_cmpl = | ||
4142 | lpfc_mbx_cmpl_dflt_rpi; | ||
4143 | pmb->context1 = mp; | ||
4144 | pmb->context2 = ndlp; | ||
4145 | pmb->vport = vport; | ||
4146 | spin_lock(&phba->hbalock); | ||
4147 | phba->sli.sli_flag &= | ||
4148 | ~LPFC_SLI_MBOX_ACTIVE; | ||
4149 | spin_unlock(&phba->hbalock); | ||
4150 | goto send_current_mbox; | ||
4151 | } | ||
4129 | } | 4152 | } |
4153 | spin_lock(&phba->pport->work_port_lock); | ||
4154 | phba->pport->work_port_events &= | ||
4155 | ~WORKER_MBOX_TMO; | ||
4156 | spin_unlock(&phba->pport->work_port_lock); | ||
4157 | lpfc_mbox_cmpl_put(phba, pmb); | ||
4130 | } | 4158 | } |
4131 | spin_lock(&phba->pport->work_port_lock); | ||
4132 | phba->pport->work_port_events &= ~WORKER_MBOX_TMO; | ||
4133 | spin_unlock(&phba->pport->work_port_lock); | ||
4134 | lpfc_mbox_cmpl_put(phba, pmb); | ||
4135 | } | 4159 | } |
4136 | if ((work_ha_copy & HA_MBATT) && | 4160 | if ((work_ha_copy & HA_MBATT) && |
4137 | (phba->sli.mbox_active == NULL)) { | 4161 | (phba->sli.mbox_active == NULL)) { |