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 | ||
