diff options
author | James Smart <james.smart@emulex.com> | 2015-04-07 15:07:09 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Odin.com> | 2015-04-10 10:45:03 -0400 |
commit | 946727dc073dbac5751f98902c1c73e3b7268218 (patch) | |
tree | 220c73d5fb08edd1f173a6fa27d9b7d876213d05 | |
parent | 77d093fb009c339f9fa15a2865787eb94eee22c6 (diff) |
lpfc: Add Lancer Temperature Event support to the lpfc driver
This will detect and send an async event if overtemp is detected
Signed-off-by: Dick Kennedy <dick.kennedy@emulex.com>
Signed-off-by: James Smart <james.smart@emulex.com>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: James Bottomley <JBottomley@Odin.com>
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hw4.h | 1 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_init.c | 179 |
2 files changed, 125 insertions, 55 deletions
diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h index f432ec180cf8..3121ec454cfa 100644 --- a/drivers/scsi/lpfc/lpfc_hw4.h +++ b/drivers/scsi/lpfc/lpfc_hw4.h | |||
@@ -3244,6 +3244,7 @@ struct lpfc_acqe_sli { | |||
3244 | #define LPFC_SLI_EVENT_TYPE_NVLOG_POST 0x4 | 3244 | #define LPFC_SLI_EVENT_TYPE_NVLOG_POST 0x4 |
3245 | #define LPFC_SLI_EVENT_TYPE_DIAG_DUMP 0x5 | 3245 | #define LPFC_SLI_EVENT_TYPE_DIAG_DUMP 0x5 |
3246 | #define LPFC_SLI_EVENT_TYPE_MISCONFIGURED 0x9 | 3246 | #define LPFC_SLI_EVENT_TYPE_MISCONFIGURED 0x9 |
3247 | #define LPFC_SLI_EVENT_TYPE_REMOTE_DPORT 0xA | ||
3247 | }; | 3248 | }; |
3248 | 3249 | ||
3249 | /* | 3250 | /* |
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 2b5b91040022..4ba91af11678 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
@@ -1330,13 +1330,14 @@ lpfc_offline_eratt(struct lpfc_hba *phba) | |||
1330 | void | 1330 | void |
1331 | lpfc_sli4_offline_eratt(struct lpfc_hba *phba) | 1331 | lpfc_sli4_offline_eratt(struct lpfc_hba *phba) |
1332 | { | 1332 | { |
1333 | spin_lock_irq(&phba->hbalock); | ||
1334 | phba->link_state = LPFC_HBA_ERROR; | ||
1335 | spin_unlock_irq(&phba->hbalock); | ||
1336 | |||
1333 | lpfc_offline_prep(phba, LPFC_MBX_NO_WAIT); | 1337 | lpfc_offline_prep(phba, LPFC_MBX_NO_WAIT); |
1334 | lpfc_offline(phba); | 1338 | lpfc_offline(phba); |
1335 | lpfc_sli4_brdreset(phba); | ||
1336 | lpfc_hba_down_post(phba); | 1339 | lpfc_hba_down_post(phba); |
1337 | lpfc_sli4_post_status_check(phba); | ||
1338 | lpfc_unblock_mgmt_io(phba); | 1340 | lpfc_unblock_mgmt_io(phba); |
1339 | phba->link_state = LPFC_HBA_ERROR; | ||
1340 | } | 1341 | } |
1341 | 1342 | ||
1342 | /** | 1343 | /** |
@@ -1629,6 +1630,7 @@ lpfc_handle_eratt_s4(struct lpfc_hba *phba) | |||
1629 | uint32_t uerrlo_reg, uemasklo_reg; | 1630 | uint32_t uerrlo_reg, uemasklo_reg; |
1630 | uint32_t pci_rd_rc1, pci_rd_rc2; | 1631 | uint32_t pci_rd_rc1, pci_rd_rc2; |
1631 | bool en_rn_msg = true; | 1632 | bool en_rn_msg = true; |
1633 | struct temp_event temp_event_data; | ||
1632 | int rc; | 1634 | int rc; |
1633 | 1635 | ||
1634 | /* If the pci channel is offline, ignore possible errors, since | 1636 | /* If the pci channel is offline, ignore possible errors, since |
@@ -1636,9 +1638,6 @@ lpfc_handle_eratt_s4(struct lpfc_hba *phba) | |||
1636 | */ | 1638 | */ |
1637 | if (pci_channel_offline(phba->pcidev)) | 1639 | if (pci_channel_offline(phba->pcidev)) |
1638 | return; | 1640 | return; |
1639 | /* If resets are disabled then leave the HBA alone and return */ | ||
1640 | if (!phba->cfg_enable_hba_reset) | ||
1641 | return; | ||
1642 | 1641 | ||
1643 | if_type = bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf); | 1642 | if_type = bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf); |
1644 | switch (if_type) { | 1643 | switch (if_type) { |
@@ -1654,6 +1653,7 @@ lpfc_handle_eratt_s4(struct lpfc_hba *phba) | |||
1654 | return; | 1653 | return; |
1655 | lpfc_sli4_offline_eratt(phba); | 1654 | lpfc_sli4_offline_eratt(phba); |
1656 | break; | 1655 | break; |
1656 | |||
1657 | case LPFC_SLI_INTF_IF_TYPE_2: | 1657 | case LPFC_SLI_INTF_IF_TYPE_2: |
1658 | pci_rd_rc1 = lpfc_readl( | 1658 | pci_rd_rc1 = lpfc_readl( |
1659 | phba->sli4_hba.u.if_type2.STATUSregaddr, | 1659 | phba->sli4_hba.u.if_type2.STATUSregaddr, |
@@ -1668,15 +1668,27 @@ lpfc_handle_eratt_s4(struct lpfc_hba *phba) | |||
1668 | reg_err1 = readl(phba->sli4_hba.u.if_type2.ERR1regaddr); | 1668 | reg_err1 = readl(phba->sli4_hba.u.if_type2.ERR1regaddr); |
1669 | reg_err2 = readl(phba->sli4_hba.u.if_type2.ERR2regaddr); | 1669 | reg_err2 = readl(phba->sli4_hba.u.if_type2.ERR2regaddr); |
1670 | if (bf_get(lpfc_sliport_status_oti, &portstat_reg)) { | 1670 | if (bf_get(lpfc_sliport_status_oti, &portstat_reg)) { |
1671 | /* TODO: Register for Overtemp async events. */ | ||
1672 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 1671 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
1673 | "2889 Port Overtemperature event, " | 1672 | "2889 Port Overtemperature event, " |
1674 | "taking port offline\n"); | 1673 | "taking port offline Data: x%x x%x\n", |
1674 | reg_err1, reg_err2); | ||
1675 | |||
1676 | temp_event_data.event_type = FC_REG_TEMPERATURE_EVENT; | ||
1677 | temp_event_data.event_code = LPFC_CRIT_TEMP; | ||
1678 | temp_event_data.data = 0xFFFFFFFF; | ||
1679 | |||
1680 | shost = lpfc_shost_from_vport(phba->pport); | ||
1681 | fc_host_post_vendor_event(shost, fc_get_event_number(), | ||
1682 | sizeof(temp_event_data), | ||
1683 | (char *)&temp_event_data, | ||
1684 | SCSI_NL_VID_TYPE_PCI | ||
1685 | | PCI_VENDOR_ID_EMULEX); | ||
1686 | |||
1675 | spin_lock_irq(&phba->hbalock); | 1687 | spin_lock_irq(&phba->hbalock); |
1676 | phba->over_temp_state = HBA_OVER_TEMP; | 1688 | phba->over_temp_state = HBA_OVER_TEMP; |
1677 | spin_unlock_irq(&phba->hbalock); | 1689 | spin_unlock_irq(&phba->hbalock); |
1678 | lpfc_sli4_offline_eratt(phba); | 1690 | lpfc_sli4_offline_eratt(phba); |
1679 | break; | 1691 | return; |
1680 | } | 1692 | } |
1681 | if (reg_err1 == SLIPORT_ERR1_REG_ERR_CODE_2 && | 1693 | if (reg_err1 == SLIPORT_ERR1_REG_ERR_CODE_2 && |
1682 | reg_err2 == SLIPORT_ERR2_REG_FW_RESTART) { | 1694 | reg_err2 == SLIPORT_ERR2_REG_FW_RESTART) { |
@@ -1693,6 +1705,10 @@ lpfc_handle_eratt_s4(struct lpfc_hba *phba) | |||
1693 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 1705 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
1694 | "3145 Port Down: Provisioning\n"); | 1706 | "3145 Port Down: Provisioning\n"); |
1695 | 1707 | ||
1708 | /* If resets are disabled then leave the HBA alone and return */ | ||
1709 | if (!phba->cfg_enable_hba_reset) | ||
1710 | return; | ||
1711 | |||
1696 | /* Check port status register for function reset */ | 1712 | /* Check port status register for function reset */ |
1697 | rc = lpfc_sli4_port_sta_fn_reset(phba, LPFC_MBX_NO_WAIT, | 1713 | rc = lpfc_sli4_port_sta_fn_reset(phba, LPFC_MBX_NO_WAIT, |
1698 | en_rn_msg); | 1714 | en_rn_msg); |
@@ -4044,18 +4060,21 @@ lpfc_sli4_async_sli_evt(struct lpfc_hba *phba, struct lpfc_acqe_sli *acqe_sli) | |||
4044 | char port_name; | 4060 | char port_name; |
4045 | char message[128]; | 4061 | char message[128]; |
4046 | uint8_t status; | 4062 | uint8_t status; |
4063 | uint8_t evt_type; | ||
4064 | struct temp_event temp_event_data; | ||
4047 | struct lpfc_acqe_misconfigured_event *misconfigured; | 4065 | struct lpfc_acqe_misconfigured_event *misconfigured; |
4066 | struct Scsi_Host *shost; | ||
4067 | |||
4068 | evt_type = bf_get(lpfc_trailer_type, acqe_sli); | ||
4048 | 4069 | ||
4049 | /* special case misconfigured event as it contains data for all ports */ | 4070 | /* Special case Lancer */ |
4050 | if ((bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) != | 4071 | if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) != |
4051 | LPFC_SLI_INTF_IF_TYPE_2) || | 4072 | LPFC_SLI_INTF_IF_TYPE_2) { |
4052 | (bf_get(lpfc_trailer_type, acqe_sli) != | ||
4053 | LPFC_SLI_EVENT_TYPE_MISCONFIGURED)) { | ||
4054 | lpfc_printf_log(phba, KERN_INFO, LOG_SLI, | 4073 | lpfc_printf_log(phba, KERN_INFO, LOG_SLI, |
4055 | "2901 Async SLI event - Event Data1:x%08x Event Data2:" | 4074 | "2901 Async SLI event - Event Data1:x%08x Event Data2:" |
4056 | "x%08x SLI Event Type:%d\n", | 4075 | "x%08x SLI Event Type:%d\n", |
4057 | acqe_sli->event_data1, acqe_sli->event_data2, | 4076 | acqe_sli->event_data1, acqe_sli->event_data2, |
4058 | bf_get(lpfc_trailer_type, acqe_sli)); | 4077 | evt_type); |
4059 | return; | 4078 | return; |
4060 | } | 4079 | } |
4061 | 4080 | ||
@@ -4063,58 +4082,107 @@ lpfc_sli4_async_sli_evt(struct lpfc_hba *phba, struct lpfc_acqe_sli *acqe_sli) | |||
4063 | if (port_name == 0x00) | 4082 | if (port_name == 0x00) |
4064 | port_name = '?'; /* get port name is empty */ | 4083 | port_name = '?'; /* get port name is empty */ |
4065 | 4084 | ||
4066 | misconfigured = (struct lpfc_acqe_misconfigured_event *) | 4085 | switch (evt_type) { |
4086 | case LPFC_SLI_EVENT_TYPE_OVER_TEMP: | ||
4087 | temp_event_data.event_type = FC_REG_TEMPERATURE_EVENT; | ||
4088 | temp_event_data.event_code = LPFC_THRESHOLD_TEMP; | ||
4089 | temp_event_data.data = (uint32_t)acqe_sli->event_data1; | ||
4090 | |||
4091 | lpfc_printf_log(phba, KERN_WARNING, LOG_SLI, | ||
4092 | "3190 Over Temperature:%d Celsius- Port Name %c\n", | ||
4093 | acqe_sli->event_data1, port_name); | ||
4094 | |||
4095 | shost = lpfc_shost_from_vport(phba->pport); | ||
4096 | fc_host_post_vendor_event(shost, fc_get_event_number(), | ||
4097 | sizeof(temp_event_data), | ||
4098 | (char *)&temp_event_data, | ||
4099 | SCSI_NL_VID_TYPE_PCI | ||
4100 | | PCI_VENDOR_ID_EMULEX); | ||
4101 | break; | ||
4102 | case LPFC_SLI_EVENT_TYPE_NORM_TEMP: | ||
4103 | temp_event_data.event_type = FC_REG_TEMPERATURE_EVENT; | ||
4104 | temp_event_data.event_code = LPFC_NORMAL_TEMP; | ||
4105 | temp_event_data.data = (uint32_t)acqe_sli->event_data1; | ||
4106 | |||
4107 | lpfc_printf_log(phba, KERN_INFO, LOG_SLI, | ||
4108 | "3191 Normal Temperature:%d Celsius - Port Name %c\n", | ||
4109 | acqe_sli->event_data1, port_name); | ||
4110 | |||
4111 | shost = lpfc_shost_from_vport(phba->pport); | ||
4112 | fc_host_post_vendor_event(shost, fc_get_event_number(), | ||
4113 | sizeof(temp_event_data), | ||
4114 | (char *)&temp_event_data, | ||
4115 | SCSI_NL_VID_TYPE_PCI | ||
4116 | | PCI_VENDOR_ID_EMULEX); | ||
4117 | break; | ||
4118 | case LPFC_SLI_EVENT_TYPE_MISCONFIGURED: | ||
4119 | misconfigured = (struct lpfc_acqe_misconfigured_event *) | ||
4067 | &acqe_sli->event_data1; | 4120 | &acqe_sli->event_data1; |
4068 | 4121 | ||
4069 | /* fetch the status for this port */ | 4122 | /* fetch the status for this port */ |
4070 | switch (phba->sli4_hba.lnk_info.lnk_no) { | 4123 | switch (phba->sli4_hba.lnk_info.lnk_no) { |
4071 | case LPFC_LINK_NUMBER_0: | 4124 | case LPFC_LINK_NUMBER_0: |
4072 | status = bf_get(lpfc_sli_misconfigured_port0, | 4125 | status = bf_get(lpfc_sli_misconfigured_port0, |
4073 | &misconfigured->theEvent); | 4126 | &misconfigured->theEvent); |
4074 | break; | 4127 | break; |
4075 | case LPFC_LINK_NUMBER_1: | 4128 | case LPFC_LINK_NUMBER_1: |
4076 | status = bf_get(lpfc_sli_misconfigured_port1, | 4129 | status = bf_get(lpfc_sli_misconfigured_port1, |
4077 | &misconfigured->theEvent); | 4130 | &misconfigured->theEvent); |
4078 | break; | 4131 | break; |
4079 | case LPFC_LINK_NUMBER_2: | 4132 | case LPFC_LINK_NUMBER_2: |
4080 | status = bf_get(lpfc_sli_misconfigured_port2, | 4133 | status = bf_get(lpfc_sli_misconfigured_port2, |
4081 | &misconfigured->theEvent); | 4134 | &misconfigured->theEvent); |
4082 | break; | 4135 | break; |
4083 | case LPFC_LINK_NUMBER_3: | 4136 | case LPFC_LINK_NUMBER_3: |
4084 | status = bf_get(lpfc_sli_misconfigured_port3, | 4137 | status = bf_get(lpfc_sli_misconfigured_port3, |
4085 | &misconfigured->theEvent); | 4138 | &misconfigured->theEvent); |
4086 | break; | 4139 | break; |
4087 | default: | 4140 | default: |
4088 | status = ~LPFC_SLI_EVENT_STATUS_VALID; | 4141 | status = ~LPFC_SLI_EVENT_STATUS_VALID; |
4089 | break; | 4142 | break; |
4090 | } | 4143 | } |
4091 | 4144 | ||
4092 | switch (status) { | 4145 | switch (status) { |
4093 | case LPFC_SLI_EVENT_STATUS_VALID: | 4146 | case LPFC_SLI_EVENT_STATUS_VALID: |
4094 | return; /* no message if the sfp is okay */ | 4147 | return; /* no message if the sfp is okay */ |
4095 | case LPFC_SLI_EVENT_STATUS_NOT_PRESENT: | 4148 | case LPFC_SLI_EVENT_STATUS_NOT_PRESENT: |
4096 | sprintf(message, "Optics faulted/incorrectly installed/not " \ | 4149 | sprintf(message, "Optics faulted/incorrectly " |
4097 | "installed - Reseat optics, if issue not " | 4150 | "installed/not installed - Reseat optics, " |
4098 | "resolved, replace."); | 4151 | "if issue not resolved, replace."); |
4099 | break; | 4152 | break; |
4100 | case LPFC_SLI_EVENT_STATUS_WRONG_TYPE: | 4153 | case LPFC_SLI_EVENT_STATUS_WRONG_TYPE: |
4101 | sprintf(message, | 4154 | sprintf(message, |
4102 | "Optics of two types installed - Remove one optic or " \ | 4155 | "Optics of two types installed - Remove one " |
4103 | "install matching pair of optics."); | 4156 | "optic or install matching pair of optics."); |
4104 | break; | 4157 | break; |
4105 | case LPFC_SLI_EVENT_STATUS_UNSUPPORTED: | 4158 | case LPFC_SLI_EVENT_STATUS_UNSUPPORTED: |
4106 | sprintf(message, "Incompatible optics - Replace with " \ | 4159 | sprintf(message, "Incompatible optics - Replace with " |
4107 | "compatible optics for card to function."); | 4160 | "compatible optics for card to function."); |
4161 | break; | ||
4162 | default: | ||
4163 | /* firmware is reporting a status we don't know about */ | ||
4164 | sprintf(message, "Unknown event status x%02x", status); | ||
4165 | break; | ||
4166 | } | ||
4167 | |||
4168 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, | ||
4169 | "3176 Misconfigured Physical Port - " | ||
4170 | "Port Name %c %s\n", port_name, message); | ||
4171 | break; | ||
4172 | case LPFC_SLI_EVENT_TYPE_REMOTE_DPORT: | ||
4173 | lpfc_printf_log(phba, KERN_INFO, LOG_SLI, | ||
4174 | "3192 Remote DPort Test Initiated - " | ||
4175 | "Event Data1:x%08x Event Data2: x%08x\n", | ||
4176 | acqe_sli->event_data1, acqe_sli->event_data2); | ||
4108 | break; | 4177 | break; |
4109 | default: | 4178 | default: |
4110 | /* firmware is reporting a status we don't know about */ | 4179 | lpfc_printf_log(phba, KERN_INFO, LOG_SLI, |
4111 | sprintf(message, "Unknown event status x%02x", status); | 4180 | "3193 Async SLI event - Event Data1:x%08x Event Data2:" |
4181 | "x%08x SLI Event Type:%d\n", | ||
4182 | acqe_sli->event_data1, acqe_sli->event_data2, | ||
4183 | evt_type); | ||
4112 | break; | 4184 | break; |
4113 | } | 4185 | } |
4114 | |||
4115 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, | ||
4116 | "3176 Misconfigured Physical Port - " | ||
4117 | "Port Name %c %s\n", port_name, message); | ||
4118 | } | 4186 | } |
4119 | 4187 | ||
4120 | /** | 4188 | /** |
@@ -5183,6 +5251,7 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) | |||
5183 | rc = lpfc_pci_function_reset(phba); | 5251 | rc = lpfc_pci_function_reset(phba); |
5184 | if (unlikely(rc)) | 5252 | if (unlikely(rc)) |
5185 | return -ENODEV; | 5253 | return -ENODEV; |
5254 | phba->temp_sensor_support = 1; | ||
5186 | } | 5255 | } |
5187 | 5256 | ||
5188 | /* Create the bootstrap mailbox command */ | 5257 | /* Create the bootstrap mailbox command */ |