KVM: MMU: Move set_pte() into guest paging mode independent code
[deliverable/linux.git] / drivers / scsi / scsi_debug.c
CommitLineData
1da177e4 1/*
1da177e4
LT
2 * vvvvvvvvvvvvvvvvvvvvvvv Original vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
3 * Copyright (C) 1992 Eric Youngdale
4 * Simulate a host adapter with 2 disks attached. Do a lot of checking
5 * to make sure that we are not getting blocks mixed up, and PANIC if
6 * anything out of the ordinary is seen.
7 * ^^^^^^^^^^^^^^^^^^^^^^^ Original ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
8 *
9 * This version is more generic, simulating a variable number of disk
23183910
DG
10 * (or disk like devices) sharing a common amount of RAM. To be more
11 * realistic, the simulated devices have the transport attributes of
12 * SAS disks.
1da177e4
LT
13 *
14 *
15 * For documentation see http://www.torque.net/sg/sdebug26.html
16 *
17 * D. Gilbert (dpg) work for Magneto-Optical device test [20010421]
18 * dpg: work for devfs large number of disks [20010809]
19 * forked for lk 2.5 series [20011216, 20020101]
20 * use vmalloc() more inquiry+mode_sense [20020302]
21 * add timers for delayed responses [20020721]
22 * Patrick Mansfield <patmans@us.ibm.com> max_luns+scsi_level [20021031]
23 * Mike Anderson <andmike@us.ibm.com> sysfs work [20021118]
24 * dpg: change style of boot options to "scsi_debug.num_tgts=2" and
25 * module options to "modprobe scsi_debug num_tgts=2" [20021221]
26 */
27
1da177e4
LT
28#include <linux/module.h>
29
30#include <linux/kernel.h>
1da177e4
LT
31#include <linux/errno.h>
32#include <linux/timer.h>
33#include <linux/types.h>
34#include <linux/string.h>
35#include <linux/genhd.h>
36#include <linux/fs.h>
37#include <linux/init.h>
38#include <linux/proc_fs.h>
1da177e4
LT
39#include <linux/vmalloc.h>
40#include <linux/moduleparam.h>
852e034d 41#include <linux/scatterlist.h>
1da177e4
LT
42
43#include <linux/blkdev.h>
44#include "scsi.h"
45#include <scsi/scsi_host.h>
46#include <scsi/scsicam.h>
47
48#include <linux/stat.h>
49
1da177e4
LT
50#include "scsi_logging.h"
51#include "scsi_debug.h"
52
6f3cbf55
DG
53#define SCSI_DEBUG_VERSION "1.81"
54static const char * scsi_debug_version_date = "20070104";
1da177e4 55
6f3cbf55 56/* Additional Sense Code (ASC) */
c65b1445
DG
57#define NO_ADDITIONAL_SENSE 0x0
58#define LOGICAL_UNIT_NOT_READY 0x4
1da177e4 59#define UNRECOVERED_READ_ERR 0x11
c65b1445 60#define PARAMETER_LIST_LENGTH_ERR 0x1a
1da177e4
LT
61#define INVALID_OPCODE 0x20
62#define ADDR_OUT_OF_RANGE 0x21
63#define INVALID_FIELD_IN_CDB 0x24
c65b1445 64#define INVALID_FIELD_IN_PARAM_LIST 0x26
1da177e4
LT
65#define POWERON_RESET 0x29
66#define SAVING_PARAMS_UNSUP 0x39
6f3cbf55 67#define TRANSPORT_PROBLEM 0x4b
c65b1445
DG
68#define THRESHOLD_EXCEEDED 0x5d
69#define LOW_POWER_COND_ON 0x5e
1da177e4 70
6f3cbf55
DG
71/* Additional Sense Code Qualifier (ASCQ) */
72#define ACK_NAK_TO 0x3
73
1da177e4
LT
74#define SDEBUG_TAGGED_QUEUING 0 /* 0 | MSG_SIMPLE_TAG | MSG_ORDERED_TAG */
75
76/* Default values for driver parameters */
77#define DEF_NUM_HOST 1
78#define DEF_NUM_TGTS 1
79#define DEF_MAX_LUNS 1
80/* With these defaults, this driver will make 1 host with 1 target
81 * (id 0) containing 1 logical unit (lun 0). That is 1 device.
82 */
83#define DEF_DELAY 1
84#define DEF_DEV_SIZE_MB 8
85#define DEF_EVERY_NTH 0
86#define DEF_NUM_PARTS 0
87#define DEF_OPTS 0
88#define DEF_SCSI_LEVEL 5 /* INQUIRY, byte2 [5->SPC-3] */
89#define DEF_PTYPE 0
90#define DEF_D_SENSE 0
c65b1445
DG
91#define DEF_NO_LUN_0 0
92#define DEF_VIRTUAL_GB 0
23183910
DG
93#define DEF_FAKE_RW 0
94#define DEF_VPD_USE_HOSTNO 1
1da177e4
LT
95
96/* bit mask values for scsi_debug_opts */
97#define SCSI_DEBUG_OPT_NOISE 1
98#define SCSI_DEBUG_OPT_MEDIUM_ERR 2
99#define SCSI_DEBUG_OPT_TIMEOUT 4
100#define SCSI_DEBUG_OPT_RECOVERED_ERR 8
6f3cbf55 101#define SCSI_DEBUG_OPT_TRANSPORT_ERR 16
1da177e4
LT
102/* When "every_nth" > 0 then modulo "every_nth" commands:
103 * - a no response is simulated if SCSI_DEBUG_OPT_TIMEOUT is set
104 * - a RECOVERED_ERROR is simulated on successful read and write
105 * commands if SCSI_DEBUG_OPT_RECOVERED_ERR is set.
6f3cbf55
DG
106 * - a TRANSPORT_ERROR is simulated on successful read and write
107 * commands if SCSI_DEBUG_OPT_TRANSPORT_ERR is set.
1da177e4
LT
108 *
109 * When "every_nth" < 0 then after "- every_nth" commands:
110 * - a no response is simulated if SCSI_DEBUG_OPT_TIMEOUT is set
111 * - a RECOVERED_ERROR is simulated on successful read and write
112 * commands if SCSI_DEBUG_OPT_RECOVERED_ERR is set.
6f3cbf55
DG
113 * - a TRANSPORT_ERROR is simulated on successful read and write
114 * commands if SCSI_DEBUG_OPT_TRANSPORT_ERR is set.
1da177e4
LT
115 * This will continue until some other action occurs (e.g. the user
116 * writing a new value (other than -1 or 1) to every_nth via sysfs).
117 */
118
119/* when 1==SCSI_DEBUG_OPT_MEDIUM_ERR, a medium error is simulated at this
120 * sector on read commands: */
121#define OPT_MEDIUM_ERR_ADDR 0x1234 /* that's sector 4660 in decimal */
122
123/* If REPORT LUNS has luns >= 256 it can choose "flat space" (value 1)
124 * or "peripheral device" addressing (value 0) */
125#define SAM2_LUN_ADDRESS_METHOD 0
c65b1445 126#define SAM2_WLUN_REPORT_LUNS 0xc101
1da177e4
LT
127
128static int scsi_debug_add_host = DEF_NUM_HOST;
129static int scsi_debug_delay = DEF_DELAY;
130static int scsi_debug_dev_size_mb = DEF_DEV_SIZE_MB;
131static int scsi_debug_every_nth = DEF_EVERY_NTH;
132static int scsi_debug_max_luns = DEF_MAX_LUNS;
133static int scsi_debug_num_parts = DEF_NUM_PARTS;
134static int scsi_debug_num_tgts = DEF_NUM_TGTS; /* targets per host */
135static int scsi_debug_opts = DEF_OPTS;
136static int scsi_debug_scsi_level = DEF_SCSI_LEVEL;
137static int scsi_debug_ptype = DEF_PTYPE; /* SCSI peripheral type (0==disk) */
138static int scsi_debug_dsense = DEF_D_SENSE;
c65b1445
DG
139static int scsi_debug_no_lun_0 = DEF_NO_LUN_0;
140static int scsi_debug_virtual_gb = DEF_VIRTUAL_GB;
23183910
DG
141static int scsi_debug_fake_rw = DEF_FAKE_RW;
142static int scsi_debug_vpd_use_hostno = DEF_VPD_USE_HOSTNO;
1da177e4
LT
143
144static int scsi_debug_cmnd_count = 0;
145
146#define DEV_READONLY(TGT) (0)
147#define DEV_REMOVEABLE(TGT) (0)
148
c65b1445
DG
149static unsigned int sdebug_store_size; /* in bytes */
150static unsigned int sdebug_store_sectors;
1da177e4
LT
151static sector_t sdebug_capacity; /* in sectors */
152
153/* old BIOS stuff, kernel may get rid of them but some mode sense pages
154 may still need them */
155static int sdebug_heads; /* heads per disk */
156static int sdebug_cylinders_per; /* cylinders per surface */
157static int sdebug_sectors_per; /* sectors per cylinder */
158
159/* default sector size is 512 bytes, 2**9 bytes */
160#define POW2_SECT_SIZE 9
161#define SECT_SIZE (1 << POW2_SECT_SIZE)
162#define SECT_SIZE_PER(TGT) SECT_SIZE
163
164#define SDEBUG_MAX_PARTS 4
165
166#define SDEBUG_SENSE_LEN 32
167
168struct sdebug_dev_info {
169 struct list_head dev_list;
170 unsigned char sense_buff[SDEBUG_SENSE_LEN]; /* weak nexus */
171 unsigned int channel;
172 unsigned int target;
173 unsigned int lun;
174 struct sdebug_host_info *sdbg_host;
c65b1445 175 unsigned int wlun;
1da177e4 176 char reset;
c65b1445 177 char stopped;
1da177e4
LT
178 char used;
179};
180
181struct sdebug_host_info {
182 struct list_head host_list;
183 struct Scsi_Host *shost;
184 struct device dev;
185 struct list_head dev_info_list;
186};
187
188#define to_sdebug_host(d) \
189 container_of(d, struct sdebug_host_info, dev)
190
191static LIST_HEAD(sdebug_host_list);
192static DEFINE_SPINLOCK(sdebug_host_list_lock);
193
194typedef void (* done_funct_t) (struct scsi_cmnd *);
195
196struct sdebug_queued_cmd {
197 int in_use;
198 struct timer_list cmnd_timer;
199 done_funct_t done_funct;
200 struct scsi_cmnd * a_cmnd;
201 int scsi_result;
202};
203static struct sdebug_queued_cmd queued_arr[SCSI_DEBUG_CANQUEUE];
204
d0be4a7d 205static struct scsi_host_template sdebug_driver_template = {
1da177e4
LT
206 .proc_info = scsi_debug_proc_info,
207 .name = "SCSI DEBUG",
208 .info = scsi_debug_info,
209 .slave_alloc = scsi_debug_slave_alloc,
210 .slave_configure = scsi_debug_slave_configure,
211 .slave_destroy = scsi_debug_slave_destroy,
212 .ioctl = scsi_debug_ioctl,
213 .queuecommand = scsi_debug_queuecommand,
214 .eh_abort_handler = scsi_debug_abort,
215 .eh_bus_reset_handler = scsi_debug_bus_reset,
216 .eh_device_reset_handler = scsi_debug_device_reset,
217 .eh_host_reset_handler = scsi_debug_host_reset,
218 .bios_param = scsi_debug_biosparam,
219 .can_queue = SCSI_DEBUG_CANQUEUE,
220 .this_id = 7,
c65b1445
DG
221 .sg_tablesize = 256,
222 .cmd_per_lun = 16,
223 .max_sectors = 0xffff,
1da177e4 224 .unchecked_isa_dma = 0,
c65b1445 225 .use_clustering = ENABLE_CLUSTERING,
1da177e4
LT
226 .module = THIS_MODULE,
227};
228
229static unsigned char * fake_storep; /* ramdisk storage */
230
231static int num_aborts = 0;
232static int num_dev_resets = 0;
233static int num_bus_resets = 0;
234static int num_host_resets = 0;
235
236static DEFINE_SPINLOCK(queued_arr_lock);
237static DEFINE_RWLOCK(atomic_rw);
238
239static char sdebug_proc_name[] = "scsi_debug";
240
241static int sdebug_driver_probe(struct device *);
242static int sdebug_driver_remove(struct device *);
243static struct bus_type pseudo_lld_bus;
244
245static struct device_driver sdebug_driverfs_driver = {
246 .name = sdebug_proc_name,
247 .bus = &pseudo_lld_bus,
1da177e4
LT
248};
249
250static const int check_condition_result =
251 (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION;
252
c65b1445
DG
253static unsigned char ctrl_m_pg[] = {0xa, 10, 2, 0, 0, 0, 0, 0,
254 0, 0, 0x2, 0x4b};
255static unsigned char iec_m_pg[] = {0x1c, 0xa, 0x08, 0, 0, 0, 0, 0,
256 0, 0, 0x0, 0x0};
257
1da177e4
LT
258/* function declarations */
259static int resp_inquiry(struct scsi_cmnd * SCpnt, int target,
260 struct sdebug_dev_info * devip);
261static int resp_requests(struct scsi_cmnd * SCpnt,
262 struct sdebug_dev_info * devip);
c65b1445
DG
263static int resp_start_stop(struct scsi_cmnd * scp,
264 struct sdebug_dev_info * devip);
5a09e398
HR
265static int resp_report_tgtpgs(struct scsi_cmnd * scp,
266 struct sdebug_dev_info * devip);
1da177e4
LT
267static int resp_readcap(struct scsi_cmnd * SCpnt,
268 struct sdebug_dev_info * devip);
c65b1445
DG
269static int resp_readcap16(struct scsi_cmnd * SCpnt,
270 struct sdebug_dev_info * devip);
271static int resp_mode_sense(struct scsi_cmnd * scp, int target,
1da177e4 272 struct sdebug_dev_info * devip);
c65b1445
DG
273static int resp_mode_select(struct scsi_cmnd * scp, int mselect6,
274 struct sdebug_dev_info * devip);
275static int resp_log_sense(struct scsi_cmnd * scp,
276 struct sdebug_dev_info * devip);
277static int resp_read(struct scsi_cmnd * SCpnt, unsigned long long lba,
278 unsigned int num, struct sdebug_dev_info * devip);
279static int resp_write(struct scsi_cmnd * SCpnt, unsigned long long lba,
280 unsigned int num, struct sdebug_dev_info * devip);
1da177e4
LT
281static int resp_report_luns(struct scsi_cmnd * SCpnt,
282 struct sdebug_dev_info * devip);
283static int fill_from_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr,
284 int arr_len);
285static int fetch_to_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr,
286 int max_arr_len);
287static void timer_intr_handler(unsigned long);
288static struct sdebug_dev_info * devInfoReg(struct scsi_device * sdev);
289static void mk_sense_buffer(struct sdebug_dev_info * devip, int key,
290 int asc, int asq);
c65b1445
DG
291static int check_readiness(struct scsi_cmnd * SCpnt, int reset_only,
292 struct sdebug_dev_info * devip);
1da177e4
LT
293static int schedule_resp(struct scsi_cmnd * cmnd,
294 struct sdebug_dev_info * devip,
295 done_funct_t done, int scsi_result, int delta_jiff);
296static void __init sdebug_build_parts(unsigned char * ramp);
297static void __init init_all_queued(void);
298static void stop_all_queued(void);
299static int stop_queued_cmnd(struct scsi_cmnd * cmnd);
5a09e398
HR
300static int inquiry_evpd_83(unsigned char * arr, int port_group_id,
301 int target_dev_id, int dev_id_num,
302 const char * dev_id_str, int dev_id_str_len);
c65b1445 303static int inquiry_evpd_88(unsigned char * arr, int target_dev_id);
6ecaff7f 304static int do_create_driverfs_files(void);
1da177e4
LT
305static void do_remove_driverfs_files(void);
306
307static int sdebug_add_adapter(void);
308static void sdebug_remove_adapter(void);
309static void sdebug_max_tgts_luns(void);
310
311static struct device pseudo_primary;
312static struct bus_type pseudo_lld_bus;
313
314
315static
316int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done)
317{
318 unsigned char *cmd = (unsigned char *) SCpnt->cmnd;
c65b1445
DG
319 int len, k, j;
320 unsigned int num;
321 unsigned long long lba;
1da177e4 322 int errsts = 0;
c65b1445 323 int target = SCpnt->device->id;
1da177e4
LT
324 struct sdebug_dev_info * devip = NULL;
325 int inj_recovered = 0;
6f3cbf55 326 int inj_transport = 0;
c65b1445 327 int delay_override = 0;
1da177e4
LT
328
329 if (done == NULL)
330 return 0; /* assume mid level reprocessing command */
331
c73961e5 332 scsi_set_resid(SCpnt, 0);
1da177e4
LT
333 if ((SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) && cmd) {
334 printk(KERN_INFO "scsi_debug: cmd ");
c65b1445 335 for (k = 0, len = SCpnt->cmd_len; k < len; ++k)
1da177e4
LT
336 printk("%02x ", (int)cmd[k]);
337 printk("\n");
338 }
339 if(target == sdebug_driver_template.this_id) {
340 printk(KERN_INFO "scsi_debug: initiator's id used as "
341 "target!\n");
342 return schedule_resp(SCpnt, NULL, done,
343 DID_NO_CONNECT << 16, 0);
344 }
345
c65b1445
DG
346 if ((SCpnt->device->lun >= scsi_debug_max_luns) &&
347 (SCpnt->device->lun != SAM2_WLUN_REPORT_LUNS))
1da177e4
LT
348 return schedule_resp(SCpnt, NULL, done,
349 DID_NO_CONNECT << 16, 0);
350 devip = devInfoReg(SCpnt->device);
351 if (NULL == devip)
352 return schedule_resp(SCpnt, NULL, done,
353 DID_NO_CONNECT << 16, 0);
354
355 if ((scsi_debug_every_nth != 0) &&
356 (++scsi_debug_cmnd_count >= abs(scsi_debug_every_nth))) {
357 scsi_debug_cmnd_count = 0;
358 if (scsi_debug_every_nth < -1)
359 scsi_debug_every_nth = -1;
360 if (SCSI_DEBUG_OPT_TIMEOUT & scsi_debug_opts)
361 return 0; /* ignore command causing timeout */
362 else if (SCSI_DEBUG_OPT_RECOVERED_ERR & scsi_debug_opts)
363 inj_recovered = 1; /* to reads and writes below */
6f3cbf55
DG
364 else if (SCSI_DEBUG_OPT_TRANSPORT_ERR & scsi_debug_opts)
365 inj_transport = 1; /* to reads and writes below */
1da177e4
LT
366 }
367
c65b1445
DG
368 if (devip->wlun) {
369 switch (*cmd) {
370 case INQUIRY:
371 case REQUEST_SENSE:
372 case TEST_UNIT_READY:
373 case REPORT_LUNS:
374 break; /* only allowable wlun commands */
375 default:
376 if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
377 printk(KERN_INFO "scsi_debug: Opcode: 0x%x "
378 "not supported for wlun\n", *cmd);
379 mk_sense_buffer(devip, ILLEGAL_REQUEST,
380 INVALID_OPCODE, 0);
381 errsts = check_condition_result;
382 return schedule_resp(SCpnt, devip, done, errsts,
383 0);
384 }
385 }
386
1da177e4
LT
387 switch (*cmd) {
388 case INQUIRY: /* mandatory, ignore unit attention */
c65b1445 389 delay_override = 1;
1da177e4
LT
390 errsts = resp_inquiry(SCpnt, target, devip);
391 break;
392 case REQUEST_SENSE: /* mandatory, ignore unit attention */
c65b1445 393 delay_override = 1;
1da177e4
LT
394 errsts = resp_requests(SCpnt, devip);
395 break;
396 case REZERO_UNIT: /* actually this is REWIND for SSC */
397 case START_STOP:
c65b1445 398 errsts = resp_start_stop(SCpnt, devip);
1da177e4
LT
399 break;
400 case ALLOW_MEDIUM_REMOVAL:
c65b1445 401 if ((errsts = check_readiness(SCpnt, 1, devip)))
1da177e4
LT
402 break;
403 if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
404 printk(KERN_INFO "scsi_debug: Medium removal %s\n",
405 cmd[4] ? "inhibited" : "enabled");
406 break;
407 case SEND_DIAGNOSTIC: /* mandatory */
c65b1445 408 errsts = check_readiness(SCpnt, 1, devip);
1da177e4
LT
409 break;
410 case TEST_UNIT_READY: /* mandatory */
c65b1445
DG
411 delay_override = 1;
412 errsts = check_readiness(SCpnt, 0, devip);
1da177e4
LT
413 break;
414 case RESERVE:
c65b1445 415 errsts = check_readiness(SCpnt, 1, devip);
1da177e4
LT
416 break;
417 case RESERVE_10:
c65b1445 418 errsts = check_readiness(SCpnt, 1, devip);
1da177e4
LT
419 break;
420 case RELEASE:
c65b1445 421 errsts = check_readiness(SCpnt, 1, devip);
1da177e4
LT
422 break;
423 case RELEASE_10:
c65b1445 424 errsts = check_readiness(SCpnt, 1, devip);
1da177e4
LT
425 break;
426 case READ_CAPACITY:
427 errsts = resp_readcap(SCpnt, devip);
428 break;
c65b1445
DG
429 case SERVICE_ACTION_IN:
430 if (SAI_READ_CAPACITY_16 != cmd[1]) {
431 mk_sense_buffer(devip, ILLEGAL_REQUEST,
432 INVALID_OPCODE, 0);
433 errsts = check_condition_result;
434 break;
435 }
436 errsts = resp_readcap16(SCpnt, devip);
437 break;
5a09e398
HR
438 case MAINTENANCE_IN:
439 if (MI_REPORT_TARGET_PGS != cmd[1]) {
440 mk_sense_buffer(devip, ILLEGAL_REQUEST,
441 INVALID_OPCODE, 0);
442 errsts = check_condition_result;
443 break;
444 }
445 errsts = resp_report_tgtpgs(SCpnt, devip);
446 break;
1da177e4
LT
447 case READ_16:
448 case READ_12:
449 case READ_10:
450 case READ_6:
c65b1445 451 if ((errsts = check_readiness(SCpnt, 0, devip)))
1da177e4 452 break;
23183910
DG
453 if (scsi_debug_fake_rw)
454 break;
1da177e4 455 if ((*cmd) == READ_16) {
c65b1445
DG
456 for (lba = 0, j = 0; j < 8; ++j) {
457 if (j > 0)
458 lba <<= 8;
459 lba += cmd[2 + j];
460 }
1da177e4
LT
461 num = cmd[13] + (cmd[12] << 8) +
462 (cmd[11] << 16) + (cmd[10] << 24);
463 } else if ((*cmd) == READ_12) {
c65b1445 464 lba = cmd[5] + (cmd[4] << 8) +
1da177e4
LT
465 (cmd[3] << 16) + (cmd[2] << 24);
466 num = cmd[9] + (cmd[8] << 8) +
467 (cmd[7] << 16) + (cmd[6] << 24);
468 } else if ((*cmd) == READ_10) {
c65b1445 469 lba = cmd[5] + (cmd[4] << 8) +
1da177e4
LT
470 (cmd[3] << 16) + (cmd[2] << 24);
471 num = cmd[8] + (cmd[7] << 8);
c65b1445
DG
472 } else { /* READ (6) */
473 lba = cmd[3] + (cmd[2] << 8) +
1da177e4 474 ((cmd[1] & 0x1f) << 16);
c65b1445 475 num = (0 == cmd[4]) ? 256 : cmd[4];
1da177e4 476 }
c65b1445 477 errsts = resp_read(SCpnt, lba, num, devip);
1da177e4
LT
478 if (inj_recovered && (0 == errsts)) {
479 mk_sense_buffer(devip, RECOVERED_ERROR,
c65b1445 480 THRESHOLD_EXCEEDED, 0);
1da177e4 481 errsts = check_condition_result;
6f3cbf55
DG
482 } else if (inj_transport && (0 == errsts)) {
483 mk_sense_buffer(devip, ABORTED_COMMAND,
484 TRANSPORT_PROBLEM, ACK_NAK_TO);
485 errsts = check_condition_result;
486 }
1da177e4
LT
487 break;
488 case REPORT_LUNS: /* mandatory, ignore unit attention */
c65b1445 489 delay_override = 1;
1da177e4
LT
490 errsts = resp_report_luns(SCpnt, devip);
491 break;
492 case VERIFY: /* 10 byte SBC-2 command */
c65b1445 493 errsts = check_readiness(SCpnt, 0, devip);
1da177e4
LT
494 break;
495 case WRITE_16:
496 case WRITE_12:
497 case WRITE_10:
498 case WRITE_6:
c65b1445 499 if ((errsts = check_readiness(SCpnt, 0, devip)))
1da177e4 500 break;
23183910
DG
501 if (scsi_debug_fake_rw)
502 break;
1da177e4 503 if ((*cmd) == WRITE_16) {
c65b1445
DG
504 for (lba = 0, j = 0; j < 8; ++j) {
505 if (j > 0)
506 lba <<= 8;
507 lba += cmd[2 + j];
508 }
1da177e4
LT
509 num = cmd[13] + (cmd[12] << 8) +
510 (cmd[11] << 16) + (cmd[10] << 24);
511 } else if ((*cmd) == WRITE_12) {
c65b1445 512 lba = cmd[5] + (cmd[4] << 8) +
1da177e4
LT
513 (cmd[3] << 16) + (cmd[2] << 24);
514 num = cmd[9] + (cmd[8] << 8) +
515 (cmd[7] << 16) + (cmd[6] << 24);
516 } else if ((*cmd) == WRITE_10) {
c65b1445 517 lba = cmd[5] + (cmd[4] << 8) +
1da177e4
LT
518 (cmd[3] << 16) + (cmd[2] << 24);
519 num = cmd[8] + (cmd[7] << 8);
c65b1445
DG
520 } else { /* WRITE (6) */
521 lba = cmd[3] + (cmd[2] << 8) +
1da177e4 522 ((cmd[1] & 0x1f) << 16);
c65b1445 523 num = (0 == cmd[4]) ? 256 : cmd[4];
1da177e4 524 }
c65b1445 525 errsts = resp_write(SCpnt, lba, num, devip);
1da177e4
LT
526 if (inj_recovered && (0 == errsts)) {
527 mk_sense_buffer(devip, RECOVERED_ERROR,
c65b1445 528 THRESHOLD_EXCEEDED, 0);
1da177e4
LT
529 errsts = check_condition_result;
530 }
531 break;
532 case MODE_SENSE:
533 case MODE_SENSE_10:
534 errsts = resp_mode_sense(SCpnt, target, devip);
535 break;
c65b1445
DG
536 case MODE_SELECT:
537 errsts = resp_mode_select(SCpnt, 1, devip);
538 break;
539 case MODE_SELECT_10:
540 errsts = resp_mode_select(SCpnt, 0, devip);
541 break;
542 case LOG_SENSE:
543 errsts = resp_log_sense(SCpnt, devip);
544 break;
1da177e4 545 case SYNCHRONIZE_CACHE:
c65b1445
DG
546 delay_override = 1;
547 errsts = check_readiness(SCpnt, 0, devip);
1da177e4 548 break;
6f3cbf55
DG
549 case WRITE_BUFFER:
550 errsts = check_readiness(SCpnt, 1, devip);
551 break;
1da177e4
LT
552 default:
553 if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
554 printk(KERN_INFO "scsi_debug: Opcode: 0x%x not "
555 "supported\n", *cmd);
c65b1445 556 if ((errsts = check_readiness(SCpnt, 1, devip)))
1da177e4
LT
557 break; /* Unit attention takes precedence */
558 mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_OPCODE, 0);
559 errsts = check_condition_result;
560 break;
561 }
c65b1445
DG
562 return schedule_resp(SCpnt, devip, done, errsts,
563 (delay_override ? 0 : scsi_debug_delay));
1da177e4
LT
564}
565
566static int scsi_debug_ioctl(struct scsi_device *dev, int cmd, void __user *arg)
567{
568 if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) {
569 printk(KERN_INFO "scsi_debug: ioctl: cmd=0x%x\n", cmd);
570 }
571 return -EINVAL;
572 /* return -ENOTTY; // correct return but upsets fdisk */
573}
574
c65b1445
DG
575static int check_readiness(struct scsi_cmnd * SCpnt, int reset_only,
576 struct sdebug_dev_info * devip)
1da177e4
LT
577{
578 if (devip->reset) {
579 if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
580 printk(KERN_INFO "scsi_debug: Reporting Unit "
581 "attention: power on reset\n");
582 devip->reset = 0;
583 mk_sense_buffer(devip, UNIT_ATTENTION, POWERON_RESET, 0);
584 return check_condition_result;
585 }
c65b1445
DG
586 if ((0 == reset_only) && devip->stopped) {
587 if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
588 printk(KERN_INFO "scsi_debug: Reporting Not "
589 "ready: initializing command required\n");
590 mk_sense_buffer(devip, NOT_READY, LOGICAL_UNIT_NOT_READY,
591 0x2);
592 return check_condition_result;
593 }
1da177e4
LT
594 return 0;
595}
596
597/* Returns 0 if ok else (DID_ERROR << 16). Sets scp->resid . */
598static int fill_from_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr,
599 int arr_len)
600{
601 int k, req_len, act_len, len, active;
602 void * kaddr;
603 void * kaddr_off;
852e034d 604 struct scatterlist * sg;
1da177e4 605
c73961e5 606 if (0 == scsi_bufflen(scp))
1da177e4 607 return 0;
c73961e5 608 if (NULL == scsi_sglist(scp))
1da177e4
LT
609 return (DID_ERROR << 16);
610 if (! ((scp->sc_data_direction == DMA_BIDIRECTIONAL) ||
611 (scp->sc_data_direction == DMA_FROM_DEVICE)))
612 return (DID_ERROR << 16);
1da177e4 613 active = 1;
852e034d 614 req_len = act_len = 0;
c73961e5 615 scsi_for_each_sg(scp, sg, scsi_sg_count(scp), k) {
1da177e4
LT
616 if (active) {
617 kaddr = (unsigned char *)
45711f1a 618 kmap_atomic(sg_page(sg), KM_USER0);
1da177e4
LT
619 if (NULL == kaddr)
620 return (DID_ERROR << 16);
852e034d
JA
621 kaddr_off = (unsigned char *)kaddr + sg->offset;
622 len = sg->length;
1da177e4
LT
623 if ((req_len + len) > arr_len) {
624 active = 0;
625 len = arr_len - req_len;
626 }
627 memcpy(kaddr_off, arr + req_len, len);
628 kunmap_atomic(kaddr, KM_USER0);
629 act_len += len;
630 }
852e034d 631 req_len += sg->length;
1da177e4 632 }
c73961e5
BH
633 if (scsi_get_resid(scp))
634 scsi_set_resid(scp, scsi_get_resid(scp) - act_len);
c65b1445 635 else
c73961e5 636 scsi_set_resid(scp, req_len - act_len);
1da177e4
LT
637 return 0;
638}
639
640/* Returns number of bytes fetched into 'arr' or -1 if error. */
641static int fetch_to_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr,
642 int max_arr_len)
643{
644 int k, req_len, len, fin;
645 void * kaddr;
646 void * kaddr_off;
852e034d 647 struct scatterlist * sg;
1da177e4 648
c73961e5 649 if (0 == scsi_bufflen(scp))
1da177e4 650 return 0;
c73961e5 651 if (NULL == scsi_sglist(scp))
1da177e4
LT
652 return -1;
653 if (! ((scp->sc_data_direction == DMA_BIDIRECTIONAL) ||
654 (scp->sc_data_direction == DMA_TO_DEVICE)))
655 return -1;
852e034d 656 req_len = fin = 0;
c73961e5 657 scsi_for_each_sg(scp, sg, scsi_sg_count(scp), k) {
45711f1a 658 kaddr = (unsigned char *)kmap_atomic(sg_page(sg), KM_USER0);
1da177e4
LT
659 if (NULL == kaddr)
660 return -1;
852e034d
JA
661 kaddr_off = (unsigned char *)kaddr + sg->offset;
662 len = sg->length;
1da177e4
LT
663 if ((req_len + len) > max_arr_len) {
664 len = max_arr_len - req_len;
665 fin = 1;
666 }
667 memcpy(arr + req_len, kaddr_off, len);
668 kunmap_atomic(kaddr, KM_USER0);
669 if (fin)
670 return req_len + len;
852e034d 671 req_len += sg->length;
1da177e4
LT
672 }
673 return req_len;
674}
675
676
677static const char * inq_vendor_id = "Linux ";
678static const char * inq_product_id = "scsi_debug ";
679static const char * inq_product_rev = "0004";
680
5a09e398
HR
681static int inquiry_evpd_83(unsigned char * arr, int port_group_id,
682 int target_dev_id, int dev_id_num,
683 const char * dev_id_str,
c65b1445 684 int dev_id_str_len)
1da177e4 685{
c65b1445
DG
686 int num, port_a;
687 char b[32];
1da177e4 688
c65b1445 689 port_a = target_dev_id + 1;
1da177e4
LT
690 /* T10 vendor identifier field format (faked) */
691 arr[0] = 0x2; /* ASCII */
692 arr[1] = 0x1;
693 arr[2] = 0x0;
694 memcpy(&arr[4], inq_vendor_id, 8);
695 memcpy(&arr[12], inq_product_id, 16);
696 memcpy(&arr[28], dev_id_str, dev_id_str_len);
697 num = 8 + 16 + dev_id_str_len;
698 arr[3] = num;
699 num += 4;
c65b1445
DG
700 if (dev_id_num >= 0) {
701 /* NAA-5, Logical unit identifier (binary) */
702 arr[num++] = 0x1; /* binary (not necessarily sas) */
703 arr[num++] = 0x3; /* PIV=0, lu, naa */
704 arr[num++] = 0x0;
705 arr[num++] = 0x8;
706 arr[num++] = 0x53; /* naa-5 ieee company id=0x333333 (fake) */
707 arr[num++] = 0x33;
708 arr[num++] = 0x33;
709 arr[num++] = 0x30;
710 arr[num++] = (dev_id_num >> 24);
711 arr[num++] = (dev_id_num >> 16) & 0xff;
712 arr[num++] = (dev_id_num >> 8) & 0xff;
713 arr[num++] = dev_id_num & 0xff;
714 /* Target relative port number */
715 arr[num++] = 0x61; /* proto=sas, binary */
716 arr[num++] = 0x94; /* PIV=1, target port, rel port */
717 arr[num++] = 0x0; /* reserved */
718 arr[num++] = 0x4; /* length */
719 arr[num++] = 0x0; /* reserved */
720 arr[num++] = 0x0; /* reserved */
721 arr[num++] = 0x0;
722 arr[num++] = 0x1; /* relative port A */
723 }
724 /* NAA-5, Target port identifier */
725 arr[num++] = 0x61; /* proto=sas, binary */
726 arr[num++] = 0x93; /* piv=1, target port, naa */
727 arr[num++] = 0x0;
728 arr[num++] = 0x8;
729 arr[num++] = 0x52; /* naa-5, company id=0x222222 (fake) */
730 arr[num++] = 0x22;
731 arr[num++] = 0x22;
732 arr[num++] = 0x20;
733 arr[num++] = (port_a >> 24);
734 arr[num++] = (port_a >> 16) & 0xff;
735 arr[num++] = (port_a >> 8) & 0xff;
736 arr[num++] = port_a & 0xff;
5a09e398
HR
737 /* NAA-5, Target port group identifier */
738 arr[num++] = 0x61; /* proto=sas, binary */
739 arr[num++] = 0x95; /* piv=1, target port group id */
740 arr[num++] = 0x0;
741 arr[num++] = 0x4;
742 arr[num++] = 0;
743 arr[num++] = 0;
744 arr[num++] = (port_group_id >> 8) & 0xff;
745 arr[num++] = port_group_id & 0xff;
c65b1445
DG
746 /* NAA-5, Target device identifier */
747 arr[num++] = 0x61; /* proto=sas, binary */
748 arr[num++] = 0xa3; /* piv=1, target device, naa */
749 arr[num++] = 0x0;
750 arr[num++] = 0x8;
751 arr[num++] = 0x52; /* naa-5, company id=0x222222 (fake) */
752 arr[num++] = 0x22;
753 arr[num++] = 0x22;
754 arr[num++] = 0x20;
755 arr[num++] = (target_dev_id >> 24);
756 arr[num++] = (target_dev_id >> 16) & 0xff;
757 arr[num++] = (target_dev_id >> 8) & 0xff;
758 arr[num++] = target_dev_id & 0xff;
759 /* SCSI name string: Target device identifier */
760 arr[num++] = 0x63; /* proto=sas, UTF-8 */
761 arr[num++] = 0xa8; /* piv=1, target device, SCSI name string */
762 arr[num++] = 0x0;
763 arr[num++] = 24;
764 memcpy(arr + num, "naa.52222220", 12);
765 num += 12;
766 snprintf(b, sizeof(b), "%08X", target_dev_id);
767 memcpy(arr + num, b, 8);
768 num += 8;
769 memset(arr + num, 0, 4);
770 num += 4;
771 return num;
772}
773
774
775static unsigned char vpd84_data[] = {
776/* from 4th byte */ 0x22,0x22,0x22,0x0,0xbb,0x0,
777 0x22,0x22,0x22,0x0,0xbb,0x1,
778 0x22,0x22,0x22,0x0,0xbb,0x2,
779};
780
781static int inquiry_evpd_84(unsigned char * arr)
782{
783 memcpy(arr, vpd84_data, sizeof(vpd84_data));
784 return sizeof(vpd84_data);
785}
786
787static int inquiry_evpd_85(unsigned char * arr)
788{
789 int num = 0;
790 const char * na1 = "https://www.kernel.org/config";
791 const char * na2 = "http://www.kernel.org/log";
792 int plen, olen;
793
794 arr[num++] = 0x1; /* lu, storage config */
795 arr[num++] = 0x0; /* reserved */
796 arr[num++] = 0x0;
797 olen = strlen(na1);
798 plen = olen + 1;
799 if (plen % 4)
800 plen = ((plen / 4) + 1) * 4;
801 arr[num++] = plen; /* length, null termianted, padded */
802 memcpy(arr + num, na1, olen);
803 memset(arr + num + olen, 0, plen - olen);
804 num += plen;
805
806 arr[num++] = 0x4; /* lu, logging */
807 arr[num++] = 0x0; /* reserved */
808 arr[num++] = 0x0;
809 olen = strlen(na2);
810 plen = olen + 1;
811 if (plen % 4)
812 plen = ((plen / 4) + 1) * 4;
813 arr[num++] = plen; /* length, null terminated, padded */
814 memcpy(arr + num, na2, olen);
815 memset(arr + num + olen, 0, plen - olen);
816 num += plen;
817
818 return num;
819}
820
821/* SCSI ports VPD page */
822static int inquiry_evpd_88(unsigned char * arr, int target_dev_id)
823{
824 int num = 0;
825 int port_a, port_b;
826
827 port_a = target_dev_id + 1;
828 port_b = port_a + 1;
829 arr[num++] = 0x0; /* reserved */
830 arr[num++] = 0x0; /* reserved */
831 arr[num++] = 0x0;
832 arr[num++] = 0x1; /* relative port 1 (primary) */
833 memset(arr + num, 0, 6);
834 num += 6;
835 arr[num++] = 0x0;
836 arr[num++] = 12; /* length tp descriptor */
837 /* naa-5 target port identifier (A) */
838 arr[num++] = 0x61; /* proto=sas, binary */
839 arr[num++] = 0x93; /* PIV=1, target port, NAA */
840 arr[num++] = 0x0; /* reserved */
841 arr[num++] = 0x8; /* length */
842 arr[num++] = 0x52; /* NAA-5, company_id=0x222222 (fake) */
843 arr[num++] = 0x22;
844 arr[num++] = 0x22;
845 arr[num++] = 0x20;
846 arr[num++] = (port_a >> 24);
847 arr[num++] = (port_a >> 16) & 0xff;
848 arr[num++] = (port_a >> 8) & 0xff;
849 arr[num++] = port_a & 0xff;
850
851 arr[num++] = 0x0; /* reserved */
852 arr[num++] = 0x0; /* reserved */
853 arr[num++] = 0x0;
854 arr[num++] = 0x2; /* relative port 2 (secondary) */
855 memset(arr + num, 0, 6);
856 num += 6;
857 arr[num++] = 0x0;
858 arr[num++] = 12; /* length tp descriptor */
859 /* naa-5 target port identifier (B) */
860 arr[num++] = 0x61; /* proto=sas, binary */
861 arr[num++] = 0x93; /* PIV=1, target port, NAA */
862 arr[num++] = 0x0; /* reserved */
863 arr[num++] = 0x8; /* length */
864 arr[num++] = 0x52; /* NAA-5, company_id=0x222222 (fake) */
865 arr[num++] = 0x22;
866 arr[num++] = 0x22;
867 arr[num++] = 0x20;
868 arr[num++] = (port_b >> 24);
869 arr[num++] = (port_b >> 16) & 0xff;
870 arr[num++] = (port_b >> 8) & 0xff;
871 arr[num++] = port_b & 0xff;
872
873 return num;
874}
875
876
877static unsigned char vpd89_data[] = {
878/* from 4th byte */ 0,0,0,0,
879'l','i','n','u','x',' ',' ',' ',
880'S','A','T',' ','s','c','s','i','_','d','e','b','u','g',' ',' ',
881'1','2','3','4',
8820x34,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,
8830xec,0,0,0,
8840x5a,0xc,0xff,0x3f,0x37,0xc8,0x10,0,0,0,0,0,0x3f,0,0,0,
8850,0,0,0,0x58,0x58,0x58,0x58,0x58,0x58,0x58,0x58,0x20,0x20,0x20,0x20,
8860x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0,0,0,0x40,0x4,0,0x2e,0x33,
8870x38,0x31,0x20,0x20,0x20,0x20,0x54,0x53,0x38,0x33,0x30,0x30,0x33,0x31,
8880x53,0x41,
8890x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
8900x20,0x20,
8910x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
8920x10,0x80,
8930,0,0,0x2f,0,0,0,0x2,0,0x2,0x7,0,0xff,0xff,0x1,0,
8940x3f,0,0xc1,0xff,0x3e,0,0x10,0x1,0xb0,0xf8,0x50,0x9,0,0,0x7,0,
8950x3,0,0x78,0,0x78,0,0xf0,0,0x78,0,0,0,0,0,0,0,
8960,0,0,0,0,0,0,0,0x2,0,0,0,0,0,0,0,
8970x7e,0,0x1b,0,0x6b,0x34,0x1,0x7d,0x3,0x40,0x69,0x34,0x1,0x3c,0x3,0x40,
8980x7f,0x40,0,0,0,0,0xfe,0xfe,0,0,0,0,0,0xfe,0,0,
8990,0,0,0,0,0,0,0,0xb0,0xf8,0x50,0x9,0,0,0,0,
9000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
9010,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
9020,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
9030x1,0,0xb0,0xf8,0x50,0x9,0xb0,0xf8,0x50,0x9,0x20,0x20,0x2,0,0xb6,0x42,
9040,0x80,0x8a,0,0x6,0x3c,0xa,0x3c,0xff,0xff,0xc6,0x7,0,0x1,0,0x8,
9050xf0,0xf,0,0x10,0x2,0,0x30,0,0,0,0,0,0,0,0x6,0xfe,
9060,0,0x2,0,0x50,0,0x8a,0,0x4f,0x95,0,0,0x21,0,0xb,0,
9070,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
9080,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
9090,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
9100,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
9110,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
9120,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
9130,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
9140,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
9150,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
9160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
9170,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
9180,0,0,0,0,0,0,0,0,0,0,0,0,0,0xa5,0x51,
919};
920
921static int inquiry_evpd_89(unsigned char * arr)
922{
923 memcpy(arr, vpd89_data, sizeof(vpd89_data));
924 return sizeof(vpd89_data);
925}
926
927
928static unsigned char vpdb0_data[] = {
929 /* from 4th byte */ 0,0,0,4,
930 0,0,0x4,0,
931 0,0,0,64,
932};
933
934static int inquiry_evpd_b0(unsigned char * arr)
935{
936 memcpy(arr, vpdb0_data, sizeof(vpdb0_data));
937 if (sdebug_store_sectors > 0x400) {
938 arr[4] = (sdebug_store_sectors >> 24) & 0xff;
939 arr[5] = (sdebug_store_sectors >> 16) & 0xff;
940 arr[6] = (sdebug_store_sectors >> 8) & 0xff;
941 arr[7] = sdebug_store_sectors & 0xff;
942 }
943 return sizeof(vpdb0_data);
1da177e4
LT
944}
945
946
947#define SDEBUG_LONG_INQ_SZ 96
c65b1445 948#define SDEBUG_MAX_INQ_ARR_SZ 584
1da177e4
LT
949
950static int resp_inquiry(struct scsi_cmnd * scp, int target,
951 struct sdebug_dev_info * devip)
952{
953 unsigned char pq_pdt;
5a09e398 954 unsigned char * arr;
1da177e4 955 unsigned char *cmd = (unsigned char *)scp->cmnd;
5a09e398 956 int alloc_len, n, ret;
1da177e4
LT
957
958 alloc_len = (cmd[3] << 8) + cmd[4];
6f3cbf55
DG
959 arr = kzalloc(SDEBUG_MAX_INQ_ARR_SZ, GFP_ATOMIC);
960 if (! arr)
961 return DID_REQUEUE << 16;
c65b1445
DG
962 if (devip->wlun)
963 pq_pdt = 0x1e; /* present, wlun */
964 else if (scsi_debug_no_lun_0 && (0 == devip->lun))
965 pq_pdt = 0x7f; /* not present, no device type */
966 else
967 pq_pdt = (scsi_debug_ptype & 0x1f);
1da177e4
LT
968 arr[0] = pq_pdt;
969 if (0x2 & cmd[1]) { /* CMDDT bit set */
970 mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB,
971 0);
5a09e398 972 kfree(arr);
1da177e4
LT
973 return check_condition_result;
974 } else if (0x1 & cmd[1]) { /* EVPD bit set */
5a09e398 975 int lu_id_num, port_group_id, target_dev_id, len;
c65b1445
DG
976 char lu_id_str[6];
977 int host_no = devip->sdbg_host->shost->host_no;
1da177e4 978
5a09e398
HR
979 port_group_id = (((host_no + 1) & 0x7f) << 8) +
980 (devip->channel & 0x7f);
23183910
DG
981 if (0 == scsi_debug_vpd_use_hostno)
982 host_no = 0;
c65b1445
DG
983 lu_id_num = devip->wlun ? -1 : (((host_no + 1) * 2000) +
984 (devip->target * 1000) + devip->lun);
985 target_dev_id = ((host_no + 1) * 2000) +
986 (devip->target * 1000) - 3;
987 len = scnprintf(lu_id_str, 6, "%d", lu_id_num);
1da177e4 988 if (0 == cmd[2]) { /* supported vital product data pages */
c65b1445
DG
989 arr[1] = cmd[2]; /*sanity */
990 n = 4;
991 arr[n++] = 0x0; /* this page */
992 arr[n++] = 0x80; /* unit serial number */
993 arr[n++] = 0x83; /* device identification */
994 arr[n++] = 0x84; /* software interface ident. */
995 arr[n++] = 0x85; /* management network addresses */
996 arr[n++] = 0x86; /* extended inquiry */
997 arr[n++] = 0x87; /* mode page policy */
998 arr[n++] = 0x88; /* SCSI ports */
999 arr[n++] = 0x89; /* ATA information */
1000 arr[n++] = 0xb0; /* Block limits (SBC) */
1001 arr[3] = n - 4; /* number of supported VPD pages */
1da177e4 1002 } else if (0x80 == cmd[2]) { /* unit serial number */
c65b1445 1003 arr[1] = cmd[2]; /*sanity */
1da177e4 1004 arr[3] = len;
c65b1445 1005 memcpy(&arr[4], lu_id_str, len);
1da177e4 1006 } else if (0x83 == cmd[2]) { /* device identification */
c65b1445 1007 arr[1] = cmd[2]; /*sanity */
5a09e398
HR
1008 arr[3] = inquiry_evpd_83(&arr[4], port_group_id,
1009 target_dev_id, lu_id_num,
1010 lu_id_str, len);
c65b1445
DG
1011 } else if (0x84 == cmd[2]) { /* Software interface ident. */
1012 arr[1] = cmd[2]; /*sanity */
1013 arr[3] = inquiry_evpd_84(&arr[4]);
1014 } else if (0x85 == cmd[2]) { /* Management network addresses */
1015 arr[1] = cmd[2]; /*sanity */
1016 arr[3] = inquiry_evpd_85(&arr[4]);
1017 } else if (0x86 == cmd[2]) { /* extended inquiry */
1018 arr[1] = cmd[2]; /*sanity */
1019 arr[3] = 0x3c; /* number of following entries */
1020 arr[4] = 0x0; /* no protection stuff */
1021 arr[5] = 0x7; /* head of q, ordered + simple q's */
1022 } else if (0x87 == cmd[2]) { /* mode page policy */
1023 arr[1] = cmd[2]; /*sanity */
1024 arr[3] = 0x8; /* number of following entries */
1025 arr[4] = 0x2; /* disconnect-reconnect mp */
1026 arr[6] = 0x80; /* mlus, shared */
1027 arr[8] = 0x18; /* protocol specific lu */
1028 arr[10] = 0x82; /* mlus, per initiator port */
1029 } else if (0x88 == cmd[2]) { /* SCSI Ports */
1030 arr[1] = cmd[2]; /*sanity */
1031 arr[3] = inquiry_evpd_88(&arr[4], target_dev_id);
1032 } else if (0x89 == cmd[2]) { /* ATA information */
1033 arr[1] = cmd[2]; /*sanity */
1034 n = inquiry_evpd_89(&arr[4]);
1035 arr[2] = (n >> 8);
1036 arr[3] = (n & 0xff);
1037 } else if (0xb0 == cmd[2]) { /* Block limits (SBC) */
1038 arr[1] = cmd[2]; /*sanity */
1039 arr[3] = inquiry_evpd_b0(&arr[4]);
1da177e4
LT
1040 } else {
1041 /* Illegal request, invalid field in cdb */
1042 mk_sense_buffer(devip, ILLEGAL_REQUEST,
1043 INVALID_FIELD_IN_CDB, 0);
5a09e398 1044 kfree(arr);
1da177e4
LT
1045 return check_condition_result;
1046 }
c65b1445 1047 len = min(((arr[2] << 8) + arr[3]) + 4, alloc_len);
5a09e398 1048 ret = fill_from_dev_buffer(scp, arr,
c65b1445 1049 min(len, SDEBUG_MAX_INQ_ARR_SZ));
5a09e398
HR
1050 kfree(arr);
1051 return ret;
1da177e4
LT
1052 }
1053 /* drops through here for a standard inquiry */
1054 arr[1] = DEV_REMOVEABLE(target) ? 0x80 : 0; /* Removable disk */
1055 arr[2] = scsi_debug_scsi_level;
1056 arr[3] = 2; /* response_data_format==2 */
1057 arr[4] = SDEBUG_LONG_INQ_SZ - 5;
5a09e398
HR
1058 if (0 == scsi_debug_vpd_use_hostno)
1059 arr[5] = 0x10; /* claim: implicit TGPS */
c65b1445 1060 arr[6] = 0x10; /* claim: MultiP */
1da177e4 1061 /* arr[6] |= 0x40; ... claim: EncServ (enclosure services) */
c65b1445 1062 arr[7] = 0xa; /* claim: LINKED + CMDQUE */
1da177e4
LT
1063 memcpy(&arr[8], inq_vendor_id, 8);
1064 memcpy(&arr[16], inq_product_id, 16);
1065 memcpy(&arr[32], inq_product_rev, 4);
1066 /* version descriptors (2 bytes each) follow */
c65b1445
DG
1067 arr[58] = 0x0; arr[59] = 0x77; /* SAM-3 ANSI */
1068 arr[60] = 0x3; arr[61] = 0x14; /* SPC-3 ANSI */
1069 n = 62;
1da177e4 1070 if (scsi_debug_ptype == 0) {
c65b1445 1071 arr[n++] = 0x3; arr[n++] = 0x3d; /* SBC-2 ANSI */
1da177e4 1072 } else if (scsi_debug_ptype == 1) {
c65b1445 1073 arr[n++] = 0x3; arr[n++] = 0x60; /* SSC-2 no version */
1da177e4 1074 }
c65b1445 1075 arr[n++] = 0xc; arr[n++] = 0xf; /* SAS-1.1 rev 10 */
5a09e398 1076 ret = fill_from_dev_buffer(scp, arr,
1da177e4 1077 min(alloc_len, SDEBUG_LONG_INQ_SZ));
5a09e398
HR
1078 kfree(arr);
1079 return ret;
1da177e4
LT
1080}
1081
1082static int resp_requests(struct scsi_cmnd * scp,
1083 struct sdebug_dev_info * devip)
1084{
1085 unsigned char * sbuff;
1086 unsigned char *cmd = (unsigned char *)scp->cmnd;
1087 unsigned char arr[SDEBUG_SENSE_LEN];
c65b1445 1088 int want_dsense;
1da177e4
LT
1089 int len = 18;
1090
c65b1445 1091 memset(arr, 0, sizeof(arr));
1da177e4 1092 if (devip->reset == 1)
c65b1445
DG
1093 mk_sense_buffer(devip, 0, NO_ADDITIONAL_SENSE, 0);
1094 want_dsense = !!(cmd[1] & 1) || scsi_debug_dsense;
1da177e4 1095 sbuff = devip->sense_buff;
c65b1445
DG
1096 if ((iec_m_pg[2] & 0x4) && (6 == (iec_m_pg[3] & 0xf))) {
1097 if (want_dsense) {
1098 arr[0] = 0x72;
1099 arr[1] = 0x0; /* NO_SENSE in sense_key */
1100 arr[2] = THRESHOLD_EXCEEDED;
1101 arr[3] = 0xff; /* TEST set and MRIE==6 */
1102 } else {
1103 arr[0] = 0x70;
1104 arr[2] = 0x0; /* NO_SENSE in sense_key */
1105 arr[7] = 0xa; /* 18 byte sense buffer */
1106 arr[12] = THRESHOLD_EXCEEDED;
1107 arr[13] = 0xff; /* TEST set and MRIE==6 */
1108 }
c65b1445 1109 } else {
1da177e4 1110 memcpy(arr, sbuff, SDEBUG_SENSE_LEN);
c65b1445
DG
1111 if ((cmd[1] & 1) && (! scsi_debug_dsense)) {
1112 /* DESC bit set and sense_buff in fixed format */
1113 memset(arr, 0, sizeof(arr));
1114 arr[0] = 0x72;
1115 arr[1] = sbuff[2]; /* sense key */
1116 arr[2] = sbuff[12]; /* asc */
1117 arr[3] = sbuff[13]; /* ascq */
1118 len = 8;
1119 }
1120 }
1121 mk_sense_buffer(devip, 0, NO_ADDITIONAL_SENSE, 0);
1da177e4
LT
1122 return fill_from_dev_buffer(scp, arr, len);
1123}
1124
c65b1445
DG
1125static int resp_start_stop(struct scsi_cmnd * scp,
1126 struct sdebug_dev_info * devip)
1127{
1128 unsigned char *cmd = (unsigned char *)scp->cmnd;
1129 int power_cond, errsts, start;
1130
1131 if ((errsts = check_readiness(scp, 1, devip)))
1132 return errsts;
1133 power_cond = (cmd[4] & 0xf0) >> 4;
1134 if (power_cond) {
1135 mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB,
1136 0);
1137 return check_condition_result;
1138 }
1139 start = cmd[4] & 1;
1140 if (start == devip->stopped)
1141 devip->stopped = !start;
1142 return 0;
1143}
1144
1da177e4
LT
1145#define SDEBUG_READCAP_ARR_SZ 8
1146static int resp_readcap(struct scsi_cmnd * scp,
1147 struct sdebug_dev_info * devip)
1148{
1149 unsigned char arr[SDEBUG_READCAP_ARR_SZ];
c65b1445 1150 unsigned int capac;
1da177e4
LT
1151 int errsts;
1152
c65b1445 1153 if ((errsts = check_readiness(scp, 1, devip)))
1da177e4 1154 return errsts;
c65b1445
DG
1155 /* following just in case virtual_gb changed */
1156 if (scsi_debug_virtual_gb > 0) {
1157 sdebug_capacity = 2048 * 1024;
1158 sdebug_capacity *= scsi_debug_virtual_gb;
1159 } else
1160 sdebug_capacity = sdebug_store_sectors;
1da177e4 1161 memset(arr, 0, SDEBUG_READCAP_ARR_SZ);
c65b1445
DG
1162 if (sdebug_capacity < 0xffffffff) {
1163 capac = (unsigned int)sdebug_capacity - 1;
1164 arr[0] = (capac >> 24);
1165 arr[1] = (capac >> 16) & 0xff;
1166 arr[2] = (capac >> 8) & 0xff;
1167 arr[3] = capac & 0xff;
1168 } else {
1169 arr[0] = 0xff;
1170 arr[1] = 0xff;
1171 arr[2] = 0xff;
1172 arr[3] = 0xff;
1173 }
1da177e4
LT
1174 arr[6] = (SECT_SIZE_PER(target) >> 8) & 0xff;
1175 arr[7] = SECT_SIZE_PER(target) & 0xff;
1176 return fill_from_dev_buffer(scp, arr, SDEBUG_READCAP_ARR_SZ);
1177}
1178
c65b1445
DG
1179#define SDEBUG_READCAP16_ARR_SZ 32
1180static int resp_readcap16(struct scsi_cmnd * scp,
1181 struct sdebug_dev_info * devip)
1182{
1183 unsigned char *cmd = (unsigned char *)scp->cmnd;
1184 unsigned char arr[SDEBUG_READCAP16_ARR_SZ];
1185 unsigned long long capac;
1186 int errsts, k, alloc_len;
1187
1188 if ((errsts = check_readiness(scp, 1, devip)))
1189 return errsts;
1190 alloc_len = ((cmd[10] << 24) + (cmd[11] << 16) + (cmd[12] << 8)
1191 + cmd[13]);
1192 /* following just in case virtual_gb changed */
1193 if (scsi_debug_virtual_gb > 0) {
1194 sdebug_capacity = 2048 * 1024;
1195 sdebug_capacity *= scsi_debug_virtual_gb;
1196 } else
1197 sdebug_capacity = sdebug_store_sectors;
1198 memset(arr, 0, SDEBUG_READCAP16_ARR_SZ);
1199 capac = sdebug_capacity - 1;
1200 for (k = 0; k < 8; ++k, capac >>= 8)
1201 arr[7 - k] = capac & 0xff;
1202 arr[8] = (SECT_SIZE_PER(target) >> 24) & 0xff;
1203 arr[9] = (SECT_SIZE_PER(target) >> 16) & 0xff;
1204 arr[10] = (SECT_SIZE_PER(target) >> 8) & 0xff;
1205 arr[11] = SECT_SIZE_PER(target) & 0xff;
1206 return fill_from_dev_buffer(scp, arr,
1207 min(alloc_len, SDEBUG_READCAP16_ARR_SZ));
1208}
1209
5a09e398
HR
1210#define SDEBUG_MAX_TGTPGS_ARR_SZ 1412
1211
1212static int resp_report_tgtpgs(struct scsi_cmnd * scp,
1213 struct sdebug_dev_info * devip)
1214{
1215 unsigned char *cmd = (unsigned char *)scp->cmnd;
1216 unsigned char * arr;
1217 int host_no = devip->sdbg_host->shost->host_no;
1218 int n, ret, alen, rlen;
1219 int port_group_a, port_group_b, port_a, port_b;
1220
1221 alen = ((cmd[6] << 24) + (cmd[7] << 16) + (cmd[8] << 8)
1222 + cmd[9]);
1223
6f3cbf55
DG
1224 arr = kzalloc(SDEBUG_MAX_TGTPGS_ARR_SZ, GFP_ATOMIC);
1225 if (! arr)
1226 return DID_REQUEUE << 16;
5a09e398
HR
1227 /*
1228 * EVPD page 0x88 states we have two ports, one
1229 * real and a fake port with no device connected.
1230 * So we create two port groups with one port each
1231 * and set the group with port B to unavailable.
1232 */
1233 port_a = 0x1; /* relative port A */
1234 port_b = 0x2; /* relative port B */
1235 port_group_a = (((host_no + 1) & 0x7f) << 8) +
1236 (devip->channel & 0x7f);
1237 port_group_b = (((host_no + 1) & 0x7f) << 8) +
1238 (devip->channel & 0x7f) + 0x80;
1239
1240 /*
1241 * The asymmetric access state is cycled according to the host_id.
1242 */
1243 n = 4;
1244 if (0 == scsi_debug_vpd_use_hostno) {
1245 arr[n++] = host_no % 3; /* Asymm access state */
1246 arr[n++] = 0x0F; /* claim: all states are supported */
1247 } else {
1248 arr[n++] = 0x0; /* Active/Optimized path */
1249 arr[n++] = 0x01; /* claim: only support active/optimized paths */
1250 }
1251 arr[n++] = (port_group_a >> 8) & 0xff;
1252 arr[n++] = port_group_a & 0xff;
1253 arr[n++] = 0; /* Reserved */
1254 arr[n++] = 0; /* Status code */
1255 arr[n++] = 0; /* Vendor unique */
1256 arr[n++] = 0x1; /* One port per group */
1257 arr[n++] = 0; /* Reserved */
1258 arr[n++] = 0; /* Reserved */
1259 arr[n++] = (port_a >> 8) & 0xff;
1260 arr[n++] = port_a & 0xff;
1261 arr[n++] = 3; /* Port unavailable */
1262 arr[n++] = 0x08; /* claim: only unavailalbe paths are supported */
1263 arr[n++] = (port_group_b >> 8) & 0xff;
1264 arr[n++] = port_group_b & 0xff;
1265 arr[n++] = 0; /* Reserved */
1266 arr[n++] = 0; /* Status code */
1267 arr[n++] = 0; /* Vendor unique */
1268 arr[n++] = 0x1; /* One port per group */
1269 arr[n++] = 0; /* Reserved */
1270 arr[n++] = 0; /* Reserved */
1271 arr[n++] = (port_b >> 8) & 0xff;
1272 arr[n++] = port_b & 0xff;
1273
1274 rlen = n - 4;
1275 arr[0] = (rlen >> 24) & 0xff;
1276 arr[1] = (rlen >> 16) & 0xff;
1277 arr[2] = (rlen >> 8) & 0xff;
1278 arr[3] = rlen & 0xff;
1279
1280 /*
1281 * Return the smallest value of either
1282 * - The allocated length
1283 * - The constructed command length
1284 * - The maximum array size
1285 */
1286 rlen = min(alen,n);
1287 ret = fill_from_dev_buffer(scp, arr,
1288 min(rlen, SDEBUG_MAX_TGTPGS_ARR_SZ));
1289 kfree(arr);
1290 return ret;
1291}
1292
1da177e4
LT
1293/* <<Following mode page info copied from ST318451LW>> */
1294
1295static int resp_err_recov_pg(unsigned char * p, int pcontrol, int target)
1296{ /* Read-Write Error Recovery page for mode_sense */
1297 unsigned char err_recov_pg[] = {0x1, 0xa, 0xc0, 11, 240, 0, 0, 0,
1298 5, 0, 0xff, 0xff};
1299
1300 memcpy(p, err_recov_pg, sizeof(err_recov_pg));
1301 if (1 == pcontrol)
1302 memset(p + 2, 0, sizeof(err_recov_pg) - 2);
1303 return sizeof(err_recov_pg);
1304}
1305
1306static int resp_disconnect_pg(unsigned char * p, int pcontrol, int target)
1307{ /* Disconnect-Reconnect page for mode_sense */
1308 unsigned char disconnect_pg[] = {0x2, 0xe, 128, 128, 0, 10, 0, 0,
1309 0, 0, 0, 0, 0, 0, 0, 0};
1310
1311 memcpy(p, disconnect_pg, sizeof(disconnect_pg));
1312 if (1 == pcontrol)
1313 memset(p + 2, 0, sizeof(disconnect_pg) - 2);
1314 return sizeof(disconnect_pg);
1315}
1316
1317static int resp_format_pg(unsigned char * p, int pcontrol, int target)
1318{ /* Format device page for mode_sense */
1319 unsigned char format_pg[] = {0x3, 0x16, 0, 0, 0, 0, 0, 0,
1320 0, 0, 0, 0, 0, 0, 0, 0,
1321 0, 0, 0, 0, 0x40, 0, 0, 0};
1322
1323 memcpy(p, format_pg, sizeof(format_pg));
1324 p[10] = (sdebug_sectors_per >> 8) & 0xff;
1325 p[11] = sdebug_sectors_per & 0xff;
1326 p[12] = (SECT_SIZE >> 8) & 0xff;
1327 p[13] = SECT_SIZE & 0xff;
1328 if (DEV_REMOVEABLE(target))
1329 p[20] |= 0x20; /* should agree with INQUIRY */
1330 if (1 == pcontrol)
1331 memset(p + 2, 0, sizeof(format_pg) - 2);
1332 return sizeof(format_pg);
1333}
1334
1335static int resp_caching_pg(unsigned char * p, int pcontrol, int target)
1336{ /* Caching page for mode_sense */
1337 unsigned char caching_pg[] = {0x8, 18, 0x14, 0, 0xff, 0xff, 0, 0,
1338 0xff, 0xff, 0xff, 0xff, 0x80, 0x14, 0, 0, 0, 0, 0, 0};
1339
1340 memcpy(p, caching_pg, sizeof(caching_pg));
1341 if (1 == pcontrol)
1342 memset(p + 2, 0, sizeof(caching_pg) - 2);
1343 return sizeof(caching_pg);
1344}
1345
1346static int resp_ctrl_m_pg(unsigned char * p, int pcontrol, int target)
1347{ /* Control mode page for mode_sense */
c65b1445
DG
1348 unsigned char ch_ctrl_m_pg[] = {/* 0xa, 10, */ 0x6, 0, 0, 0, 0, 0,
1349 0, 0, 0, 0};
1350 unsigned char d_ctrl_m_pg[] = {0xa, 10, 2, 0, 0, 0, 0, 0,
1da177e4
LT
1351 0, 0, 0x2, 0x4b};
1352
1353 if (scsi_debug_dsense)
1354 ctrl_m_pg[2] |= 0x4;
c65b1445
DG
1355 else
1356 ctrl_m_pg[2] &= ~0x4;
1da177e4
LT
1357 memcpy(p, ctrl_m_pg, sizeof(ctrl_m_pg));
1358 if (1 == pcontrol)
c65b1445
DG
1359 memcpy(p + 2, ch_ctrl_m_pg, sizeof(ch_ctrl_m_pg));
1360 else if (2 == pcontrol)
1361 memcpy(p, d_ctrl_m_pg, sizeof(d_ctrl_m_pg));
1da177e4
LT
1362 return sizeof(ctrl_m_pg);
1363}
1364
c65b1445 1365
1da177e4
LT
1366static int resp_iec_m_pg(unsigned char * p, int pcontrol, int target)
1367{ /* Informational Exceptions control mode page for mode_sense */
c65b1445
DG
1368 unsigned char ch_iec_m_pg[] = {/* 0x1c, 0xa, */ 0x4, 0xf, 0, 0, 0, 0,
1369 0, 0, 0x0, 0x0};
1370 unsigned char d_iec_m_pg[] = {0x1c, 0xa, 0x08, 0, 0, 0, 0, 0,
1371 0, 0, 0x0, 0x0};
1372
1da177e4
LT
1373 memcpy(p, iec_m_pg, sizeof(iec_m_pg));
1374 if (1 == pcontrol)
c65b1445
DG
1375 memcpy(p + 2, ch_iec_m_pg, sizeof(ch_iec_m_pg));
1376 else if (2 == pcontrol)
1377 memcpy(p, d_iec_m_pg, sizeof(d_iec_m_pg));
1da177e4
LT
1378 return sizeof(iec_m_pg);
1379}
1380
c65b1445
DG
1381static int resp_sas_sf_m_pg(unsigned char * p, int pcontrol, int target)
1382{ /* SAS SSP mode page - short format for mode_sense */
1383 unsigned char sas_sf_m_pg[] = {0x19, 0x6,
1384 0x6, 0x0, 0x7, 0xd0, 0x0, 0x0};
1385
1386 memcpy(p, sas_sf_m_pg, sizeof(sas_sf_m_pg));
1387 if (1 == pcontrol)
1388 memset(p + 2, 0, sizeof(sas_sf_m_pg) - 2);
1389 return sizeof(sas_sf_m_pg);
1390}
1391
1392
1393static int resp_sas_pcd_m_spg(unsigned char * p, int pcontrol, int target,
1394 int target_dev_id)
1395{ /* SAS phy control and discover mode page for mode_sense */
1396 unsigned char sas_pcd_m_pg[] = {0x59, 0x1, 0, 0x64, 0, 0x6, 0, 2,
1397 0, 0, 0, 0, 0x10, 0x9, 0x8, 0x0,
1398 0x52, 0x22, 0x22, 0x20, 0x0, 0x0, 0x0, 0x0,
1399 0x51, 0x11, 0x11, 0x10, 0x0, 0x0, 0x0, 0x1,
1400 0x2, 0, 0, 0, 0, 0, 0, 0,
1401 0x88, 0x99, 0, 0, 0, 0, 0, 0,
1402 0, 0, 0, 0, 0, 0, 0, 0,
1403 0, 1, 0, 0, 0x10, 0x9, 0x8, 0x0,
1404 0x52, 0x22, 0x22, 0x20, 0x0, 0x0, 0x0, 0x0,
1405 0x51, 0x11, 0x11, 0x10, 0x0, 0x0, 0x0, 0x1,
1406 0x3, 0, 0, 0, 0, 0, 0, 0,
1407 0x88, 0x99, 0, 0, 0, 0, 0, 0,
1408 0, 0, 0, 0, 0, 0, 0, 0,
1409 };
1410 int port_a, port_b;
1411
1412 port_a = target_dev_id + 1;
1413 port_b = port_a + 1;
1414 memcpy(p, sas_pcd_m_pg, sizeof(sas_pcd_m_pg));
1415 p[20] = (port_a >> 24);
1416 p[21] = (port_a >> 16) & 0xff;
1417 p[22] = (port_a >> 8) & 0xff;
1418 p[23] = port_a & 0xff;
1419 p[48 + 20] = (port_b >> 24);
1420 p[48 + 21] = (port_b >> 16) & 0xff;
1421 p[48 + 22] = (port_b >> 8) & 0xff;
1422 p[48 + 23] = port_b & 0xff;
1423 if (1 == pcontrol)
1424 memset(p + 4, 0, sizeof(sas_pcd_m_pg) - 4);
1425 return sizeof(sas_pcd_m_pg);
1426}
1427
1428static int resp_sas_sha_m_spg(unsigned char * p, int pcontrol)
1429{ /* SAS SSP shared protocol specific port mode subpage */
1430 unsigned char sas_sha_m_pg[] = {0x59, 0x2, 0, 0xc, 0, 0x6, 0x10, 0,
1431 0, 0, 0, 0, 0, 0, 0, 0,
1432 };
1433
1434 memcpy(p, sas_sha_m_pg, sizeof(sas_sha_m_pg));
1435 if (1 == pcontrol)
1436 memset(p + 4, 0, sizeof(sas_sha_m_pg) - 4);
1437 return sizeof(sas_sha_m_pg);
1438}
1439
1da177e4
LT
1440#define SDEBUG_MAX_MSENSE_SZ 256
1441
1442static int resp_mode_sense(struct scsi_cmnd * scp, int target,
1443 struct sdebug_dev_info * devip)
1444{
23183910
DG
1445 unsigned char dbd, llbaa;
1446 int pcontrol, pcode, subpcode, bd_len;
1da177e4 1447 unsigned char dev_spec;
23183910 1448 int k, alloc_len, msense_6, offset, len, errsts, target_dev_id;
1da177e4
LT
1449 unsigned char * ap;
1450 unsigned char arr[SDEBUG_MAX_MSENSE_SZ];
1451 unsigned char *cmd = (unsigned char *)scp->cmnd;
1452
c65b1445 1453 if ((errsts = check_readiness(scp, 1, devip)))
1da177e4 1454 return errsts;
23183910 1455 dbd = !!(cmd[1] & 0x8);
1da177e4
LT
1456 pcontrol = (cmd[2] & 0xc0) >> 6;
1457 pcode = cmd[2] & 0x3f;
1458 subpcode = cmd[3];
1459 msense_6 = (MODE_SENSE == cmd[0]);
23183910
DG
1460 llbaa = msense_6 ? 0 : !!(cmd[1] & 0x10);
1461 if ((0 == scsi_debug_ptype) && (0 == dbd))
1462 bd_len = llbaa ? 16 : 8;
1463 else
1464 bd_len = 0;
1da177e4
LT
1465 alloc_len = msense_6 ? cmd[4] : ((cmd[7] << 8) | cmd[8]);
1466 memset(arr, 0, SDEBUG_MAX_MSENSE_SZ);
1467 if (0x3 == pcontrol) { /* Saving values not supported */
1468 mk_sense_buffer(devip, ILLEGAL_REQUEST, SAVING_PARAMS_UNSUP,
1469 0);
1470 return check_condition_result;
1471 }
c65b1445
DG
1472 target_dev_id = ((devip->sdbg_host->shost->host_no + 1) * 2000) +
1473 (devip->target * 1000) - 3;
23183910
DG
1474 /* set DPOFUA bit for disks */
1475 if (0 == scsi_debug_ptype)
1476 dev_spec = (DEV_READONLY(target) ? 0x80 : 0x0) | 0x10;
1477 else
1478 dev_spec = 0x0;
1da177e4
LT
1479 if (msense_6) {
1480 arr[2] = dev_spec;
23183910 1481 arr[3] = bd_len;
1da177e4
LT
1482 offset = 4;
1483 } else {
1484 arr[3] = dev_spec;
23183910
DG
1485 if (16 == bd_len)
1486 arr[4] = 0x1; /* set LONGLBA bit */
1487 arr[7] = bd_len; /* assume 255 or less */
1da177e4
LT
1488 offset = 8;
1489 }
1490 ap = arr + offset;
23183910
DG
1491 if ((bd_len > 0) && (0 == sdebug_capacity)) {
1492 if (scsi_debug_virtual_gb > 0) {
1493 sdebug_capacity = 2048 * 1024;
1494 sdebug_capacity *= scsi_debug_virtual_gb;
1495 } else
1496 sdebug_capacity = sdebug_store_sectors;
1497 }
1498 if (8 == bd_len) {
1499 if (sdebug_capacity > 0xfffffffe) {
1500 ap[0] = 0xff;
1501 ap[1] = 0xff;
1502 ap[2] = 0xff;
1503 ap[3] = 0xff;
1504 } else {
1505 ap[0] = (sdebug_capacity >> 24) & 0xff;
1506 ap[1] = (sdebug_capacity >> 16) & 0xff;
1507 ap[2] = (sdebug_capacity >> 8) & 0xff;
1508 ap[3] = sdebug_capacity & 0xff;
1509 }
1510 ap[6] = (SECT_SIZE_PER(target) >> 8) & 0xff;
1511 ap[7] = SECT_SIZE_PER(target) & 0xff;
1512 offset += bd_len;
1513 ap = arr + offset;
1514 } else if (16 == bd_len) {
1515 unsigned long long capac = sdebug_capacity;
1516
1517 for (k = 0; k < 8; ++k, capac >>= 8)
1518 ap[7 - k] = capac & 0xff;
1519 ap[12] = (SECT_SIZE_PER(target) >> 24) & 0xff;
1520 ap[13] = (SECT_SIZE_PER(target) >> 16) & 0xff;
1521 ap[14] = (SECT_SIZE_PER(target) >> 8) & 0xff;
1522 ap[15] = SECT_SIZE_PER(target) & 0xff;
1523 offset += bd_len;
1524 ap = arr + offset;
1525 }
1da177e4 1526
c65b1445
DG
1527 if ((subpcode > 0x0) && (subpcode < 0xff) && (0x19 != pcode)) {
1528 /* TODO: Control Extension page */
1da177e4
LT
1529 mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB,
1530 0);
1531 return check_condition_result;
1532 }
1533 switch (pcode) {
1534 case 0x1: /* Read-Write error recovery page, direct access */
1535 len = resp_err_recov_pg(ap, pcontrol, target);
1536 offset += len;
1537 break;
1538 case 0x2: /* Disconnect-Reconnect page, all devices */
1539 len = resp_disconnect_pg(ap, pcontrol, target);
1540 offset += len;
1541 break;
1542 case 0x3: /* Format device page, direct access */
1543 len = resp_format_pg(ap, pcontrol, target);
1544 offset += len;
1545 break;
1546 case 0x8: /* Caching page, direct access */
1547 len = resp_caching_pg(ap, pcontrol, target);
1548 offset += len;
1549 break;
1550 case 0xa: /* Control Mode page, all devices */
1551 len = resp_ctrl_m_pg(ap, pcontrol, target);
1552 offset += len;
1553 break;
c65b1445
DG
1554 case 0x19: /* if spc==1 then sas phy, control+discover */
1555 if ((subpcode > 0x2) && (subpcode < 0xff)) {
1556 mk_sense_buffer(devip, ILLEGAL_REQUEST,
1557 INVALID_FIELD_IN_CDB, 0);
1558 return check_condition_result;
1559 }
1560 len = 0;
1561 if ((0x0 == subpcode) || (0xff == subpcode))
1562 len += resp_sas_sf_m_pg(ap + len, pcontrol, target);
1563 if ((0x1 == subpcode) || (0xff == subpcode))
1564 len += resp_sas_pcd_m_spg(ap + len, pcontrol, target,
1565 target_dev_id);
1566 if ((0x2 == subpcode) || (0xff == subpcode))
1567 len += resp_sas_sha_m_spg(ap + len, pcontrol);
1568 offset += len;
1569 break;
1da177e4
LT
1570 case 0x1c: /* Informational Exceptions Mode page, all devices */
1571 len = resp_iec_m_pg(ap, pcontrol, target);
1572 offset += len;
1573 break;
1574 case 0x3f: /* Read all Mode pages */
c65b1445
DG
1575 if ((0 == subpcode) || (0xff == subpcode)) {
1576 len = resp_err_recov_pg(ap, pcontrol, target);
1577 len += resp_disconnect_pg(ap + len, pcontrol, target);
1578 len += resp_format_pg(ap + len, pcontrol, target);
1579 len += resp_caching_pg(ap + len, pcontrol, target);
1580 len += resp_ctrl_m_pg(ap + len, pcontrol, target);
1581 len += resp_sas_sf_m_pg(ap + len, pcontrol, target);
1582 if (0xff == subpcode) {
1583 len += resp_sas_pcd_m_spg(ap + len, pcontrol,
1584 target, target_dev_id);
1585 len += resp_sas_sha_m_spg(ap + len, pcontrol);
1586 }
1587 len += resp_iec_m_pg(ap + len, pcontrol, target);
1588 } else {
1589 mk_sense_buffer(devip, ILLEGAL_REQUEST,
1590 INVALID_FIELD_IN_CDB, 0);
1591 return check_condition_result;
1592 }
1da177e4
LT
1593 offset += len;
1594 break;
1595 default:
1596 mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB,
1597 0);
1598 return check_condition_result;
1599 }
1600 if (msense_6)
1601 arr[0] = offset - 1;
1602 else {
1603 arr[0] = ((offset - 2) >> 8) & 0xff;
1604 arr[1] = (offset - 2) & 0xff;
1605 }
1606 return fill_from_dev_buffer(scp, arr, min(alloc_len, offset));
1607}
1608
c65b1445
DG
1609#define SDEBUG_MAX_MSELECT_SZ 512
1610
1611static int resp_mode_select(struct scsi_cmnd * scp, int mselect6,
1612 struct sdebug_dev_info * devip)
1613{
1614 int pf, sp, ps, md_len, bd_len, off, spf, pg_len;
1615 int param_len, res, errsts, mpage;
1616 unsigned char arr[SDEBUG_MAX_MSELECT_SZ];
1617 unsigned char *cmd = (unsigned char *)scp->cmnd;
1618
1619 if ((errsts = check_readiness(scp, 1, devip)))
1620 return errsts;
1621 memset(arr, 0, sizeof(arr));
1622 pf = cmd[1] & 0x10;
1623 sp = cmd[1] & 0x1;
1624 param_len = mselect6 ? cmd[4] : ((cmd[7] << 8) + cmd[8]);
1625 if ((0 == pf) || sp || (param_len > SDEBUG_MAX_MSELECT_SZ)) {
1626 mk_sense_buffer(devip, ILLEGAL_REQUEST,
1627 INVALID_FIELD_IN_CDB, 0);
1628 return check_condition_result;
1629 }
1630 res = fetch_to_dev_buffer(scp, arr, param_len);
1631 if (-1 == res)
1632 return (DID_ERROR << 16);
1633 else if ((res < param_len) &&
1634 (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts))
1635 printk(KERN_INFO "scsi_debug: mode_select: cdb indicated=%d, "
1636 " IO sent=%d bytes\n", param_len, res);
1637 md_len = mselect6 ? (arr[0] + 1) : ((arr[0] << 8) + arr[1] + 2);
1638 bd_len = mselect6 ? arr[3] : ((arr[6] << 8) + arr[7]);
23183910 1639 if (md_len > 2) {
c65b1445
DG
1640 mk_sense_buffer(devip, ILLEGAL_REQUEST,
1641 INVALID_FIELD_IN_PARAM_LIST, 0);
1642 return check_condition_result;
1643 }
1644 off = bd_len + (mselect6 ? 4 : 8);
1645 mpage = arr[off] & 0x3f;
1646 ps = !!(arr[off] & 0x80);
1647 if (ps) {
1648 mk_sense_buffer(devip, ILLEGAL_REQUEST,
1649 INVALID_FIELD_IN_PARAM_LIST, 0);
1650 return check_condition_result;
1651 }
1652 spf = !!(arr[off] & 0x40);
1653 pg_len = spf ? ((arr[off + 2] << 8) + arr[off + 3] + 4) :
1654 (arr[off + 1] + 2);
1655 if ((pg_len + off) > param_len) {
1656 mk_sense_buffer(devip, ILLEGAL_REQUEST,
1657 PARAMETER_LIST_LENGTH_ERR, 0);
1658 return check_condition_result;
1659 }
1660 switch (mpage) {
1661 case 0xa: /* Control Mode page */
1662 if (ctrl_m_pg[1] == arr[off + 1]) {
1663 memcpy(ctrl_m_pg + 2, arr + off + 2,
1664 sizeof(ctrl_m_pg) - 2);
1665 scsi_debug_dsense = !!(ctrl_m_pg[2] & 0x4);
1666 return 0;
1667 }
1668 break;
1669 case 0x1c: /* Informational Exceptions Mode page */
1670 if (iec_m_pg[1] == arr[off + 1]) {
1671 memcpy(iec_m_pg + 2, arr + off + 2,
1672 sizeof(iec_m_pg) - 2);
1673 return 0;
1674 }
1675 break;
1676 default:
1677 break;
1678 }
1679 mk_sense_buffer(devip, ILLEGAL_REQUEST,
1680 INVALID_FIELD_IN_PARAM_LIST, 0);
1681 return check_condition_result;
1682}
1683
1684static int resp_temp_l_pg(unsigned char * arr)
1685{
1686 unsigned char temp_l_pg[] = {0x0, 0x0, 0x3, 0x2, 0x0, 38,
1687 0x0, 0x1, 0x3, 0x2, 0x0, 65,
1688 };
1689
1690 memcpy(arr, temp_l_pg, sizeof(temp_l_pg));
1691 return sizeof(temp_l_pg);
1692}
1693
1694static int resp_ie_l_pg(unsigned char * arr)
1695{
1696 unsigned char ie_l_pg[] = {0x0, 0x0, 0x3, 0x3, 0x0, 0x0, 38,
1697 };
1698
1699 memcpy(arr, ie_l_pg, sizeof(ie_l_pg));
1700 if (iec_m_pg[2] & 0x4) { /* TEST bit set */
1701 arr[4] = THRESHOLD_EXCEEDED;
1702 arr[5] = 0xff;
1703 }
1704 return sizeof(ie_l_pg);
1705}
1706
1707#define SDEBUG_MAX_LSENSE_SZ 512
1708
1709static int resp_log_sense(struct scsi_cmnd * scp,
1710 struct sdebug_dev_info * devip)
1711{
23183910 1712 int ppc, sp, pcontrol, pcode, subpcode, alloc_len, errsts, len, n;
c65b1445
DG
1713 unsigned char arr[SDEBUG_MAX_LSENSE_SZ];
1714 unsigned char *cmd = (unsigned char *)scp->cmnd;
1715
1716 if ((errsts = check_readiness(scp, 1, devip)))
1717 return errsts;
1718 memset(arr, 0, sizeof(arr));
1719 ppc = cmd[1] & 0x2;
1720 sp = cmd[1] & 0x1;
1721 if (ppc || sp) {
1722 mk_sense_buffer(devip, ILLEGAL_REQUEST,
1723 INVALID_FIELD_IN_CDB, 0);
1724 return check_condition_result;
1725 }
1726 pcontrol = (cmd[2] & 0xc0) >> 6;
1727 pcode = cmd[2] & 0x3f;
23183910 1728 subpcode = cmd[3] & 0xff;
c65b1445
DG
1729 alloc_len = (cmd[7] << 8) + cmd[8];
1730 arr[0] = pcode;
23183910
DG
1731 if (0 == subpcode) {
1732 switch (pcode) {
1733 case 0x0: /* Supported log pages log page */
1734 n = 4;
1735 arr[n++] = 0x0; /* this page */
1736 arr[n++] = 0xd; /* Temperature */
1737 arr[n++] = 0x2f; /* Informational exceptions */
1738 arr[3] = n - 4;
1739 break;
1740 case 0xd: /* Temperature log page */
1741 arr[3] = resp_temp_l_pg(arr + 4);
1742 break;
1743 case 0x2f: /* Informational exceptions log page */
1744 arr[3] = resp_ie_l_pg(arr + 4);
1745 break;
1746 default:
1747 mk_sense_buffer(devip, ILLEGAL_REQUEST,
1748 INVALID_FIELD_IN_CDB, 0);
1749 return check_condition_result;
1750 }
1751 } else if (0xff == subpcode) {
1752 arr[0] |= 0x40;
1753 arr[1] = subpcode;
1754 switch (pcode) {
1755 case 0x0: /* Supported log pages and subpages log page */
1756 n = 4;
1757 arr[n++] = 0x0;
1758 arr[n++] = 0x0; /* 0,0 page */
1759 arr[n++] = 0x0;
1760 arr[n++] = 0xff; /* this page */
1761 arr[n++] = 0xd;
1762 arr[n++] = 0x0; /* Temperature */
1763 arr[n++] = 0x2f;
1764 arr[n++] = 0x0; /* Informational exceptions */
1765 arr[3] = n - 4;
1766 break;
1767 case 0xd: /* Temperature subpages */
1768 n = 4;
1769 arr[n++] = 0xd;
1770 arr[n++] = 0x0; /* Temperature */
1771 arr[3] = n - 4;
1772 break;
1773 case 0x2f: /* Informational exceptions subpages */
1774 n = 4;
1775 arr[n++] = 0x2f;
1776 arr[n++] = 0x0; /* Informational exceptions */
1777 arr[3] = n - 4;
1778 break;
1779 default:
1780 mk_sense_buffer(devip, ILLEGAL_REQUEST,
1781 INVALID_FIELD_IN_CDB, 0);
1782 return check_condition_result;
1783 }
1784 } else {
c65b1445
DG
1785 mk_sense_buffer(devip, ILLEGAL_REQUEST,
1786 INVALID_FIELD_IN_CDB, 0);
1787 return check_condition_result;
1788 }
1789 len = min(((arr[2] << 8) + arr[3]) + 4, alloc_len);
1790 return fill_from_dev_buffer(scp, arr,
1791 min(len, SDEBUG_MAX_INQ_ARR_SZ));
1792}
1793
1794static int resp_read(struct scsi_cmnd * SCpnt, unsigned long long lba,
1795 unsigned int num, struct sdebug_dev_info * devip)
1da177e4
LT
1796{
1797 unsigned long iflags;
c65b1445
DG
1798 unsigned int block, from_bottom;
1799 unsigned long long u;
1da177e4
LT
1800 int ret;
1801
c65b1445 1802 if (lba + num > sdebug_capacity) {
1da177e4
LT
1803 mk_sense_buffer(devip, ILLEGAL_REQUEST, ADDR_OUT_OF_RANGE,
1804 0);
1805 return check_condition_result;
1806 }
c65b1445
DG
1807 /* transfer length excessive (tie in to block limits VPD page) */
1808 if (num > sdebug_store_sectors) {
1809 mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB,
1810 0);
1811 return check_condition_result;
1812 }
1da177e4 1813 if ((SCSI_DEBUG_OPT_MEDIUM_ERR & scsi_debug_opts) &&
c65b1445
DG
1814 (lba <= OPT_MEDIUM_ERR_ADDR) &&
1815 ((lba + num) > OPT_MEDIUM_ERR_ADDR)) {
1816 /* claim unrecoverable read error */
1da177e4
LT
1817 mk_sense_buffer(devip, MEDIUM_ERROR, UNRECOVERED_READ_ERR,
1818 0);
c65b1445
DG
1819 /* set info field and valid bit for fixed descriptor */
1820 if (0x70 == (devip->sense_buff[0] & 0x7f)) {
1821 devip->sense_buff[0] |= 0x80; /* Valid bit */
1822 ret = OPT_MEDIUM_ERR_ADDR;
1823 devip->sense_buff[3] = (ret >> 24) & 0xff;
1824 devip->sense_buff[4] = (ret >> 16) & 0xff;
1825 devip->sense_buff[5] = (ret >> 8) & 0xff;
1826 devip->sense_buff[6] = ret & 0xff;
1827 }
1da177e4
LT
1828 return check_condition_result;
1829 }
1830 read_lock_irqsave(&atomic_rw, iflags);
c65b1445
DG
1831 if ((lba + num) <= sdebug_store_sectors)
1832 ret = fill_from_dev_buffer(SCpnt,
1833 fake_storep + (lba * SECT_SIZE),
1834 num * SECT_SIZE);
1835 else {
1836 /* modulo when one arg is 64 bits needs do_div() */
1837 u = lba;
1838 block = do_div(u, sdebug_store_sectors);
1839 from_bottom = 0;
1840 if ((block + num) > sdebug_store_sectors)
1841 from_bottom = (block + num) - sdebug_store_sectors;
1842 ret = fill_from_dev_buffer(SCpnt,
1843 fake_storep + (block * SECT_SIZE),
1844 (num - from_bottom) * SECT_SIZE);
1845 if ((0 == ret) && (from_bottom > 0))
1846 ret = fill_from_dev_buffer(SCpnt, fake_storep,
1847 from_bottom * SECT_SIZE);
1848 }
1da177e4
LT
1849 read_unlock_irqrestore(&atomic_rw, iflags);
1850 return ret;
1851}
1852
c65b1445
DG
1853static int resp_write(struct scsi_cmnd * SCpnt, unsigned long long lba,
1854 unsigned int num, struct sdebug_dev_info * devip)
1da177e4
LT
1855{
1856 unsigned long iflags;
c65b1445
DG
1857 unsigned int block, to_bottom;
1858 unsigned long long u;
1da177e4
LT
1859 int res;
1860
c65b1445 1861 if (lba + num > sdebug_capacity) {
1da177e4
LT
1862 mk_sense_buffer(devip, ILLEGAL_REQUEST, ADDR_OUT_OF_RANGE,
1863 0);
1864 return check_condition_result;
1865 }
c65b1445
DG
1866 /* transfer length excessive (tie in to block limits VPD page) */
1867 if (num > sdebug_store_sectors) {
1868 mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB,
1869 0);
1870 return check_condition_result;
1871 }
1da177e4
LT
1872
1873 write_lock_irqsave(&atomic_rw, iflags);
c65b1445
DG
1874 if ((lba + num) <= sdebug_store_sectors)
1875 res = fetch_to_dev_buffer(SCpnt,
1876 fake_storep + (lba * SECT_SIZE),
1877 num * SECT_SIZE);
1878 else {
1879 /* modulo when one arg is 64 bits needs do_div() */
1880 u = lba;
1881 block = do_div(u, sdebug_store_sectors);
1882 to_bottom = 0;
1883 if ((block + num) > sdebug_store_sectors)
1884 to_bottom = (block + num) - sdebug_store_sectors;
1885 res = fetch_to_dev_buffer(SCpnt,
1886 fake_storep + (block * SECT_SIZE),
1887 (num - to_bottom) * SECT_SIZE);
1888 if ((0 == res) && (to_bottom > 0))
1889 res = fetch_to_dev_buffer(SCpnt, fake_storep,
1890 to_bottom * SECT_SIZE);
1891 }
1da177e4
LT
1892 write_unlock_irqrestore(&atomic_rw, iflags);
1893 if (-1 == res)
1894 return (DID_ERROR << 16);
1895 else if ((res < (num * SECT_SIZE)) &&
1896 (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts))
c65b1445 1897 printk(KERN_INFO "scsi_debug: write: cdb indicated=%u, "
1da177e4
LT
1898 " IO sent=%d bytes\n", num * SECT_SIZE, res);
1899 return 0;
1900}
1901
c65b1445 1902#define SDEBUG_RLUN_ARR_SZ 256
1da177e4
LT
1903
1904static int resp_report_luns(struct scsi_cmnd * scp,
1905 struct sdebug_dev_info * devip)
1906{
1907 unsigned int alloc_len;
c65b1445 1908 int lun_cnt, i, upper, num, n, wlun, lun;
1da177e4
LT
1909 unsigned char *cmd = (unsigned char *)scp->cmnd;
1910 int select_report = (int)cmd[2];
1911 struct scsi_lun *one_lun;
1912 unsigned char arr[SDEBUG_RLUN_ARR_SZ];
c65b1445 1913 unsigned char * max_addr;
1da177e4
LT
1914
1915 alloc_len = cmd[9] + (cmd[8] << 8) + (cmd[7] << 16) + (cmd[6] << 24);
c65b1445 1916 if ((alloc_len < 4) || (select_report > 2)) {
1da177e4
LT
1917 mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB,
1918 0);
1919 return check_condition_result;
1920 }
1921 /* can produce response with up to 16k luns (lun 0 to lun 16383) */
1922 memset(arr, 0, SDEBUG_RLUN_ARR_SZ);
1923 lun_cnt = scsi_debug_max_luns;
c65b1445
DG
1924 if (1 == select_report)
1925 lun_cnt = 0;
1926 else if (scsi_debug_no_lun_0 && (lun_cnt > 0))
1927 --lun_cnt;
1928 wlun = (select_report > 0) ? 1 : 0;
1929 num = lun_cnt + wlun;
1930 arr[2] = ((sizeof(struct scsi_lun) * num) >> 8) & 0xff;
1931 arr[3] = (sizeof(struct scsi_lun) * num) & 0xff;
1932 n = min((int)((SDEBUG_RLUN_ARR_SZ - 8) /
1933 sizeof(struct scsi_lun)), num);
1934 if (n < num) {
1935 wlun = 0;
1936 lun_cnt = n;
1937 }
1da177e4 1938 one_lun = (struct scsi_lun *) &arr[8];
c65b1445
DG
1939 max_addr = arr + SDEBUG_RLUN_ARR_SZ;
1940 for (i = 0, lun = (scsi_debug_no_lun_0 ? 1 : 0);
1941 ((i < lun_cnt) && ((unsigned char *)(one_lun + i) < max_addr));
1942 i++, lun++) {
1943 upper = (lun >> 8) & 0x3f;
1da177e4
LT
1944 if (upper)
1945 one_lun[i].scsi_lun[0] =
1946 (upper | (SAM2_LUN_ADDRESS_METHOD << 6));
c65b1445
DG
1947 one_lun[i].scsi_lun[1] = lun & 0xff;
1948 }
1949 if (wlun) {
1950 one_lun[i].scsi_lun[0] = (SAM2_WLUN_REPORT_LUNS >> 8) & 0xff;
1951 one_lun[i].scsi_lun[1] = SAM2_WLUN_REPORT_LUNS & 0xff;
1952 i++;
1da177e4 1953 }
c65b1445 1954 alloc_len = (unsigned char *)(one_lun + i) - arr;
1da177e4
LT
1955 return fill_from_dev_buffer(scp, arr,
1956 min((int)alloc_len, SDEBUG_RLUN_ARR_SZ));
1957}
1958
1959/* When timer goes off this function is called. */
1960static void timer_intr_handler(unsigned long indx)
1961{
1962 struct sdebug_queued_cmd * sqcp;
1963 unsigned long iflags;
1964
1965 if (indx >= SCSI_DEBUG_CANQUEUE) {
1966 printk(KERN_ERR "scsi_debug:timer_intr_handler: indx too "
1967 "large\n");
1968 return;
1969 }
1970 spin_lock_irqsave(&queued_arr_lock, iflags);
1971 sqcp = &queued_arr[(int)indx];
1972 if (! sqcp->in_use) {
1973 printk(KERN_ERR "scsi_debug:timer_intr_handler: Unexpected "
1974 "interrupt\n");
1975 spin_unlock_irqrestore(&queued_arr_lock, iflags);
1976 return;
1977 }
1978 sqcp->in_use = 0;
1979 if (sqcp->done_funct) {
1980 sqcp->a_cmnd->result = sqcp->scsi_result;
1981 sqcp->done_funct(sqcp->a_cmnd); /* callback to mid level */
1982 }
1983 sqcp->done_funct = NULL;
1984 spin_unlock_irqrestore(&queued_arr_lock, iflags);
1985}
1986
1987static int scsi_debug_slave_alloc(struct scsi_device * sdp)
1988{
1989 if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
c65b1445
DG
1990 printk(KERN_INFO "scsi_debug: slave_alloc <%u %u %u %u>\n",
1991 sdp->host->host_no, sdp->channel, sdp->id, sdp->lun);
1da177e4
LT
1992 return 0;
1993}
1994
1995static int scsi_debug_slave_configure(struct scsi_device * sdp)
1996{
1997 struct sdebug_dev_info * devip;
1998
1999 if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
c65b1445
DG
2000 printk(KERN_INFO "scsi_debug: slave_configure <%u %u %u %u>\n",
2001 sdp->host->host_no, sdp->channel, sdp->id, sdp->lun);
1da177e4
LT
2002 if (sdp->host->max_cmd_len != SCSI_DEBUG_MAX_CMD_LEN)
2003 sdp->host->max_cmd_len = SCSI_DEBUG_MAX_CMD_LEN;
2004 devip = devInfoReg(sdp);
6f3cbf55
DG
2005 if (NULL == devip)
2006 return 1; /* no resources, will be marked offline */
1da177e4
LT
2007 sdp->hostdata = devip;
2008 if (sdp->host->cmd_per_lun)
2009 scsi_adjust_queue_depth(sdp, SDEBUG_TAGGED_QUEUING,
2010 sdp->host->cmd_per_lun);
c65b1445 2011 blk_queue_max_segment_size(sdp->request_queue, 256 * 1024);
1da177e4
LT
2012 return 0;
2013}
2014
2015static void scsi_debug_slave_destroy(struct scsi_device * sdp)
2016{
2017 struct sdebug_dev_info * devip =
2018 (struct sdebug_dev_info *)sdp->hostdata;
2019
2020 if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
c65b1445
DG
2021 printk(KERN_INFO "scsi_debug: slave_destroy <%u %u %u %u>\n",
2022 sdp->host->host_no, sdp->channel, sdp->id, sdp->lun);
1da177e4
LT
2023 if (devip) {
2024 /* make this slot avaliable for re-use */
2025 devip->used = 0;
2026 sdp->hostdata = NULL;
2027 }
2028}
2029
2030static struct sdebug_dev_info * devInfoReg(struct scsi_device * sdev)
2031{
2032 struct sdebug_host_info * sdbg_host;
2033 struct sdebug_dev_info * open_devip = NULL;
2034 struct sdebug_dev_info * devip =
2035 (struct sdebug_dev_info *)sdev->hostdata;
2036
2037 if (devip)
2038 return devip;
2039 sdbg_host = *(struct sdebug_host_info **) sdev->host->hostdata;
2040 if(! sdbg_host) {
2041 printk(KERN_ERR "Host info NULL\n");
2042 return NULL;
2043 }
2044 list_for_each_entry(devip, &sdbg_host->dev_info_list, dev_list) {
2045 if ((devip->used) && (devip->channel == sdev->channel) &&
2046 (devip->target == sdev->id) &&
2047 (devip->lun == sdev->lun))
2048 return devip;
2049 else {
2050 if ((!devip->used) && (!open_devip))
2051 open_devip = devip;
2052 }
2053 }
2054 if (NULL == open_devip) { /* try and make a new one */
6f3cbf55 2055 open_devip = kzalloc(sizeof(*open_devip),GFP_ATOMIC);
1da177e4
LT
2056 if (NULL == open_devip) {
2057 printk(KERN_ERR "%s: out of memory at line %d\n",
2058 __FUNCTION__, __LINE__);
2059 return NULL;
2060 }
1da177e4
LT
2061 open_devip->sdbg_host = sdbg_host;
2062 list_add_tail(&open_devip->dev_list,
2063 &sdbg_host->dev_info_list);
2064 }
2065 if (open_devip) {
2066 open_devip->channel = sdev->channel;
2067 open_devip->target = sdev->id;
2068 open_devip->lun = sdev->lun;
2069 open_devip->sdbg_host = sdbg_host;
2070 open_devip->reset = 1;
2071 open_devip->used = 1;
2072 memset(open_devip->sense_buff, 0, SDEBUG_SENSE_LEN);
2073 if (scsi_debug_dsense)
2074 open_devip->sense_buff[0] = 0x72;
2075 else {
2076 open_devip->sense_buff[0] = 0x70;
2077 open_devip->sense_buff[7] = 0xa;
2078 }
c65b1445
DG
2079 if (sdev->lun == SAM2_WLUN_REPORT_LUNS)
2080 open_devip->wlun = SAM2_WLUN_REPORT_LUNS & 0xff;
1da177e4
LT
2081 return open_devip;
2082 }
2083 return NULL;
2084}
2085
2086static void mk_sense_buffer(struct sdebug_dev_info * devip, int key,
2087 int asc, int asq)
2088{
2089 unsigned char * sbuff;
2090
2091 sbuff = devip->sense_buff;
2092 memset(sbuff, 0, SDEBUG_SENSE_LEN);
2093 if (scsi_debug_dsense) {
2094 sbuff[0] = 0x72; /* descriptor, current */
2095 sbuff[1] = key;
2096 sbuff[2] = asc;
2097 sbuff[3] = asq;
2098 } else {
2099 sbuff[0] = 0x70; /* fixed, current */
2100 sbuff[2] = key;
2101 sbuff[7] = 0xa; /* implies 18 byte sense buffer */
2102 sbuff[12] = asc;
2103 sbuff[13] = asq;
2104 }
2105 if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
2106 printk(KERN_INFO "scsi_debug: [sense_key,asc,ascq]: "
2107 "[0x%x,0x%x,0x%x]\n", key, asc, asq);
2108}
2109
2110static int scsi_debug_abort(struct scsi_cmnd * SCpnt)
2111{
2112 if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
2113 printk(KERN_INFO "scsi_debug: abort\n");
2114 ++num_aborts;
2115 stop_queued_cmnd(SCpnt);
2116 return SUCCESS;
2117}
2118
2119static int scsi_debug_biosparam(struct scsi_device *sdev,
2120 struct block_device * bdev, sector_t capacity, int *info)
2121{
2122 int res;
2123 unsigned char *buf;
2124
2125 if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
2126 printk(KERN_INFO "scsi_debug: biosparam\n");
2127 buf = scsi_bios_ptable(bdev);
2128 if (buf) {
2129 res = scsi_partsize(buf, capacity,
2130 &info[2], &info[0], &info[1]);
2131 kfree(buf);
2132 if (! res)
2133 return res;
2134 }
2135 info[0] = sdebug_heads;
2136 info[1] = sdebug_sectors_per;
2137 info[2] = sdebug_cylinders_per;
2138 return 0;
2139}
2140
2141static int scsi_debug_device_reset(struct scsi_cmnd * SCpnt)
2142{
2143 struct sdebug_dev_info * devip;
2144
2145 if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
2146 printk(KERN_INFO "scsi_debug: device_reset\n");
2147 ++num_dev_resets;
2148 if (SCpnt) {
2149 devip = devInfoReg(SCpnt->device);
2150 if (devip)
2151 devip->reset = 1;
2152 }
2153 return SUCCESS;
2154}
2155
2156static int scsi_debug_bus_reset(struct scsi_cmnd * SCpnt)
2157{
2158 struct sdebug_host_info *sdbg_host;
2159 struct sdebug_dev_info * dev_info;
2160 struct scsi_device * sdp;
2161 struct Scsi_Host * hp;
2162
2163 if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
2164 printk(KERN_INFO "scsi_debug: bus_reset\n");
2165 ++num_bus_resets;
2166 if (SCpnt && ((sdp = SCpnt->device)) && ((hp = sdp->host))) {
2167 sdbg_host = *(struct sdebug_host_info **) hp->hostdata;
2168 if (sdbg_host) {
2169 list_for_each_entry(dev_info,
2170 &sdbg_host->dev_info_list,
2171 dev_list)
2172 dev_info->reset = 1;
2173 }
2174 }
2175 return SUCCESS;
2176}
2177
2178static int scsi_debug_host_reset(struct scsi_cmnd * SCpnt)
2179{
2180 struct sdebug_host_info * sdbg_host;
2181 struct sdebug_dev_info * dev_info;
2182
2183 if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
2184 printk(KERN_INFO "scsi_debug: host_reset\n");
2185 ++num_host_resets;
2186 spin_lock(&sdebug_host_list_lock);
2187 list_for_each_entry(sdbg_host, &sdebug_host_list, host_list) {
2188 list_for_each_entry(dev_info, &sdbg_host->dev_info_list,
2189 dev_list)
2190 dev_info->reset = 1;
2191 }
2192 spin_unlock(&sdebug_host_list_lock);
2193 stop_all_queued();
2194 return SUCCESS;
2195}
2196
2197/* Returns 1 if found 'cmnd' and deleted its timer. else returns 0 */
2198static int stop_queued_cmnd(struct scsi_cmnd * cmnd)
2199{
2200 unsigned long iflags;
2201 int k;
2202 struct sdebug_queued_cmd * sqcp;
2203
2204 spin_lock_irqsave(&queued_arr_lock, iflags);
2205 for (k = 0; k < SCSI_DEBUG_CANQUEUE; ++k) {
2206 sqcp = &queued_arr[k];
2207 if (sqcp->in_use && (cmnd == sqcp->a_cmnd)) {
2208 del_timer_sync(&sqcp->cmnd_timer);
2209 sqcp->in_use = 0;
2210 sqcp->a_cmnd = NULL;
2211 break;
2212 }
2213 }
2214 spin_unlock_irqrestore(&queued_arr_lock, iflags);
2215 return (k < SCSI_DEBUG_CANQUEUE) ? 1 : 0;
2216}
2217
2218/* Deletes (stops) timers of all queued commands */
2219static void stop_all_queued(void)
2220{
2221 unsigned long iflags;
2222 int k;
2223 struct sdebug_queued_cmd * sqcp;
2224
2225 spin_lock_irqsave(&queued_arr_lock, iflags);
2226 for (k = 0; k < SCSI_DEBUG_CANQUEUE; ++k) {
2227 sqcp = &queued_arr[k];
2228 if (sqcp->in_use && sqcp->a_cmnd) {
2229 del_timer_sync(&sqcp->cmnd_timer);
2230 sqcp->in_use = 0;
2231 sqcp->a_cmnd = NULL;
2232 }
2233 }
2234 spin_unlock_irqrestore(&queued_arr_lock, iflags);
2235}
2236
2237/* Initializes timers in queued array */
2238static void __init init_all_queued(void)
2239{
2240 unsigned long iflags;
2241 int k;
2242 struct sdebug_queued_cmd * sqcp;
2243
2244 spin_lock_irqsave(&queued_arr_lock, iflags);
2245 for (k = 0; k < SCSI_DEBUG_CANQUEUE; ++k) {
2246 sqcp = &queued_arr[k];
2247 init_timer(&sqcp->cmnd_timer);
2248 sqcp->in_use = 0;
2249 sqcp->a_cmnd = NULL;
2250 }
2251 spin_unlock_irqrestore(&queued_arr_lock, iflags);
2252}
2253
2254static void __init sdebug_build_parts(unsigned char * ramp)
2255{
2256 struct partition * pp;
2257 int starts[SDEBUG_MAX_PARTS + 2];
2258 int sectors_per_part, num_sectors, k;
2259 int heads_by_sects, start_sec, end_sec;
2260
2261 /* assume partition table already zeroed */
2262 if ((scsi_debug_num_parts < 1) || (sdebug_store_size < 1048576))
2263 return;
2264 if (scsi_debug_num_parts > SDEBUG_MAX_PARTS) {
2265 scsi_debug_num_parts = SDEBUG_MAX_PARTS;
2266 printk(KERN_WARNING "scsi_debug:build_parts: reducing "
2267 "partitions to %d\n", SDEBUG_MAX_PARTS);
2268 }
c65b1445 2269 num_sectors = (int)sdebug_store_sectors;
1da177e4
LT
2270 sectors_per_part = (num_sectors - sdebug_sectors_per)
2271 / scsi_debug_num_parts;
2272 heads_by_sects = sdebug_heads * sdebug_sectors_per;
2273 starts[0] = sdebug_sectors_per;
2274 for (k = 1; k < scsi_debug_num_parts; ++k)
2275 starts[k] = ((k * sectors_per_part) / heads_by_sects)
2276 * heads_by_sects;
2277 starts[scsi_debug_num_parts] = num_sectors;
2278 starts[scsi_debug_num_parts + 1] = 0;
2279
2280 ramp[510] = 0x55; /* magic partition markings */
2281 ramp[511] = 0xAA;
2282 pp = (struct partition *)(ramp + 0x1be);
2283 for (k = 0; starts[k + 1]; ++k, ++pp) {
2284 start_sec = starts[k];
2285 end_sec = starts[k + 1] - 1;
2286 pp->boot_ind = 0;
2287
2288 pp->cyl = start_sec / heads_by_sects;
2289 pp->head = (start_sec - (pp->cyl * heads_by_sects))
2290 / sdebug_sectors_per;
2291 pp->sector = (start_sec % sdebug_sectors_per) + 1;
2292
2293 pp->end_cyl = end_sec / heads_by_sects;
2294 pp->end_head = (end_sec - (pp->end_cyl * heads_by_sects))
2295 / sdebug_sectors_per;
2296 pp->end_sector = (end_sec % sdebug_sectors_per) + 1;
2297
2298 pp->start_sect = start_sec;
2299 pp->nr_sects = end_sec - start_sec + 1;
2300 pp->sys_ind = 0x83; /* plain Linux partition */
2301 }
2302}
2303
2304static int schedule_resp(struct scsi_cmnd * cmnd,
2305 struct sdebug_dev_info * devip,
2306 done_funct_t done, int scsi_result, int delta_jiff)
2307{
2308 if ((SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) && cmnd) {
2309 if (scsi_result) {
2310 struct scsi_device * sdp = cmnd->device;
2311
c65b1445
DG
2312 printk(KERN_INFO "scsi_debug: <%u %u %u %u> "
2313 "non-zero result=0x%x\n", sdp->host->host_no,
2314 sdp->channel, sdp->id, sdp->lun, scsi_result);
1da177e4
LT
2315 }
2316 }
2317 if (cmnd && devip) {
2318 /* simulate autosense by this driver */
2319 if (SAM_STAT_CHECK_CONDITION == (scsi_result & 0xff))
2320 memcpy(cmnd->sense_buffer, devip->sense_buff,
2321 (SCSI_SENSE_BUFFERSIZE > SDEBUG_SENSE_LEN) ?
2322 SDEBUG_SENSE_LEN : SCSI_SENSE_BUFFERSIZE);
2323 }
2324 if (delta_jiff <= 0) {
2325 if (cmnd)
2326 cmnd->result = scsi_result;
2327 if (done)
2328 done(cmnd);
2329 return 0;
2330 } else {
2331 unsigned long iflags;
2332 int k;
2333 struct sdebug_queued_cmd * sqcp = NULL;
2334
2335 spin_lock_irqsave(&queued_arr_lock, iflags);
2336 for (k = 0; k < SCSI_DEBUG_CANQUEUE; ++k) {
2337 sqcp = &queued_arr[k];
2338 if (! sqcp->in_use)
2339 break;
2340 }
2341 if (k >= SCSI_DEBUG_CANQUEUE) {
2342 spin_unlock_irqrestore(&queued_arr_lock, iflags);
2343 printk(KERN_WARNING "scsi_debug: can_queue exceeded\n");
2344 return 1; /* report busy to mid level */
2345 }
2346 sqcp->in_use = 1;
2347 sqcp->a_cmnd = cmnd;
2348 sqcp->scsi_result = scsi_result;
2349 sqcp->done_funct = done;
2350 sqcp->cmnd_timer.function = timer_intr_handler;
2351 sqcp->cmnd_timer.data = k;
2352 sqcp->cmnd_timer.expires = jiffies + delta_jiff;
2353 add_timer(&sqcp->cmnd_timer);
2354 spin_unlock_irqrestore(&queued_arr_lock, iflags);
2355 if (cmnd)
2356 cmnd->result = 0;
2357 return 0;
2358 }
2359}
2360
23183910
DG
2361/* Note: The following macros create attribute files in the
2362 /sys/module/scsi_debug/parameters directory. Unfortunately this
2363 driver is unaware of a change and cannot trigger auxiliary actions
2364 as it can when the corresponding attribute in the
2365 /sys/bus/pseudo/drivers/scsi_debug directory is changed.
2366 */
c65b1445
DG
2367module_param_named(add_host, scsi_debug_add_host, int, S_IRUGO | S_IWUSR);
2368module_param_named(delay, scsi_debug_delay, int, S_IRUGO | S_IWUSR);
2369module_param_named(dev_size_mb, scsi_debug_dev_size_mb, int, S_IRUGO);
2370module_param_named(dsense, scsi_debug_dsense, int, S_IRUGO | S_IWUSR);
2371module_param_named(every_nth, scsi_debug_every_nth, int, S_IRUGO | S_IWUSR);
23183910 2372module_param_named(fake_rw, scsi_debug_fake_rw, int, S_IRUGO | S_IWUSR);
c65b1445
DG
2373module_param_named(max_luns, scsi_debug_max_luns, int, S_IRUGO | S_IWUSR);
2374module_param_named(no_lun_0, scsi_debug_no_lun_0, int, S_IRUGO | S_IWUSR);
2375module_param_named(num_parts, scsi_debug_num_parts, int, S_IRUGO);
2376module_param_named(num_tgts, scsi_debug_num_tgts, int, S_IRUGO | S_IWUSR);
2377module_param_named(opts, scsi_debug_opts, int, S_IRUGO | S_IWUSR);
2378module_param_named(ptype, scsi_debug_ptype, int, S_IRUGO | S_IWUSR);
2379module_param_named(scsi_level, scsi_debug_scsi_level, int, S_IRUGO);
2380module_param_named(virtual_gb, scsi_debug_virtual_gb, int, S_IRUGO | S_IWUSR);
23183910
DG
2381module_param_named(vpd_use_hostno, scsi_debug_vpd_use_hostno, int,
2382 S_IRUGO | S_IWUSR);
1da177e4
LT
2383
2384MODULE_AUTHOR("Eric Youngdale + Douglas Gilbert");
2385MODULE_DESCRIPTION("SCSI debug adapter driver");
2386MODULE_LICENSE("GPL");
2387MODULE_VERSION(SCSI_DEBUG_VERSION);
2388
2389MODULE_PARM_DESC(add_host, "0..127 hosts allowed(def=1)");
2390MODULE_PARM_DESC(delay, "# of jiffies to delay response(def=1)");
c65b1445
DG
2391MODULE_PARM_DESC(dev_size_mb, "size in MB of ram shared by devs(def=8)");
2392MODULE_PARM_DESC(dsense, "use descriptor sense format(def=0 -> fixed)");
beb87c33 2393MODULE_PARM_DESC(every_nth, "timeout every nth command(def=0)");
23183910 2394MODULE_PARM_DESC(fake_rw, "fake reads/writes instead of copying (def=0)");
c65b1445
DG
2395MODULE_PARM_DESC(max_luns, "number of LUNs per target to simulate(def=1)");
2396MODULE_PARM_DESC(no_lun_0, "no LU number 0 (def=0 -> have lun 0)");
1da177e4 2397MODULE_PARM_DESC(num_parts, "number of partitions(def=0)");
c65b1445 2398MODULE_PARM_DESC(num_tgts, "number of targets per host to simulate(def=1)");
6f3cbf55 2399MODULE_PARM_DESC(opts, "1->noise, 2->medium_err, 4->timeout, 8->recovered_err... (def=0)");
1da177e4
LT
2400MODULE_PARM_DESC(ptype, "SCSI peripheral type(def=0[disk])");
2401MODULE_PARM_DESC(scsi_level, "SCSI level to simulate(def=5[SPC-3])");
c65b1445 2402MODULE_PARM_DESC(virtual_gb, "virtual gigabyte size (def=0 -> use dev_size_mb)");
23183910 2403MODULE_PARM_DESC(vpd_use_hostno, "0 -> dev ids ignore hostno (def=1 -> unique dev ids)");
1da177e4
LT
2404
2405
2406static char sdebug_info[256];
2407
2408static const char * scsi_debug_info(struct Scsi_Host * shp)
2409{
2410 sprintf(sdebug_info, "scsi_debug, version %s [%s], "
2411 "dev_size_mb=%d, opts=0x%x", SCSI_DEBUG_VERSION,
2412 scsi_debug_version_date, scsi_debug_dev_size_mb,
2413 scsi_debug_opts);
2414 return sdebug_info;
2415}
2416
2417/* scsi_debug_proc_info
2418 * Used if the driver currently has no own support for /proc/scsi
2419 */
2420static int scsi_debug_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
2421 int length, int inout)
2422{
2423 int len, pos, begin;
2424 int orig_length;
2425
2426 orig_length = length;
2427
2428 if (inout == 1) {
2429 char arr[16];
2430 int minLen = length > 15 ? 15 : length;
2431
2432 if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
2433 return -EACCES;
2434 memcpy(arr, buffer, minLen);
2435 arr[minLen] = '\0';
2436 if (1 != sscanf(arr, "%d", &pos))
2437 return -EINVAL;
2438 scsi_debug_opts = pos;
2439 if (scsi_debug_every_nth != 0)
2440 scsi_debug_cmnd_count = 0;
2441 return length;
2442 }
2443 begin = 0;
2444 pos = len = sprintf(buffer, "scsi_debug adapter driver, version "
2445 "%s [%s]\n"
2446 "num_tgts=%d, shared (ram) size=%d MB, opts=0x%x, "
2447 "every_nth=%d(curr:%d)\n"
2448 "delay=%d, max_luns=%d, scsi_level=%d\n"
2449 "sector_size=%d bytes, cylinders=%d, heads=%d, sectors=%d\n"
2450 "number of aborts=%d, device_reset=%d, bus_resets=%d, "
2451 "host_resets=%d\n",
2452 SCSI_DEBUG_VERSION, scsi_debug_version_date, scsi_debug_num_tgts,
2453 scsi_debug_dev_size_mb, scsi_debug_opts, scsi_debug_every_nth,
2454 scsi_debug_cmnd_count, scsi_debug_delay,
2455 scsi_debug_max_luns, scsi_debug_scsi_level,
2456 SECT_SIZE, sdebug_cylinders_per, sdebug_heads, sdebug_sectors_per,
2457 num_aborts, num_dev_resets, num_bus_resets, num_host_resets);
2458 if (pos < offset) {
2459 len = 0;
2460 begin = pos;
2461 }
2462 *start = buffer + (offset - begin); /* Start of wanted data */
2463 len -= (offset - begin);
2464 if (len > length)
2465 len = length;
2466 return len;
2467}
2468
2469static ssize_t sdebug_delay_show(struct device_driver * ddp, char * buf)
2470{
2471 return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_delay);
2472}
2473
2474static ssize_t sdebug_delay_store(struct device_driver * ddp,
2475 const char * buf, size_t count)
2476{
2477 int delay;
2478 char work[20];
2479
2480 if (1 == sscanf(buf, "%10s", work)) {
2481 if ((1 == sscanf(work, "%d", &delay)) && (delay >= 0)) {
2482 scsi_debug_delay = delay;
2483 return count;
2484 }
2485 }
2486 return -EINVAL;
2487}
2488DRIVER_ATTR(delay, S_IRUGO | S_IWUSR, sdebug_delay_show,
2489 sdebug_delay_store);
2490
2491static ssize_t sdebug_opts_show(struct device_driver * ddp, char * buf)
2492{
2493 return scnprintf(buf, PAGE_SIZE, "0x%x\n", scsi_debug_opts);
2494}
2495
2496static ssize_t sdebug_opts_store(struct device_driver * ddp,
2497 const char * buf, size_t count)
2498{
2499 int opts;
2500 char work[20];
2501
2502 if (1 == sscanf(buf, "%10s", work)) {
2503 if (0 == strnicmp(work,"0x", 2)) {
2504 if (1 == sscanf(&work[2], "%x", &opts))
2505 goto opts_done;
2506 } else {
2507 if (1 == sscanf(work, "%d", &opts))
2508 goto opts_done;
2509 }
2510 }
2511 return -EINVAL;
2512opts_done:
2513 scsi_debug_opts = opts;
2514 scsi_debug_cmnd_count = 0;
2515 return count;
2516}
2517DRIVER_ATTR(opts, S_IRUGO | S_IWUSR, sdebug_opts_show,
2518 sdebug_opts_store);
2519
2520static ssize_t sdebug_ptype_show(struct device_driver * ddp, char * buf)
2521{
2522 return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_ptype);
2523}
2524static ssize_t sdebug_ptype_store(struct device_driver * ddp,
2525 const char * buf, size_t count)
2526{
2527 int n;
2528
2529 if ((count > 0) && (1 == sscanf(buf, "%d", &n)) && (n >= 0)) {
2530 scsi_debug_ptype = n;
2531 return count;
2532 }
2533 return -EINVAL;
2534}
2535DRIVER_ATTR(ptype, S_IRUGO | S_IWUSR, sdebug_ptype_show, sdebug_ptype_store);
2536
2537static ssize_t sdebug_dsense_show(struct device_driver * ddp, char * buf)
2538{
2539 return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_dsense);
2540}
2541static ssize_t sdebug_dsense_store(struct device_driver * ddp,
2542 const char * buf, size_t count)
2543{
2544 int n;
2545
2546 if ((count > 0) && (1 == sscanf(buf, "%d", &n)) && (n >= 0)) {
2547 scsi_debug_dsense = n;
2548 return count;
2549 }
2550 return -EINVAL;
2551}
2552DRIVER_ATTR(dsense, S_IRUGO | S_IWUSR, sdebug_dsense_show,
2553 sdebug_dsense_store);
2554
23183910
DG
2555static ssize_t sdebug_fake_rw_show(struct device_driver * ddp, char * buf)
2556{
2557 return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_fake_rw);
2558}
2559static ssize_t sdebug_fake_rw_store(struct device_driver * ddp,
2560 const char * buf, size_t count)
2561{
2562 int n;
2563
2564 if ((count > 0) && (1 == sscanf(buf, "%d", &n)) && (n >= 0)) {
2565 scsi_debug_fake_rw = n;
2566 return count;
2567 }
2568 return -EINVAL;
2569}
2570DRIVER_ATTR(fake_rw, S_IRUGO | S_IWUSR, sdebug_fake_rw_show,
2571 sdebug_fake_rw_store);
2572
c65b1445
DG
2573static ssize_t sdebug_no_lun_0_show(struct device_driver * ddp, char * buf)
2574{
2575 return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_no_lun_0);
2576}
2577static ssize_t sdebug_no_lun_0_store(struct device_driver * ddp,
2578 const char * buf, size_t count)
2579{
2580 int n;
2581
2582 if ((count > 0) && (1 == sscanf(buf, "%d", &n)) && (n >= 0)) {
2583 scsi_debug_no_lun_0 = n;
2584 return count;
2585 }
2586 return -EINVAL;
2587}
2588DRIVER_ATTR(no_lun_0, S_IRUGO | S_IWUSR, sdebug_no_lun_0_show,
2589 sdebug_no_lun_0_store);
2590
1da177e4
LT
2591static ssize_t sdebug_num_tgts_show(struct device_driver * ddp, char * buf)
2592{
2593 return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_num_tgts);
2594}
2595static ssize_t sdebug_num_tgts_store(struct device_driver * ddp,
2596 const char * buf, size_t count)
2597{
2598 int n;
2599
2600 if ((count > 0) && (1 == sscanf(buf, "%d", &n)) && (n >= 0)) {
2601 scsi_debug_num_tgts = n;
2602 sdebug_max_tgts_luns();
2603 return count;
2604 }
2605 return -EINVAL;
2606}
2607DRIVER_ATTR(num_tgts, S_IRUGO | S_IWUSR, sdebug_num_tgts_show,
2608 sdebug_num_tgts_store);
2609
2610static ssize_t sdebug_dev_size_mb_show(struct device_driver * ddp, char * buf)
2611{
2612 return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_dev_size_mb);
2613}
2614DRIVER_ATTR(dev_size_mb, S_IRUGO, sdebug_dev_size_mb_show, NULL);
2615
2616static ssize_t sdebug_num_parts_show(struct device_driver * ddp, char * buf)
2617{
2618 return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_num_parts);
2619}
2620DRIVER_ATTR(num_parts, S_IRUGO, sdebug_num_parts_show, NULL);
2621
2622static ssize_t sdebug_every_nth_show(struct device_driver * ddp, char * buf)
2623{
2624 return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_every_nth);
2625}
2626static ssize_t sdebug_every_nth_store(struct device_driver * ddp,
2627 const char * buf, size_t count)
2628{
2629 int nth;
2630
2631 if ((count > 0) && (1 == sscanf(buf, "%d", &nth))) {
2632 scsi_debug_every_nth = nth;
2633 scsi_debug_cmnd_count = 0;
2634 return count;
2635 }
2636 return -EINVAL;
2637}
2638DRIVER_ATTR(every_nth, S_IRUGO | S_IWUSR, sdebug_every_nth_show,
2639 sdebug_every_nth_store);
2640
2641static ssize_t sdebug_max_luns_show(struct device_driver * ddp, char * buf)
2642{
2643 return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_max_luns);
2644}
2645static ssize_t sdebug_max_luns_store(struct device_driver * ddp,
2646 const char * buf, size_t count)
2647{
2648 int n;
2649
2650 if ((count > 0) && (1 == sscanf(buf, "%d", &n)) && (n >= 0)) {
2651 scsi_debug_max_luns = n;
2652 sdebug_max_tgts_luns();
2653 return count;
2654 }
2655 return -EINVAL;
2656}
2657DRIVER_ATTR(max_luns, S_IRUGO | S_IWUSR, sdebug_max_luns_show,
2658 sdebug_max_luns_store);
2659
2660static ssize_t sdebug_scsi_level_show(struct device_driver * ddp, char * buf)
2661{
2662 return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_scsi_level);
2663}
2664DRIVER_ATTR(scsi_level, S_IRUGO, sdebug_scsi_level_show, NULL);
2665
c65b1445
DG
2666static ssize_t sdebug_virtual_gb_show(struct device_driver * ddp, char * buf)
2667{
2668 return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_virtual_gb);
2669}
2670static ssize_t sdebug_virtual_gb_store(struct device_driver * ddp,
2671 const char * buf, size_t count)
2672{
2673 int n;
2674
2675 if ((count > 0) && (1 == sscanf(buf, "%d", &n)) && (n >= 0)) {
2676 scsi_debug_virtual_gb = n;
2677 if (scsi_debug_virtual_gb > 0) {
2678 sdebug_capacity = 2048 * 1024;
2679 sdebug_capacity *= scsi_debug_virtual_gb;
2680 } else
2681 sdebug_capacity = sdebug_store_sectors;
2682 return count;
2683 }
2684 return -EINVAL;
2685}
2686DRIVER_ATTR(virtual_gb, S_IRUGO | S_IWUSR, sdebug_virtual_gb_show,
2687 sdebug_virtual_gb_store);
2688
1da177e4
LT
2689static ssize_t sdebug_add_host_show(struct device_driver * ddp, char * buf)
2690{
2691 return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_add_host);
2692}
2693
2694static ssize_t sdebug_add_host_store(struct device_driver * ddp,
2695 const char * buf, size_t count)
2696{
2697 int delta_hosts;
2698 char work[20];
2699
2700 if (1 != sscanf(buf, "%10s", work))
2701 return -EINVAL;
2702 { /* temporary hack around sscanf() problem with -ve nums */
2703 int neg = 0;
2704
2705 if ('-' == *work)
2706 neg = 1;
2707 if (1 != sscanf(work + neg, "%d", &delta_hosts))
2708 return -EINVAL;
2709 if (neg)
2710 delta_hosts = -delta_hosts;
2711 }
2712 if (delta_hosts > 0) {
2713 do {
2714 sdebug_add_adapter();
2715 } while (--delta_hosts);
2716 } else if (delta_hosts < 0) {
2717 do {
2718 sdebug_remove_adapter();
2719 } while (++delta_hosts);
2720 }
2721 return count;
2722}
2723DRIVER_ATTR(add_host, S_IRUGO | S_IWUSR, sdebug_add_host_show,
2724 sdebug_add_host_store);
2725
23183910
DG
2726static ssize_t sdebug_vpd_use_hostno_show(struct device_driver * ddp,
2727 char * buf)
2728{
2729 return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_vpd_use_hostno);
2730}
2731static ssize_t sdebug_vpd_use_hostno_store(struct device_driver * ddp,
2732 const char * buf, size_t count)
2733{
2734 int n;
2735
2736 if ((count > 0) && (1 == sscanf(buf, "%d", &n)) && (n >= 0)) {
2737 scsi_debug_vpd_use_hostno = n;
2738 return count;
2739 }
2740 return -EINVAL;
2741}
2742DRIVER_ATTR(vpd_use_hostno, S_IRUGO | S_IWUSR, sdebug_vpd_use_hostno_show,
2743 sdebug_vpd_use_hostno_store);
2744
2745/* Note: The following function creates attribute files in the
2746 /sys/bus/pseudo/drivers/scsi_debug directory. The advantage of these
2747 files (over those found in the /sys/module/scsi_debug/parameters
2748 directory) is that auxiliary actions can be triggered when an attribute
2749 is changed. For example see: sdebug_add_host_store() above.
2750 */
6ecaff7f 2751static int do_create_driverfs_files(void)
1da177e4 2752{
6ecaff7f
RD
2753 int ret;
2754
2755 ret = driver_create_file(&sdebug_driverfs_driver, &driver_attr_add_host);
2756 ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_delay);
2757 ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_dev_size_mb);
2758 ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_dsense);
2759 ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_every_nth);
23183910 2760 ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_fake_rw);
6ecaff7f 2761 ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_max_luns);
23183910 2762 ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_no_lun_0);
6ecaff7f 2763 ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_num_parts);
23183910 2764 ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_num_tgts);
6ecaff7f
RD
2765 ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_ptype);
2766 ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_opts);
2767 ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_scsi_level);
23183910
DG
2768 ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_virtual_gb);
2769 ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_vpd_use_hostno);
6ecaff7f 2770 return ret;
1da177e4
LT
2771}
2772
2773static void do_remove_driverfs_files(void)
2774{
23183910
DG
2775 driver_remove_file(&sdebug_driverfs_driver, &driver_attr_vpd_use_hostno);
2776 driver_remove_file(&sdebug_driverfs_driver, &driver_attr_virtual_gb);
1da177e4
LT
2777 driver_remove_file(&sdebug_driverfs_driver, &driver_attr_scsi_level);
2778 driver_remove_file(&sdebug_driverfs_driver, &driver_attr_opts);
2779 driver_remove_file(&sdebug_driverfs_driver, &driver_attr_ptype);
1da177e4 2780 driver_remove_file(&sdebug_driverfs_driver, &driver_attr_num_tgts);
23183910
DG
2781 driver_remove_file(&sdebug_driverfs_driver, &driver_attr_num_parts);
2782 driver_remove_file(&sdebug_driverfs_driver, &driver_attr_no_lun_0);
1da177e4 2783 driver_remove_file(&sdebug_driverfs_driver, &driver_attr_max_luns);
23183910 2784 driver_remove_file(&sdebug_driverfs_driver, &driver_attr_fake_rw);
1da177e4
LT
2785 driver_remove_file(&sdebug_driverfs_driver, &driver_attr_every_nth);
2786 driver_remove_file(&sdebug_driverfs_driver, &driver_attr_dsense);
2787 driver_remove_file(&sdebug_driverfs_driver, &driver_attr_dev_size_mb);
2788 driver_remove_file(&sdebug_driverfs_driver, &driver_attr_delay);
2789 driver_remove_file(&sdebug_driverfs_driver, &driver_attr_add_host);
2790}
2791
2792static int __init scsi_debug_init(void)
2793{
c65b1445 2794 unsigned int sz;
1da177e4
LT
2795 int host_to_add;
2796 int k;
6ecaff7f 2797 int ret;
1da177e4
LT
2798
2799 if (scsi_debug_dev_size_mb < 1)
2800 scsi_debug_dev_size_mb = 1; /* force minimum 1 MB ramdisk */
c65b1445
DG
2801 sdebug_store_size = (unsigned int)scsi_debug_dev_size_mb * 1048576;
2802 sdebug_store_sectors = sdebug_store_size / SECT_SIZE;
2803 if (scsi_debug_virtual_gb > 0) {
2804 sdebug_capacity = 2048 * 1024;
2805 sdebug_capacity *= scsi_debug_virtual_gb;
2806 } else
2807 sdebug_capacity = sdebug_store_sectors;
1da177e4
LT
2808
2809 /* play around with geometry, don't waste too much on track 0 */
2810 sdebug_heads = 8;
2811 sdebug_sectors_per = 32;
2812 if (scsi_debug_dev_size_mb >= 16)
2813 sdebug_heads = 32;
2814 else if (scsi_debug_dev_size_mb >= 256)
2815 sdebug_heads = 64;
2816 sdebug_cylinders_per = (unsigned long)sdebug_capacity /
2817 (sdebug_sectors_per * sdebug_heads);
2818 if (sdebug_cylinders_per >= 1024) {
2819 /* other LLDs do this; implies >= 1GB ram disk ... */
2820 sdebug_heads = 255;
2821 sdebug_sectors_per = 63;
2822 sdebug_cylinders_per = (unsigned long)sdebug_capacity /
2823 (sdebug_sectors_per * sdebug_heads);
2824 }
2825
2826 sz = sdebug_store_size;
2827 fake_storep = vmalloc(sz);
2828 if (NULL == fake_storep) {
2829 printk(KERN_ERR "scsi_debug_init: out of memory, 1\n");
2830 return -ENOMEM;
2831 }
2832 memset(fake_storep, 0, sz);
2833 if (scsi_debug_num_parts > 0)
2834 sdebug_build_parts(fake_storep);
2835
6ecaff7f
RD
2836 ret = device_register(&pseudo_primary);
2837 if (ret < 0) {
2838 printk(KERN_WARNING "scsi_debug: device_register error: %d\n",
2839 ret);
2840 goto free_vm;
2841 }
2842 ret = bus_register(&pseudo_lld_bus);
2843 if (ret < 0) {
2844 printk(KERN_WARNING "scsi_debug: bus_register error: %d\n",
2845 ret);
2846 goto dev_unreg;
2847 }
2848 ret = driver_register(&sdebug_driverfs_driver);
2849 if (ret < 0) {
2850 printk(KERN_WARNING "scsi_debug: driver_register error: %d\n",
2851 ret);
2852 goto bus_unreg;
2853 }
2854 ret = do_create_driverfs_files();
2855 if (ret < 0) {
2856 printk(KERN_WARNING "scsi_debug: driver_create_file error: %d\n",
2857 ret);
2858 goto del_files;
2859 }
1da177e4 2860
6ecaff7f 2861 init_all_queued();
1da177e4 2862
b02b6bc4 2863 sdebug_driver_template.proc_name = sdebug_proc_name;
1da177e4
LT
2864
2865 host_to_add = scsi_debug_add_host;
2866 scsi_debug_add_host = 0;
2867
2868 for (k = 0; k < host_to_add; k++) {
2869 if (sdebug_add_adapter()) {
2870 printk(KERN_ERR "scsi_debug_init: "
2871 "sdebug_add_adapter failed k=%d\n", k);
2872 break;
2873 }
2874 }
2875
2876 if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) {
2877 printk(KERN_INFO "scsi_debug_init: built %d host(s)\n",
2878 scsi_debug_add_host);
2879 }
2880 return 0;
6ecaff7f
RD
2881
2882del_files:
2883 do_remove_driverfs_files();
2884 driver_unregister(&sdebug_driverfs_driver);
2885bus_unreg:
2886 bus_unregister(&pseudo_lld_bus);
2887dev_unreg:
2888 device_unregister(&pseudo_primary);
2889free_vm:
2890 vfree(fake_storep);
2891
2892 return ret;
1da177e4
LT
2893}
2894
2895static void __exit scsi_debug_exit(void)
2896{
2897 int k = scsi_debug_add_host;
2898
2899 stop_all_queued();
2900 for (; k; k--)
2901 sdebug_remove_adapter();
2902 do_remove_driverfs_files();
2903 driver_unregister(&sdebug_driverfs_driver);
2904 bus_unregister(&pseudo_lld_bus);
2905 device_unregister(&pseudo_primary);
2906
2907 vfree(fake_storep);
2908}
2909
2910device_initcall(scsi_debug_init);
2911module_exit(scsi_debug_exit);
2912
52c1da39 2913static void pseudo_0_release(struct device * dev)
1da177e4
LT
2914{
2915 if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
2916 printk(KERN_INFO "scsi_debug: pseudo_0_release() called\n");
2917}
2918
2919static struct device pseudo_primary = {
2920 .bus_id = "pseudo_0",
2921 .release = pseudo_0_release,
2922};
2923
2924static int pseudo_lld_bus_match(struct device *dev,
2925 struct device_driver *dev_driver)
2926{
2927 return 1;
2928}
2929
2930static struct bus_type pseudo_lld_bus = {
2931 .name = "pseudo",
2932 .match = pseudo_lld_bus_match,
bbbe3a41
RK
2933 .probe = sdebug_driver_probe,
2934 .remove = sdebug_driver_remove,
1da177e4
LT
2935};
2936
2937static void sdebug_release_adapter(struct device * dev)
2938{
2939 struct sdebug_host_info *sdbg_host;
2940
2941 sdbg_host = to_sdebug_host(dev);
2942 kfree(sdbg_host);
2943}
2944
2945static int sdebug_add_adapter(void)
2946{
2947 int k, devs_per_host;
2948 int error = 0;
2949 struct sdebug_host_info *sdbg_host;
2950 struct sdebug_dev_info *sdbg_devinfo;
2951 struct list_head *lh, *lh_sf;
2952
c65b1445 2953 sdbg_host = kzalloc(sizeof(*sdbg_host),GFP_KERNEL);
1da177e4
LT
2954 if (NULL == sdbg_host) {
2955 printk(KERN_ERR "%s: out of memory at line %d\n",
2956 __FUNCTION__, __LINE__);
2957 return -ENOMEM;
2958 }
2959
1da177e4
LT
2960 INIT_LIST_HEAD(&sdbg_host->dev_info_list);
2961
2962 devs_per_host = scsi_debug_num_tgts * scsi_debug_max_luns;
2963 for (k = 0; k < devs_per_host; k++) {
c65b1445 2964 sdbg_devinfo = kzalloc(sizeof(*sdbg_devinfo),GFP_KERNEL);
1da177e4
LT
2965 if (NULL == sdbg_devinfo) {
2966 printk(KERN_ERR "%s: out of memory at line %d\n",
2967 __FUNCTION__, __LINE__);
2968 error = -ENOMEM;
2969 goto clean;
2970 }
1da177e4
LT
2971 sdbg_devinfo->sdbg_host = sdbg_host;
2972 list_add_tail(&sdbg_devinfo->dev_list,
2973 &sdbg_host->dev_info_list);
2974 }
2975
2976 spin_lock(&sdebug_host_list_lock);
2977 list_add_tail(&sdbg_host->host_list, &sdebug_host_list);
2978 spin_unlock(&sdebug_host_list_lock);
2979
2980 sdbg_host->dev.bus = &pseudo_lld_bus;
2981 sdbg_host->dev.parent = &pseudo_primary;
2982 sdbg_host->dev.release = &sdebug_release_adapter;
2983 sprintf(sdbg_host->dev.bus_id, "adapter%d", scsi_debug_add_host);
2984
2985 error = device_register(&sdbg_host->dev);
2986
2987 if (error)
2988 goto clean;
2989
2990 ++scsi_debug_add_host;
2991 return error;
2992
2993clean:
2994 list_for_each_safe(lh, lh_sf, &sdbg_host->dev_info_list) {
2995 sdbg_devinfo = list_entry(lh, struct sdebug_dev_info,
2996 dev_list);
2997 list_del(&sdbg_devinfo->dev_list);
2998 kfree(sdbg_devinfo);
2999 }
3000
3001 kfree(sdbg_host);
3002 return error;
3003}
3004
3005static void sdebug_remove_adapter(void)
3006{
3007 struct sdebug_host_info * sdbg_host = NULL;
3008
3009 spin_lock(&sdebug_host_list_lock);
3010 if (!list_empty(&sdebug_host_list)) {
3011 sdbg_host = list_entry(sdebug_host_list.prev,
3012 struct sdebug_host_info, host_list);
3013 list_del(&sdbg_host->host_list);
3014 }
3015 spin_unlock(&sdebug_host_list_lock);
3016
3017 if (!sdbg_host)
3018 return;
3019
3020 device_unregister(&sdbg_host->dev);
3021 --scsi_debug_add_host;
3022}
3023
3024static int sdebug_driver_probe(struct device * dev)
3025{
3026 int error = 0;
3027 struct sdebug_host_info *sdbg_host;
3028 struct Scsi_Host *hpnt;
3029
3030 sdbg_host = to_sdebug_host(dev);
3031
3032 hpnt = scsi_host_alloc(&sdebug_driver_template, sizeof(sdbg_host));
3033 if (NULL == hpnt) {
3034 printk(KERN_ERR "%s: scsi_register failed\n", __FUNCTION__);
3035 error = -ENODEV;
3036 return error;
3037 }
3038
3039 sdbg_host->shost = hpnt;
3040 *((struct sdebug_host_info **)hpnt->hostdata) = sdbg_host;
3041 if ((hpnt->this_id >= 0) && (scsi_debug_num_tgts > hpnt->this_id))
3042 hpnt->max_id = scsi_debug_num_tgts + 1;
3043 else
3044 hpnt->max_id = scsi_debug_num_tgts;
c65b1445 3045 hpnt->max_lun = SAM2_WLUN_REPORT_LUNS; /* = scsi_debug_max_luns; */
1da177e4
LT
3046
3047 error = scsi_add_host(hpnt, &sdbg_host->dev);
3048 if (error) {
3049 printk(KERN_ERR "%s: scsi_add_host failed\n", __FUNCTION__);
3050 error = -ENODEV;
3051 scsi_host_put(hpnt);
3052 } else
3053 scsi_scan_host(hpnt);
3054
3055
3056 return error;
3057}
3058
3059static int sdebug_driver_remove(struct device * dev)
3060{
3061 struct list_head *lh, *lh_sf;
3062 struct sdebug_host_info *sdbg_host;
3063 struct sdebug_dev_info *sdbg_devinfo;
3064
3065 sdbg_host = to_sdebug_host(dev);
3066
3067 if (!sdbg_host) {
3068 printk(KERN_ERR "%s: Unable to locate host info\n",
3069 __FUNCTION__);
3070 return -ENODEV;
3071 }
3072
3073 scsi_remove_host(sdbg_host->shost);
3074
3075 list_for_each_safe(lh, lh_sf, &sdbg_host->dev_info_list) {
3076 sdbg_devinfo = list_entry(lh, struct sdebug_dev_info,
3077 dev_list);
3078 list_del(&sdbg_devinfo->dev_list);
3079 kfree(sdbg_devinfo);
3080 }
3081
3082 scsi_host_put(sdbg_host->shost);
3083 return 0;
3084}
3085
3086static void sdebug_max_tgts_luns(void)
3087{
3088 struct sdebug_host_info * sdbg_host;
3089 struct Scsi_Host *hpnt;
3090
3091 spin_lock(&sdebug_host_list_lock);
3092 list_for_each_entry(sdbg_host, &sdebug_host_list, host_list) {
3093 hpnt = sdbg_host->shost;
3094 if ((hpnt->this_id >= 0) &&
3095 (scsi_debug_num_tgts > hpnt->this_id))
3096 hpnt->max_id = scsi_debug_num_tgts + 1;
3097 else
3098 hpnt->max_id = scsi_debug_num_tgts;
c65b1445 3099 hpnt->max_lun = SAM2_WLUN_REPORT_LUNS; /* scsi_debug_max_luns; */
1da177e4
LT
3100 }
3101 spin_unlock(&sdebug_host_list_lock);
3102}
This page took 0.441819 seconds and 5 git commands to generate.