scsi_debug.c 160 KB
Newer Older
Linus Torvalds's avatar
Linus Torvalds committed
1
2
3
4
5
6
7
8
9
/*
 * vvvvvvvvvvvvvvvvvvvvvvv Original vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
 *  Copyright (C) 1992  Eric Youngdale
 *  Simulate a host adapter with 2 disks attached.  Do a lot of checking
 *  to make sure that we are not getting blocks mixed up, and PANIC if
 *  anything out of the ordinary is seen.
 * ^^^^^^^^^^^^^^^^^^^^^^^ Original ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 *
 *  This version is more generic, simulating a variable number of disk
10
11
12
 *  (or disk like devices) sharing a common amount of RAM. To be more
 *  realistic, the simulated devices have the transport attributes of
 *  SAS disks.
Linus Torvalds's avatar
Linus Torvalds committed
13
14
 *
 *
15
 *  For documentation see http://sg.danny.cz/sg/sdebug26.html
Linus Torvalds's avatar
Linus Torvalds committed
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
 *
 *   D. Gilbert (dpg) work for Magneto-Optical device test [20010421]
 *   dpg: work for devfs large number of disks [20010809]
 *        forked for lk 2.5 series [20011216, 20020101]
 *        use vmalloc() more inquiry+mode_sense [20020302]
 *        add timers for delayed responses [20020721]
 *   Patrick Mansfield <patmans@us.ibm.com> max_luns+scsi_level [20021031]
 *   Mike Anderson <andmike@us.ibm.com> sysfs work [20021118]
 *   dpg: change style of boot options to "scsi_debug.num_tgts=2" and
 *        module options to "modprobe scsi_debug num_tgts=2" [20021221]
 */

#include <linux/module.h>

#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/timer.h>
33
#include <linux/slab.h>
Linus Torvalds's avatar
Linus Torvalds committed
34
35
36
37
38
39
40
41
#include <linux/types.h>
#include <linux/string.h>
#include <linux/genhd.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/proc_fs.h>
#include <linux/vmalloc.h>
#include <linux/moduleparam.h>
Jens Axboe's avatar
Jens Axboe committed
42
#include <linux/scatterlist.h>
Linus Torvalds's avatar
Linus Torvalds committed
43
#include <linux/blkdev.h>
44
#include <linux/crc-t10dif.h>
45
46
47
48
#include <linux/spinlock.h>
#include <linux/interrupt.h>
#include <linux/atomic.h>
#include <linux/hrtimer.h>
49
50

#include <net/checksum.h>
51

52
53
#include <asm/unaligned.h>

54
55
56
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h>
Linus Torvalds's avatar
Linus Torvalds committed
57
58
#include <scsi/scsi_host.h>
#include <scsi/scsicam.h>
59
#include <scsi/scsi_eh.h>
60
#include <scsi/scsi_tcq.h>
61
#include <scsi/scsi_dbg.h>
Linus Torvalds's avatar
Linus Torvalds committed
62

63
#include "sd.h"
Linus Torvalds's avatar
Linus Torvalds committed
64
65
#include "scsi_logging.h"

66
67
#define SCSI_DEBUG_VERSION "1.85"
static const char *scsi_debug_version_date = "20141022";
68
69

#define MY_NAME "scsi_debug"
Linus Torvalds's avatar
Linus Torvalds committed
70

71
/* Additional Sense Code (ASC) */
72
73
#define NO_ADDITIONAL_SENSE 0x0
#define LOGICAL_UNIT_NOT_READY 0x4
74
#define LOGICAL_UNIT_COMMUNICATION_FAILURE 0x8
Linus Torvalds's avatar
Linus Torvalds committed
75
#define UNRECOVERED_READ_ERR 0x11
76
#define PARAMETER_LIST_LENGTH_ERR 0x1a
Linus Torvalds's avatar
Linus Torvalds committed
77
#define INVALID_OPCODE 0x20
78
#define LBA_OUT_OF_RANGE 0x21
Linus Torvalds's avatar
Linus Torvalds committed
79
#define INVALID_FIELD_IN_CDB 0x24
80
#define INVALID_FIELD_IN_PARAM_LIST 0x26
81
82
#define UA_RESET_ASC 0x29
#define UA_CHANGED_ASC 0x2a
83
84
#define TARGET_CHANGED_ASC 0x3f
#define LUNS_CHANGED_ASCQ 0x0e
85
86
#define INSUFF_RES_ASC 0x55
#define INSUFF_RES_ASCQ 0x3
87
88
89
#define POWER_ON_RESET_ASCQ 0x0
#define BUS_RESET_ASCQ 0x2	/* scsi bus reset occurred */
#define MODE_CHANGED_ASCQ 0x1	/* mode parameters changed */
90
#define CAPACITY_CHANGED_ASCQ 0x9
Linus Torvalds's avatar
Linus Torvalds committed
91
#define SAVING_PARAMS_UNSUP 0x39
92
#define TRANSPORT_PROBLEM 0x4b
93
94
#define THRESHOLD_EXCEEDED 0x5d
#define LOW_POWER_COND_ON 0x5e
95
#define MISCOMPARE_VERIFY_ASC 0x1d
96
97
#define MICROCODE_CHANGED_ASCQ 0x1	/* with TARGET_CHANGED_ASC */
#define MICROCODE_CHANGED_WO_RESET_ASCQ 0x16
Linus Torvalds's avatar
Linus Torvalds committed
98

99
100
101
/* Additional Sense Code Qualifier (ASCQ) */
#define ACK_NAK_TO 0x3

Linus Torvalds's avatar
Linus Torvalds committed
102
103
104
105
106
107
108
109

/* Default values for driver parameters */
#define DEF_NUM_HOST   1
#define DEF_NUM_TGTS   1
#define DEF_MAX_LUNS   1
/* With these defaults, this driver will make 1 host with 1 target
 * (id 0) containing 1 logical unit (lun 0). That is 1 device.
 */
110
#define DEF_ATO 1
111
#define DEF_DELAY   1		/* if > 0 unit is a jiffy */
Linus Torvalds's avatar
Linus Torvalds committed
112
#define DEF_DEV_SIZE_MB   8
113
114
#define DEF_DIF 0
#define DEF_DIX 0
Linus Torvalds's avatar
Linus Torvalds committed
115
#define DEF_D_SENSE   0
116
#define DEF_EVERY_NTH   0
117
#define DEF_FAKE_RW	0
118
#define DEF_GUARD 0
119
#define DEF_HOST_LOCK 0
120
121
122
#define DEF_LBPU 0
#define DEF_LBPWS 0
#define DEF_LBPWS10 0
123
#define DEF_LBPRZ 1
124
#define DEF_LOWEST_ALIGNED 0
125
#define DEF_NDELAY   0		/* if > 0 unit is a nanosecond */
126
127
128
#define DEF_NO_LUN_0   0
#define DEF_NUM_PARTS   0
#define DEF_OPTS   0
129
#define DEF_OPT_BLKS 64
130
131
#define DEF_PHYSBLK_EXP 0
#define DEF_PTYPE   0
132
#define DEF_REMOVABLE false
133
#define DEF_SCSI_LEVEL   6    /* INQUIRY, byte2 [6->SPC-4] */
134
135
136
#define DEF_SECTOR_SIZE 512
#define DEF_UNMAP_ALIGNMENT 0
#define DEF_UNMAP_GRANULARITY 1
137
138
#define DEF_UNMAP_MAX_BLOCKS 0xFFFFFFFF
#define DEF_UNMAP_MAX_DESC 256
139
140
141
#define DEF_VIRTUAL_GB   0
#define DEF_VPD_USE_HOSTNO 1
#define DEF_WRITESAME_LENGTH 0xFFFF
142
#define DEF_STRICT 0
143
#define DELAY_OVERRIDDEN -9999
Linus Torvalds's avatar
Linus Torvalds committed
144
145
146
147
148
149

