Commit 2944369144548432f3a5ffce7a2926bfb4ce4f0a

Authored by Vikas Chaudhary
Committed by James Bottomley
1 parent 6085491c34

[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 */