aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/scsi_sysfs.c
diff options
context:
space:
mode:
authorHannes Reinecke <hare@suse.de>2016-03-03 01:54:07 -0500
committerMartin K. Petersen <martin.petersen@oracle.com>2016-03-05 17:14:37 -0500
commit77c9df9644d7c35516770a21cb56b413e8547d8f (patch)
treebb7303df95797e5b6d2b3a6961b079a6725c24e6 /drivers/scsi/scsi_sysfs.c
parent7e47976bcff23cbe011635e8931855cd3fb3aa6f (diff)
scsi: Add 'access_state' and 'preferred_path' attribute
Add an 'access_state' field to struct scsi_device and display them in sysfs as 'access_state' and 'preferred_path' attribute. Signed-off-by: Hannes Reinecke <hare@suse.de> Reviewed-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de> Reviewed-by: Bart van Assche <bart.vanassche@sandisk.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/scsi_sysfs.c')
-rw-r--r--drivers/scsi/scsi_sysfs.c74
1 files changed, 74 insertions, 0 deletions
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index 7e57800684e8..c5ac1719d89d 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -81,6 +81,33 @@ const char *scsi_host_state_name(enum scsi_host_state state)
81 return name; 81 return name;
82} 82}
83 83
84static const struct {
85 unsigned char value;
86 char *name;
87} sdev_access_states[] = {
88 { SCSI_ACCESS_STATE_OPTIMAL, "active/optimized" },
89 { SCSI_ACCESS_STATE_ACTIVE, "active/non-optimized" },
90 { SCSI_ACCESS_STATE_STANDBY, "standby" },
91 { SCSI_ACCESS_STATE_UNAVAILABLE, "unavailable" },
92 { SCSI_ACCESS_STATE_LBA, "lba-dependent" },
93 { SCSI_ACCESS_STATE_OFFLINE, "offline" },
94 { SCSI_ACCESS_STATE_TRANSITIONING, "transitioning" },
95};
96
97const char *scsi_access_state_name(unsigned char state)
98{
99 int i;
100 char *name = NULL;
101
102 for (i = 0; i < ARRAY_SIZE(sdev_access_states); i++) {
103 if (sdev_access_states[i].value == state) {
104 name = sdev_access_states[i].name;
105 break;
106 }
107 }
108 return name;
109}
110
84static int check_set(unsigned long long *val, char *src) 111static int check_set(unsigned long long *val, char *src)
85{ 112{
86 char *last; 113 char *last;
@@ -973,6 +1000,43 @@ sdev_store_dh_state(struct device *dev, struct device_attribute *attr,
973 1000
974static DEVICE_ATTR(dh_state, S_IRUGO | S_IWUSR, sdev_show_dh_state, 1001static DEVICE_ATTR(dh_state, S_IRUGO | S_IWUSR, sdev_show_dh_state,
975 sdev_store_dh_state); 1002 sdev_store_dh_state);
1003
1004static ssize_t
1005sdev_show_access_state(struct device *dev,
1006 struct device_attribute *attr,
1007 char *buf)
1008{
1009 struct scsi_device *sdev = to_scsi_device(dev);
1010 unsigned char access_state;
1011 const char *access_state_name;
1012
1013 if (!sdev->handler)
1014 return -EINVAL;
1015
1016 access_state = (sdev->access_state & SCSI_ACCESS_STATE_MASK);
1017 access_state_name = scsi_access_state_name(access_state);
1018
1019 return sprintf(buf, "%s\n",
1020 access_state_name ? access_state_name : "unknown");
1021}
1022static DEVICE_ATTR(access_state, S_IRUGO, sdev_show_access_state, NULL);
1023
1024static ssize_t
1025sdev_show_preferred_path(struct device *dev,
1026 struct device_attribute *attr,
1027 char *buf)
1028{
1029 struct scsi_device *sdev = to_scsi_device(dev);
1030
1031 if (!sdev->handler)
1032 return -EINVAL;
1033
1034 if (sdev->access_state & SCSI_ACCESS_STATE_PREFERRED)
1035 return sprintf(buf, "1\n");
1036 else
1037 return sprintf(buf, "0\n");
1038}
1039static DEVICE_ATTR(preferred_path, S_IRUGO, sdev_show_preferred_path, NULL);
976#endif 1040#endif
977 1041
978static ssize_t 1042static ssize_t
@@ -1020,6 +1084,14 @@ static umode_t scsi_sdev_attr_is_visible(struct kobject *kobj,
1020 !sdev->host->hostt->change_queue_depth) 1084 !sdev->host->hostt->change_queue_depth)
1021 return 0; 1085 return 0;
1022 1086
1087#ifdef CONFIG_SCSI_DH
1088 if (attr == &dev_attr_access_state.attr &&
1089 !sdev->handler)
1090 return 0;
1091 if (attr == &dev_attr_preferred_path.attr &&
1092 !sdev->handler)
1093 return 0;
1094#endif
1023 return attr->mode; 1095 return attr->mode;
1024} 1096}
1025 1097
@@ -1063,6 +1135,8 @@ static struct attribute *scsi_sdev_attrs[] = {
1063 &dev_attr_wwid.attr, 1135 &dev_attr_wwid.attr,
1064#ifdef CONFIG_SCSI_DH 1136#ifdef CONFIG_SCSI_DH
1065 &dev_attr_dh_state.attr, 1137 &dev_attr_dh_state.attr,
1138 &dev_attr_access_state.attr,
1139 &dev_attr_preferred_path.attr,
1066#endif 1140#endif
1067 &dev_attr_queue_ramp_up_period.attr, 1141 &dev_attr_queue_ramp_up_period.attr,
1068 REF_EVT(media_change), 1142 REF_EVT(media_change),