42
42
#include <linux/xarray.h>
43
43
#include <linux/prefetch.h>
44
44
#include <linux/debugfs.h>
45
+ #include <linux/async.h>
45
46
46
47
#include <net/checksum.h>
47
48
@@ -357,6 +358,11 @@ struct sdebug_dev_info {
357
358
struct list_head inject_err_list ;
358
359
};
359
360
361
+ struct sdebug_target_info {
362
+ bool reset_fail ;
363
+ struct dentry * debugfs_entry ;
364
+ };
365
+
360
366
struct sdebug_host_info {
361
367
struct list_head host_list ;
362
368
int si_idx ; /* sdeb_store_info (per host) xarray index */
@@ -1082,6 +1088,91 @@ static const struct file_operations sdebug_error_fops = {
1082
1088
.release = single_release ,
1083
1089
};
1084
1090
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
+
1085
1176
/* Only do the extra work involved in logical block provisioning if one or
1086
1177
* more of the lbpu, lbpws or lbpws10 parameters are given and we are doing
1087
1178
* 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)
5642
5733
return SUCCESS ;
5643
5734
}
5644
5735
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
+
5645
5748
static int scsi_debug_target_reset (struct scsi_cmnd * SCpnt )
5646
5749
{
5647
5750
struct scsi_device * sdp = SCpnt -> device ;
5648
5751
struct sdebug_host_info * sdbg_host = shost_to_sdebug_host (sdp -> host );
5649
5752
struct sdebug_dev_info * devip ;
5753
+ u8 * cmd = SCpnt -> cmnd ;
5754
+ u8 opcode = cmd [0 ];
5650
5755
int k = 0 ;
5651
5756
5652
5757
++ num_target_resets ;
@@ -5664,6 +5769,12 @@ static int scsi_debug_target_reset(struct scsi_cmnd *SCpnt)
5664
5769
sdev_printk (KERN_INFO , sdp ,
5665
5770
"%s: %d device(s) found in target\n" , __func__ , k );
5666
5771
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
+
5667
5778
return SUCCESS ;
5668
5779
}
5669
5780
@@ -8119,7 +8230,6 @@ static int sdebug_init_cmd_priv(struct Scsi_Host *shost, struct scsi_cmnd *cmd)
8119
8230
return 0 ;
8120
8231
}
8121
8232
8122
-
8123
8233
static struct scsi_host_template sdebug_driver_template = {
8124
8234
.show_info = scsi_debug_show_info ,
8125
8235
.write_info = scsi_debug_write_info ,
@@ -8149,6 +8259,8 @@ static struct scsi_host_template sdebug_driver_template = {
8149
8259
.track_queue_depth = 1 ,
8150
8260
.cmd_size = sizeof (struct sdebug_scsi_cmd ),
8151
8261
.init_cmd_priv = sdebug_init_cmd_priv ,
8262
+ .target_alloc = sdebug_target_alloc ,
8263
+ .target_destroy = sdebug_target_destroy ,
8152
8264
};
8153
8265
8154
8266
static int sdebug_driver_probe (struct device * dev )
0 commit comments