aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_sli.c
diff options
context:
space:
mode:
authorJames Smart <James.Smart@Emulex.Com>2008-01-11 01:52:54 -0500
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-01-23 12:29:22 -0500
commit0937282036d9ae798e02c9c69a8b2ef044048855 (patch)
tree55c8ef65c9c55e74e8985b58396516b3d3b925ad /drivers/scsi/lpfc/lpfc_sli.c
parent13815c8344a238c204e4f4339b22dc4833c6df0f (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.c156
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)) {