diff options
Diffstat (limited to 'drivers/scsi/scsi_sysfs.c')
-rw-r--r-- | drivers/scsi/scsi_sysfs.c | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index beed7fbe1cbe..dae59d1da07a 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c | |||
@@ -48,6 +48,30 @@ const char *scsi_device_state_name(enum scsi_device_state state) | |||
48 | return name; | 48 | return name; |
49 | } | 49 | } |
50 | 50 | ||
51 | static struct { | ||
52 | enum scsi_host_state value; | ||
53 | char *name; | ||
54 | } shost_states[] = { | ||
55 | { SHOST_CREATED, "created" }, | ||
56 | { SHOST_RUNNING, "running" }, | ||
57 | { SHOST_CANCEL, "cancel" }, | ||
58 | { SHOST_DEL, "deleted" }, | ||
59 | { SHOST_RECOVERY, "recovery" }, | ||
60 | }; | ||
61 | const char *scsi_host_state_name(enum scsi_host_state state) | ||
62 | { | ||
63 | int i; | ||
64 | char *name = NULL; | ||
65 | |||
66 | for (i = 0; i < sizeof(shost_states)/sizeof(shost_states[0]); i++) { | ||
67 | if (shost_states[i].value == state) { | ||
68 | name = shost_states[i].name; | ||
69 | break; | ||
70 | } | ||
71 | } | ||
72 | return name; | ||
73 | } | ||
74 | |||
51 | static int check_set(unsigned int *val, char *src) | 75 | static int check_set(unsigned int *val, char *src) |
52 | { | 76 | { |
53 | char *last; | 77 | char *last; |
@@ -124,6 +148,43 @@ static ssize_t store_scan(struct class_device *class_dev, const char *buf, | |||
124 | }; | 148 | }; |
125 | static CLASS_DEVICE_ATTR(scan, S_IWUSR, NULL, store_scan); | 149 | static CLASS_DEVICE_ATTR(scan, S_IWUSR, NULL, store_scan); |
126 | 150 | ||
151 | static ssize_t | ||
152 | store_shost_state(struct class_device *class_dev, const char *buf, size_t count) | ||
153 | { | ||
154 | int i; | ||
155 | struct Scsi_Host *shost = class_to_shost(class_dev); | ||
156 | enum scsi_host_state state = 0; | ||
157 | |||
158 | for (i = 0; i < sizeof(shost_states)/sizeof(shost_states[0]); i++) { | ||
159 | const int len = strlen(shost_states[i].name); | ||
160 | if (strncmp(shost_states[i].name, buf, len) == 0 && | ||
161 | buf[len] == '\n') { | ||
162 | state = shost_states[i].value; | ||
163 | break; | ||
164 | } | ||
165 | } | ||
166 | if (!state) | ||
167 | return -EINVAL; | ||
168 | |||
169 | if (scsi_host_set_state(shost, state)) | ||
170 | return -EINVAL; | ||
171 | return count; | ||
172 | } | ||
173 | |||
174 | static ssize_t | ||
175 | show_shost_state(struct class_device *class_dev, char *buf) | ||
176 | { | ||
177 | struct Scsi_Host *shost = class_to_shost(class_dev); | ||
178 | const char *name = scsi_host_state_name(shost->shost_state); | ||
179 | |||
180 | if (!name) | ||
181 | return -EINVAL; | ||
182 | |||
183 | return snprintf(buf, 20, "%s\n", name); | ||
184 | } | ||
185 | |||
186 | static CLASS_DEVICE_ATTR(state, S_IRUGO | S_IWUSR, show_shost_state, store_shost_state); | ||
187 | |||
127 | shost_rd_attr(unique_id, "%u\n"); | 188 | shost_rd_attr(unique_id, "%u\n"); |
128 | shost_rd_attr(host_busy, "%hu\n"); | 189 | shost_rd_attr(host_busy, "%hu\n"); |
129 | shost_rd_attr(cmd_per_lun, "%hd\n"); | 190 | shost_rd_attr(cmd_per_lun, "%hd\n"); |
@@ -139,6 +200,7 @@ static struct class_device_attribute *scsi_sysfs_shost_attrs[] = { | |||
139 | &class_device_attr_unchecked_isa_dma, | 200 | &class_device_attr_unchecked_isa_dma, |
140 | &class_device_attr_proc_name, | 201 | &class_device_attr_proc_name, |
141 | &class_device_attr_scan, | 202 | &class_device_attr_scan, |
203 | &class_device_attr_state, | ||
142 | NULL | 204 | NULL |
143 | }; | 205 | }; |
144 | 206 | ||