OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [scsi/] [scsi_debug.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
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"

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.