summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/mpt2sas/mpt2sas_ctl.c
diff options
context:
space:
mode:
authorsreekanth.reddy@lsi.com <sreekanth.reddy@lsi.com>2012-07-17 15:56:07 +0530
committerJames Bottomley <JBottomley@Parallels.com>2012-08-24 13:10:25 +0400
commit6c265660c26267754a02063642ae042d469b4ef9 (patch)
treea6550ee176bf29c9c3f88f48de0c73bbebc56809 /drivers/scsi/mpt2sas/mpt2sas_ctl.c
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>
Diffstat (limited to 'drivers/scsi/mpt2sas/mpt2sas_ctl.c')
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_ctl.c70
1 files changed, 70 insertions, 0 deletions
diff --git a/drivers/scsi/mpt2sas/mpt2sas_ctl.c b/drivers/scsi/mpt2sas/mpt2sas_ctl.c
index 6da4a408358..64254416a17 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,
static DEVICE_ATTR(reply_queue_count, S_IRUGO,
_ctl_ioc_reply_queue_count_show, NULL);
+/**
+ * _ctl_BRM_status_show - Backup Rail Monitor Status
+ * @cdev - pointer to embedded class device
+ * @buf - the buffer returned
+ *
+ * This is number of reply queues
+ *
+ * A sysfs 'read-only' shost attribute.
+ */
+static ssize_t
+_ctl_BRM_status_show(struct device *cdev, struct device_attribute *attr,
+ char *buf)
+{
+ struct Scsi_Host *shost = class_to_shost(cdev);
+ struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
+ Mpi2IOUnitPage3_t *io_unit_pg3 = NULL;
+ Mpi2ConfigReply_t mpi_reply;
+ u16 backup_rail_monitor_status = 0;
+ u16 ioc_status;
+ int sz;
+ ssize_t rc = 0;
+
+ if (!ioc->is_warpdrive) {
+ printk(MPT2SAS_ERR_FMT "%s: BRM attribute is only for"\
+ "warpdrive\n", ioc->name, __func__);
+ goto out;
+ }
+
+ /* allocate upto GPIOVal 36 entries */
+ sz = offsetof(Mpi2IOUnitPage3_t, GPIOVal) + (sizeof(u16) * 36);
+ io_unit_pg3 = kzalloc(sz, GFP_KERNEL);
+ if (!io_unit_pg3) {
+ printk(MPT2SAS_ERR_FMT "%s: failed allocating memory"\
+ "for iounit_pg3: (%d) bytes\n", ioc->name, __func__, sz);
+ goto out;
+ }
+
+ if (mpt2sas_config_get_iounit_pg3(ioc, &mpi_reply, io_unit_pg3, sz) !=
+ 0) {
+ printk(MPT2SAS_ERR_FMT
+ "%s: failed reading iounit_pg3\n", ioc->name,
+ __func__);
+ goto out;
+ }
+
+ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK;
+ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
+ printk(MPT2SAS_ERR_FMT "%s: iounit_pg3 failed with"\
+ "ioc_status(0x%04x)\n", ioc->name, __func__, ioc_status);
+ goto out;
+ }
+
+ if (io_unit_pg3->GPIOCount < 25) {
+ printk(MPT2SAS_ERR_FMT "%s: iounit_pg3->GPIOCount less than"\
+ "25 entries, detected (%d) entries\n", ioc->name, __func__,
+ io_unit_pg3->GPIOCount);
+ goto out;
+ }
+
+ /* BRM status is in bit zero of GPIOVal[24] */
+ backup_rail_monitor_status = le16_to_cpu(io_unit_pg3->GPIOVal[24]);
+ rc = snprintf(buf, PAGE_SIZE, "%d\n", (backup_rail_monitor_status & 1));
+
+ out:
+ kfree(io_unit_pg3);
+ return rc;
+}
+static DEVICE_ATTR(BRM_status, S_IRUGO, _ctl_BRM_status_show, NULL);
+
struct DIAG_BUFFER_START {
__le32 Size;
__le32 DiagVersion;
@@ -2901,6 +2970,7 @@ struct device_attribute *mpt2sas_host_attrs[] = {
&dev_attr_host_trace_buffer,
&dev_attr_host_trace_buffer_enable,
&dev_attr_reply_queue_count,
+ &dev_attr_BRM_status,
NULL,
};