make oldconfig will rebuild these...
[linux-2.4.21-pre4.git] / drivers / scsi / scsi_debug.c
1 /* 
2  *  linux/kernel/scsi_debug.c
3  *
4  *  Copyright (C) 1992  Eric Youngdale
5  *  Simulate a host adapter with 2 disks attached.  Do a lot of checking
6  *  to make sure that we are not getting blocks mixed up, and PANIC if
7  *  anything out of the ordinary is seen.
8  *
9  *  This version is more generic, simulating a variable number of disk 
10  *  (or disk like devices) sharing a common amount of RAM (default 8 MB
11  *  but can be set at driver/module load time).
12  *
13  *  For documentation see http://www.torque.net/sg/sdebug.html
14  *
15  *   D. Gilbert (dpg) work for Magneto-Optical device test [20010421]
16  *   dpg: work for devfs large number of disks [20010809]
17  *        use vmalloc() more inquiry+mode_sense [20020302]
18  *        add timers for delayed responses [20020721]
19  */
20
21 #include <linux/config.h>
22 #include <linux/module.h>
23
24 #include <linux/kernel.h>
25 #include <linux/sched.h>
26 #include <linux/errno.h>
27 #include <linux/timer.h>
28 #include <linux/types.h>
29 #include <linux/string.h>
30 #include <linux/genhd.h>
31 #include <linux/fs.h>
32 #include <linux/init.h>
33 #include <linux/proc_fs.h>
34 #include <linux/smp_lock.h>
35 #include <linux/vmalloc.h>
36
37 #include <asm/io.h>
38
39 #include <linux/blk.h>
40 #include "scsi.h"
41 #include "hosts.h"
42
43 #include <linux/stat.h>
44
45 #ifndef LINUX_VERSION_CODE
46 #include <linux/version.h>
47 #endif
48
49 #include "scsi_debug.h"
50
51 static const char * scsi_debug_version_str = "Version: 0.61 (20020815)";
52
53
54 #ifndef SCSI_CMD_READ_16
55 #define SCSI_CMD_READ_16 0x88
56 #endif
57 #ifndef SCSI_CMD_WRITE_16
58 #define SCSI_CMD_WRITE_16 0x8a
59 #endif
60 #ifndef REPORT_LUNS
61 #define REPORT_LUNS 0xa0
62 #endif
63
64 /* A few options that we want selected */
65 #define DEF_NR_FAKE_DEVS   1
66 #define DEF_DEV_SIZE_MB   8
67 #define DEF_FAKE_BLK0   0
68 #define DEF_EVERY_NTH   100
69 #define DEF_DELAY   1
70
71 #define DEF_OPTS   0
72 #define SCSI_DEBUG_OPT_NOISE   1
73 #define SCSI_DEBUG_OPT_MEDIUM_ERR   2
74 #define SCSI_DEBUG_OPT_EVERY_NTH   4
75
76 #define OPT_MEDIUM_ERR_ADDR   0x1234
77
78 static int scsi_debug_num_devs = DEF_NR_FAKE_DEVS;
79 static int scsi_debug_opts = DEF_OPTS;
80 static int scsi_debug_every_nth = DEF_EVERY_NTH;
81 static int scsi_debug_cmnd_count = 0;
82 static int scsi_debug_delay = DEF_DELAY;
83
84 #define NR_HOSTS_PRESENT (((scsi_debug_num_devs - 1) / 7) + 1)
85 #define N_HEAD          8
86 #define N_SECTOR        32
87 #define DEV_READONLY(TGT)      (0)
88 #define DEV_REMOVEABLE(TGT)    (0)
89 #define PERIPH_DEVICE_TYPE(TGT) (TYPE_DISK);
90
91 static int scsi_debug_dev_size_mb = DEF_DEV_SIZE_MB;
92 #define STORE_SIZE (scsi_debug_dev_size_mb * 1024 * 1024)
93
94 /* default sector size is 512 bytes, 2**9 bytes */
95 #define POW2_SECT_SIZE 9
96 #define SECT_SIZE (1 << POW2_SECT_SIZE)
97
98 #define N_CYLINDER (STORE_SIZE / (SECT_SIZE * N_SECTOR * N_HEAD))
99
100 /* Time to wait before completing a command */
101 #define CAPACITY (N_HEAD * N_SECTOR * N_CYLINDER)
102 #define SECT_SIZE_PER(TGT) SECT_SIZE
103
104
105 #define SDEBUG_SENSE_LEN 32
106
107 struct sdebug_dev_info {
108         Scsi_Device * sdp;
109         unsigned char sense_buff[SDEBUG_SENSE_LEN];     /* weak nexus */
110         char reset;
111 };
112 static struct sdebug_dev_info * devInfop;
113
114 typedef void (* done_funct_t) (Scsi_Cmnd *);
115
116 struct sdebug_queued_cmd {
117         int in_use;
118         struct timer_list cmnd_timer;
119         done_funct_t done_funct;
120         struct scsi_cmnd * a_cmnd;
121         int scsi_result;
122 };
123 static struct sdebug_queued_cmd queued_arr[SCSI_DEBUG_CANQUEUE];
124
125 static unsigned char * fake_storep;     /* ramdisk storage */
126
127 static unsigned char broken_buff[SDEBUG_SENSE_LEN];
128
129 static int num_aborts = 0;
130 static int num_dev_resets = 0;
131 static int num_bus_resets = 0;
132 static int num_host_resets = 0;
133
134 static spinlock_t queued_arr_lock = SPIN_LOCK_UNLOCKED;
135 static rwlock_t atomic_rw = RW_LOCK_UNLOCKED;
136
137
138 /* function declarations */
139 static int resp_inquiry(unsigned char * cmd, int target, unsigned char * buff,
140                         int bufflen, struct sdebug_dev_info * devip);
141 static int resp_mode_sense(unsigned char * cmd, int target,
142                            unsigned char * buff, int bufflen,
143                            struct sdebug_dev_info * devip);
144 static int resp_read(Scsi_Cmnd * SCpnt, int upper_blk, int block, 
145                      int num, struct sdebug_dev_info * devip);
146 static int resp_write(Scsi_Cmnd * SCpnt, int upper_blk, int block, int num,
147                       struct sdebug_dev_info * devip);
148 static int resp_report_luns(unsigned char * cmd, unsigned char * buff,
149                             int bufflen, struct sdebug_dev_info * devip);
150 static void timer_intr_handler(unsigned long);
151 static struct sdebug_dev_info * devInfoReg(Scsi_Device * sdp);
152 static void mk_sense_buffer(struct sdebug_dev_info * devip, int key, 
153                             int asc, int asq, int inbandLen);
154 static int check_reset(Scsi_Cmnd * SCpnt, struct sdebug_dev_info * devip);
155 static int schedule_resp(struct scsi_cmnd * cmnd, 
156                          struct sdebug_dev_info * devip, 
157                          done_funct_t done, int scsi_result, int delta_jiff);
158 static void init_all_queued(void);
159 static void stop_all_queued(void);
160 static int stop_queued_cmnd(struct scsi_cmnd * cmnd);
161 static int inquiry_evpd_83(unsigned char * arr, int dev_id_num,
162                            const char * dev_id_str, int dev_id_str_len);
163
164
165 static Scsi_Host_Template driver_template = SCSI_DEBUG_TEMPLATE;
166
167
168 static
169 int scsi_debug_queuecommand(Scsi_Cmnd * SCpnt, done_funct_t done)
170 {
171         unsigned char *cmd = (unsigned char *) SCpnt->cmnd;
172         int block;
173         int upper_blk;
174         unsigned char *buff;
175         int errsts = 0;
176         int target = SCpnt->target;
177         int bufflen = SCpnt->request_bufflen;
178         int num, capac;
179         struct sdebug_dev_info * devip = NULL;
180         unsigned char * sbuff;
181
182         if (done == NULL)
183                 return 0;       /* assume mid level reprocessing command */
184
185         if (SCpnt->use_sg) { /* just use first element */
186                 struct scatterlist *sgpnt = (struct scatterlist *)
187                                                 SCpnt->request_buffer;
188
189                 buff = sgpnt[0].address;
190                 bufflen = sgpnt[0].length;
191                 /* READ and WRITE process scatterlist themselves */
192         }
193         else 
194                 buff = (unsigned char *) SCpnt->request_buffer;
195         if (NULL == buff) {
196                 printk(KERN_WARNING "scsi_debug:qc: buff was NULL??\n");
197                 buff = broken_buff;     /* just point at dummy */
198                 bufflen = SDEBUG_SENSE_LEN;
199         }
200
201         if(target == driver_template.this_id) {
202                 printk(KERN_WARNING 
203                        "scsi_debug: initiator's id used as target!\n");
204                 return schedule_resp(SCpnt, NULL, done, 0, 0);
205         }
206
207         if ((target > driver_template.this_id) || (SCpnt->lun != 0))
208                 return schedule_resp(SCpnt, NULL, done, 
209                                      DID_NO_CONNECT << 16, 0);
210 #if 0
211         printk(KERN_INFO "sdebug:qc: host_no=%d, id=%d, sdp=%p, cmd=0x%x\n",
212                (int)SCpnt->device->host->host_no, (int)SCpnt->device->id,
213                SCpnt->device, (int)*cmd);
214 #endif
215         if (NULL == SCpnt->device->hostdata) {
216                 devip = devInfoReg(SCpnt->device);
217                 if (NULL == devip)
218                         return schedule_resp(SCpnt, NULL, done, 
219                                              DID_NO_CONNECT << 16, 0);
220                 SCpnt->device->hostdata = devip;
221         }
222         devip = SCpnt->device->hostdata;
223
224         if ((SCSI_DEBUG_OPT_EVERY_NTH & scsi_debug_opts) &&
225             (scsi_debug_every_nth > 0) &&
226             (++scsi_debug_cmnd_count >= scsi_debug_every_nth)) {
227                 scsi_debug_cmnd_count =0;
228                 return 0; /* ignore command causing timeout */
229         }
230
231         switch (*cmd) {
232         case INQUIRY:     /* mandatory */
233                 /* assume INQUIRY called first so setup max_cmd_len */
234                 if (SCpnt->host->max_cmd_len != SCSI_DEBUG_MAX_CMD_LEN)
235                         SCpnt->host->max_cmd_len = SCSI_DEBUG_MAX_CMD_LEN;
236                 errsts = resp_inquiry(cmd, target, buff, bufflen, devip);
237                 break;
238         case REQUEST_SENSE:     /* mandatory */
239                 /* Since this driver indicates autosense by placing the
240                  * sense buffer in the scsi_cmnd structure in the response
241                  * (when CHECK_CONDITION is set), the mid level shouldn't
242                  * need to call REQUEST_SENSE */
243                 if (devip) {
244                         sbuff = devip->sense_buff;
245                         memcpy(buff, sbuff, (bufflen < SDEBUG_SENSE_LEN) ? 
246                                              bufflen : SDEBUG_SENSE_LEN);
247                         mk_sense_buffer(devip, 0, 0x0, 0, 7);
248                 } else {
249                         memset(buff, 0, bufflen);
250                         buff[0] = 0x70;
251                 }
252                 break;
253         case START_STOP:
254                 errsts = check_reset(SCpnt, devip);
255                 break;
256         case ALLOW_MEDIUM_REMOVAL:
257                 if ((errsts = check_reset(SCpnt, devip)))
258                         break;
259                 if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
260                         printk("\tMedium removal %s\n",
261                                cmd[4] ? "inhibited" : "enabled");
262                 break;
263         case SEND_DIAGNOSTIC:     /* mandatory */
264                 memset(buff, 0, bufflen);
265                 break;
266         case TEST_UNIT_READY:     /* mandatory */
267                 memset(buff, 0, bufflen);
268                 break;
269         case RESERVE:
270                 errsts = check_reset(SCpnt, devip);
271                 memset(buff, 0, bufflen);
272                 break;
273         case RESERVE_10:
274                 errsts = check_reset(SCpnt, devip);
275                 memset(buff, 0, bufflen);
276                 break;
277         case RELEASE:
278                 errsts = check_reset(SCpnt, devip);
279                 memset(buff, 0, bufflen);
280                 break;
281         case RELEASE_10:
282                 errsts = check_reset(SCpnt, devip);
283                 memset(buff, 0, bufflen);
284                 break;
285         case READ_CAPACITY:
286                 errsts = check_reset(SCpnt, devip);
287                 memset(buff, 0, bufflen);
288                 if (bufflen > 7) {
289                         capac = CAPACITY - 1;
290                         buff[0] = (capac >> 24);
291                         buff[1] = (capac >> 16) & 0xff;
292                         buff[2] = (capac >> 8) & 0xff;
293                         buff[3] = capac & 0xff;
294                         buff[6] = (SECT_SIZE_PER(target) >> 8) & 0xff;
295                         buff[7] = SECT_SIZE_PER(target) & 0xff;
296                 }
297                 break;
298         case SCSI_CMD_READ_16:  /* SBC-2 */
299         case READ_12:
300         case READ_10:
301         case READ_6:
302                 if ((errsts = check_reset(SCpnt, devip)))
303                         break;
304                 upper_blk = 0;
305                 if ((*cmd) == SCSI_CMD_READ_16) {
306                         upper_blk = cmd[5] + (cmd[4] << 8) + 
307                                     (cmd[3] << 16) + (cmd[2] << 24);
308                         block = cmd[9] + (cmd[8] << 8) + 
309                                 (cmd[7] << 16) + (cmd[6] << 24);
310                         num = cmd[13] + (cmd[12] << 8) + 
311                                 (cmd[11] << 16) + (cmd[10] << 24);
312                 } else if ((*cmd) == READ_12) {
313                         block = cmd[5] + (cmd[4] << 8) + 
314                                 (cmd[3] << 16) + (cmd[2] << 24);
315                         num = cmd[9] + (cmd[8] << 8) + 
316                                 (cmd[7] << 16) + (cmd[6] << 24);
317                 } else if ((*cmd) == READ_10) {
318                         block = cmd[5] + (cmd[4] << 8) + 
319                                 (cmd[3] << 16) + (cmd[2] << 24);
320                         num = cmd[8] + (cmd[7] << 8);
321                 } else {
322                         block = cmd[3] + (cmd[2] << 8) + 
323                                 ((cmd[1] & 0x1f) << 16);
324                         num = cmd[4];
325                 }
326                 errsts = resp_read(SCpnt, upper_blk, block, num, devip);
327                 break;
328         case REPORT_LUNS:
329                 errsts = resp_report_luns(cmd, buff, bufflen, devip);
330                 break;
331         case SCSI_CMD_WRITE_16: /* SBC-2 */
332         case WRITE_12:
333         case WRITE_10:
334         case WRITE_6:
335                 if ((errsts = check_reset(SCpnt, devip)))
336                         break;
337                 upper_blk = 0;
338                 if ((*cmd) == SCSI_CMD_WRITE_16) {
339                         upper_blk = cmd[5] + (cmd[4] << 8) + 
340                                     (cmd[3] << 16) + (cmd[2] << 24);
341                         block = cmd[9] + (cmd[8] << 8) + 
342                                 (cmd[7] << 16) + (cmd[6] << 24);
343                         num = cmd[13] + (cmd[12] << 8) + 
344                                 (cmd[11] << 16) + (cmd[10] << 24);
345                 } else if ((*cmd) == WRITE_12) {
346                         block = cmd[5] + (cmd[4] << 8) + 
347                                 (cmd[3] << 16) + (cmd[2] << 24);
348                         num = cmd[9] + (cmd[8] << 8) + 
349                                 (cmd[7] << 16) + (cmd[6] << 24);
350                 } else if ((*cmd) == WRITE_10) {
351                         block = cmd[5] + (cmd[4] << 8) + 
352                                 (cmd[3] << 16) + (cmd[2] << 24);
353                         num = cmd[8] + (cmd[7] << 8);
354                 } else {
355                         block = cmd[3] + (cmd[2] << 8) + 
356                                 ((cmd[1] & 0x1f) << 16);
357                         num = cmd[4];
358                 }
359                 errsts = resp_write(SCpnt, upper_blk, block, num, devip);
360                 break;
361         case MODE_SENSE:
362         case MODE_SENSE_10:
363                 errsts = resp_mode_sense(cmd, target, buff, bufflen, devip);
364                 break;
365         default:
366 #if 0
367                 printk(KERN_INFO "scsi_debug: Unsupported command, "
368                        "opcode=0x%x\n", (int)cmd[0]);
369 #endif
370                 if ((errsts = check_reset(SCpnt, devip)))
371                         break;
372                 mk_sense_buffer(devip, ILLEGAL_REQUEST, 0x20, 0, 14);
373                 errsts = (COMMAND_COMPLETE << 8) | (CHECK_CONDITION << 1);
374                 break;
375         }
376         return schedule_resp(SCpnt, devip, done, errsts, scsi_debug_delay);
377 }
378
379 static int scsi_debug_ioctl(Scsi_Device *dev, int cmd, void *arg)
380 {
381         if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) {
382                 printk(KERN_INFO "scsi_debug: ioctl: cmd=0x%x\n", cmd);
383         }
384         /* return -ENOTTY; // Unix mandates this but apps get upset */
385         return -EINVAL;
386 }
387
388 static int check_reset(Scsi_Cmnd * SCpnt, struct sdebug_dev_info * devip)
389 {
390         if (devip->reset) {
391                 devip->reset = 0;
392                 mk_sense_buffer(devip, UNIT_ATTENTION, 0x29, 0, 14);
393                 return (COMMAND_COMPLETE << 8) | (CHECK_CONDITION << 1);
394         }
395         return 0;
396 }
397
398 #define SDEBUG_LONG_INQ_SZ 58
399 #define SDEBUG_MAX_INQ_ARR_SZ 128
400
401 static const char * vendor_id = "Linux   ";
402 static const char * product_id = "scsi_debug      ";
403 static const char * product_rev = "0004";
404
405 static int inquiry_evpd_83(unsigned char * arr, int dev_id_num, 
406                            const char * dev_id_str, int dev_id_str_len)
407 {
408         int num;
409
410         /* Two identification descriptors: */
411         /* T10 vendor identifier field format (faked) */
412         arr[0] = 0x2;   /* ASCII */
413         arr[1] = 0x1;
414         arr[2] = 0x0;
415         memcpy(&arr[4], vendor_id, 8);
416         memcpy(&arr[12], product_id, 16);
417         memcpy(&arr[28], dev_id_str, dev_id_str_len);
418         num = 8 + 16 + dev_id_str_len;
419         arr[3] = num;
420         num += 4;
421         /* NAA IEEE registered identifier (faked) */
422         arr[num] = 0x1; /* binary */
423         arr[num + 1] = 0x3;
424         arr[num + 2] = 0x0;
425         arr[num + 3] = 0x8;
426         arr[num + 4] = 0x51;    /* ieee company id=0x123456 (faked) */
427         arr[num + 5] = 0x23;
428         arr[num + 6] = 0x45;
429         arr[num + 7] = 0x60;
430         arr[num + 8] = (dev_id_num >> 24);
431         arr[num + 9] = (dev_id_num >> 16) & 0xff;
432         arr[num + 10] = (dev_id_num >> 8) & 0xff;
433         arr[num + 11] = dev_id_num & 0xff;
434         return num + 12;
435 }
436
437 static int resp_inquiry(unsigned char * cmd, int target, unsigned char * buff,
438                         int bufflen, struct sdebug_dev_info * devip)
439 {
440         unsigned char pq_pdt;
441         unsigned char arr[SDEBUG_MAX_INQ_ARR_SZ];
442         int min_len = bufflen > SDEBUG_MAX_INQ_ARR_SZ ? 
443                         SDEBUG_MAX_INQ_ARR_SZ : bufflen;
444
445         if (bufflen < cmd[4])
446                 printk(KERN_INFO "scsi_debug: inquiry: bufflen=%d "
447                        "< alloc_length=%d\n", bufflen, (int)cmd[4]);
448         memset(buff, 0, bufflen);
449         memset(arr, 0, SDEBUG_MAX_INQ_ARR_SZ);
450         pq_pdt = PERIPH_DEVICE_TYPE(target);
451         arr[0] = pq_pdt;
452         if (0x2 & cmd[1]) {  /* CMDDT bit set */
453                 mk_sense_buffer(devip, ILLEGAL_REQUEST, 0x24, 0, 14);
454                 return (COMMAND_COMPLETE << 8) | (CHECK_CONDITION << 1);
455         } else if (0x1 & cmd[1]) {  /* EVPD bit set */
456                 int dev_id_num, len;
457                 char dev_id_str[6];
458                 
459                 dev_id_num = ((devip->sdp->host->host_no + 1) * 1000) + 
460                               devip->sdp->id;
461                 len = snprintf(dev_id_str, 6, "%d", dev_id_num);
462                 len = (len > 6) ? 6 : len;
463                 if (0 == cmd[2]) { /* supported vital product data pages */
464                         arr[3] = 3;
465                         arr[4] = 0x0; /* this page */
466                         arr[5] = 0x80; /* unit serial number */
467                         arr[6] = 0x83; /* device identification */
468                 } else if (0x80 == cmd[2]) { /* unit serial number */
469                         arr[1] = 0x80;
470                         arr[3] = len;
471                         memcpy(&arr[4], dev_id_str, len);
472                 } else if (0x83 == cmd[2]) { /* device identification */
473                         arr[1] = 0x83;
474                         arr[3] = inquiry_evpd_83(&arr[4], dev_id_num,
475                                                  dev_id_str, len);
476                 } else {
477                         /* Illegal request, invalid field in cdb */
478                         mk_sense_buffer(devip, ILLEGAL_REQUEST, 0x24, 0, 14);
479                         return (COMMAND_COMPLETE << 8) | (CHECK_CONDITION << 1);
480                 }
481                 memcpy(buff, arr, min_len); 
482                 return 0;
483         }
484         /* drops through here for a standard inquiry */
485         arr[1] = DEV_REMOVEABLE(target) ? 0x80 : 0;     /* Removable disk */
486         arr[2] = 3;     /* claim SCSI 3 */
487         arr[4] = SDEBUG_LONG_INQ_SZ - 5;
488         arr[7] = 0x3a; /* claim: WBUS16, SYNC, LINKED + CMDQUE */
489         memcpy(&arr[8], vendor_id, 8);
490         memcpy(&arr[16], product_id, 16);
491         memcpy(&arr[32], product_rev, 4);
492         memcpy(buff, arr, min_len);
493         return 0;
494 }
495
496 /* <<Following mode page info copied from ST318451LW>> */ 
497
498 static int resp_err_recov_pg(unsigned char * p, int pcontrol, int target)
499 {       /* Read-Write Error Recovery page for mode_sense */
500         unsigned char err_recov_pg[] = {0x1, 0xa, 0xc0, 11, 240, 0, 0, 0, 
501                                         5, 0, 0xff, 0xff};
502
503         memcpy(p, err_recov_pg, sizeof(err_recov_pg));
504         if (1 == pcontrol)
505                 memset(p + 2, 0, sizeof(err_recov_pg) - 2);
506         return sizeof(err_recov_pg);
507 }
508
509 static int resp_disconnect_pg(unsigned char * p, int pcontrol, int target)
510 {       /* Disconnect-Reconnect page for mode_sense */
511         unsigned char disconnect_pg[] = {0x2, 0xe, 128, 128, 0, 10, 0, 0, 
512                                          0, 0, 0, 0, 0, 0, 0, 0};
513
514         memcpy(p, disconnect_pg, sizeof(disconnect_pg));
515         if (1 == pcontrol)
516                 memset(p + 2, 0, sizeof(disconnect_pg) - 2);
517         return sizeof(disconnect_pg);
518 }
519
520 static int resp_format_pg(unsigned char * p, int pcontrol, int target)
521 {       /* Format device page for mode_sense */
522         unsigned char format_pg[] = {0x3, 0x16, 0, 0, 0, 0, 0, 0,
523                                      0, 0, 0, 0, 0, 0, 0, 0,
524                                      0, 0, 0, 0, 0x40, 0, 0, 0};
525
526         memcpy(p, format_pg, sizeof(format_pg));
527         p[10] = (N_SECTOR >> 8) & 0xff;
528         p[11] = N_SECTOR & 0xff;
529         p[12] = (SECT_SIZE >> 8) & 0xff;
530         p[13] = SECT_SIZE & 0xff;
531         if (DEV_REMOVEABLE(target))
532                 p[20] |= 0x20; /* should agree with INQUIRY */
533         if (1 == pcontrol)
534                 memset(p + 2, 0, sizeof(format_pg) - 2);
535         return sizeof(format_pg);
536 }
537
538 static int resp_caching_pg(unsigned char * p, int pcontrol, int target)
539 {       /* Caching page for mode_sense */
540         unsigned char caching_pg[] = {0x8, 18, 0x14, 0, 0xff, 0xff, 0, 0, 
541                 0xff, 0xff, 0xff, 0xff, 0x80, 0x14, 0, 0,     0, 0, 0, 0};
542
543         memcpy(p, caching_pg, sizeof(caching_pg));
544         if (1 == pcontrol)
545                 memset(p + 2, 0, sizeof(caching_pg) - 2);
546         return sizeof(caching_pg);
547 }
548
549 static int resp_ctrl_m_pg(unsigned char * p, int pcontrol, int target)
550 {       /* Control mode page for mode_sense */
551         unsigned char ctrl_m_pg[] = {0xa, 10, 2, 0, 0, 0, 0, 0,
552                                      0, 0, 0x2, 0x4b};
553
554         memcpy(p, ctrl_m_pg, sizeof(ctrl_m_pg));
555         if (1 == pcontrol)
556                 memset(p + 2, 0, sizeof(ctrl_m_pg) - 2);
557         return sizeof(ctrl_m_pg);
558 }
559
560
561 #define SDEBUG_MAX_MSENSE_SZ 256
562
563 static int resp_mode_sense(unsigned char * cmd, int target,
564                            unsigned char * buff, int bufflen,
565                            struct sdebug_dev_info * devip)
566 {
567         unsigned char dbd;
568         int pcontrol, pcode;
569         unsigned char dev_spec;
570         int alloc_len, msense_6, offset, len;
571         unsigned char * ap;
572         unsigned char arr[SDEBUG_MAX_MSENSE_SZ];
573         int min_len = bufflen > SDEBUG_MAX_MSENSE_SZ ? 
574                         SDEBUG_MAX_MSENSE_SZ : bufflen;
575
576         SCSI_LOG_LLQUEUE(3, printk("Mode sense ...(%p %d)\n", buff, bufflen));
577         dbd = cmd[1] & 0x8;
578         pcontrol = (cmd[2] & 0xc0) >> 6;
579         pcode = cmd[2] & 0x3f;
580         msense_6 = (MODE_SENSE == cmd[0]);
581         alloc_len = msense_6 ? cmd[4] : ((cmd[7] << 8) | cmd[6]);
582         /* printk(KERN_INFO "msense: dbd=%d pcontrol=%d pcode=%d "
583                 "msense_6=%d alloc_len=%d\n", dbd, pcontrol, pcode, "
584                 "msense_6, alloc_len); */
585         if (bufflen < alloc_len)
586                 printk(KERN_INFO "scsi_debug: mode_sense: bufflen=%d "
587                        "< alloc_length=%d\n", bufflen, alloc_len);
588         memset(buff, 0, bufflen);
589         memset(arr, 0, SDEBUG_MAX_MSENSE_SZ);
590         if (0x3 == pcontrol) {  /* Saving values not supported */
591                 mk_sense_buffer(devip, ILLEGAL_REQUEST, 0x39, 0, 14);
592                 return (COMMAND_COMPLETE << 8) | (CHECK_CONDITION << 1);
593         }
594         dev_spec = DEV_READONLY(target) ? 0x80 : 0x0;
595         if (msense_6) {
596                 arr[2] = dev_spec;
597                 offset = 4;
598         } else {
599                 arr[3] = dev_spec;
600                 offset = 8;
601         }
602         ap = arr + offset;
603
604         switch (pcode) {
605         case 0x1:       /* Read-Write error recovery page, direct access */
606                 len = resp_err_recov_pg(ap, pcontrol, target);
607                 offset += len;
608                 break;
609         case 0x2:       /* Disconnect-Reconnect page, all devices */
610                 len = resp_disconnect_pg(ap, pcontrol, target);
611                 offset += len;
612                 break;
613         case 0x3:       /* Format device page, direct access */
614                 len = resp_format_pg(ap, pcontrol, target);
615                 offset += len;
616                 break;
617         case 0x8:       /* Caching page, direct access */
618                 len = resp_caching_pg(ap, pcontrol, target);
619                 offset += len;
620                 break;
621         case 0xa:       /* Control Mode page, all devices */
622                 len = resp_ctrl_m_pg(ap, pcontrol, target);
623                 offset += len;
624                 break;
625         case 0x3f:      /* Read all Mode pages */
626                 len = resp_err_recov_pg(ap, pcontrol, target);
627                 len += resp_disconnect_pg(ap + len, pcontrol, target);
628                 len += resp_caching_pg(ap + len, pcontrol, target);
629                 len += resp_ctrl_m_pg(ap + len, pcontrol, target);
630                 offset += len;
631                 break;
632         default:
633                 mk_sense_buffer(devip, ILLEGAL_REQUEST, 0x24, 0, 14);
634                 return (COMMAND_COMPLETE << 8) | (CHECK_CONDITION << 1);
635         }
636         if (msense_6)
637                 arr[0] = offset - 1;
638         else {
639                 offset -= 2;
640                 arr[0] = (offset >> 8) & 0xff; 
641                 arr[1] = offset & 0xff; 
642         }
643         memcpy(buff, arr, min_len);
644         return 0;
645 }
646
647 static int resp_read(Scsi_Cmnd * SCpnt, int upper_blk, int block, int num, 
648                      struct sdebug_dev_info * devip)
649 {
650         unsigned char *buff = (unsigned char *) SCpnt->request_buffer;
651         int nbytes, sgcount;
652         struct scatterlist *sgpnt = NULL;
653         int bufflen = SCpnt->request_bufflen;
654         unsigned long iflags;
655
656         if (upper_blk || (block + num > CAPACITY)) {
657                 mk_sense_buffer(devip, ILLEGAL_REQUEST, 0x21, 0, 14);
658                 return (COMMAND_COMPLETE << 8) | (CHECK_CONDITION << 1);
659         }
660         if ((SCSI_DEBUG_OPT_MEDIUM_ERR & scsi_debug_opts) &&
661             (block >= OPT_MEDIUM_ERR_ADDR) && 
662             (block < (OPT_MEDIUM_ERR_ADDR + num))) {
663                 mk_sense_buffer(devip, MEDIUM_ERROR, 0x11, 0, 14);
664                 /* claim unrecoverable read error */
665                 return (COMMAND_COMPLETE << 8) | (CHECK_CONDITION << 1);
666         }
667         read_lock_irqsave(&atomic_rw, iflags);
668         sgcount = 0;
669         nbytes = bufflen;
670         /* printk(KERN_INFO "scsi_debug_read: block=%d, tot_bufflen=%d\n", 
671                block, bufflen); */
672         if (SCpnt->use_sg) {
673                 sgcount = 0;
674                 sgpnt = (struct scatterlist *) buff;
675                 buff = sgpnt[sgcount].address;
676                 bufflen = sgpnt[sgcount].length;
677         }
678         do {
679                 memcpy(buff, fake_storep + (block * SECT_SIZE), bufflen);
680                 nbytes -= bufflen;
681                 if (SCpnt->use_sg) {
682                         block += bufflen >> POW2_SECT_SIZE;
683                         sgcount++;
684                         if (nbytes) {
685                                 buff = sgpnt[sgcount].address;
686                                 bufflen = sgpnt[sgcount].length;
687                         }
688                 } else if (nbytes > 0)
689                         printk(KERN_WARNING "scsi_debug:resp_read: unexpected "
690                                "nbytes=%d\n", nbytes);
691         } while (nbytes);
692         read_unlock_irqrestore(&atomic_rw, iflags);
693         return 0;
694 }
695
696 static int resp_write(Scsi_Cmnd * SCpnt, int upper_blk, int block, int num, 
697                       struct sdebug_dev_info * devip)
698 {
699         unsigned char *buff = (unsigned char *) SCpnt->request_buffer;
700         int nbytes, sgcount;
701         struct scatterlist *sgpnt = NULL;
702         int bufflen = SCpnt->request_bufflen;
703         unsigned long iflags;
704
705         if (upper_blk || (block + num > CAPACITY)) {
706                 mk_sense_buffer(devip, ILLEGAL_REQUEST, 0x21, 0, 14);
707                 return (COMMAND_COMPLETE << 8) | (CHECK_CONDITION << 1);
708         }
709
710         write_lock_irqsave(&atomic_rw, iflags);
711         sgcount = 0;
712         nbytes = bufflen;
713         if (SCpnt->use_sg) {
714                 sgcount = 0;
715                 sgpnt = (struct scatterlist *) buff;
716                 buff = sgpnt[sgcount].address;
717                 bufflen = sgpnt[sgcount].length;
718         }
719         do {
720                 memcpy(fake_storep + (block * SECT_SIZE), buff, bufflen);
721
722                 nbytes -= bufflen;
723                 if (SCpnt->use_sg) {
724                         block += bufflen >> POW2_SECT_SIZE;
725                         sgcount++;
726                         if (nbytes) {
727                                 buff = sgpnt[sgcount].address;
728                                 bufflen = sgpnt[sgcount].length;
729                         }
730                 } else if (nbytes > 0)
731                         printk(KERN_WARNING "scsi_debug:resp_write: "
732                                "unexpected nbytes=%d\n", nbytes);
733         } while (nbytes);
734         write_unlock_irqrestore(&atomic_rw, iflags);
735         return 0;
736 }
737
738 static int resp_report_luns(unsigned char * cmd, unsigned char * buff,
739                             int bufflen, struct sdebug_dev_info * devip)
740 {
741         unsigned int alloc_len;
742         int select_report = (int)cmd[2];
743
744         alloc_len = cmd[9] + (cmd[8] << 8) + (cmd[7] << 16) + (cmd[6] << 24);
745         if ((alloc_len < 16) || (select_report > 2)) {
746                 mk_sense_buffer(devip, ILLEGAL_REQUEST, 0x24, 0, 14);
747                 return (COMMAND_COMPLETE << 8) | (CHECK_CONDITION << 1);
748         }
749         if (bufflen > 3) {
750                 memset(buff, 0, bufflen);
751                 buff[3] = 8;
752         }
753         return 0;
754 }
755
756 /* When timer goes off this function is called. */
757 static void timer_intr_handler(unsigned long indx)
758 {
759         struct sdebug_queued_cmd * sqcp;
760         unsigned int iflags;
761
762         if (indx >= SCSI_DEBUG_CANQUEUE) {
763                 printk(KERN_ERR "scsi_debug:timer_intr_handler: indx too "
764                        "large\n");
765                 return;
766         }
767         spin_lock_irqsave(&queued_arr_lock, iflags);
768         sqcp = &queued_arr[(int)indx];
769         if (! sqcp->in_use) {
770                 printk(KERN_ERR "scsi_debug:timer_intr_handler: Unexpected "
771                        "interrupt\n");
772                 spin_unlock_irqrestore(&queued_arr_lock, iflags);
773                 return;
774         }
775         sqcp->in_use = 0;
776         if (sqcp->done_funct)
777                 sqcp->done_funct(sqcp->a_cmnd); /* callback to mid level */
778         sqcp->done_funct = NULL;
779         spin_unlock_irqrestore(&queued_arr_lock, iflags);
780 }
781
782 static int initialized = 0;
783 static int num_present = 0;
784 static const char * sdebug_proc_name = "scsi_debug";
785
786 static int scsi_debug_detect(Scsi_Host_Template * tpnt)
787 {
788         int k, sz;
789
790         if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
791                 printk(KERN_INFO "scsi_debug: detect\n");
792         if (0 == initialized) {
793                 ++initialized;
794                 sz = sizeof(struct sdebug_dev_info) * scsi_debug_num_devs;
795                 devInfop = vmalloc(sz);
796                 if (NULL == devInfop) {
797                         printk(KERN_ERR "scsi_debug_detect: out of "
798                                "memory, 0.5\n");
799                         return 0;
800                 }
801                 memset(devInfop, 0, sz);
802                 sz = STORE_SIZE;
803                 fake_storep = vmalloc(sz);
804                 if (NULL == fake_storep) {
805                         printk(KERN_ERR "scsi_debug_detect: out of memory"
806                                ", 0\n");
807                         return 0;
808                 }
809                 memset(fake_storep, 0, sz);
810                 init_all_queued();
811                 tpnt->proc_name = (char *)sdebug_proc_name;
812                 for (num_present = 0, k = 0; k < NR_HOSTS_PRESENT; k++) {
813                         if (NULL == scsi_register(tpnt, 0))
814                                 printk(KERN_ERR "scsi_debug_detect: "
815                                         "scsi_register failed k=%d\n", k);
816                         else
817                                 ++num_present;
818                 }
819                 return num_present;
820         } else {
821                 printk(KERN_WARNING "scsi_debug_detect: called again\n");
822                 return 0;
823         }
824 }
825
826
827 static int num_releases = 0;
828
829 static int scsi_debug_release(struct Scsi_Host * hpnt)
830 {
831         if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
832                 printk(KERN_INFO "scsi_debug: release\n");
833         stop_all_queued();
834         scsi_unregister(hpnt);
835         if (++num_releases == num_present) {
836                 vfree(fake_storep);
837                 vfree(devInfop);
838         }
839         return 0;
840 }
841
842 static struct sdebug_dev_info * devInfoReg(Scsi_Device * sdp)
843 {
844         int k;
845         struct sdebug_dev_info * devip;
846
847         for (k = 0; k < scsi_debug_num_devs; ++k) {
848                 devip = &devInfop[k];
849                 if (devip->sdp == sdp)
850                         return devip;
851         }
852         for (k = 0; k < scsi_debug_num_devs; ++k) {
853                 devip = &devInfop[k];
854                 if (NULL == devip->sdp) {
855                         devip->sdp = sdp;
856                         devip->reset = 1;
857                         memset(devip->sense_buff, 0, SDEBUG_SENSE_LEN);
858                         devip->sense_buff[0] = 0x70;
859                         return devip;
860                 }
861         }
862         return NULL;
863 }
864
865 static void mk_sense_buffer(struct sdebug_dev_info * devip, int key, 
866                             int asc, int asq, int inbandLen)
867 {
868         unsigned char * sbuff;
869
870         sbuff = devip->sense_buff;
871         memset(sbuff, 0, SDEBUG_SENSE_LEN);
872         if (inbandLen > SDEBUG_SENSE_LEN)
873                 inbandLen = SDEBUG_SENSE_LEN;
874         sbuff[0] = 0x70;
875         sbuff[2] = key;
876         sbuff[7] = (inbandLen > 7) ? (inbandLen - 8) : 0;
877         sbuff[12] = asc;
878         sbuff[13] = asq;
879 }
880
881 static int scsi_debug_abort(Scsi_Cmnd * SCpnt)
882 {
883         if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
884                 printk(KERN_INFO "scsi_debug: abort\n");
885         ++num_aborts;
886         stop_queued_cmnd(SCpnt);
887         return SUCCESS;
888 }
889
890 static int scsi_debug_biosparam(Disk * disk, kdev_t dev, int *info)
891 {
892         if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
893                 printk(KERN_INFO "scsi_debug: biosparam\n");
894         /* int size = disk->capacity; */
895         info[0] = N_HEAD;
896         info[1] = N_SECTOR;
897         info[2] = N_CYLINDER;
898         if (info[2] >= 1024)
899                 info[2] = 1024;
900         return 0;
901 }
902
903 static int scsi_debug_device_reset(Scsi_Cmnd * SCpnt)
904 {
905         Scsi_Device * sdp;
906         int k;
907
908         if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
909                 printk(KERN_INFO "scsi_debug: device_reset\n");
910         ++num_dev_resets;
911         if (SCpnt && ((sdp = SCpnt->device))) {
912                 for (k = 0; k < scsi_debug_num_devs; ++k) {
913                         if (sdp->hostdata == (devInfop + k))
914                                 break;
915                 }
916                 if (k < scsi_debug_num_devs)
917                         devInfop[k].reset = 1;
918         }
919         return SUCCESS;
920 }
921
922 static int scsi_debug_bus_reset(Scsi_Cmnd * SCpnt)
923 {
924         Scsi_Device * sdp;
925         struct Scsi_Host * hp;
926         int k;
927
928         if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
929                 printk(KERN_INFO "scsi_debug: bus_reset\n");
930         ++num_bus_resets;
931         if (SCpnt && ((sdp = SCpnt->device)) && ((hp = sdp->host))) {
932                 for (k = 0; k < scsi_debug_num_devs; ++k) {
933                         if (hp == devInfop[k].sdp->host)
934                                 devInfop[k].reset = 1;
935                 }
936         }
937         return SUCCESS;
938 }
939
940 static int scsi_debug_host_reset(Scsi_Cmnd * SCpnt)
941 {
942         int k;
943
944         if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
945                 printk(KERN_INFO "scsi_debug: host_reset\n");
946         ++num_host_resets;
947         for (k = 0; k < scsi_debug_num_devs; ++k)
948                 devInfop[k].reset = 1;
949         stop_all_queued();
950
951         return SUCCESS;
952 }
953
954 /* Returns 1 if found 'cmnd' and deleted its timer. else returns 0 */
955 static int stop_queued_cmnd(struct scsi_cmnd * cmnd)
956 {
957         unsigned long iflags;
958         int k;
959         struct sdebug_queued_cmd * sqcp;
960
961         spin_lock_irqsave(&queued_arr_lock, iflags);
962         for (k = 0; k < SCSI_DEBUG_CANQUEUE; ++k) {
963                 sqcp = &queued_arr[k];
964                 if (sqcp->in_use && (cmnd == sqcp->a_cmnd)) {
965                         del_timer_sync(&sqcp->cmnd_timer);
966                         sqcp->in_use = 0;
967                         sqcp->a_cmnd = NULL;
968                         break;
969                 }
970         }
971         spin_unlock_irqrestore(&queued_arr_lock, iflags);
972         return (k < SCSI_DEBUG_CANQUEUE) ? 1 : 0;
973 }
974
975 /* Deletes (stops) timers of all queued commands */
976 static void stop_all_queued(void)
977 {
978         unsigned long iflags;
979         int k;
980         struct sdebug_queued_cmd * sqcp;
981
982         spin_lock_irqsave(&queued_arr_lock, iflags);
983         for (k = 0; k < SCSI_DEBUG_CANQUEUE; ++k) {
984                 sqcp = &queued_arr[k];
985                 if (sqcp->in_use && sqcp->a_cmnd) {
986                         del_timer_sync(&sqcp->cmnd_timer);
987                         sqcp->in_use = 0;
988                         sqcp->a_cmnd = NULL;
989                 }
990         }
991         spin_unlock_irqrestore(&queued_arr_lock, iflags);
992 }
993
994 /* Initializes timers in queued array */
995 static void init_all_queued(void)
996 {
997         unsigned long iflags;
998         int k;
999         struct sdebug_queued_cmd * sqcp;
1000
1001         spin_lock_irqsave(&queued_arr_lock, iflags);
1002         for (k = 0; k < SCSI_DEBUG_CANQUEUE; ++k) {
1003                 sqcp = &queued_arr[k];
1004                 init_timer(&sqcp->cmnd_timer);
1005                 sqcp->in_use = 0;
1006                 sqcp->a_cmnd = NULL;
1007         }
1008         spin_unlock_irqrestore(&queued_arr_lock, iflags);
1009 }
1010
1011 static int schedule_resp(struct scsi_cmnd * cmnd, 
1012                          struct sdebug_dev_info * devip,
1013                          done_funct_t done, int scsi_result, int delta_jiff)
1014 {
1015         int k, num; 
1016
1017         if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) {
1018                 printk(KERN_INFO "scsi_debug: cmd ");
1019                 for (k = 0, num = cmnd->cmd_len; k < num; ++k)
1020                     printk("%02x ", (int)cmnd->cmnd[k]);
1021                 printk("result=0x%x\n", scsi_result);
1022         }
1023         if (cmnd && devip) {
1024                 /* simulate autosense by this driver */
1025                 if (CHECK_CONDITION == status_byte(scsi_result))
1026                         memcpy(cmnd->sense_buffer, devip->sense_buff, 
1027                                (SCSI_SENSE_BUFFERSIZE > SDEBUG_SENSE_LEN) ?
1028                                SDEBUG_SENSE_LEN : SCSI_SENSE_BUFFERSIZE);
1029         }
1030         if (delta_jiff <= 0) {
1031                 if (cmnd)
1032                         cmnd->result = scsi_result;
1033                 if (done)
1034                         done(cmnd);
1035                 return 0;
1036         } else {
1037                 unsigned long iflags;
1038                 int k;
1039                 struct sdebug_queued_cmd * sqcp = NULL;
1040
1041                 spin_lock_irqsave(&queued_arr_lock, iflags);
1042                 for (k = 0; k < SCSI_DEBUG_CANQUEUE; ++k) {
1043                         sqcp = &queued_arr[k];
1044                         if (! sqcp->in_use)
1045                                 break;
1046                 }
1047                 if (k >= SCSI_DEBUG_CANQUEUE) {
1048                         spin_unlock_irqrestore(&queued_arr_lock, iflags);
1049                         printk(KERN_WARNING "scsi_debug: can_queue exceeded\n");
1050                         return 1;       /* report busy to mid level */
1051                 }
1052                 sqcp->in_use = 1;
1053                 sqcp->a_cmnd = cmnd;
1054                 sqcp->scsi_result = scsi_result;
1055                 sqcp->done_funct = done;
1056                 sqcp->cmnd_timer.function = timer_intr_handler;
1057                 sqcp->cmnd_timer.data = k;
1058                 sqcp->cmnd_timer.expires = jiffies + delta_jiff;
1059                 add_timer(&sqcp->cmnd_timer);
1060                 spin_unlock_irqrestore(&queued_arr_lock, iflags);
1061                 return 0;
1062         }
1063 }
1064
1065 #ifndef MODULE
1066 static int __init num_devs_setup(char *str)
1067 {   
1068     int tmp; 
1069     
1070     if (get_option(&str, &tmp) == 1) {
1071         if (tmp > 0)
1072             scsi_debug_num_devs = tmp;
1073         return 1;
1074     } else {
1075         printk(KERN_INFO "scsi_debug_num_devs: usage scsi_debug_num_devs=<n> "
1076                "(<n> can be from 1 to around 2000)\n");
1077         return 0;
1078     }
1079 }
1080 __setup("scsi_debug_num_devs=", num_devs_setup);
1081
1082 static int __init dev_size_mb_setup(char *str)
1083 {   
1084     int tmp; 
1085     
1086     if (get_option(&str, &tmp) == 1) {
1087         if (tmp > 0)
1088             scsi_debug_dev_size_mb = tmp;
1089         return 1;
1090     } else {
1091         printk(KERN_INFO "scsi_debug_dev_size_mb: usage "
1092                "scsi_debug_dev_size_mb=<n>\n"
1093                "    (<n> is number of MB ram shared by all devs\n");
1094         return 0;
1095     }
1096 }
1097 __setup("scsi_debug_dev_size_mb=", dev_size_mb_setup);
1098
1099 static int __init opts_setup(char *str)
1100 {   
1101     int tmp; 
1102     
1103     if (get_option(&str, &tmp) == 1) {
1104         if (tmp > 0)
1105             scsi_debug_opts = tmp;
1106         return 1;
1107     } else {
1108         printk(KERN_INFO "scsi_debug_opts: usage "
1109                "scsi_debug_opts=<n>\n"
1110                "    (1->noise, 2->medium_error, 4->... (can be or-ed)\n");
1111         return 0;
1112     }
1113 }
1114 __setup("scsi_debug_opts=", opts_setup);
1115
1116 static int __init every_nth_setup(char *str)
1117 {
1118     int tmp;
1119
1120     if (get_option(&str, &tmp) == 1) {
1121         if (tmp > 0)
1122             scsi_debug_every_nth = tmp;
1123         return 1;
1124     } else {
1125         printk(KERN_INFO "scsi_debug_every_nth: usage "
1126                "scsi_debug_every_nth=<n>\n"
1127                "    timeout every nth command (when ...)\n");
1128         return 0;
1129     }
1130 }
1131 __setup("scsi_debug_every_nth=", every_nth_setup);
1132
1133 static int __init delay_setup(char *str)
1134 {
1135     int tmp;
1136
1137     if (get_option(&str, &tmp) == 1) {
1138         scsi_debug_delay = tmp;
1139         return 1;
1140     } else {
1141         printk(KERN_INFO "scsi_debug_delay: usage "
1142                "scsi_debug_delay=<n>\n"
1143                "    delay response <n> jiffies\n");
1144         return 0;
1145     }
1146 }
1147 __setup("scsi_debug_delay=", delay_setup);
1148
1149 #endif
1150
1151 MODULE_AUTHOR("Eric Youngdale + Douglas Gilbert");
1152 MODULE_DESCRIPTION("SCSI debug adapter driver");
1153 MODULE_PARM(scsi_debug_num_devs, "i");
1154 MODULE_PARM_DESC(scsi_debug_num_devs, "number of SCSI devices to simulate");
1155 MODULE_PARM(scsi_debug_dev_size_mb, "i");
1156 MODULE_PARM_DESC(scsi_debug_dev_size_mb, "size in MB of ram shared by devs");
1157 MODULE_PARM(scsi_debug_opts, "i");
1158 MODULE_PARM_DESC(scsi_debug_opts, "1->noise, 2->medium_error, 4->...");
1159 MODULE_PARM(scsi_debug_every_nth, "i");
1160 MODULE_PARM_DESC(scsi_debug_every_nth, "timeout every nth command(def=100)");
1161 MODULE_PARM(scsi_debug_delay, "i");
1162 MODULE_PARM_DESC(scsi_debug_delay, "# of jiffies to delay response(def=1)");
1163 #ifdef MODULE_LICENSE
1164 MODULE_LICENSE("GPL");
1165 #endif
1166
1167 static char sdebug_info[256];
1168
1169 static const char * scsi_debug_info(struct Scsi_Host * shp)
1170 {
1171         sprintf(sdebug_info, "scsi_debug, %s, num_devs=%d, "
1172                 "dev_size_mb=%d, opts=0x%x", scsi_debug_version_str,
1173                 scsi_debug_num_devs, scsi_debug_dev_size_mb,
1174                 scsi_debug_opts);
1175         return sdebug_info;
1176 }
1177
1178 /* scsi_debug_proc_info
1179  * Used if the driver currently has no own support for /proc/scsi
1180  */
1181 static int scsi_debug_proc_info(char *buffer, char **start, off_t offset,
1182                                 int length, int inode, int inout)
1183 {
1184         int len, pos, begin;
1185         int orig_length;
1186
1187         orig_length = length;
1188
1189         if (inout == 1) {
1190                 char arr[16];
1191                 int minLen = length > 15 ? 15 : length;
1192
1193                 if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
1194                         return -EACCES;
1195                 memcpy(arr, buffer, minLen);
1196                 arr[minLen] = '\0';
1197                 if (1 != sscanf(arr, "%d", &pos))
1198                         return -EINVAL;
1199                 scsi_debug_opts = pos;
1200                 if (SCSI_DEBUG_OPT_EVERY_NTH & scsi_debug_opts)
1201                         scsi_debug_cmnd_count = 0;
1202                 return length;
1203         }
1204         begin = 0;
1205         pos = len = sprintf(buffer, "scsi_debug adapter driver, %s\n"
1206             "num_devs=%d, shared (ram) size=%d MB, opts=0x%x, "
1207             "every_nth=%d(curr:%d)\n"
1208             "sector_size=%d bytes, cylinders=%d, heads=%d, sectors=%d, "
1209             "delay=%d\nnumber of aborts=%d, device_reset=%d, bus_resets=%d, " 
1210             "host_resets=%d\n",
1211             scsi_debug_version_str, scsi_debug_num_devs, 
1212             scsi_debug_dev_size_mb, scsi_debug_opts, scsi_debug_every_nth,
1213             scsi_debug_cmnd_count,
1214             SECT_SIZE, N_CYLINDER, N_HEAD, N_SECTOR, scsi_debug_delay,
1215             num_aborts, num_dev_resets, num_bus_resets, num_host_resets);
1216         if (pos < offset) {
1217                 len = 0;
1218                 begin = pos;
1219         }
1220         *start = buffer + (offset - begin);     /* Start of wanted data */
1221         len -= (offset - begin);
1222         if (len > length)
1223                 len = length;
1224
1225         return (len);
1226 }
1227
1228 #include "scsi_module.c"