@@ -81,6 +81,33 @@ const char *scsi_host_state_name(enum scsi_host_state state)
81
81
return name ;
82
82
}
83
83
84
+ static 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
+
97
+ const 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
+
84
111
static int check_set (unsigned long long * val , char * src )
85
112
{
86
113
char * last ;
@@ -973,6 +1000,43 @@ sdev_store_dh_state(struct device *dev, struct device_attribute *attr,
973
1000
974
1001
static DEVICE_ATTR (dh_state , S_IRUGO | S_IWUSR , sdev_show_dh_state ,
975
1002
sdev_store_dh_state ) ;
1003
+
1004
+ static ssize_t
1005
+ sdev_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
+ }
1022
+ static DEVICE_ATTR (access_state , S_IRUGO , sdev_show_access_state , NULL) ;
1023
+
1024
+ static ssize_t
1025
+ sdev_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
+ }
1039
+ static DEVICE_ATTR (preferred_path , S_IRUGO , sdev_show_preferred_path , NULL) ;
976
1040
#endif
977
1041
978
1042
static ssize_t
@@ -1020,6 +1084,14 @@ static umode_t scsi_sdev_attr_is_visible(struct kobject *kobj,
1020
1084
!sdev -> host -> hostt -> change_queue_depth )
1021
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
1095
return attr -> mode ;
1024
1096
}
1025
1097
@@ -1063,6 +1135,8 @@ static struct attribute *scsi_sdev_attrs[] = {
1063
1135
& dev_attr_wwid .attr ,
1064
1136
#ifdef CONFIG_SCSI_DH
1065
1137
& dev_attr_dh_state .attr ,
1138
+ & dev_attr_access_state .attr ,
1139
+ & dev_attr_preferred_path .attr ,
1066
1140
#endif
1067
1141
& dev_attr_queue_ramp_up_period .attr ,
1068
1142
REF_EVT (media_change ),
0 commit comments