aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsreekanth.reddy@lsi.com <sreekanth.reddy@lsi.com>2012-07-17 06:26:07 -0400
committerJames Bottomley <JBottomley@Parallels.com>2012-08-24 05:10:25 -0400
commit6c265660c26267754a02063642ae042d469b4ef9 (patch)
treea6550ee176bf29c9c3f88f48de0c73bbebc56809
parente17eee45102bfd28f357efa119c4ecaf7a17c155 (diff)
[SCSI] mpt2sas: Provide 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 the path /sys/class/scsi_host/host#/BMR_status when reading this adapter attribute, then driver will output the state of GPIO[24]. It returns "0" if BMR is healthy and it returns "1" for failure. if it returns an empty string then it means that there was an error while obtaining the BMR status. Then check dmesg for what error has occured. Signed-off-by: Sreekanth Reddy <sreekanth.reddy@lsi.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_base.h2
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_config.c36
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_ctl.c70
3 files changed, 108 insertions, 0 deletions
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.h b/drivers/scsi/mpt2sas/mpt2sas_base.h
index 2aeb6f974602..3d1a30ab9a41 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_base.h
+++ b/drivers/scsi/mpt2sas/mpt2sas_base.h
@@ -1096,6 +1096,8 @@ int mpt2sas_config_get_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1096 *mpi_reply, Mpi2IOUnitPage1_t *config_page); 1096 *mpi_reply, Mpi2IOUnitPage1_t *config_page);
1097int mpt2sas_config_set_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t 1097int mpt2sas_config_set_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1098 *mpi_reply, Mpi2IOUnitPage1_t *config_page); 1098 *mpi_reply, Mpi2IOUnitPage1_t *config_page);
1099int mpt2sas_config_get_iounit_pg3(struct MPT2SAS_ADAPTER *ioc,
1100 Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage3_t *config_page, u16 sz);
1099int mpt2sas_config_get_sas_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t 1101int mpt2sas_config_get_sas_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1100 *mpi_reply, Mpi2SasIOUnitPage1_t *config_page, u16 sz); 1102 *mpi_reply, Mpi2SasIOUnitPage1_t *config_page, u16 sz);
1101int mpt2sas_config_set_sas_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, 1103int mpt2sas_config_set_sas_iounit_pg1(struct MPT2SAS_ADAPTER *ioc,
diff --git a/drivers/scsi/mpt2sas/mpt2sas_config.c b/drivers/scsi/mpt2sas/mpt2sas_config.c
index 323309b22c8d..863778071a9d 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_config.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_config.c
@@ -683,6 +683,42 @@ mpt2sas_config_set_iounit_pg1(struct MPT2SAS_ADAPTER *ioc,
683} 683}
684 684
685/** 685/**
686 * mpt2sas_config_get_iounit_pg3 - obtain iounit page 3
687 * @ioc: per adapter object
688 * @mpi_reply: reply mf payload returned from firmware
689 * @config_page: contents of the config page
690 * @sz: size of buffer passed in config_page
691 * Context: sleep.
692 *
693 * Returns 0 for success, non-zero for failure.
694 */
695int
696mpt2sas_config_get_iounit_pg3(struct MPT2SAS_ADAPTER *ioc,
697 Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage3_t *config_page, u16 sz)
698{
699 Mpi2ConfigRequest_t mpi_request;
700 int r;
701
702 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
703 mpi_request.Function = MPI2_FUNCTION_CONFIG;
704 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
705 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
706 mpi_request.Header.PageNumber = 3;
707 mpi_request.Header.PageVersion = MPI2_IOUNITPAGE3_PAGEVERSION;
708 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
709 r = _config_request(ioc, &mpi_request, mpi_reply,
710 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
711 if (r)
712 goto out;
713
714 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
715 r = _config_request(ioc, &mpi_request, mpi_reply,
716 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
717 out:
718 return r;
719}
720
721/**
686 * mpt2sas_config_get_ioc_pg8 - obtain ioc page 8 722 * mpt2sas_config_get_ioc_pg8 - obtain ioc page 8
687 * @ioc: per adapter object 723 * @ioc: per adapter object
688 * @mpi_reply: reply mf payload returned from firmware 724 * @mpi_reply: reply mf payload returned from firmware
diff --git a/drivers/scsi/mpt2sas/mpt2sas_ctl.c b/drivers/scsi/mpt2sas/mpt2sas_ctl.c
index 6da4a408358c..64254416a178 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_ctl.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_ctl.c
@@ -2690,6 +2690,75 @@ _ctl_ioc_reply_queue_count_show(struct device *cdev,
2690static DEVICE_ATTR(reply_queue_count, S_IRUGO, 2690static DEVICE_ATTR(reply_queue_count, S_IRUGO,
2691 _ctl_ioc_reply_queue_count_show, NULL); 2691 _ctl_ioc_reply_queue_count_show, NULL);
2692 2692
2693/**
2694 * _ctl_BRM_status_show - Backup Rail Monitor Status
2695 * @cdev - pointer to embedded class device
2696 * @buf - the buffer returned
2697 *
2698 * This is number of reply queues
2699 *
2700 * A sysfs 'read-only' shost attribute.
2701 */
2702static ssize_t
2703_ctl_BRM_status_show(struct device *cdev, struct device_attribute *attr,
2704 char *buf)
2705{
2706 struct Scsi_Host *shost = class_to_shost(cdev);
2707 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
2708 Mpi2IOUnitPage3_t *io_unit_pg3 = NULL;
2709 Mpi2ConfigReply_t mpi_reply;
2710 u16 backup_rail_monitor_status = 0;
2711 u16 ioc_status;
2712 int sz;
2713 ssize_t rc = 0;
2714
2715 if (!ioc->is_warpdrive) {
2716 printk(MPT2SAS_ERR_FMT "%s: BRM attribute is only for"\
2717 "warpdrive\n", ioc->name, __func__);
2718 goto out;
2719 }
2720
2721 /* allocate upto GPIOVal 36 entries */
2722 sz = offsetof(Mpi2IOUnitPage3_t, GPIOVal) + (sizeof(u16) * 36);
2723 io_unit_pg3 = kzalloc(sz, GFP_KERNEL);
2724 if (!io_unit_pg3) {
2725 printk(MPT2SAS_ERR_FMT "%s: failed allocating memory"\
2726 "for iounit_pg3: (%d) bytes\n", ioc->name, __func__, sz);
2727 goto out;
2728 }
2729
2730 if (mpt2sas_config_get_iounit_pg3(ioc, &mpi_reply, io_unit_pg3, sz) !=
2731 0) {
2732 printk(MPT2SAS_ERR_FMT
2733 "%s: failed reading iounit_pg3\n", ioc->name,
2734 __func__);
2735 goto out;
2736 }
2737
2738 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK;
2739 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
2740 printk(MPT2SAS_ERR_FMT "%s: iounit_pg3 failed with"\
2741 "ioc_status(0x%04x)\n", ioc->name, __func__, ioc_status);
2742 goto out;
2743 }
2744
2745 if (io_unit_pg3->GPIOCount < 25) {
2746 printk(MPT2SAS_ERR_FMT "%s: iounit_pg3->GPIOCount less than"\
2747 "25 entries, detected (%d) entries\n", ioc->name, __func__,
2748 io_unit_pg3->GPIOCount);
2749 goto out;
2750 }
2751
2752 /* BRM status is in bit zero of GPIOVal[24] */
2753 backup_rail_monitor_status = le16_to_cpu(io_unit_pg3->GPIOVal[24]);
2754 rc = snprintf(buf, PAGE_SIZE, "%d\n", (backup_rail_monitor_status & 1));
2755
2756 out:
2757 kfree(io_unit_pg3);
2758 return rc;
2759}
2760static DEVICE_ATTR(BRM_status, S_IRUGO, _ctl_BRM_status_show, NULL);
2761
2693struct DIAG_BUFFER_START { 2762struct DIAG_BUFFER_START {
2694 __le32 Size; 2763 __le32 Size;
2695 __le32 DiagVersion; 2764 __le32 DiagVersion;
@@ -2901,6 +2970,7 @@ struct device_attribute *mpt2sas_host_attrs[] = {
2901 &dev_attr_host_trace_buffer, 2970 &dev_attr_host_trace_buffer,
2902 &dev_attr_host_trace_buffer_enable, 2971 &dev_attr_host_trace_buffer_enable,
2903 &dev_attr_reply_queue_count, 2972 &dev_attr_reply_queue_count,
2973 &dev_attr_BRM_status,
2904 NULL, 2974 NULL,
2905}; 2975};
2906 2976