/* bit mask values for scsi_debug_opts */
#define SCSI_DEBUG_OPT_NOISE   1
#define SCSI_DEBUG_OPT_MEDIUM_ERR   2
#define SCSI_DEBUG_OPT_TIMEOUT   4
#define SCSI_DEBUG_OPT_RECOVERED_ERR   8
150
#define SCSI_DEBUG_OPT_TRANSPORT_ERR   16
151
152
#define SCSI_DEBUG_OPT_DIF_ERR   32
#define SCSI_DEBUG_OPT_DIX_ERR   64
153
#define SCSI_DEBUG_OPT_MAC_TIMEOUT  128
154
155
156
157
158
159
160
161
#define SCSI_DEBUG_OPT_SHORT_TRANSFER	0x100
#define SCSI_DEBUG_OPT_Q_NOISE	0x200
#define SCSI_DEBUG_OPT_ALL_TSF	0x400
#define SCSI_DEBUG_OPT_RARE_TSF	0x800
#define SCSI_DEBUG_OPT_N_WCE	0x1000
#define SCSI_DEBUG_OPT_RESET_NOISE 0x2000
#define SCSI_DEBUG_OPT_NO_CDB_NOISE 0x4000
#define SCSI_DEBUG_OPT_ALL_NOISE (0x1 | 0x200 | 0x2000)
Linus Torvalds's avatar
Linus Torvalds committed
162
163
164
165
/* When "every_nth" > 0 then modulo "every_nth" commands:
 *   - a no response is simulated if SCSI_DEBUG_OPT_TIMEOUT is set
 *   - a RECOVERED_ERROR is simulated on successful read and write
 *     commands if SCSI_DEBUG_OPT_RECOVERED_ERR is set.
166
167
 *   - a TRANSPORT_ERROR is simulated on successful read and write
 *     commands if SCSI_DEBUG_OPT_TRANSPORT_ERR is set.
Linus Torvalds's avatar
Linus Torvalds committed
168
169
170
171
172
 *
 * When "every_nth" < 0 then after "- every_nth" commands:
 *   - a no response is simulated if SCSI_DEBUG_OPT_TIMEOUT is set
 *   - a RECOVERED_ERROR is simulated on successful read and write
 *     commands if SCSI_DEBUG_OPT_RECOVERED_ERR is set.
173
174
 *   - a TRANSPORT_ERROR is simulated on successful read and write
 *     commands if SCSI_DEBUG_OPT_TRANSPORT_ERR is set.
Linus Torvalds's avatar
Linus Torvalds committed
175
176
177
178
 * This will continue until some other action occurs (e.g. the user
 * writing a new value (other than -1 or 1) to every_nth via sysfs).
 */

179
180
181
182
183
184
185
/* As indicated in SAM-5 and SPC-4 Unit Attentions (UAs)are returned in
 * priority order. In the subset implemented here lower numbers have higher
 * priority. The UA numbers should be a sequence starting from 0 with
 * SDEBUG_NUM_UAS being 1 higher than the highest numbered UA. */
#define SDEBUG_UA_POR 0		/* Power on, reset, or bus device reset */
#define SDEBUG_UA_BUS_RESET 1
#define SDEBUG_UA_MODE_CHANGED 2
186
#define SDEBUG_UA_CAPACITY_CHANGED 3
187
#define SDEBUG_UA_LUNS_CHANGED 4
188
189
190
#define SDEBUG_UA_MICROCODE_CHANGED 5	/* simulate firmware change */
#define SDEBUG_UA_MICROCODE_CHANGED_WO_RESET 6
#define SDEBUG_NUM_UAS 7
191
192

/* for check_readiness() */
193
194
#define UAS_ONLY 1	/* check for UAs only */
#define UAS_TUR 0	/* if no UAs then check if media access possible */
195

Linus Torvalds's avatar
Linus Torvalds committed
196
197
198
/* when 1==SCSI_DEBUG_OPT_MEDIUM_ERR, a medium error is simulated at this
 * sector on read commands: */
#define OPT_MEDIUM_ERR_ADDR   0x1234 /* that's sector 4660 in decimal */
199
#define OPT_MEDIUM_ERR_NUM    10     /* number of consecutive medium errs */
Linus Torvalds's avatar
Linus Torvalds committed
200
201
202
203

/* If REPORT LUNS has luns >= 256 it can choose "flat space" (value 1)
 * or "peripheral device" addressing (value 0) */
#define SAM2_LUN_ADDRESS_METHOD 0
204
#define SAM2_WLUN_REPORT_LUNS 0xc101
Linus Torvalds's avatar
Linus Torvalds committed
205

206
207
208
209
210
211
212
213
214
215
216
217
218
/* SCSI_DEBUG_CANQUEUE is the maximum number of commands that can be queued
 * (for response) at one time. Can be reduced by max_queue option. Command
 * responses are not queued when delay=0 and ndelay=0. The per-device
 * DEF_CMD_PER_LUN can be changed via sysfs:
 * /sys/class/scsi_device/<h:c:t:l>/device/queue_depth but cannot exceed
 * SCSI_DEBUG_CANQUEUE. */
#define SCSI_DEBUG_CANQUEUE_WORDS  9	/* a WORD is bits in a long */
#define SCSI_DEBUG_CANQUEUE  (SCSI_DEBUG_CANQUEUE_WORDS * BITS_PER_LONG)
#define DEF_CMD_PER_LUN  255

#if DEF_CMD_PER_LUN > SCSI_DEBUG_CANQUEUE
#warning "Expect DEF_CMD_PER_LUN <= SCSI_DEBUG_CANQUEUE"
#endif
219

