aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSreekanth Reddy <sreekanth.reddy@avagotech.com>2015-11-11 07:00:29 -0500
committerMartin K. Petersen <martin.petersen@oracle.com>2015-11-11 18:56:21 -0500
commit422630955ea34841a2a074cb6734ec5d70758b0d (patch)
treed8a46831c5d2ececaa1ede81e0dabf423e8f1a78
parent7786ab6aff9cea97eb0a8d67705c68e97a664bf3 (diff)
mpt3sas: sysfs attribute to report Backup Rail Monitor Status
A new sysfs shost attribute called "BMR_status" is implemented to report Backup Rail Monitor status. This attribute is located in: /sys/class/scsi_host/host#/BMR_status When reading this adapter attribute, the driver will output the state of GPIO[24]. It returns "0" if BMR is healthy and "1" for failure. If it returns an empty string then it means that there was an error while obtaining the BMR status. Check dmesg for what error has occurred. This sysfs shost attribute is mainly for WarpDrive controllers. This commit is a port of 6c265660c262 ("mpt2sas: Provide sysfs attribute to report Backup Rail Monitor Status"). Signed-off-by: Sreekanth Reddy <Sreekanth.Reddy@avagotech.com> Acked-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Hannes Reinecke <hare@suse.de> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-rw-r--r--drivers/scsi/mpt3sas/mpt3sas_base.h4
-rw-r--r--drivers/scsi/mpt3sas/mpt3sas_config.c38
-rw-r--r--drivers/scsi/mpt3sas/mpt3sas_ctl.c74
3 files changed, 116 insertions, 0 deletions
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h
index 397f8a5e51b8..3b4aaa1a05a1 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -1224,6 +1224,10 @@ int mpt3sas_config_get_sas_iounit_pg0(struct MPT3SAS_ADAPTER *ioc,
1224 u16 sz); 1224 u16 sz);
1225int mpt3sas_config_get_iounit_pg1(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t 1225int mpt3sas_config_get_iounit_pg1(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1226 *mpi_reply, Mpi2IOUnitPage1_t *config_page); 1226 *mpi_reply, Mpi2IOUnitPage1_t *config_page);
1227#ifdef SCSI_MPT2SAS
1228int mpt3sas_config_get_iounit_pg3(struct MPT3SAS_ADAPTER *ioc,
1229 Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage3_t *config_page, u16 sz);
1230#endif
1227int mpt3sas_config_set_iounit_pg1(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t 1231int mpt3sas_config_set_iounit_pg1(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1228 *mpi_reply, Mpi2IOUnitPage1_t *config_page); 1232 *mpi_reply, Mpi2IOUnitPage1_t *config_page);
1229int mpt3sas_config_get_iounit_pg8(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t 1233int mpt3sas_config_get_iounit_pg8(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
diff --git a/drivers/scsi/mpt3sas/mpt3sas_config.c b/drivers/scsi/mpt3sas/mpt3sas_config.c
index 53eb70130621..2bbb0346b462 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_config.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_config.c
@@ -865,6 +865,44 @@ mpt3sas_config_set_iounit_pg1(struct MPT3SAS_ADAPTER *ioc,
865 return r; 865 return r;
866} 866}
867 867
868#ifdef SCSI_MPT2SAS
869/**
870 * mpt3sas_config_get_iounit_pg3 - obtain iounit page 3
871 * @ioc: per adapter object
872 * @mpi_reply: reply mf payload returned from firmware
873 * @config_page: contents of the config page
874 * @sz: size of buffer passed in config_page
875 * Context: sleep.
876 *
877 * Returns 0 for success, non-zero for failure.
878 */
879int
880mpt3sas_config_get_iounit_pg3(struct MPT3SAS_ADAPTER *ioc,
881 Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage3_t *config_page, u16 sz)
882{
883 Mpi2ConfigRequest_t mpi_request;
884 int r;
885
886 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
887 mpi_request.Function = MPI2_FUNCTION_CONFIG;
888 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
889 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
890 mpi_request.Header.PageNumber = 3;
891 mpi_request.Header.PageVersion = MPI2_IOUNITPAGE3_PAGEVERSION;
892 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
893 r = _config_request(ioc, &mpi_request, mpi_reply,
894 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
895 if (r)
896 goto out;
897
898 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
899 r = _config_request(ioc, &mpi_request, mpi_reply,
900 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
901 out:
902 return r;
903}
904#endif
905
868/** 906/**
869 * mpt3sas_config_get_iounit_pg8 - obtain iounit page 8 907 * mpt3sas_config_get_iounit_pg8 - obtain iounit page 8
870 * @ioc: per adapter object 908 * @ioc: per adapter object
diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c b/drivers/scsi/mpt3sas/mpt3sas_ctl.c
index 3f22754adb4f..1c62db8d80c7 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c
@@ -2720,6 +2720,77 @@ _ctl_ioc_reply_queue_count_show(struct device *cdev,
2720static DEVICE_ATTR(reply_queue_count, S_IRUGO, _ctl_ioc_reply_queue_count_show, 2720static DEVICE_ATTR(reply_queue_count, S_IRUGO, _ctl_ioc_reply_queue_count_show,
2721 NULL); 2721 NULL);
2722 2722
2723#ifdef SCSI_MPT2SAS
2724/**
2725 * _ctl_BRM_status_show - Backup Rail Monitor Status
2726 * @cdev - pointer to embedded class device
2727 * @buf - the buffer returned
2728 *
2729 * This is number of reply queues
2730 *
2731 * A sysfs 'read-only' shost attribute.
2732 */
2733static ssize_t
2734_ctl_BRM_status_show(struct device *cdev, struct device_attribute *attr,
2735 char *buf)
2736{
2737 struct Scsi_Host *shost = class_to_shost(cdev);
2738 struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);
2739 Mpi2IOUnitPage3_t *io_unit_pg3 = NULL;
2740 Mpi2ConfigReply_t mpi_reply;
2741 u16 backup_rail_monitor_status = 0;
2742 u16 ioc_status;
2743 int sz;
2744 ssize_t rc = 0;
2745
2746 if (!ioc->is_warpdrive) {
2747 pr_err(MPT3SAS_FMT "%s: BRM attribute is only for"
2748 " warpdrive\n", ioc->name, __func__);
2749 goto out;
2750 }
2751
2752 /* allocate upto GPIOVal 36 entries */
2753 sz = offsetof(Mpi2IOUnitPage3_t, GPIOVal) + (sizeof(u16) * 36);
2754 io_unit_pg3 = kzalloc(sz, GFP_KERNEL);
2755 if (!io_unit_pg3) {
2756 pr_err(MPT3SAS_FMT "%s: failed allocating memory "
2757 "for iounit_pg3: (%d) bytes\n", ioc->name, __func__, sz);
2758 goto out;
2759 }
2760
2761 if (mpt3sas_config_get_iounit_pg3(ioc, &mpi_reply, io_unit_pg3, sz) !=
2762 0) {
2763 pr_err(MPT3SAS_FMT
2764 "%s: failed reading iounit_pg3\n", ioc->name,
2765 __func__);
2766 goto out;
2767 }
2768
2769 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK;
2770 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
2771 pr_err(MPT3SAS_FMT "%s: iounit_pg3 failed with "
2772 "ioc_status(0x%04x)\n", ioc->name, __func__, ioc_status);
2773 goto out;
2774 }
2775
2776 if (io_unit_pg3->GPIOCount < 25) {
2777 pr_err(MPT3SAS_FMT "%s: iounit_pg3->GPIOCount less than "
2778 "25 entries, detected (%d) entries\n", ioc->name, __func__,
2779 io_unit_pg3->GPIOCount);
2780 goto out;
2781 }
2782
2783 /* BRM status is in bit zero of GPIOVal[24] */
2784 backup_rail_monitor_status = le16_to_cpu(io_unit_pg3->GPIOVal[24]);
2785 rc = snprintf(buf, PAGE_SIZE, "%d\n", (backup_rail_monitor_status & 1));
2786
2787 out:
2788 kfree(io_unit_pg3);
2789 return rc;
2790}
2791static DEVICE_ATTR(BRM_status, S_IRUGO, _ctl_BRM_status_show, NULL);
2792#endif
2793
2723struct DIAG_BUFFER_START { 2794struct DIAG_BUFFER_START {
2724 __le32 Size; 2795 __le32 Size;
2725 __le32 DiagVersion; 2796 __le32 DiagVersion;
@@ -3172,6 +3243,9 @@ struct device_attribute *mpt3sas_host_attrs[] = {
3172 &dev_attr_diag_trigger_event, 3243 &dev_attr_diag_trigger_event,
3173 &dev_attr_diag_trigger_scsi, 3244 &dev_attr_diag_trigger_scsi,
3174 &dev_attr_diag_trigger_mpi, 3245 &dev_attr_diag_trigger_mpi,
3246#ifdef SCSI_MPT2SAS
3247 &dev_attr_BRM_status,
3248#endif
3175 NULL, 3249 NULL,
3176}; 3250};
3177 3251