diff options
author | Douglas Gilbert <dgilbert@interlog.com> | 2014-11-24 20:27:51 -0500 |
---|---|---|
committer | Christoph Hellwig <hch@lst.de> | 2014-11-25 15:42:56 +0100 |
commit | 0d01c5df5cd470515a88a454ba69126f4b7abdab (patch) | |
tree | 6a09abfc3527fee50ec14cfb28c5a3c9daf2ee2b /drivers/scsi/scsi_debug.c | |
parent | 817fd66beb779dbbe44c46dd11e64d8275efb593 (diff) | |
download | linux-0d01c5df5cd470515a88a454ba69126f4b7abdab.tar.gz linux-0d01c5df5cd470515a88a454ba69126f4b7abdab.tar.bz2 linux-0d01c5df5cd470515a88a454ba69126f4b7abdab.zip |
scsi_debug: add Capacity Changed Unit Attention
Via sysfs the virtual_gb scsi_debug parameter can be changed while
LUs are in use. If that changes, the 'Capacity data has changed'
Unit Attention is queued on all LUs.
Signed-off-by: Douglas Gilbert <dgilbert@interlog.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'drivers/scsi/scsi_debug.c')
-rw-r--r-- | drivers/scsi/scsi_debug.c | 28 |
1 files changed, 24 insertions, 4 deletions
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index d337eaa128d0..ee99aca92bca 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -179,7 +179,8 @@ static const char *scsi_debug_version_date = "20141022"; #define SDEBUG_UA_POR 0 /* Power on, reset, or bus device reset */ #define SDEBUG_UA_BUS_RESET 1 #define SDEBUG_UA_MODE_CHANGED 2 -#define SDEBUG_NUM_UAS 3 +#define SDEBUG_UA_CAPACITY_CHANGED 3 +#define SDEBUG_NUM_UAS 4 /* for check_readiness() */ #define UAS_ONLY 1 @@ -582,6 +583,11 @@ static int check_readiness(struct scsi_cmnd *SCpnt, int uas_only, if (debug) cp = "mode parameters changed"; break; + case SDEBUG_UA_CAPACITY_CHANGED: + mk_sense_buffer(SCpnt, UNIT_ATTENTION, + UA_CHANGED_ASC, CAPACITY_CHANGED_ASCQ); + if (debug) + cp = "capacity data changed"; default: pr_warn("%s: unexpected unit attention code=%d\n", __func__, k); @@ -3638,16 +3644,30 @@ static ssize_t virtual_gb_show(struct device_driver *ddp, char *buf) { return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_virtual_gb); } + static ssize_t virtual_gb_store(struct device_driver *ddp, const char *buf, size_t count) { - int n; + int n; + bool changed; if ((count > 0) && (1 == sscanf(buf, "%d", &n)) && (n >= 0)) { + changed = (scsi_debug_virtual_gb != n); scsi_debug_virtual_gb = n; - sdebug_capacity = get_sdebug_capacity(); - + if (changed) { + struct sdebug_host_info *sdhp; + struct sdebug_dev_info *dp; + + list_for_each_entry(sdhp, &sdebug_host_list, + host_list) { + list_for_each_entry(dp, &sdhp->dev_info_list, + dev_list) { + set_bit(SDEBUG_UA_CAPACITY_CHANGED, + dp->uas_bm); + } + } + } return count; } return -EINVAL; |