220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
/* SCSI opcodes (first byte of cdb) mapped onto these indexes */
enum sdeb_opcode_index {
	SDEB_I_INVALID_OPCODE =	0,
	SDEB_I_INQUIRY = 1,
	SDEB_I_REPORT_LUNS = 2,
	SDEB_I_REQUEST_SENSE = 3,
	SDEB_I_TEST_UNIT_READY = 4,
	SDEB_I_MODE_SENSE = 5,		/* 6, 10 */
	SDEB_I_MODE_SELECT = 6,		/* 6, 10 */
	SDEB_I_LOG_SENSE = 7,
	SDEB_I_READ_CAPACITY = 8,	/* 10; 16 is in SA_IN(16) */
	SDEB_I_READ = 9,		/* 6, 10, 12, 16 */
	SDEB_I_WRITE = 10,		/* 6, 10, 12, 16 */
	SDEB_I_START_STOP = 11,
	SDEB_I_SERV_ACT_IN = 12,	/* 12, 16 */
	SDEB_I_SERV_ACT_OUT = 13,	/* 12, 16 */
	SDEB_I_MAINT_IN = 14,
	SDEB_I_MAINT_OUT = 15,
	SDEB_I_VERIFY = 16,		/* 10 only */
	SDEB_I_VARIABLE_LEN = 17,
	SDEB_I_RESERVE = 18,		/* 6, 10 */
	SDEB_I_RELEASE = 19,		/* 6, 10 */
	SDEB_I_ALLOW_REMOVAL = 20,	/* PREVENT ALLOW MEDIUM REMOVAL */
	SDEB_I_REZERO_UNIT = 21,	/* REWIND in SSC */
	SDEB_I_ATA_PT = 22,		/* 12, 16 */
	SDEB_I_SEND_DIAG = 23,
	SDEB_I_UNMAP = 24,
	SDEB_I_XDWRITEREAD = 25,	/* 10 only */
	SDEB_I_WRITE_BUFFER = 26,
	SDEB_I_WRITE_SAME = 27,		/* 10, 16 */
	SDEB_I_SYNC_CACHE = 28,		/* 10 only */
	SDEB_I_COMP_WRITE = 29,
	SDEB_I_LAST_ELEMENT = 30,	/* keep this last */
};

static const unsigned char opcode_ind_arr[256] = {
/* 0x0; 0x0->0x1f: 6 byte cdbs */
	SDEB_I_TEST_UNIT_READY, SDEB_I_REZERO_UNIT, 0, SDEB_I_REQUEST_SENSE,
	    0, 0, 0, 0,
	SDEB_I_READ, 0, SDEB_I_WRITE, 0, 0, 0, 0, 0,
	0, 0, SDEB_I_INQUIRY, 0, 0, SDEB_I_MODE_SELECT, SDEB_I_RESERVE,
	    SDEB_I_RELEASE,
	0, 0, SDEB_I_MODE_SENSE, SDEB_I_START_STOP, 0, SDEB_I_SEND_DIAG,
	    SDEB_I_ALLOW_REMOVAL, 0,
/* 0x20; 0x20->0x3f: 10 byte cdbs */
	0, 0, 0, 0, 0, SDEB_I_READ_CAPACITY, 0, 0,
	SDEB_I_READ, 0, SDEB_I_WRITE, 0, 0, 0, 0, SDEB_I_VERIFY,
	0, 0, 0, 0, 0, SDEB_I_SYNC_CACHE, 0, 0,
	0, 0, 0, SDEB_I_WRITE_BUFFER, 0, 0, 0, 0,
/* 0x40; 0x40->0x5f: 10 byte cdbs */
	0, SDEB_I_WRITE_SAME, SDEB_I_UNMAP, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, SDEB_I_LOG_SENSE, 0, 0,
	0, 0, 0, SDEB_I_XDWRITEREAD, 0, SDEB_I_MODE_SELECT, SDEB_I_RESERVE,
	    SDEB_I_RELEASE,
	0, 0, SDEB_I_MODE_SENSE, 0, 0, 0, 0, 0,
/* 0x60; 0x60->0x7d are reserved */
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, SDEB_I_VARIABLE_LEN,
/* 0x80; 0x80->0x9f: 16 byte cdbs */
	0, 0, 0, 0, 0, SDEB_I_ATA_PT, 0, 0,
	SDEB_I_READ, SDEB_I_COMP_WRITE, SDEB_I_WRITE, 0, 0, 0, 0, 0,
	0, 0, 0, SDEB_I_WRITE_SAME, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, SDEB_I_SERV_ACT_IN, SDEB_I_SERV_ACT_OUT,
/* 0xa0; 0xa0->0xbf: 12 byte cdbs */
	SDEB_I_REPORT_LUNS, SDEB_I_ATA_PT, 0, SDEB_I_MAINT_IN,
	     SDEB_I_MAINT_OUT, 0, 0, 0,
	SDEB_I_READ, SDEB_I_SERV_ACT_OUT, SDEB_I_WRITE, SDEB_I_SERV_ACT_IN,
	     0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0,
/* 0xc0; 0xc0->0xff: vendor specific */
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};

#define F_D_IN			1
#define F_D_OUT			2
#define F_D_OUT_MAYBE		4	/* WRITE SAME, NDOB bit */
#define F_D_UNKN		8
#define F_RL_WLUN_OK		0x10
#define F_SKIP_UA		0x20
#define F_DELAY_OVERR		0x40
#define F_SA_LOW		0x80	/* cdb byte 1, bits 4 to 0 */
#define F_SA_HIGH		0x100	/* as used by variable length cdbs */
#define F_INV_OP		0x200
#define F_FAKE_RW		0x400
#define F_M_ACCESS		0x800	/* media access */

#define FF_RESPOND (F_RL_WLUN_OK | F_SKIP_UA | F_DELAY_OVERR)
#define FF_DIRECT_IO (F_M_ACCESS | F_FAKE_RW)
#define FF_SA (F_SA_HIGH | F_SA_LOW)

struct sdebug_dev_info;
static int resp_inquiry(struct scsi_cmnd *, struct sdebug_dev_info *);
static int resp_report_luns(struct scsi_cmnd *, struct sdebug_dev_info *);
static int resp_requests(struct scsi_cmnd *, struct sdebug_dev_info *);
static int resp_mode_sense(struct scsi_cmnd *, struct sdebug_dev_info *);
static int resp_mode_select(struct scsi_cmnd *, struct sdebug_dev_info *);
static int resp_log_sense(struct scsi_cmnd *, struct sdebug_dev_info *);
static int resp_readcap(struct scsi_cmnd *, struct sdebug_dev_info *);
static int resp_read_dt0(struct scsi_cmnd *, struct sdebug_dev_info *);
static int resp_write_dt0(struct scsi_cmnd *, struct sdebug_dev_info *);
static int resp_start_stop(struct scsi_cmnd *, struct sdebug_dev_info *);
static int resp_readcap16(struct scsi_cmnd *, struct sdebug_dev_info *);
static int resp_get_lba_status(struct scsi_cmnd *, struct sdebug_dev_info *);
static int resp_report_tgtpgs(struct scsi_cmnd *, struct sdebug_dev_info *);
static int resp_unmap(struct scsi_cmnd *, struct sdebug_dev_info *);
330
331
static int resp_rsup_opcodes(struct scsi_cmnd *, struct sdebug_dev_info *);
static int resp_rsup_tmfs(struct scsi_cmnd *, struct sdebug_dev_info *);
332
333
334
static int resp_write_same_10(struct scsi_cmnd *, struct sdebug_dev_info *);
static int resp_write_same_16(struct scsi_cmnd *, struct sdebug_dev_info *);
static int resp_xdwriteread_10(struct scsi_cmnd *, struct sdebug_dev_info *);
335
static int resp_comp_write(struct scsi_cmnd *, struct sdebug_dev_info *);
336
static int resp_write_buffer(struct scsi_cmnd *, struct sdebug_dev_info *);
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394

