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