4242#include <linux/xarray.h>
4343#include <linux/prefetch.h>
4444#include <linux/debugfs.h>
45+ #include <linux/async.h>
4546
4647#include <net/checksum.h>
4748
@@ -357,6 +358,11 @@ struct sdebug_dev_info {
357358 struct list_head inject_err_list ;
358359};
359360
361+ struct sdebug_target_info {
362+ bool reset_fail ;
363+ struct dentry * debugfs_entry ;
364+ };
365+
360366struct sdebug_host_info {
361367 struct list_head host_list ;
362368 int si_idx ; /* sdeb_store_info (per host) xarray index */
@@ -1082,6 +1088,91 @@ static const struct file_operations sdebug_error_fops = {
10821088 .release = single_release ,
10831089};
10841090
1091+ static int sdebug_target_reset_fail_show (struct seq_file * m , void * p )
1092+ {
1093+ struct scsi_target * starget = (struct scsi_target * )m -> private ;
1094+ struct sdebug_target_info * targetip =
1095+ (struct sdebug_target_info * )starget -> hostdata ;
1096+
1097+ if (targetip )
1098+ seq_printf (m , "%c\n" , targetip -> reset_fail ? 'Y' : 'N' );
1099+
1100+ return 0 ;
1101+ }
1102+
1103+ static int sdebug_target_reset_fail_open (struct inode * inode , struct file * file )
1104+ {
1105+ return single_open (file , sdebug_target_reset_fail_show , inode -> i_private );
1106+ }
1107+
1108+ static ssize_t sdebug_target_reset_fail_write (struct file * file ,
1109+ const char __user * ubuf , size_t count , loff_t * ppos )
1110+ {
1111+ int ret ;
1112+ struct scsi_target * starget =
1113+ (struct scsi_target * )file -> f_inode -> i_private ;
1114+ struct sdebug_target_info * targetip =
1115+ (struct sdebug_target_info * )starget -> hostdata ;
1116+
1117+ if (targetip ) {
1118+ ret = kstrtobool_from_user (ubuf , count , & targetip -> reset_fail );
1119+ return ret < 0 ? ret : count ;
1120+ }
1121+ return - ENODEV ;
1122+ }
1123+
1124+ static const struct file_operations sdebug_target_reset_fail_fops = {
1125+ .open = sdebug_target_reset_fail_open ,
1126+ .read = seq_read ,
1127+ .write = sdebug_target_reset_fail_write ,
1128+ .release = single_release ,
1129+ };
1130+
1131+ static int sdebug_target_alloc (struct scsi_target * starget )
1132+ {
1133+ struct sdebug_target_info * targetip ;
1134+ struct dentry * dentry ;
1135+
1136+ targetip = kzalloc (sizeof (struct sdebug_target_info ), GFP_KERNEL );
1137+ if (!targetip )
1138+ return - ENOMEM ;
1139+
1140+ targetip -> debugfs_entry = debugfs_create_dir (dev_name (& starget -> dev ),
1141+ sdebug_debugfs_root );
1142+ if (IS_ERR_OR_NULL (targetip -> debugfs_entry ))
1143+ pr_info ("%s: failed to create debugfs directory for target %s\n" ,
1144+ __func__ , dev_name (& starget -> dev ));
1145+
1146+ debugfs_create_file ("fail_reset" , 0600 , targetip -> debugfs_entry , starget ,
1147+ & sdebug_target_reset_fail_fops );
1148+ if (IS_ERR_OR_NULL (dentry ))
1149+ pr_info ("%s: failed to create fail_reset file for target %s\n" ,
1150+ __func__ , dev_name (& starget -> dev ));
1151+
1152+ starget -> hostdata = targetip ;
1153+
1154+ return 0 ;
1155+ }
1156+
1157+ static void sdebug_tartget_cleanup_async (void * data , async_cookie_t cookie )
1158+ {
1159+ struct sdebug_target_info * targetip = data ;
1160+
1161+ debugfs_remove (targetip -> debugfs_entry );
1162+ kfree (targetip );
1163+ }
1164+
1165+ static void sdebug_target_destroy (struct scsi_target * starget )
1166+ {
1167+ struct sdebug_target_info * targetip ;
1168+
1169+ targetip = (struct sdebug_target_info * )starget -> hostdata ;
1170+ if (targetip ) {
1171+ starget -> hostdata = NULL ;
1172+ async_schedule (sdebug_tartget_cleanup_async , targetip );
1173+ }
1174+ }
1175+
10851176/* Only do the extra work involved in logical block provisioning if one or
10861177 * more of the lbpu, lbpws or lbpws10 parameters are given and we are doing
10871178 * real reads and writes (i.e. not skipping them for speed).
@@ -5642,11 +5733,25 @@ static int scsi_debug_device_reset(struct scsi_cmnd *SCpnt)
56425733 return SUCCESS ;
56435734}
56445735
5736+ static int sdebug_fail_target_reset (struct scsi_cmnd * cmnd )
5737+ {
5738+ struct scsi_target * starget = scsi_target (cmnd -> device );
5739+ struct sdebug_target_info * targetip =
5740+ (struct sdebug_target_info * )starget -> hostdata ;
5741+
5742+ if (targetip )
5743+ return targetip -> reset_fail ;
5744+
5745+ return 0 ;
5746+ }
5747+
56455748static int scsi_debug_target_reset (struct scsi_cmnd * SCpnt )
56465749{
56475750 struct scsi_device * sdp = SCpnt -> device ;
56485751 struct sdebug_host_info * sdbg_host = shost_to_sdebug_host (sdp -> host );
56495752 struct sdebug_dev_info * devip ;
5753+ u8 * cmd = SCpnt -> cmnd ;
5754+ u8 opcode = cmd [0 ];
56505755 int k = 0 ;
56515756
56525757 ++ num_target_resets ;
@@ -5664,6 +5769,12 @@ static int scsi_debug_target_reset(struct scsi_cmnd *SCpnt)
56645769 sdev_printk (KERN_INFO , sdp ,
56655770 "%s: %d device(s) found in target\n" , __func__ , k );
56665771
5772+ if (sdebug_fail_target_reset (SCpnt )) {
5773+ scmd_printk (KERN_INFO , SCpnt , "fail target reset 0x%x\n" ,
5774+ opcode );
5775+ return FAILED ;
5776+ }
5777+
56675778 return SUCCESS ;
56685779}
56695780
@@ -8119,7 +8230,6 @@ static int sdebug_init_cmd_priv(struct Scsi_Host *shost, struct scsi_cmnd *cmd)
81198230 return 0 ;
81208231}
81218232
8122-
81238233static struct scsi_host_template sdebug_driver_template = {
81248234 .show_info = scsi_debug_show_info ,
81258235 .write_info = scsi_debug_write_info ,
@@ -8149,6 +8259,8 @@ static struct scsi_host_template sdebug_driver_template = {
81498259 .track_queue_depth = 1 ,
81508260 .cmd_size = sizeof (struct sdebug_scsi_cmd ),
81518261 .init_cmd_priv = sdebug_init_cmd_priv ,
8262+ .target_alloc = sdebug_target_alloc ,
8263+ .target_destroy = sdebug_target_destroy ,
81528264};
81538265
81548266static int sdebug_driver_probe (struct device * dev )
0 commit comments