struct opcode_info_t {
	u8 num_attached;	/* 0 if this is it (i.e. a leaf); use 0xff
				 * for terminating element */
	u8 opcode;		/* if num_attached > 0, preferred */
	u16 sa;			/* service action */
	u32 flags;		/* OR-ed set of SDEB_F_* */
	int (*pfp)(struct scsi_cmnd *, struct sdebug_dev_info *);
	const struct opcode_info_t *arrp;  /* num_attached elements or NULL */
	u8 len_mask[16];	/* len=len_mask[0], then mask for cdb[1]... */
				/* ignore cdb bytes after position 15 */
};

static const struct opcode_info_t msense_iarr[1] = {
	{0, 0x1a, 0, F_D_IN, NULL, NULL,
	    {6,  0xe8, 0xff, 0xff, 0xff, 0xc7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
};

static const struct opcode_info_t mselect_iarr[1] = {
	{0, 0x15, 0, F_D_OUT, NULL, NULL,
	    {6,  0xf1, 0, 0, 0xff, 0xc7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
};

static const struct opcode_info_t read_iarr[3] = {
	{0, 0x28, 0, F_D_IN | FF_DIRECT_IO, resp_read_dt0, NULL,/* READ(10) */
	    {10,  0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, 0xc7, 0, 0,
	     0, 0, 0, 0} },
	{0, 0x8, 0, F_D_IN | FF_DIRECT_IO, resp_read_dt0, NULL, /* READ(6) */
	    {6,  0xff, 0xff, 0xff, 0xff, 0xc7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
	{0, 0xa8, 0, F_D_IN | FF_DIRECT_IO, resp_read_dt0, NULL,/* READ(12) */
	    {12,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9f,
	     0xc7, 0, 0, 0, 0} },
};

static const struct opcode_info_t write_iarr[3] = {
	{0, 0x2a, 0, F_D_OUT | FF_DIRECT_IO, resp_write_dt0, NULL,   /* 10 */
	    {10,  0xfb, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, 0xc7, 0, 0,
	     0, 0, 0, 0} },
	{0, 0xa, 0, F_D_OUT | FF_DIRECT_IO, resp_write_dt0, NULL,    /* 6 */
	    {6,  0xff, 0xff, 0xff, 0xff, 0xc7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
	{0, 0xaa, 0, F_D_OUT | FF_DIRECT_IO, resp_write_dt0, NULL,   /* 12 */
	    {12,  0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9f,
	     0xc7, 0, 0, 0, 0} },
};

static const struct opcode_info_t sa_in_iarr[1] = {
	{0, 0x9e, 0x12, F_SA_LOW | F_D_IN, resp_get_lba_status, NULL,
	    {16,  0x12, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	     0xff, 0xff, 0xff, 0, 0xc7} },
};

static const struct opcode_info_t vl_iarr[1] = {	/* VARIABLE LENGTH */
	{0, 0x7f, 0xb, F_SA_HIGH | F_D_OUT | FF_DIRECT_IO, resp_write_dt0,
	    NULL, {32,  0xc7, 0, 0, 0, 0, 0x1f, 0x18, 0x0, 0xb, 0xfa,
		   0, 0xff, 0xff, 0xff, 0xff} },	/* WRITE(32) */
};

static const struct opcode_info_t maint_in_iarr[2] = {
395
	{0, 0xa3, 0xc, F_SA_LOW | F_D_IN, resp_rsup_opcodes, NULL,
396
397
	    {12,  0xc, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0,
	     0xc7, 0, 0, 0, 0} },
398
	{0, 0xa3, 0xd, F_SA_LOW | F_D_IN, resp_rsup_tmfs, NULL,
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
	    {12,  0xd, 0x80, 0, 0, 0, 0xff, 0xff, 0xff, 0xff, 0, 0xc7, 0, 0,
	     0, 0} },
};

static const struct opcode_info_t write_same_iarr[1] = {
	{0, 0x93, 0, F_D_OUT_MAYBE | FF_DIRECT_IO, resp_write_same_16, NULL,
	    {16,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	     0xff, 0xff, 0xff, 0x1f, 0xc7} },
};

static const struct opcode_info_t reserve_iarr[1] = {
	{0, 0x16, 0, F_D_OUT, NULL, NULL,	/* RESERVE(6) */
	    {6,  0x1f, 0xff, 0xff, 0xff, 0xc7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
};

static const struct opcode_info_t release_iarr[1] = {
	{0, 0x17, 0, F_D_OUT, NULL, NULL,	/* RELEASE(6) */
	    {6,  0x1f, 0xff, 0, 0, 0xc7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
};


/* This array is accessed via SDEB_I_* values. Make sure all are mapped,
 * plus the terminating elements for logic that scans this table such as
 * REPORT SUPPORTED OPERATION CODES. */
static const struct opcode_info_t opcode_info_arr[SDEB_I_LAST_ELEMENT + 1] = {
/* 0 */
	{0, 0, 0, F_INV_OP | FF_RESPOND, NULL, NULL,
	    {0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
	{0, 0x12, 0, FF_RESPOND | F_D_IN, resp_inquiry, NULL,
	    {6,  0xe3, 0xff, 0xff, 0xff, 0xc7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
	{0, 0xa0, 0, FF_RESPOND | F_D_IN, resp_report_luns, NULL,
	    {12,  0xe3, 0xff, 0, 0, 0, 0xff, 0xff, 0xff, 0xff, 0, 0xc7, 0, 0,
	     0, 0} },
	{0, 0x3, 0, FF_RESPOND | F_D_IN, resp_requests, NULL,
	    {6,  0xe1, 0, 0, 0xff, 0xc7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
	{0, 0x0, 0, F_M_ACCESS | F_RL_WLUN_OK, NULL, NULL,/* TEST UNIT READY */
	    {6,  0, 0, 0, 0, 0xc7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
	{1, 0x5a, 0, F_D_IN, resp_mode_sense, msense_iarr,
	    {10,  0xf8, 0xff, 0xff, 0, 0, 0, 0xff, 0xff, 0xc7, 0, 0, 0, 0, 0,
	     0} },
	{1, 0x55, 0, F_D_OUT, resp_mode_select, mselect_iarr,
	    {10,  0xf1, 0, 0, 0, 0, 0, 0xff, 0xff, 0xc7, 0, 0, 0, 0, 0, 0} },
	{0, 0x4d, 0, F_D_IN, resp_log_sense, NULL,
	    {10,  0xe3, 0xff, 0xff, 0, 0xff, 0xff, 0xff, 0xff, 0xc7, 0, 0, 0,
	     0, 0, 0} },
	{0, 0x25, 0, F_D_IN, resp_readcap, NULL,
	    {10,  0xe1, 0xff, 0xff, 0xff, 0xff, 0, 0, 0x1, 0xc7, 0, 0, 0, 0,
	     0, 0} },
	{3, 0x88, 0, F_D_IN | FF_DIRECT_IO, resp_read_dt0, read_iarr,
	    {16,  0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	     0xff, 0xff, 0xff, 0x9f, 0xc7} },		/* READ(16) */
/* 10 */
	{3, 0x8a, 0, F_D_OUT | FF_DIRECT_IO, resp_write_dt0, write_iarr,
	    {16,  0xfa, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	     0xff, 0xff, 0xff, 0x9f, 0xc7} },		/* WRITE(16) */
	{0, 0x1b, 0, 0, resp_start_stop, NULL,		/* START STOP UNIT */
	    {6,  0x1, 0, 0xf, 0xf7, 0xc7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
	{1, 0x9e, 0x10, F_SA_LOW | F_D_IN, resp_readcap16, sa_in_iarr,
	    {16,  0x10, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	     0xff, 0xff, 0xff, 0x1, 0xc7} },	/* READ CAPACITY(16) */
	{0, 0, 0, F_INV_OP | FF_RESPOND, NULL, NULL, /* SA OUT */
	    {0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
	{2, 0xa3, 0xa, F_SA_LOW | F_D_IN, resp_report_tgtpgs, maint_in_iarr,
	    {12,  0xea, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff, 0, 0xc7, 0, 0, 0,
	     0} },
	{0, 0, 0, F_INV_OP | FF_RESPOND, NULL, NULL, /* MAINT OUT */
	    {0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
	{0, 0, 0, F_INV_OP | FF_RESPOND, NULL, NULL, /* VERIFY */
	    {0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
	{1, 0x7f, 0x9, F_SA_HIGH | F_D_IN | FF_DIRECT_IO, resp_read_dt0,
	    vl_iarr, {32,  0xc7, 0, 0, 0, 0, 0x1f, 0x18, 0x0, 0x9, 0xfe, 0,
		      0xff, 0xff, 0xff, 0xff} },/* VARIABLE LENGTH, READ(32) */
	{1, 0x56, 0, F_D_OUT, NULL, reserve_iarr, /* RESERVE(10) */
	    {10,  0xff, 0xff, 0xff, 0, 0, 0, 0xff, 0xff, 0xc7, 0, 0, 0, 0, 0,
	     0} },
	{1, 0x57, 0, F_D_OUT, NULL, release_iarr, /* RELEASE(10) */
	    {10,  0x13, 0xff, 0xff, 0, 0, 0, 0xff, 0xff, 0xc7, 0, 0, 0, 0, 0,
	     0} },
/* 20 */
	{0, 0, 0, F_INV_OP | FF_RESPOND, NULL, NULL, /* ALLOW REMOVAL */
	    {0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
	{0, 0x1, 0, 0, resp_start_stop, NULL, /* REWIND ?? */
	    {6,  0x1, 0, 0, 0, 0xc7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
	{0, 0, 0, F_INV_OP | FF_RESPOND, NULL, NULL, /* ATA_PT */
	    {0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
	{0, 0x1d, F_D_OUT, 0, NULL, NULL,	/* SEND DIAGNOSTIC */
	    {6,  0xf7, 0, 0xff, 0xff, 0xc7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
	{0, 0x42, 0, F_D_OUT | FF_DIRECT_IO, resp_unmap, NULL, /* UNMAP */
	    {10,  0x1, 0, 0, 0, 0, 0x1f, 0xff, 0xff, 0xc7, 0, 0, 0, 0, 0, 0} },
	{0, 0x53, 0, F_D_IN | F_D_OUT | FF_DIRECT_IO, resp_xdwriteread_10,
	    NULL, {10,  0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, 0xc7,
		   0, 0, 0, 0, 0, 0} },
491
492
493
	{0, 0x3b, 0, F_D_OUT_MAYBE, resp_write_buffer, NULL,
	    {10,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc7, 0, 0,
	     0, 0, 0, 0} },			/* WRITE_BUFFER */
494
495
496
497
498
499
	{1, 0x41, 0, F_D_OUT_MAYBE | FF_DIRECT_IO, resp_write_same_10,
	    write_same_iarr, {10,  0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xff,
			      0xff, 0xc7, 0, 0, 0, 0, 0, 0} },
	{0, 0x35, 0, F_DELAY_OVERR | FF_DIRECT_IO, NULL, NULL, /* SYNC_CACHE */
	    {10,  0x7, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, 0xc7, 0, 0,
	     0, 0, 0, 0} },
500
	{0, 0x89, 0, F_D_OUT | FF_DIRECT_IO, resp_comp_write, NULL,
501
502
503
504
505
506
507
508
	    {16,  0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0,
	     0, 0xff, 0x1f, 0xc7} },		/* COMPARE AND WRITE */

/* 30 */
	{0xff, 0, 0, 0, NULL, NULL,		/* terminating element */
	    {0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
};

509
510
511
512
513
514
515
516
struct sdebug_scmd_extra_t {
	bool inj_recovered;
	bool inj_transport;
	bool inj_dif;
	bool inj_dix;
	bool inj_short;
};

Linus Torvalds's avatar
Linus Torvalds committed
517
static int scsi_debug_add_host = DEF_NUM_HOST;
518
static int scsi_debug_ato = DEF_ATO;
Linus Torvalds's avatar
Linus Torvalds committed
519
520
static int scsi_debug_delay = DEF_DELAY;
static int scsi_debug_dev_size_mb = DEF_DEV_SIZE_MB;
521
522
523
static int scsi_debug_dif = DEF_DIF;
static int scsi_debug_dix = DEF_DIX;
static int scsi_debug_dsense = DEF_D_SENSE;
Linus Torvalds's avatar
Linus Torvalds committed
524
static int scsi_debug_every_nth = DEF_EVERY_NTH;
525
static int scsi_debug_fake_rw = DEF_FAKE_RW;
526
static unsigned int scsi_debug_guard = DEF_GUARD;
527
static int scsi_debug_lowest_aligned = DEF_LOWEST_ALIGNED;
Linus Torvalds's avatar
Linus Torvalds committed
528
static int scsi_debug_max_luns = DEF_MAX_LUNS;
529
static int scsi_debug_max_queue = SCSI_DEBUG_CANQUEUE;
530
531
static atomic_t retired_max_queue;	/* if > 0 then was prior max_queue */
static int scsi_debug_ndelay = DEF_NDELAY;
532
static int scsi_debug_no_lun_0 = DEF_NO_LUN_0;
533
static int scsi_debug_no_uld = 0;
534
static int scsi_debug_num_parts = DEF_NUM_PARTS;
Linus Torvalds's avatar
Linus Torvalds committed
535
static int scsi_debug_num_tgts = DEF_NUM_TGTS; /* targets per host */
536
static int scsi_debug_opt_blks = DEF_OPT_BLKS;
Linus Torvalds's avatar
Linus Torvalds committed
537
static int scsi_debug_opts = DEF_OPTS;
538
static int scsi_debug_physblk_exp = DEF_PHYSBLK_EXP;
Linus Torvalds's avatar
Linus Torvalds committed
539
static int scsi_debug_ptype = DEF_PTYPE; /* SCSI peripheral type (0==disk) */
540
541
static int scsi_debug_scsi_level = DEF_SCSI_LEVEL;
static int scsi_debug_sector_size = DEF_SECTOR_SIZE;
542
static int scsi_debug_virtual_gb = DEF_VIRTUAL_GB;
543
static int scsi_debug_vpd_use_hostno = DEF_VPD_USE_HOSTNO;
544
545
546
static unsigned int scsi_debug_lbpu = DEF_LBPU;
static unsigned int scsi_debug_lbpws = DEF_LBPWS;
static unsigned int scsi_debug_lbpws10 = DEF_LBPWS10;
547
static unsigned int scsi_debug_lbprz = DEF_LBPRZ;
548
static unsigned int scsi_debug_unmap_alignment = DEF_UNMAP_ALIGNMENT;
549
550
551
552
static unsigned int scsi_debug_unmap_granularity = DEF_UNMAP_GRANULARITY;
static unsigned int scsi_debug_unmap_max_blocks = DEF_UNMAP_MAX_BLOCKS;
static unsigned int scsi_debug_unmap_max_desc = DEF_UNMAP_MAX_DESC;
static unsigned int scsi_debug_write_same_length = DEF_WRITESAME_LENGTH;
553
static bool scsi_debug_removable = DEF_REMOVABLE;
554
static bool scsi_debug_clustering;
555
static bool scsi_debug_host_lock = DEF_HOST_LOCK;
556
static bool scsi_debug_strict = DEF_STRICT;
557
static bool sdebug_any_injecting_opt;
Linus Torvalds's avatar
Linus Torvalds committed
558

559
560
561
static atomic_t sdebug_cmnd_count;
static atomic_t sdebug_completions;
static atomic_t sdebug_a_tsf;		/* counter of 'almost' TSFs */
Linus Torvalds's avatar
Linus Torvalds committed
562
563
564

#define DEV_READONLY(TGT)      (0)

565
static unsigned int sdebug_store_sectors;
Linus Torvalds's avatar
Linus Torvalds committed
566
567
568
569
570
571
572
573
574
575
static sector_t sdebug_capacity;	/* in sectors */

/* old BIOS stuff, kernel may get rid of them but some mode sense pages
   may still need them */
static int sdebug_heads;		/* heads per disk */
static int sdebug_cylinders_per;	/* cylinders per surface */
static int sdebug_sectors_per;		/* sectors per cylinder */

#define SDEBUG_MAX_PARTS 4

576
#define SCSI_DEBUG_MAX_CMD_LEN 32
577

578
579
static unsigned int scsi_debug_lbp(void)
{
580
581
	return ((0 == scsi_debug_fake_rw) &&
		(scsi_debug_lbpu | scsi_debug_lbpws | scsi_debug_lbpws10));
582
583
}

Linus Torvalds's avatar
Linus Torvalds committed
584
585
586
587
struct sdebug_dev_info {
	struct list_head dev_list;
	unsigned int channel;
	unsigned int target;
Hannes Reinecke's avatar
Hannes Reinecke committed
588
	u64 lun;
Linus Torvalds's avatar
Linus Torvalds committed
589
	struct sdebug_host_info *sdbg_host;
590
591
	unsigned long uas_bm[1];
	atomic_t num_in_q;
592
593
	char stopped;		/* TODO: should be atomic */
	bool used;
Linus Torvalds's avatar
Linus Torvalds committed
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
};

struct sdebug_host_info {
	struct list_head host_list;
	struct Scsi_Host *shost;
	struct device dev;
	struct list_head dev_info_list;
};

#define to_sdebug_host(d)	\
	container_of(d, struct sdebug_host_info, dev)

static LIST_HEAD(sdebug_host_list);
static DEFINE_SPINLOCK(sdebug_host_list_lock);

609
610
611
612
613

struct sdebug_hrtimer {		/* ... is derived from hrtimer */
	struct hrtimer hrt;	/* must be first element */
	int qa_indx;
};
Linus Torvalds's avatar
Linus Torvalds committed
614
615

struct sdebug_queued_cmd {
616
617
618
619
	/* in_use flagged by a bit in queued_in_use_bm[] */
	struct timer_list *cmnd_timerp;
	struct tasklet_struct *tletp;
	struct sdebug_hrtimer *sd_hrtp;
Linus Torvalds's avatar
Linus Torvalds committed
620
621
622
	struct scsi_cmnd * a_cmnd;
};
static struct sdebug_queued_cmd queued_arr[SCSI_DEBUG_CANQUEUE];
623
624
static unsigned long queued_in_use_bm[SCSI_DEBUG_CANQUEUE_WORDS];

Linus Torvalds's avatar
Linus Torvalds committed
625
626

static unsigned char * fake_storep;	/* ramdisk storage */
627
static struct sd_dif_tuple *dif_storep;	/* protection info */
628
static void *map_storep;		/* provisioning map */
Linus Torvalds's avatar
Linus Torvalds committed
629

630
static unsigned long map_size;
631
632
633
634
635
static int num_aborts;
static int num_dev_resets;
static int num_target_resets;
static int num_bus_resets;
static int num_host_resets;
636
637
638
static int dix_writes;
static int dix_reads;
static int dif_errors;
Linus Torvalds's avatar
Linus Torvalds committed
639
640
641
642

static DEFINE_SPINLOCK(queued_arr_lock);
static DEFINE_RWLOCK(atomic_rw);

643
644
static char sdebug_proc_name[] = MY_NAME;
static const char *my_name = MY_NAME;
Linus Torvalds's avatar
Linus Torvalds committed
645
646
647
648
649
650
651
652
653
654
655

static struct bus_type pseudo_lld_bus;

static struct device_driver sdebug_driverfs_driver = {
	.name 		= sdebug_proc_name,
	.bus		= &pseudo_lld_bus,
};

static const int check_condition_result =
		(DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION;

656
657
658
static const int illegal_condition_result =
	(DRIVER_SENSE << 24) | (DID_ABORT << 16) | SAM_STAT_CHECK_CONDITION;

659
660
661
662
663
664
static const int device_qfull_result =
	(DID_OK << 16) | (COMMAND_COMPLETE << 8) | SAM_STAT_TASK_SET_FULL;

static unsigned char caching_pg[] = {0x8, 18, 0x14, 0, 0xff, 0xff, 0, 0,
				     0xff, 0xff, 0xff, 0xff, 0x80, 0x14, 0, 0,
				     0, 0, 0, 0};
665
666
667
668
669
static unsigned char ctrl_m_pg[] = {0xa, 10, 2, 0, 0, 0, 0, 0,
				    0, 0, 0x2, 0x4b};
static unsigned char iec_m_pg[] = {0x1c, 0xa, 0x08, 0, 0, 0, 0, 0,
			           0, 0, 0x0, 0x0};

670
671
672
673
674
675
676
677
678
679
680
681
682
683
static void *fake_store(unsigned long long lba)
{
	lba = do_div(lba, sdebug_store_sectors);

	return fake_storep + lba * scsi_debug_sector_size;
}

static struct sd_dif_tuple *dif_store(sector_t sector)
{
	sector = do_div(sector, sdebug_store_sectors);

	return dif_storep + sector;
}

Linus Torvalds's avatar
Linus Torvalds committed
684
685
686
static int sdebug_add_adapter(void);
static void sdebug_remove_adapter(void);

687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
static void sdebug_max_tgts_luns(void)
{
	struct sdebug_host_info *sdbg_host;
	struct Scsi_Host *hpnt;

	spin_lock(&sdebug_host_list_lock);
	list_for_each_entry(sdbg_host, &sdebug_host_list, host_list) {
		hpnt = sdbg_host->shost;
		if ((hpnt->this_id >= 0) &&
		    (scsi_debug_num_tgts > hpnt->this_id))
			hpnt->max_id = scsi_debug_num_tgts + 1;
		else
			hpnt->max_id = scsi_debug_num_tgts;
		/* scsi_debug_max_luns; */
		hpnt->max_lun = SAM2_WLUN_REPORT_LUNS;
	}
	spin_unlock(&sdebug_host_list_lock);
}

706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
enum sdeb_cmd_data {SDEB_IN_DATA = 0, SDEB_IN_CDB = 1};

/* Set in_bit to -1 to indicate no bit position of invalid field */
static void
mk_sense_invalid_fld(struct scsi_cmnd *scp, enum sdeb_cmd_data c_d,
		     int in_byte, int in_bit)
{
	unsigned char *sbuff;
	u8 sks[4];
	int sl, asc;

	sbuff = scp->sense_buffer;
	if (!sbuff) {
		sdev_printk(KERN_ERR, scp->device,
			    "%s: sense_buffer is NULL\n", __func__);
		return;
	}
	asc = c_d ? INVALID_FIELD_IN_CDB : INVALID_FIELD_IN_PARAM_LIST;
	memset(sbuff, 0, SCSI_SENSE_BUFFERSIZE);
	scsi_build_sense_buffer(scsi_debug_dsense, sbuff, ILLEGAL_REQUEST,
				asc, 0);
	memset(sks, 0, sizeof(sks));
	sks[0] = 0x80;
	if (c_d)
		sks[0] |= 0x40;
	if (in_bit >= 0) {
		sks[0] |= 0x8;
		sks[0] |= 0x7 & in_bit;
	}
	put_unaligned_be16(in_byte, sks + 1);
	if (scsi_debug_dsense) {
		sl = sbuff[7] + 8;
		sbuff[7] = sl;
		sbuff[sl] = 0x2;
		sbuff[sl + 1] = 0x6;
		memcpy(sbuff + sl + 4, sks, 3);
	} else
		memcpy(sbuff + 15, sks, 3);
	if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
		sdev_printk(KERN_INFO, scp->device, "%s:  [sense_key,asc,ascq"
			    "]: [0x5,0x%x,0x0] %c byte=%d, bit=%d\n",
			    my_name, asc, c_d ? 'C' : 'D', in_byte, in_bit);
}

750
static void mk_sense_buffer(struct scsi_cmnd *scp, int key, int asc, int asq)
751
752
753
{
	unsigned char *sbuff;

754
755
756
757
758
759
760
	sbuff = scp->sense_buffer;
	if (!sbuff) {
		sdev_printk(KERN_ERR, scp->device,
			    "%s: sense_buffer is NULL\n", __func__);
		return;
	}
	memset(sbuff, 0, SCSI_SENSE_BUFFERSIZE);
761
762
763
764

	scsi_build_sense_buffer(scsi_debug_dsense, sbuff, key, asc, asq);

	if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
765
766
767
		sdev_printk(KERN_INFO, scp->device,
			    "%s:  [sense_key,asc,ascq]: [0x%x,0x%x,0x%x]\n",
			    my_name, key, asc, asq);
768
}
Linus Torvalds's avatar
Linus Torvalds committed
769

770
771
772
773
774
775
static void
mk_sense_invalid_opcode(struct scsi_cmnd *scp)
{
	mk_sense_buffer(scp, ILLEGAL_REQUEST, INVALID_OPCODE, 0);
}

Linus Torvalds's avatar
Linus Torvalds committed
776
777
778
static int scsi_debug_ioctl(struct scsi_device *dev, int cmd, void __user *arg)
{
	if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) {
779
780
781
782
783
784
785
786
787
788
		if (0x1261 == cmd)
			sdev_printk(KERN_INFO, dev,
				    "%s: BLKFLSBUF [0x1261]\n", __func__);
		else if (0x5331 == cmd)
			sdev_printk(KERN_INFO, dev,
				    "%s: CDROM_GET_CAPABILITY [0x5331]\n",
				    __func__);
		else
			sdev_printk(KERN_INFO, dev, "%s: cmd=0x%x\n",
				    __func__, cmd);
Linus Torvalds's avatar
Linus Torvalds committed
789
790
791
792
793
	}
	return -EINVAL;
	/* return -ENOTTY; // correct return but upsets fdisk */
}

794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
static void clear_luns_changed_on_target(struct sdebug_dev_info *devip)
{
	struct sdebug_host_info *sdhp;
	struct sdebug_dev_info *dp;

	spin_lock(&sdebug_host_list_lock);
	list_for_each_entry(sdhp, &sdebug_host_list, host_list) {
		list_for_each_entry(dp, &sdhp->dev_info_list, dev_list) {
			if ((devip->sdbg_host == dp->sdbg_host) &&
			    (devip->target == dp->target))
				clear_bit(SDEBUG_UA_LUNS_CHANGED, dp->uas_bm);
		}
	}
	spin_unlock(&sdebug_host_list_lock);
}

810
static int check_readiness(struct scsi_cmnd *SCpnt, int uas_only,
811
			   struct sdebug_dev_info * devip)
Linus Torvalds's avatar
Linus Torvalds committed
812
{
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
	int k;
	bool debug = !!(SCSI_DEBUG_OPT_NOISE & scsi_debug_opts);

	k = find_first_bit(devip->uas_bm, SDEBUG_NUM_UAS);
	if (k != SDEBUG_NUM_UAS) {
		const char *cp = NULL;

		switch (k) {
		case SDEBUG_UA_POR:
			mk_sense_buffer(SCpnt, UNIT_ATTENTION,
					UA_RESET_ASC, POWER_ON_RESET_ASCQ);
			if (debug)
				cp = "power on reset";
			break;
		case SDEBUG_UA_BUS_RESET:
			mk_sense_buffer(SCpnt, UNIT_ATTENTION,
					UA_RESET_ASC, BUS_RESET_ASCQ);
			if (debug)
				cp = "bus reset";
			break;
		case SDEBUG_UA_MODE_CHANGED:
			mk_sense_buffer(SCpnt, UNIT_ATTENTION,
					UA_CHANGED_ASC, MODE_CHANGED_ASCQ);
			if (debug)
				cp = "mode parameters changed";
			break;
839
840
841
842
843
		case SDEBUG_UA_CAPACITY_CHANGED:
			mk_sense_buffer(SCpnt, UNIT_ATTENTION,
					UA_CHANGED_ASC, CAPACITY_CHANGED_ASCQ);
			if (debug)
				cp = "capacity data changed";
844
			break;
845
846
847
848
849
850
851
852
853
854
855
856
857
		case SDEBUG_UA_MICROCODE_CHANGED:
			mk_sense_buffer(SCpnt, UNIT_ATTENTION,
				 TARGET_CHANGED_ASC, MICROCODE_CHANGED_ASCQ);
			if (debug)
				cp = "microcode has been changed";
			break;
		case SDEBUG_UA_MICROCODE_CHANGED_WO_RESET:
			mk_sense_buffer(SCpnt, UNIT_ATTENTION,
					TARGET_CHANGED_ASC,
					MICROCODE_CHANGED_WO_RESET_ASCQ);
			if (debug)
				cp = "microcode has been changed without reset";
			break;
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
		case SDEBUG_UA_LUNS_CHANGED:
			/*
			 * SPC-3 behavior is to report a UNIT ATTENTION with
			 * ASC/ASCQ REPORTED LUNS DATA HAS CHANGED on every LUN
			 * on the target, until a REPORT LUNS command is
			 * received.  SPC-4 behavior is to report it only once.
			 * NOTE:  scsi_debug_scsi_level does not use the same
			 * values as struct scsi_device->scsi_level.
			 */
			if (scsi_debug_scsi_level >= 6)	/* SPC-4 and above */
				clear_luns_changed_on_target(devip);
			mk_sense_buffer(SCpnt, UNIT_ATTENTION,
					TARGET_CHANGED_ASC,
					LUNS_CHANGED_ASCQ);
			if (debug)
				cp = "reported luns data has changed";
			break;
875
876
877
878
879
880
881
882
883
884
885
886
		default:
			pr_warn("%s: unexpected unit attention code=%d\n",
				__func__, k);
			if (debug)
				cp = "unknown";
			break;
		}
		clear_bit(k, devip->uas_bm);
		if (debug)
			sdev_printk(KERN_INFO, SCpnt->device,
				   "%s reports: Unit attention: %s\n",
				   my_name, cp);
Linus Torvalds's avatar
Linus Torvalds committed
887
888
		return check_condition_result;
	}
889
890
	if ((UAS_TUR == uas_only) && devip->stopped) {
		mk_sense_buffer(SCpnt, NOT_READY, LOGICAL_UNIT_NOT_READY,
891
				0x2);
892
893
894
895
		if (debug)
			sdev_printk(KERN_INFO, SCpnt->device,
				    "%s reports: Not ready: %s\n", my_name,
				    "initializing command required");
896
897
		return check_condition_result;
	}
Linus Torvalds's avatar
Linus Torvalds committed
898
899
900
901
	return 0;
}

/* Returns 0 if ok else (DID_ERROR << 16). Sets scp->resid . */
902
static int fill_from_dev_buffer(struct scsi_cmnd *scp, unsigned char *arr,
Linus Torvalds's avatar
Linus Torvalds committed
903
904
				int arr_len)
{
905
	int act_len;
906
	struct scsi_data_buffer *sdb = scsi_in(scp);
Linus Torvalds's avatar
Linus Torvalds committed
907

908
	if (!sdb->length)
Linus Torvalds's avatar
Linus Torvalds committed
909
		return 0;
910
	if (!(scsi_bidi_cmnd(scp) || scp->sc_data_direction == DMA_FROM_DEVICE))
Linus Torvalds's avatar
Linus Torvalds committed
911
		return (DID_ERROR << 16);
912
913
914

	act_len = sg_copy_from_buffer(sdb->table.sgl, sdb->table.nents,
				      arr, arr_len);
915
	sdb->resid = scsi_bufflen(scp) - act_len;
916

Linus Torvalds's avatar
Linus Torvalds committed
917
918
919
920
	return 0;
}

/* Returns number of bytes fetched into 'arr' or -1 if error. */
921
922
static int fetch_to_dev_buffer(struct scsi_cmnd *scp, unsigned char *arr,
			       int arr_len)
Linus Torvalds's avatar
Linus Torvalds committed
923
{
924
	if (!scsi_bufflen(scp))
Linus Torvalds's avatar
Linus Torvalds committed
925
		return 0;
926
	if (!(scsi_bidi_cmnd(scp) || scp->sc_data_direction == DMA_TO_DEVICE))
Linus Torvalds's avatar
Linus Torvalds committed
927
		return -1;
928
929

	return scsi_sg_copy_to_buffer(scp, arr, arr_len);
Linus Torvalds's avatar
Linus Torvalds committed
930
931
932
933
934
}


static const char * inq_vendor_id = "Linux   ";
static const char * inq_product_id = "scsi_debug      ";
935
static const char *inq_product_rev = "0184";	/* version less '.' */
Linus Torvalds's avatar
Linus Torvalds committed
936

937
/* Device identification VPD page. Returns number of bytes placed in arr */
938
939
940
static int inquiry_evpd_83(unsigned char * arr, int port_group_id,
			   int target_dev_id, int dev_id_num,
			   const char * dev_id_str,
941
			   int dev_id_str_len)
Linus Torvalds's avatar
Linus Torvalds committed
942
{
943
944
	int num, port_a;
	char b[32];
Linus Torvalds's avatar
Linus Torvalds committed
945

946
	port_a = target_dev_id + 1;
Linus Torvalds's avatar
Linus Torvalds committed
947
948
949
950
951
952
953
954
955
956
	/* T10 vendor identifier field format (faked) */
	arr[0] = 0x2;	/* ASCII */
	arr[1] = 0x1;
	arr[2] = 0x0;
	memcpy(&arr[4], inq_vendor_id, 8);
	memcpy(&arr[12], inq_product_id, 16);
	memcpy(&arr[28], dev_id_str, dev_id_str_len);
	num = 8 + 16 + dev_id_str_len;
	arr[3] = num;
	num += 4;
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
	if (dev_id_num >= 0) {
		/* NAA-5, Logical unit identifier (binary) */
		arr[num++] = 0x1;	/* binary (not necessarily sas) */
		arr[num++] = 0x3;	/* PIV=0, lu, naa */
		arr[num++] = 0x0;
		arr[num++] = 0x8;
		arr[num++] = 0x53;  /* naa-5 ieee company id=0x333333 (fake) */
		arr[num++] = 0x33;
		arr[num++] = 0x33;
		arr[num++] = 0x30;
		arr[num++] = (dev_id_num >> 24);
		arr[num++] = (dev_id_num >> 16) & 0xff;
		arr[num++] = (dev_id_num >> 8) & 0xff;
		arr[num++] = dev_id_num & 0xff;
		/* Target relative port number */
		arr[num++] = 0x61;	/* proto=sas, binary */
		arr[num++] = 0x94;	/* PIV=1, target port, rel port */
		arr[num++] = 0x0;	/* reserved */
		arr[num++] = 0x4;	/* length */
		arr[num++] = 0x0;	/* reserved */
		arr[num++] = 0x0;	/* reserved */
		arr[num++] = 0x0;
		arr[num++] = 0x1;	/* relative port A */
	}
	/* NAA-5, Target port identifier */
	arr[num++] = 0x61;	/* proto=sas, binary */
	arr[num++] = 0x93;	/* piv=1, target port, naa */
	arr[num++] = 0x0;
	arr[num++] = 0x8;
	arr[num++] = 0x52;	/* naa-5, company id=0x222222 (fake) */
	arr[num++] = 0x22;
	arr[num++] = 0x22;
	arr[num++] = 0x20;
	arr[num++] = (port_a >> 24);
	arr[num++] = (port_a >> 16) & 0xff;
	arr[num++] = (port_a >> 8) & 0xff;
	arr[num++] = port_a & 0xff;
994
995
996
997
998
999
1000
	/* NAA-5, Target port group identifier */
	arr[num++] = 0x61;	/* proto=sas, binary */
	arr[num++] = 0x95;	/* piv=1, target port group id */
	arr[num++] = 0x0;
	arr[num++] = 0x4;
	arr[num++] = 0;
	arr[num++] = 0;
For faster browsing, not all history is shown. View entire blame