Commit 2944369144548432f3a5ffce7a2926bfb4ce4f0a
Committed by
James Bottomley
1 parent
6085491c34
Exists in
master
and in
20 other branches
[SCSI] scsi: Added support for adapter and firmware reset
Added new sysfs attr 'host_reset' in scsi_sysfs.c to perform adapter or firmware reset as suggested by Mike Christie here: http://marc.info/?l=linux-scsi&m=127359347111167&w=2 user/application can write "adapter" or "firmware" on this attr and it will call newly added function hook in scsi_host_template to call LDD adapter or firmware reset implementation. Signed-off-by: Vikas Chaudhary <vikas.chaudhary@qlogic.com> Reviewed-by: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Showing 2 changed files with 51 additions and 0 deletions Side-by-side Diff
drivers/scsi/scsi_sysfs.c
... | ... | @@ -246,6 +246,43 @@ |
246 | 246 | |
247 | 247 | static DEVICE_ATTR(active_mode, S_IRUGO | S_IWUSR, show_shost_active_mode, NULL); |
248 | 248 | |
249 | +static int check_reset_type(char *str) | |
250 | +{ | |
251 | + if (strncmp(str, "adapter", 10) == 0) | |
252 | + return SCSI_ADAPTER_RESET; | |
253 | + else if (strncmp(str, "firmware", 10) == 0) | |
254 | + return SCSI_FIRMWARE_RESET; | |
255 | + else | |
256 | + return 0; | |
257 | +} | |
258 | + | |
259 | +static ssize_t | |
260 | +store_host_reset(struct device *dev, struct device_attribute *attr, | |
261 | + const char *buf, size_t count) | |
262 | +{ | |
263 | + struct Scsi_Host *shost = class_to_shost(dev); | |
264 | + struct scsi_host_template *sht = shost->hostt; | |
265 | + int ret = -EINVAL; | |
266 | + char str[10]; | |
267 | + int type; | |
268 | + | |
269 | + sscanf(buf, "%s", str); | |
270 | + type = check_reset_type(str); | |
271 | + | |
272 | + if (!type) | |
273 | + goto exit_store_host_reset; | |
274 | + | |
275 | + if (sht->host_reset) | |
276 | + ret = sht->host_reset(shost, type); | |
277 | + | |
278 | +exit_store_host_reset: | |
279 | + if (ret == 0) | |
280 | + ret = count; | |
281 | + return ret; | |
282 | +} | |
283 | + | |
284 | +static DEVICE_ATTR(host_reset, S_IWUSR, NULL, store_host_reset); | |
285 | + | |
249 | 286 | shost_rd_attr(unique_id, "%u\n"); |
250 | 287 | shost_rd_attr(host_busy, "%hu\n"); |
251 | 288 | shost_rd_attr(cmd_per_lun, "%hd\n"); |
... | ... | @@ -272,6 +309,7 @@ |
272 | 309 | &dev_attr_active_mode.attr, |
273 | 310 | &dev_attr_prot_capabilities.attr, |
274 | 311 | &dev_attr_prot_guard_type.attr, |
312 | + &dev_attr_host_reset.attr, | |
275 | 313 | NULL |
276 | 314 | }; |
277 | 315 |
include/scsi/scsi_host.h
... | ... | @@ -355,6 +355,19 @@ |
355 | 355 | */ |
356 | 356 | enum blk_eh_timer_return (*eh_timed_out)(struct scsi_cmnd *); |
357 | 357 | |
358 | + /* This is an optional routine that allows transport to initiate | |
359 | + * LLD adapter or firmware reset using sysfs attribute. | |
360 | + * | |
361 | + * Return values: 0 on success, -ve value on failure. | |
362 | + * | |
363 | + * Status: OPTIONAL | |
364 | + */ | |
365 | + | |
366 | + int (*host_reset)(struct Scsi_Host *shost, int reset_type); | |
367 | +#define SCSI_ADAPTER_RESET 1 | |
368 | +#define SCSI_FIRMWARE_RESET 2 | |
369 | + | |
370 | + | |
358 | 371 | /* |
359 | 372 | * Name of proc directory |
360 | 373 | */ |