From 2d8ce8c9d4b25b88eb4aa6bc52492eb7e0ae1dab Mon Sep 17 00:00:00 2001 From: Sreekanth Reddy Date: Mon, 12 Jan 2015 11:38:56 +0530 Subject: [PATCH] mpt2sas, mpt3sas: log exceeded temperature thresholds This patch will log a message when driver receives "Temperature Threshold exceeded" event from any temperature sensor. The message will look similar to like: mpt3sas0: Temperature Threshold flags a b c d exceeded for Sensor: x !!! mpt3sas0: Current Temp In Celsius: y where a b c d are threshold flags 0 1 2 3 Change_set: 1. Get the number of sensor count of this IOC by reading IO Unit page 8 at driver initialization time. 2. Also unmask the Temperature Threshold Event at driver initialization time 3. Whenever a MPI2_EVENT_TEMP_THRESHOLD event is received from the firmware, then print the sensor number, the maximum threshold number it has exceed and the current temperature of this sensor. Signed-off-by: Sreekanth Reddy Reviewed-by: Martin K. Petersen Signed-off-by: Christoph Hellwig --- drivers/scsi/mpt2sas/mpt2sas_base.c | 7 ++++++ drivers/scsi/mpt2sas/mpt2sas_base.h | 6 +++++ drivers/scsi/mpt2sas/mpt2sas_config.c | 36 +++++++++++++++++++++++++++ drivers/scsi/mpt2sas/mpt2sas_scsih.c | 31 +++++++++++++++++++++++ drivers/scsi/mpt3sas/mpt3sas_base.c | 8 ++++++ drivers/scsi/mpt3sas/mpt3sas_base.h | 6 +++++ drivers/scsi/mpt3sas/mpt3sas_config.c | 36 +++++++++++++++++++++++++++ drivers/scsi/mpt3sas/mpt3sas_scsih.c | 31 +++++++++++++++++++++++ 8 files changed, 161 insertions(+) diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c index 3fb01d1883c6..14ebb54fae33 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_base.c +++ b/drivers/scsi/mpt2sas/mpt2sas_base.c @@ -639,6 +639,9 @@ _base_display_event_data(struct MPT2SAS_ADAPTER *ioc, if (!ioc->hide_ir_msg) desc = "Log Entry Added"; break; + case MPI2_EVENT_TEMP_THRESHOLD: + desc = "Temperature Threshold"; + break; } if (!desc) @@ -2338,6 +2341,7 @@ _base_static_config_pages(struct MPT2SAS_ADAPTER *ioc) mpt2sas_config_get_ioc_pg8(ioc, &mpi_reply, &ioc->ioc_pg8); mpt2sas_config_get_iounit_pg0(ioc, &mpi_reply, &ioc->iounit_pg0); mpt2sas_config_get_iounit_pg1(ioc, &mpi_reply, &ioc->iounit_pg1); + mpt2sas_config_get_iounit_pg8(ioc, &mpi_reply, &ioc->iounit_pg8); _base_display_ioc_capabilities(ioc); /* @@ -2355,6 +2359,8 @@ _base_static_config_pages(struct MPT2SAS_ADAPTER *ioc) ioc->iounit_pg1.Flags = cpu_to_le32(iounit_pg1_flags); mpt2sas_config_set_iounit_pg1(ioc, &mpi_reply, &ioc->iounit_pg1); + if (ioc->iounit_pg8.NumSensors) + ioc->temp_sensors_count = ioc->iounit_pg8.NumSensors; } /** @@ -4594,6 +4600,7 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc) _base_unmask_events(ioc, MPI2_EVENT_IR_PHYSICAL_DISK); _base_unmask_events(ioc, MPI2_EVENT_IR_OPERATION_STATUS); _base_unmask_events(ioc, MPI2_EVENT_LOG_ENTRY_ADDED); + _base_unmask_events(ioc, MPI2_EVENT_TEMP_THRESHOLD); r = _base_make_ioc_operational(ioc, CAN_SLEEP); if (r) goto out_free_resources; diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.h b/drivers/scsi/mpt2sas/mpt2sas_base.h index 239f169b0673..8a41a4e99d71 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_base.h +++ b/drivers/scsi/mpt2sas/mpt2sas_base.h @@ -725,6 +725,7 @@ typedef void (*MPT2SAS_FLUSH_RUNNING_CMDS)(struct MPT2SAS_ADAPTER *ioc); * @ioc_pg8: static ioc page 8 * @iounit_pg0: static iounit page 0 * @iounit_pg1: static iounit page 1 + * @iounit_pg8: static iounit page 8 * @sas_hba: sas host object * @sas_expander_list: expander object list * @sas_node_lock: @@ -795,6 +796,7 @@ typedef void (*MPT2SAS_FLUSH_RUNNING_CMDS)(struct MPT2SAS_ADAPTER *ioc); * @reply_post_host_index: head index in the pool where FW completes IO * @delayed_tr_list: target reset link list * @delayed_tr_volume_list: volume target reset link list + * @@temp_sensors_count: flag to carry the number of temperature sensors */ struct MPT2SAS_ADAPTER { struct list_head list; @@ -892,6 +894,7 @@ struct MPT2SAS_ADAPTER { Mpi2IOCPage8_t ioc_pg8; Mpi2IOUnitPage0_t iounit_pg0; Mpi2IOUnitPage1_t iounit_pg1; + Mpi2IOUnitPage8_t iounit_pg8; struct _boot_device req_boot_device; struct _boot_device req_alt_boot_device; @@ -992,6 +995,7 @@ struct MPT2SAS_ADAPTER { struct list_head delayed_tr_list; struct list_head delayed_tr_volume_list; + u8 temp_sensors_count; /* diag buffer support */ u8 *diag_buffer[MPI2_DIAG_BUF_TYPE_COUNT]; @@ -1120,6 +1124,8 @@ int mpt2sas_config_get_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage1_t *config_page); int mpt2sas_config_set_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage1_t *config_page); +int mpt2sas_config_get_iounit_pg8(struct MPT2SAS_ADAPTER *ioc, + Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage8_t *config_page); int mpt2sas_config_get_iounit_pg3(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage3_t *config_page, u16 sz); int mpt2sas_config_get_sas_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t diff --git a/drivers/scsi/mpt2sas/mpt2sas_config.c b/drivers/scsi/mpt2sas/mpt2sas_config.c index c72a2fff5dbb..41a8f84ec8a4 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_config.c +++ b/drivers/scsi/mpt2sas/mpt2sas_config.c @@ -718,6 +718,42 @@ mpt2sas_config_get_iounit_pg3(struct MPT2SAS_ADAPTER *ioc, return r; } +/** + * mpt2sas_config_get_iounit_pg8 - obtain iounit page 8 + * @ioc: per adapter object + * @mpi_reply: reply mf payload returned from firmware + * @config_page: contents of the config page + * Context: sleep. + * + * Returns 0 for success, non-zero for failure. + */ +int +mpt2sas_config_get_iounit_pg8(struct MPT2SAS_ADAPTER *ioc, + Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage8_t *config_page) +{ + Mpi2ConfigRequest_t mpi_request; + int r; + + memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); + mpi_request.Function = MPI2_FUNCTION_CONFIG; + mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; + mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT; + mpi_request.Header.PageNumber = 8; + mpi_request.Header.PageVersion = MPI2_IOUNITPAGE8_PAGEVERSION; + mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE); + r = _config_request(ioc, &mpi_request, mpi_reply, + MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); + if (r) + goto out; + + mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; + r = _config_request(ioc, &mpi_request, mpi_reply, + MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, + sizeof(*config_page)); + out: + return r; +} + /** * mpt2sas_config_get_ioc_pg8 - obtain ioc page 8 * @ioc: per adapter object diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c index 6a1c036a6f3f..7000815277b1 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c +++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c @@ -3646,6 +3646,31 @@ _scsih_check_volume_delete_events(struct MPT2SAS_ADAPTER *ioc, le16_to_cpu(event_data->VolDevHandle)); } +/** + * _scsih_temp_threshold_events - display temperature threshold exceeded events + * @ioc: per adapter object + * @event_data: the temp threshold event data + * Context: interrupt time. + * + * Return nothing. + */ +static void +_scsih_temp_threshold_events(struct MPT2SAS_ADAPTER *ioc, + Mpi2EventDataTemperature_t *event_data) +{ + if (ioc->temp_sensors_count >= event_data->SensorNum) { + printk(MPT2SAS_ERR_FMT "Temperature Threshold flags %s%s%s%s" + " exceeded for Sensor: %d !!!\n", ioc->name, + ((le16_to_cpu(event_data->Status) & 0x1) == 1) ? "0 " : " ", + ((le16_to_cpu(event_data->Status) & 0x2) == 2) ? "1 " : " ", + ((le16_to_cpu(event_data->Status) & 0x4) == 4) ? "2 " : " ", + ((le16_to_cpu(event_data->Status) & 0x8) == 8) ? "3 " : " ", + event_data->SensorNum); + printk(MPT2SAS_ERR_FMT "Current Temp In Celsius: %d\n", + ioc->name, event_data->CurrentTemperature); + } +} + /** * _scsih_flush_running_cmds - completing outstanding commands. * @ioc: per adapter object @@ -7557,6 +7582,12 @@ mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index, case MPI2_EVENT_IR_PHYSICAL_DISK: break; + case MPI2_EVENT_TEMP_THRESHOLD: + _scsih_temp_threshold_events(ioc, + (Mpi2EventDataTemperature_t *) + mpi_reply->EventData); + break; + default: /* ignore the rest */ return; } diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c index b9c27398e206..678e1ff33f1e 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.c +++ b/drivers/scsi/mpt3sas/mpt3sas_base.c @@ -619,6 +619,9 @@ _base_display_event_data(struct MPT3SAS_ADAPTER *ioc, case MPI2_EVENT_LOG_ENTRY_ADDED: desc = "Log Entry Added"; break; + case MPI2_EVENT_TEMP_THRESHOLD: + desc = "Temperature Threshold"; + break; } if (!desc) @@ -2500,6 +2503,7 @@ _base_static_config_pages(struct MPT3SAS_ADAPTER *ioc) mpt3sas_config_get_ioc_pg8(ioc, &mpi_reply, &ioc->ioc_pg8); mpt3sas_config_get_iounit_pg0(ioc, &mpi_reply, &ioc->iounit_pg0); mpt3sas_config_get_iounit_pg1(ioc, &mpi_reply, &ioc->iounit_pg1); + mpt3sas_config_get_iounit_pg8(ioc, &mpi_reply, &ioc->iounit_pg8); _base_display_ioc_capabilities(ioc); /* @@ -2516,6 +2520,9 @@ _base_static_config_pages(struct MPT3SAS_ADAPTER *ioc) MPI2_IOUNITPAGE1_DISABLE_TASK_SET_FULL_HANDLING; ioc->iounit_pg1.Flags = cpu_to_le32(iounit_pg1_flags); mpt3sas_config_set_iounit_pg1(ioc, &mpi_reply, &ioc->iounit_pg1); + + if (ioc->iounit_pg8.NumSensors) + ioc->temp_sensors_count = ioc->iounit_pg8.NumSensors; } /** @@ -4720,6 +4727,7 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc) _base_unmask_events(ioc, MPI2_EVENT_IR_PHYSICAL_DISK); _base_unmask_events(ioc, MPI2_EVENT_IR_OPERATION_STATUS); _base_unmask_events(ioc, MPI2_EVENT_LOG_ENTRY_ADDED); + _base_unmask_events(ioc, MPI2_EVENT_TEMP_THRESHOLD); r = _base_make_ioc_operational(ioc, CAN_SLEEP); if (r) diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h index 40926aa9b24d..4fef8f38cae4 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.h +++ b/drivers/scsi/mpt3sas/mpt3sas_base.h @@ -659,6 +659,7 @@ typedef void (*MPT3SAS_FLUSH_RUNNING_CMDS)(struct MPT3SAS_ADAPTER *ioc); * @ioc_pg8: static ioc page 8 * @iounit_pg0: static iounit page 0 * @iounit_pg1: static iounit page 1 + * @iounit_pg8: static iounit page 8 * @sas_hba: sas host object * @sas_expander_list: expander object list * @sas_node_lock: @@ -728,6 +729,7 @@ typedef void (*MPT3SAS_FLUSH_RUNNING_CMDS)(struct MPT3SAS_ADAPTER *ioc); * @reply_post_host_index: head index in the pool where FW completes IO * @delayed_tr_list: target reset link list * @delayed_tr_volume_list: volume target reset link list + * @@temp_sensors_count: flag to carry the number of temperature sensors */ struct MPT3SAS_ADAPTER { struct list_head list; @@ -834,6 +836,7 @@ struct MPT3SAS_ADAPTER { Mpi2IOCPage8_t ioc_pg8; Mpi2IOUnitPage0_t iounit_pg0; Mpi2IOUnitPage1_t iounit_pg1; + Mpi2IOUnitPage8_t iounit_pg8; struct _boot_device req_boot_device; struct _boot_device req_alt_boot_device; @@ -934,6 +937,7 @@ struct MPT3SAS_ADAPTER { struct list_head delayed_tr_list; struct list_head delayed_tr_volume_list; + u8 temp_sensors_count; /* diag buffer support */ u8 *diag_buffer[MPI2_DIAG_BUF_TYPE_COUNT]; @@ -1082,6 +1086,8 @@ int mpt3sas_config_get_iounit_pg1(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage1_t *config_page); int mpt3sas_config_set_iounit_pg1(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage1_t *config_page); +int mpt3sas_config_get_iounit_pg8(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t + *mpi_reply, Mpi2IOUnitPage8_t *config_page); int mpt3sas_config_get_sas_iounit_pg1(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage1_t *config_page, u16 sz); diff --git a/drivers/scsi/mpt3sas/mpt3sas_config.c b/drivers/scsi/mpt3sas/mpt3sas_config.c index 4472c2af9255..6582193d3ccf 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_config.c +++ b/drivers/scsi/mpt3sas/mpt3sas_config.c @@ -870,6 +870,42 @@ mpt3sas_config_set_iounit_pg1(struct MPT3SAS_ADAPTER *ioc, return r; } +/** + * mpt3sas_config_get_iounit_pg8 - obtain iounit page 8 + * @ioc: per adapter object + * @mpi_reply: reply mf payload returned from firmware + * @config_page: contents of the config page + * Context: sleep. + * + * Returns 0 for success, non-zero for failure. + */ +int +mpt3sas_config_get_iounit_pg8(struct MPT3SAS_ADAPTER *ioc, + Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage8_t *config_page) +{ + Mpi2ConfigRequest_t mpi_request; + int r; + + memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); + mpi_request.Function = MPI2_FUNCTION_CONFIG; + mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; + mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT; + mpi_request.Header.PageNumber = 8; + mpi_request.Header.PageVersion = MPI2_IOUNITPAGE8_PAGEVERSION; + ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); + r = _config_request(ioc, &mpi_request, mpi_reply, + MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); + if (r) + goto out; + + mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; + r = _config_request(ioc, &mpi_request, mpi_reply, + MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, + sizeof(*config_page)); + out: + return r; +} + /** * mpt3sas_config_get_ioc_pg8 - obtain ioc page 8 * @ioc: per adapter object diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c index 94261ee9e72d..c3c0b45df102 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c +++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c @@ -3341,6 +3341,31 @@ _scsih_check_volume_delete_events(struct MPT3SAS_ADAPTER *ioc, le16_to_cpu(event_data->VolDevHandle)); } +/** + * _scsih_temp_threshold_events - display temperature threshold exceeded events + * @ioc: per adapter object + * @event_data: the temp threshold event data + * Context: interrupt time. + * + * Return nothing. + */ +static void +_scsih_temp_threshold_events(struct MPT3SAS_ADAPTER *ioc, + Mpi2EventDataTemperature_t *event_data) +{ + if (ioc->temp_sensors_count >= event_data->SensorNum) { + pr_err(MPT3SAS_FMT "Temperature Threshold flags %s%s%s%s" + " exceeded for Sensor: %d !!!\n", ioc->name, + ((le16_to_cpu(event_data->Status) & 0x1) == 1) ? "0 " : " ", + ((le16_to_cpu(event_data->Status) & 0x2) == 2) ? "1 " : " ", + ((le16_to_cpu(event_data->Status) & 0x4) == 4) ? "2 " : " ", + ((le16_to_cpu(event_data->Status) & 0x8) == 8) ? "3 " : " ", + event_data->SensorNum); + pr_err(MPT3SAS_FMT "Current Temp In Celsius: %d\n", + ioc->name, event_data->CurrentTemperature); + } +} + /** * _scsih_flush_running_cmds - completing outstanding commands. * @ioc: per adapter object @@ -7194,6 +7219,12 @@ mpt3sas_scsih_event_callback(struct MPT3SAS_ADAPTER *ioc, u8 msix_index, case MPI2_EVENT_IR_PHYSICAL_DISK: break; + case MPI2_EVENT_TEMP_THRESHOLD: + _scsih_temp_threshold_events(ioc, + (Mpi2EventDataTemperature_t *) + mpi_reply->EventData); + break; + default: /* ignore the rest */ return 1; } -- 2.39.5