From: "Ewan D. Milne" <emilne@xxxxxxxxxx> Added capability to scsi_debug to generate sense and Unit Attention conditions to exercise the enhanced sense and Unit Attention handling. Signed-off-by: Ewan D. Milne <emilne@xxxxxxxxxx> --- drivers/scsi/scsi_debug.c | 138 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 138 insertions(+) diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 182d5a5..1d8c2bb 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -230,6 +230,7 @@ struct sdebug_dev_info { char reset; char stopped; char used; + char sense_pending; }; struct sdebug_host_info { @@ -3050,10 +3051,27 @@ static ssize_t sdebug_max_luns_store(struct device_driver * ddp, const char * buf, size_t count) { int n; +#ifdef CONFIG_SCSI_ENHANCED_UA + struct sdebug_host_info *sdbg_host; + struct sdebug_dev_info *devip; +#endif if ((count > 0) && (1 == sscanf(buf, "%d", &n)) && (n >= 0)) { scsi_debug_max_luns = n; sdebug_max_tgts_luns(); + +#ifdef CONFIG_SCSI_ENHANCED_UA + spin_lock(&sdebug_host_list_lock); + list_for_each_entry(sdbg_host, &sdebug_host_list, host_list) { + list_for_each_entry(devip, &sdbg_host->dev_info_list, + dev_list) { + mk_sense_buffer(devip, UNIT_ATTENTION, + 0x3f, 0x0e); + devip->sense_pending = 1; + } + } + spin_unlock(&sdebug_host_list_lock); +#endif return count; } return -EINVAL; @@ -3100,12 +3118,28 @@ static ssize_t sdebug_virtual_gb_store(struct device_driver * ddp, const char * buf, size_t count) { int n; +#ifdef CONFIG_SCSI_ENHANCED_UA + struct sdebug_host_info *sdbg_host; + struct sdebug_dev_info *devip; +#endif if ((count > 0) && (1 == sscanf(buf, "%d", &n)) && (n >= 0)) { scsi_debug_virtual_gb = n; sdebug_capacity = get_sdebug_capacity(); +#ifdef CONFIG_SCSI_ENHANCED_UA + spin_lock(&sdebug_host_list_lock); + list_for_each_entry(sdbg_host, &sdebug_host_list, host_list) { + list_for_each_entry(devip, &sdbg_host->dev_info_list, + dev_list) { + mk_sense_buffer(devip, UNIT_ATTENTION, + 0x2a, 0x09); + devip->sense_pending = 1; + } + } + spin_unlock(&sdebug_host_list_lock); +#endif return count; } return -EINVAL; @@ -3206,6 +3240,89 @@ static ssize_t sdebug_map_show(struct device_driver *ddp, char *buf) DRIVER_ATTR(map, S_IRUGO, sdebug_map_show, NULL); +#ifdef CONFIG_SCSI_ENHANCED_UA +static ssize_t sdebug_ua_overflow_store(struct device_driver *ddp, + const char *buf, size_t count) +{ + int n; + struct sdebug_host_info *sdbg_host; + struct sdebug_dev_info *devip; + + if ((count > 0) && (1 == sscanf(buf, "%d", &n)) && (n >= 0) && + scsi_debug_dsense) { + spin_lock(&sdebug_host_list_lock); + list_for_each_entry(sdbg_host, &sdebug_host_list, host_list) { + list_for_each_entry(devip, &sdbg_host->dev_info_list, + dev_list) { + mk_sense_buffer(devip, UNIT_ATTENTION, + 0, 0); + devip->sense_buff[7] = 8; + devip->sense_buff[8] = 0x02; + devip->sense_buff[9] = 0x06; + devip->sense_buff[12] = 0x01; + devip->sense_pending = 1; + } + } + spin_unlock(&sdebug_host_list_lock); + return count; + } + return -EINVAL; +} +DRIVER_ATTR(ua_overflow, S_IWUSR, NULL, sdebug_ua_overflow_store); + +static ssize_t sdebug_soft_threshold_reached_store(struct device_driver *ddp, + const char *buf, + size_t count) +{ + int n; + struct sdebug_host_info *sdbg_host; + struct sdebug_dev_info *devip; + + if ((count > 0) && (1 == sscanf(buf, "%d", &n)) && (n >= 0)) { + spin_lock(&sdebug_host_list_lock); + list_for_each_entry(sdbg_host, &sdebug_host_list, host_list) { + list_for_each_entry(devip, &sdbg_host->dev_info_list, + dev_list) { + mk_sense_buffer(devip, UNIT_ATTENTION, + 0x38, 0x07); + devip->sense_pending = 1; + } + } + spin_unlock(&sdebug_host_list_lock); + return count; + } + return -EINVAL; +} +DRIVER_ATTR(soft_threshold_reached, S_IWUSR, NULL, + sdebug_soft_threshold_reached_store); + +static ssize_t sdebug_mode_parameters_changed_store(struct device_driver *ddp, + const char *buf, + size_t count) +{ + int n; + struct sdebug_host_info *sdbg_host; + struct sdebug_dev_info *devip; + + if ((count > 0) && (1 == sscanf(buf, "%d", &n)) && (n >= 0)) { + spin_lock(&sdebug_host_list_lock); + list_for_each_entry(sdbg_host, &sdebug_host_list, host_list) { + list_for_each_entry(devip, &sdbg_host->dev_info_list, + dev_list) { + mk_sense_buffer(devip, UNIT_ATTENTION, + 0x2a, 0x01); + devip->sense_pending = 1; + } + } + spin_unlock(&sdebug_host_list_lock); + return count; + } + return -EINVAL; +} +DRIVER_ATTR(mode_parameters_changed, S_IWUSR, NULL, + sdebug_mode_parameters_changed_store); +#endif + /* Note: The following function creates attribute files in the /sys/bus/pseudo/drivers/scsi_debug directory. The advantage of these files (over those found in the /sys/module/scsi_debug/parameters @@ -3239,11 +3356,27 @@ static int do_create_driverfs_files(void) ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_guard); ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_ato); ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_map); +#ifdef CONFIG_SCSI_ENHANCED_UA + ret |= driver_create_file(&sdebug_driverfs_driver, + &driver_attr_ua_overflow); + ret |= driver_create_file(&sdebug_driverfs_driver, + &driver_attr_soft_threshold_reached); + ret |= driver_create_file(&sdebug_driverfs_driver, + &driver_attr_mode_parameters_changed); +#endif return ret; } static void do_remove_driverfs_files(void) { +#ifdef CONFIG_SCSI_ENHANCED_UA + driver_remove_file(&sdebug_driverfs_driver, + &driver_attr_mode_parameters_changed); + driver_remove_file(&sdebug_driverfs_driver, + &driver_attr_soft_threshold_reached); + driver_remove_file(&sdebug_driverfs_driver, + &driver_attr_ua_overflow); +#endif driver_remove_file(&sdebug_driverfs_driver, &driver_attr_map); driver_remove_file(&sdebug_driverfs_driver, &driver_attr_ato); driver_remove_file(&sdebug_driverfs_driver, &driver_attr_guard); @@ -3926,6 +4059,11 @@ write: errsts = check_condition_result; break; } + if (!errsts && devip->sense_pending && (*cmd != INQUIRY) && + (*cmd != REPORT_LUNS)) { + devip->sense_pending = 0; + errsts = check_condition_result; + } return schedule_resp(SCpnt, devip, done, errsts, (delay_override ? 0 : scsi_debug_delay)); } -- 1.7.11.7 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html