aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Smart <james.smart@emulex.com>2015-04-07 15:07:09 -0400
committerJames Bottomley <JBottomley@Odin.com>2015-04-10 10:45:03 -0400
commit946727dc073dbac5751f98902c1c73e3b7268218 (patch)
tree220c73d5fb08edd1f173a6fa27d9b7d876213d05
parent77d093fb009c339f9fa15a2865787eb94eee22c6 (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.h1
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c179
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)
1330void 1330void
1331lpfc_sli4_offline_eratt(struct lpfc_hba *phba) 1331lpfc_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 */