Annotation of Gnu-Mach/i386/i386at/gpl/linux/scsi/scsi_debug.c, revision 1.1.1.1

1.1       root        1: /* $Id: scsi_debug.c,v 1.1.1.1 1997/02/25 21:27:51 thomas Exp $
                      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: 
                     10: #include <linux/module.h>
                     11: 
                     12: #include <linux/kernel.h>
                     13: #include <linux/sched.h>
                     14: #include <linux/errno.h>
                     15: #include <linux/timer.h>
                     16: #include <linux/head.h>
                     17: #include <linux/types.h>
                     18: #include <linux/string.h>
                     19: #include <linux/genhd.h>
                     20: #include <linux/fs.h>
                     21: #include <linux/proc_fs.h>
                     22: 
                     23: #include <asm/system.h>
                     24: #include <asm/io.h>
                     25: 
                     26: #ifdef MODULE
                     27: #include <linux/module.h>
                     28: #endif
                     29: 
                     30: #include <linux/blk.h>
                     31: #include "scsi.h"
                     32: #include "hosts.h"
                     33: 
                     34: #include "sd.h"
                     35: 
                     36: #include<linux/stat.h>
                     37: 
                     38: struct proc_dir_entry proc_scsi_scsi_debug = {
                     39:     PROC_SCSI_SCSI_DEBUG, 10, "scsi_debug",
                     40:     S_IFDIR | S_IRUGO | S_IXUGO, 2
                     41: };
                     42: 
                     43: 
                     44: /* A few options that we want selected */
                     45: 
                     46: /* Do not attempt to use a timer to simulate a real disk with latency */
                     47: /* Only use this in the actual kernel, not in the simulator. */
                     48: #define IMMEDIATE
                     49: 
                     50: /* Skip some consistency checking.  Good for benchmarking */
                     51: #define SPEEDY
                     52: 
                     53: /* Number of real scsi disks that will be detected ahead of time */
                     54: static int NR_REAL=-1;
                     55: 
                     56: #define NR_BLK_DEV  12
                     57: #ifndef MAJOR_NR
                     58: #define MAJOR_NR 8
                     59: #endif
                     60: #define START_PARTITION 4
                     61: #define SCSI_DEBUG_TIMER 20
                     62: /* Number of jiffies to wait before completing a command */
                     63: #define DISK_SPEED     10
                     64: #define CAPACITY (0x80000)
                     65: 
                     66: static int starts[] = {4, 1000, 50000, CAPACITY, 0};
                     67: static int npart = 0;
                     68: 
                     69: #include "scsi_debug.h"
                     70: #ifdef DEBUG
                     71: #define DEB(x) x
                     72: #else
                     73: #define DEB(x)
                     74: #endif
                     75: 
                     76: #ifdef SPEEDY
                     77: #define VERIFY1_DEBUG(RW) 1
                     78: #define VERIFY_DEBUG(RW) 1
                     79: #else
                     80: 
                     81: #define VERIFY1_DEBUG(RW)                           \
                     82:     if (bufflen != 1024) {printk("%d", bufflen); panic("(1)Bad bufflen");};         \
                     83:     start = 0;                          \
                     84:     if ((MINOR(SCpnt->request.rq_dev) & 0xf) != 0) start = starts[(MINOR(SCpnt->request.rq_dev) & 0xf) - 1];        \
                     85:     if (bh){                            \
                     86:        if (bh->b_size != 1024) panic ("Wrong bh size");    \
                     87:        if ((bh->b_blocknr << 1) + start != block)          \
                     88:        {   printk("Wrong bh block# %d %d ",bh->b_blocknr, block);  \
                     89:            panic ("Wrong bh block#"); \
                     90:        };  \
                     91:        if (bh->b_dev != SCpnt->request.rq_dev)  \
                     92:            panic ("Bad bh target"); \
                     93:     };
                     94: 
                     95: #define VERIFY_DEBUG(RW)                            \
                     96:     if (bufflen != 1024 && (!SCpnt->use_sg)) {printk("%x %d\n ",bufflen, SCpnt->use_sg); panic("Bad bufflen");};    \
                     97:     start = 0;                          \
                     98:     if ((MINOR(SCpnt->request.rq_dev) & 0xf) > npart) panic ("Bad partition");    \
                     99:     if ((MINOR(SCpnt->request.rq_dev) & 0xf) != 0) start = starts[(MINOR(SCpnt->request.rq_dev) & 0xf) - 1];        \
                    100:     if (SCpnt->request.cmd != RW) panic ("Wrong  operation");       \
                    101:     if (SCpnt->request.sector + start != block) panic("Wrong block.");  \
                    102:     if (SCpnt->request.current_nr_sectors != 2 && (!SCpnt->use_sg)) panic ("Wrong # blocks");   \
                    103:     if (SCpnt->request.bh){                         \
                    104:        if (SCpnt->request.bh->b_size != 1024) panic ("Wrong bh size"); \
                    105:        if ((SCpnt->request.bh->b_blocknr << 1) + start != block)           \
                    106:        {   printk("Wrong bh block# %d %d ",SCpnt->request.bh->b_blocknr, block);  \
                    107:            panic ("Wrong bh block#"); \
                    108:        };  \
                    109:        if (SCpnt->request.bh->b_dev != SCpnt->request.rq_dev) \
                    110:            panic ("Bad bh target");\
                    111:     };
                    112: #endif
                    113: 
                    114: static volatile void (*do_done[SCSI_DEBUG_MAILBOXES])(Scsi_Cmnd *) = {NULL, };
                    115: extern void scsi_debug_interrupt();
                    116: 
                    117: volatile Scsi_Cmnd * SCint[SCSI_DEBUG_MAILBOXES] = {NULL,};
                    118: static char SCrst[SCSI_DEBUG_MAILBOXES] = {0,};
                    119: static volatile unsigned int timeout[8] ={0,};
                    120: 
                    121: /*
                    122:  * Semaphore used to simulate bus lockups.
                    123:  */
                    124: static int scsi_debug_lockup = 0;
                    125: 
                    126: static char sense_buffer[128] = {0,};
                    127: 
                    128: static void scsi_dump(Scsi_Cmnd * SCpnt, int flag){
                    129:     int i;
                    130: #if 0
                    131:     unsigned char * pnt;
                    132: #endif
                    133:     unsigned int * lpnt;
                    134:     struct scatterlist * sgpnt = NULL;
                    135:     printk("use_sg: %d",SCpnt->use_sg);
                    136:     if (SCpnt->use_sg){
                    137:        sgpnt = (struct scatterlist *) SCpnt->buffer;
                    138:        for(i=0; i<SCpnt->use_sg; i++) {
                    139:            lpnt = (int *) sgpnt[i].alt_address;
                    140:            printk(":%x %x %d\n",sgpnt[i].alt_address, sgpnt[i].address, sgpnt[i].length);
                    141:            if (lpnt) printk(" (Alt %x) ",lpnt[15]);
                    142:        };
                    143:     } else {
                    144:        printk("nosg: %x %x %d\n",SCpnt->request.buffer, SCpnt->buffer,
                    145:               SCpnt->bufflen);
                    146:        lpnt = (int *) SCpnt->request.buffer;
                    147:        if (lpnt) printk(" (Alt %x) ",lpnt[15]);
                    148:     };
                    149:     lpnt = (unsigned int *) SCpnt;
                    150:     for (i=0;i<sizeof(Scsi_Cmnd)/4+1; i++) {
                    151:        if ((i & 7) == 0) printk("\n");
                    152:        printk("%x ",*lpnt++);
                    153:     };
                    154:     printk("\n");
                    155:     if (flag == 0) return;
                    156:     lpnt = (unsigned int *) sgpnt[0].alt_address;
                    157:     for (i=0;i<sizeof(Scsi_Cmnd)/4+1; i++) {
                    158:        if ((i & 7) == 0) printk("\n");
                    159:        printk("%x ",*lpnt++);
                    160:     };
                    161: #if 0
                    162:     printk("\n");
                    163:     lpnt = (unsigned int *) sgpnt[0].address;
                    164:     for (i=0;i<sizeof(Scsi_Cmnd)/4+1; i++) {
                    165:        if ((i & 7) == 0) printk("\n");
                    166:        printk("%x ",*lpnt++);
                    167:     };
                    168:     printk("\n");
                    169: #endif
                    170:     printk("DMA free %d sectors.\n", dma_free_sectors);
                    171: }
                    172: 
                    173: int scsi_debug_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
                    174: {
                    175:     unchar *cmd = (unchar *) SCpnt->cmnd;
                    176:     struct partition * p;
                    177:     int block, start;
                    178:     struct buffer_head * bh = NULL;
                    179:     unsigned char * buff;
                    180:     int nbytes, sgcount;
                    181:     int scsi_debug_errsts;
                    182:     struct scatterlist * sgpnt;
                    183:     int target = SCpnt->target;
                    184:     int bufflen = SCpnt->request_bufflen;
                    185:     unsigned long flags;
                    186:     int i;
                    187:     sgcount = 0;
                    188:     sgpnt = NULL;
                    189:     
                    190:     DEB(if (target > 1) { SCpnt->result = DID_TIME_OUT << 16;done(SCpnt);return 0;});
                    191:     
                    192:     buff = (unsigned char *) SCpnt->request_buffer;
                    193:     
                    194:     if(target>=1 || SCpnt->lun != 0) {
                    195:        SCpnt->result =  DID_NO_CONNECT << 16;
                    196:        done(SCpnt);
                    197:        return 0;
                    198:     };
                    199:     
                    200:     if( SCrst[target] != 0 && !scsi_debug_lockup )
                    201:     {
                    202:         SCrst[target] = 0;
                    203:         memset(SCpnt->sense_buffer, 0, sizeof(SCpnt->sense_buffer));
                    204:         SCpnt->sense_buffer[0] = 0x70;
                    205:         SCpnt->sense_buffer[2] = UNIT_ATTENTION;
                    206:        SCpnt->result = (CHECK_CONDITION << 1);
                    207:        done(SCpnt);         
                    208:     }
                    209:     switch(*cmd){
                    210:     case REQUEST_SENSE:
                    211:        printk("Request sense...\n");
                    212: #ifndef DEBUG
                    213:        { 
                    214:            int i;
                    215:            printk("scsi_debug: Requesting sense buffer (%x %x %x %d):", SCpnt, buff, done, bufflen);
                    216:            for(i=0;i<12;i++) printk("%d ",sense_buffer[i]);
                    217:            printk("\n");
                    218:        };
                    219: #endif
                    220:        memset(buff, 0, bufflen);
                    221:        memcpy(buff, sense_buffer, bufflen);
                    222:        memset(sense_buffer, 0, sizeof(sense_buffer));
                    223:        SCpnt->result = 0;
                    224:        done(SCpnt); 
                    225:        return 0;
                    226:     case ALLOW_MEDIUM_REMOVAL:
                    227:        if(cmd[4]) printk("Medium removal inhibited...");
                    228:        else printk("Medium removal enabled...");
                    229:        scsi_debug_errsts = 0;
                    230:        break;
                    231:     case INQUIRY:
                    232:        printk("Inquiry...(%x %d)\n", buff, bufflen);
                    233:        memset(buff, 0, bufflen);
                    234:        buff[0] = TYPE_DISK;
                    235:        buff[1] = 0x80;  /* Removable disk */
                    236:        buff[2] = 1;
                    237:        buff[4] = 33 - 5;
                    238:        memcpy(&buff[8],"Foo Inc",7);
                    239:        memcpy(&buff[16],"XYZZY",5);
                    240:        memcpy(&buff[32],"1",1);
                    241:        scsi_debug_errsts = 0;
                    242:        break;
                    243:     case TEST_UNIT_READY:
                    244:        printk("Test unit ready(%x %d)\n", buff, bufflen);
                    245:        if (buff)
                    246:            memset(buff, 0, bufflen);
                    247:        scsi_debug_errsts = 0;
                    248:        break;
                    249:     case READ_CAPACITY:
                    250:        printk("Read Capacity\n");
                    251:        if(NR_REAL < 0) NR_REAL = (MINOR(SCpnt->request.rq_dev) >> 4) & 0x0f;
                    252:        memset(buff, 0, bufflen);
                    253:        buff[0] = (CAPACITY >> 24);
                    254:        buff[1] = (CAPACITY >> 16) & 0xff;
                    255:        buff[2] = (CAPACITY >> 8) & 0xff;
                    256:        buff[3] = CAPACITY & 0xff;
                    257:        buff[6] = 2; /* 512 byte sectors */
                    258:        scsi_debug_errsts = 0;
                    259:        break;
                    260:     case READ_10:
                    261:     case READ_6:
                    262: #ifdef DEBUG
                    263:        printk("Read...");
                    264: #endif
                    265:        if ((*cmd) == READ_10)
                    266:            block = cmd[5] + (cmd[4] << 8) + (cmd[3] << 16) + (cmd[2] << 24); 
                    267:        else 
                    268:            block = cmd[3] + (cmd[2] << 8) + ((cmd[1] & 0x1f) << 16);
                    269:        VERIFY_DEBUG(READ);
                    270: #if defined(SCSI_SETUP_LATENCY) || defined(SCSI_DATARATE)
                    271:     {
                    272:        int delay = SCSI_SETUP_LATENCY;
                    273:        double usec;
                    274:        
                    275:        usec = 0.0;
                    276:        usec = (SCpnt->request.nr_sectors << 9) * 1.0e6 / SCSI_DATARATE;
                    277:        delay += usec;
                    278:        if(delay) usleep(delay);
                    279:     };
                    280: #endif
                    281:        
                    282: #ifdef DEBUG
                    283:        printk("(r%d)",SCpnt->request.nr_sectors);
                    284: #endif
                    285:        nbytes = bufflen;
                    286:        if(SCpnt->use_sg){
                    287:            sgcount = 0;
                    288:            sgpnt = (struct scatterlist *) buff;
                    289:            buff = sgpnt[sgcount].address;
                    290:            bufflen = sgpnt[sgcount].length;
                    291:            bh = SCpnt->request.bh;
                    292:        };
                    293:        scsi_debug_errsts = 0;
                    294:        do{
                    295:            VERIFY1_DEBUG(READ);
                    296:            /* For the speedy test, we do not even want to fill the buffer with anything */
                    297: #ifndef SPEEDY
                    298:            memset(buff, 0, bufflen);
                    299: #endif
                    300:            /* If this is block 0, then we want to read the partition table for this
                    301:             * device.  Let's make one up */
                    302:            if(block == 0 && target == 0) {
                    303:                 memset(buff, 0, bufflen);
                    304:                *((unsigned short *) (buff+510)) = 0xAA55;
                    305:                p = (struct partition* ) (buff + 0x1be);
                    306:                npart = 0;
                    307:                while(starts[npart+1]){
                    308:                    p->start_sect = starts[npart];
                    309:                    p->nr_sects = starts[npart+1] - starts [npart];
                    310:                    p->sys_ind = 0x81;  /* Linux partition */
                    311:                    p++;
                    312:                    npart++;
                    313:                };
                    314:                scsi_debug_errsts = 0;
                    315:                break;
                    316:            };
                    317: #ifdef DEBUG
                    318:            if (SCpnt->use_sg) printk("Block %x (%d %d)\n",block, SCpnt->request.nr_sectors,
                    319:                                      SCpnt->request.current_nr_sectors);
                    320: #endif
                    321:            
                    322: #if 0
                    323:            /* Simulate a disk change */
                    324:            if(block == 0xfff0) {
                    325:                sense_buffer[0] = 0x70;
                    326:                sense_buffer[2] = UNIT_ATTENTION;
                    327:                starts[0] += 10;
                    328:                starts[1] += 10;
                    329:                starts[2] += 10;
                    330:                
                    331: #ifdef DEBUG
                    332:                { 
                    333:                    int i;
                    334:                    printk("scsi_debug: Filling sense buffer:");
                    335:                    for(i=0;i<12;i++) printk("%d ",sense_buffer[i]);
                    336:                    printk("\n");
                    337:                };
                    338: #endif
                    339:                scsi_debug_errsts = (COMMAND_COMPLETE << 8) | (CHECK_CONDITION << 1);
                    340:                break;
                    341:            } /* End phony disk change code */
                    342: #endif
                    343:            
                    344: #ifndef SPEEDY
                    345:            memcpy(buff, &target, sizeof(target));
                    346:            memcpy(buff+sizeof(target), cmd, 24);
                    347:            memcpy(buff+60, &block, sizeof(block));
                    348:            memcpy(buff+64, SCpnt, sizeof(Scsi_Cmnd));
                    349: #endif
                    350:            nbytes -= bufflen;
                    351:            if(SCpnt->use_sg){
                    352: #ifndef SPEEDY
                    353:                memcpy(buff+128, bh, sizeof(struct buffer_head));
                    354: #endif
                    355:                block += bufflen >> 9;
                    356:                bh = bh->b_reqnext;
                    357:                sgcount++;
                    358:                if (nbytes) {
                    359:                    if(!bh) panic("Too few blocks for linked request.");
                    360:                    buff = sgpnt[sgcount].address;
                    361:                    bufflen = sgpnt[sgcount].length;
                    362:                };
                    363:            }
                    364:        } while(nbytes);
                    365:        
                    366:        SCpnt->result = 0;
                    367:        (done)(SCpnt);
                    368:        return;
                    369:        
                    370:        if (SCpnt->use_sg && !scsi_debug_errsts)
                    371:            if(bh) scsi_dump(SCpnt, 0);
                    372:        break;
                    373:     case WRITE_10:
                    374:     case WRITE_6:
                    375: #ifdef DEBUG
                    376:        printk("Write\n");
                    377: #endif
                    378:        if ((*cmd) == WRITE_10)
                    379:            block = cmd[5] + (cmd[4] << 8) + (cmd[3] << 16) + (cmd[2] << 24); 
                    380:        else 
                    381:            block = cmd[3] + (cmd[2] << 8) + ((cmd[1] & 0x1f) << 16);
                    382:        VERIFY_DEBUG(WRITE);
                    383:        /*      printk("(w%d)",SCpnt->request.nr_sectors); */
                    384:        if (SCpnt->use_sg){
                    385:            if ((bufflen >> 9) != SCpnt->request.nr_sectors)
                    386:                panic ("Trying to write wrong number of blocks\n");
                    387:            sgpnt = (struct scatterlist *) buff;
                    388:            buff = sgpnt[sgcount].address;
                    389:        };
                    390: #if 0
                    391:        if (block != *((unsigned long *) (buff+60))) {
                    392:            printk("%x %x :",block,  *((unsigned long *) (buff+60)));
                    393:            scsi_dump(SCpnt,1);
                    394:            panic("Bad block written.\n");
                    395:        };
                    396: #endif
                    397:        scsi_debug_errsts = 0;
                    398:        break;
                    399:     default:
                    400:        printk("Unknown command %d\n",*cmd);
                    401:        SCpnt->result =  DID_NO_CONNECT << 16;
                    402:        done(SCpnt);
                    403:        return 0;
                    404:     };
                    405:     
                    406:     save_flags(flags); 
                    407:     cli();
                    408:     for(i=0;i<SCSI_DEBUG_MAILBOXES; i++){
                    409:        if (SCint[i] == 0) break;
                    410:     };
                    411:     
                    412:     if (i >= SCSI_DEBUG_MAILBOXES || SCint[i] != 0) 
                    413:        panic("Unable to find empty SCSI_DEBUG command slot.\n");
                    414:     
                    415:     SCint[i] = SCpnt;
                    416:     
                    417:     if (done) {
                    418:        DEB(printk("scsi_debug_queuecommand: now waiting for interrupt "););
                    419:        if (do_done[i])
                    420:            printk("scsi_debug_queuecommand: Two concurrent queuecommand?\n");
                    421:        else
                    422:            do_done[i] = done;
                    423:     }
                    424:     else
                    425:        printk("scsi_debug_queuecommand: done cant be NULL\n");
                    426:     
                    427: #ifdef IMMEDIATE
                    428:     if( !scsi_debug_lockup )
                    429:     {
                    430:         SCpnt->result = scsi_debug_errsts;
                    431:         scsi_debug_intr_handle();  /* No timer - do this one right away */
                    432:     }
                    433:     restore_flags(flags);
                    434: #else
                    435:     timeout[i] = jiffies+DISK_SPEED;
                    436:     
                    437:     /* If no timers active, then set this one */
                    438:     if ((timer_active & (1 << SCSI_DEBUG_TIMER)) == 0) {
                    439:        timer_table[SCSI_DEBUG_TIMER].expires = timeout[i];
                    440:        timer_active |= 1 << SCSI_DEBUG_TIMER;
                    441:     };
                    442:     
                    443:     SCpnt->result = scsi_debug_errsts;
                    444:     restore_flags(flags);
                    445:     
                    446: #if 0
                    447:     printk("Sending command (%d %x %d %d)...", i, done, timeout[i],jiffies);
                    448: #endif
                    449: #endif
                    450:     
                    451:     return 0;
                    452: }
                    453: 
                    454: volatile static int internal_done_flag = 0;
                    455: volatile static int internal_done_errcode = 0;
                    456: static void internal_done(Scsi_Cmnd * SCpnt)
                    457: {
                    458:     internal_done_errcode = SCpnt->result;
                    459:     ++internal_done_flag;
                    460: }
                    461: 
                    462: int scsi_debug_command(Scsi_Cmnd * SCpnt)
                    463: {
                    464:     DEB(printk("scsi_debug_command: ..calling scsi_debug_queuecommand\n"));
                    465:     scsi_debug_queuecommand(SCpnt, internal_done);
                    466:     
                    467:     while (!internal_done_flag);
                    468:     internal_done_flag = 0;
                    469:     return internal_done_errcode;
                    470: }
                    471: 
                    472: /* A "high" level interrupt handler.  This should be called once per jiffy
                    473:  * to simulate a regular scsi disk.  We use a timer to do this. */
                    474: 
                    475: static void scsi_debug_intr_handle(void)
                    476: {
                    477:     Scsi_Cmnd * SCtmp;
                    478:     int i, pending;
                    479:     void (*my_done)(Scsi_Cmnd *); 
                    480:     unsigned long flags;
                    481:     int to;
                    482:     
                    483: #ifndef IMMEDIATE
                    484:     timer_table[SCSI_DEBUG_TIMER].expires = 0;
                    485:     timer_active &= ~(1 << SCSI_DEBUG_TIMER);
                    486: #endif
                    487:     
                    488:  repeat:
                    489:     save_flags(flags);
                    490:     cli();
                    491:     for(i=0;i<SCSI_DEBUG_MAILBOXES; i++) {
                    492:        if (SCint[i] == 0) continue;
                    493: #ifndef IMMEDIATE
                    494:        if (timeout[i] == 0) continue;
                    495:        if (timeout[i] <= jiffies) break;
                    496: #else
                    497:        break;
                    498: #endif
                    499:     };
                    500:     
                    501:     if(i == SCSI_DEBUG_MAILBOXES){
                    502: #ifndef IMMEDIATE
                    503:        pending = INT_MAX;
                    504:        for(i=0;i<SCSI_DEBUG_MAILBOXES; i++) {
                    505:            if (SCint[i] == 0) continue;
                    506:            if (timeout[i] == 0) continue;
                    507:            if (timeout[i] <= jiffies) {restore_flags(flags); goto repeat;};
                    508:            if (timeout[i] > jiffies) {
                    509:                if (pending > timeout[i]) pending = timeout[i];
                    510:                continue;
                    511:            };
                    512:        };
                    513:        if (pending && pending != INT_MAX) {
                    514:            timer_table[SCSI_DEBUG_TIMER].expires = 
                    515:                (pending <= jiffies ? jiffies+1 : pending);
                    516:            timer_active |= 1 << SCSI_DEBUG_TIMER;
                    517:        };
                    518:        restore_flags(flags);
                    519: #endif
                    520:        return;
                    521:     };
                    522:     
                    523:     if(i < SCSI_DEBUG_MAILBOXES){
                    524:        timeout[i] = 0;
                    525:        my_done = do_done[i];
                    526:        do_done[i] = NULL;
                    527:        to = timeout[i];
                    528:        timeout[i] = 0;
                    529:        SCtmp = (Scsi_Cmnd *) SCint[i];
                    530:        SCint[i] = NULL;
                    531:        restore_flags(flags);
                    532:        
                    533:        if (!my_done) {
                    534:            printk("scsi_debug_intr_handle: Unexpected interrupt\n"); 
                    535:            return;
                    536:        }
                    537:        
                    538: #ifdef DEBUG
                    539:        printk("In intr_handle...");
                    540:        printk("...done %d %x %d %d\n",i , my_done, to, jiffies);
                    541:        printk("In intr_handle: %d %x %x\n",i, SCtmp, my_done);
                    542: #endif
                    543:        
                    544:        my_done(SCtmp);
                    545: #ifdef DEBUG
                    546:        printk("Called done.\n");
                    547: #endif
                    548:     };
                    549:     goto repeat;
                    550: }
                    551: 
                    552: 
                    553: int scsi_debug_detect(Scsi_Host_Template * tpnt)
                    554: {
                    555:     tpnt->proc_dir = &proc_scsi_scsi_debug;
                    556: #ifndef IMMEDIATE
                    557:     timer_table[SCSI_DEBUG_TIMER].fn = scsi_debug_intr_handle;
                    558:     timer_table[SCSI_DEBUG_TIMER].expires = 0;
                    559: #endif
                    560:     return 1;
                    561: }
                    562: 
                    563: int scsi_debug_abort(Scsi_Cmnd * SCpnt)
                    564: {
                    565:     int j;
                    566:     void (*my_done)(Scsi_Cmnd *);
                    567:     unsigned long flags;
                    568:     
                    569:     DEB(printk("scsi_debug_abort\n"));
                    570: #if 0
                    571:     SCpnt->result = SCpnt->abort_reason << 16;
                    572:     for(j=0;j<SCSI_DEBUG_MAILBOXES; j++) {
                    573:        if(SCpnt == SCint[j]) {
                    574:            my_done = do_done[j];
                    575:            my_done(SCpnt);
                    576:            save_flags(flags);
                    577:            cli();
                    578:            timeout[j] = 0;
                    579:            SCint[j] = NULL;
                    580:            do_done[j] = NULL;
                    581:            restore_flags(flags);
                    582:        };
                    583:     };
                    584: #endif
                    585:     return SCSI_ABORT_SNOOZE;
                    586: }
                    587: 
                    588: int scsi_debug_biosparam(Disk * disk, kdev_t dev, int* info){
                    589:     int size = disk->capacity;
                    590:     info[0] = 32;
                    591:     info[1] = 64;
                    592:     info[2] = (size + 2047) >> 11;
                    593:     if (info[2] >= 1024) info[2] = 1024;
                    594:     return 0;
                    595: }
                    596: 
                    597: int scsi_debug_reset(Scsi_Cmnd * SCpnt)
                    598: {
                    599:     int i;
                    600:     unsigned long flags;
                    601:     
                    602:     void (*my_done)(Scsi_Cmnd *);
                    603:     printk("Bus unlocked by reset(%d)\n", SCpnt->host->suggest_bus_reset);
                    604:     scsi_debug_lockup = 0;
                    605:     DEB(printk("scsi_debug_reset called\n"));
                    606:     for(i=0;i<SCSI_DEBUG_MAILBOXES; i++) {
                    607:         if (SCint[i] == NULL) continue;
                    608:         SCint[i]->result = DID_RESET << 16;
                    609:         my_done = do_done[i];
                    610:         my_done(SCint[i]);
                    611:         save_flags(flags);
                    612:         cli();
                    613:         SCint[i] = NULL;
                    614:         do_done[i] = NULL;
                    615:         timeout[i] = 0;
                    616:         restore_flags(flags);
                    617:     }
                    618:     return SCSI_RESET_SUCCESS;
                    619: }
                    620: 
                    621: const char *scsi_debug_info(void)
                    622: {
                    623:     static char buffer[] = " ";         /* looks nicer without anything here */
                    624:     return buffer;
                    625: }
                    626: 
                    627: /* scsi_debug_proc_info
                    628:  * Used if the driver currently has no own support for /proc/scsi
                    629:  */
                    630: int scsi_debug_proc_info(char *buffer, char **start, off_t offset, 
                    631:                     int length, int inode, int inout)
                    632: {
                    633:     int len, pos, begin;
                    634:     int orig_length;
                    635: 
                    636:     if(inout == 1)
                    637:     {
                    638:         /* First check for the Signature */
                    639:         if (length >= 10 && strncmp(buffer, "scsi_debug", 10) == 0) {
                    640:             buffer += 11;
                    641:             length -= 11;
                    642:             /*
                    643:              * OK, we are getting some kind of command.  Figure out
                    644:              * what we are supposed to do here.  Simulate bus lockups
                    645:              * to test our reset capability.
                    646:              */
                    647:             if( length == 6 && strncmp(buffer, "lockup", length) == 0 )
                    648:             {
                    649:                 scsi_debug_lockup = 1;
                    650:                 return length;
                    651:             } 
                    652:             
                    653:             if( length == 6 && strncmp(buffer, "unlock", length) == 0 )
                    654:             {
                    655:                 scsi_debug_lockup = 0;
                    656:                 return length;
                    657:             } 
                    658:             
                    659:             printk("Unknown command:%s\n", buffer);
                    660:         } else 
                    661:             printk("Wrong Signature:%10s\n", (char *) ((ulong)buffer-11));
                    662: 
                    663:         return -EINVAL;
                    664:         
                    665:     }
                    666:     
                    667:     begin = 0;
                    668:     pos = len = sprintf(buffer, 
                    669:                        "This driver is not a real scsi driver, but it plays one on TV.\n"
                    670:                         "It is very handy for debugging specific problems because you\n"
                    671:                         "can simulate a variety of error conditions\n");
                    672:     if(pos < offset)
                    673:     {
                    674:        len = 0;
                    675:        begin = pos;
                    676:     }
                    677:     
                    678:     *start = buffer + (offset - begin);   /* Start of wanted data */
                    679:     len -= (offset - begin);
                    680:     if(len > length)
                    681:        len = length;
                    682:     
                    683:     return(len);
                    684: }
                    685: 
                    686: #ifdef MODULE
                    687: /* Eventually this will go into an include file, but this will be later */
                    688: Scsi_Host_Template driver_template = SCSI_DEBUG;
                    689: 
                    690: #include "scsi_module.c"
                    691: #endif
                    692:  
                    693: /*
                    694:  * Overrides for Emacs so that we almost follow Linus's tabbing style.
                    695:  * Emacs will notice this stuff at the end of the file and automatically
                    696:  * adjust the settings for this buffer only.  This must remain at the end
                    697:  * of the file.
                    698:  * ---------------------------------------------------------------------------
                    699:  * Local variables:
                    700:  * c-indent-level: 4
                    701:  * c-brace-imaginary-offset: 0
                    702:  * c-brace-offset: -4
                    703:  * c-argdecl-indent: 4
                    704:  * c-label-offset: -4
                    705:  * c-continued-statement-offset: 4
                    706:  * c-continued-brace-offset: 0
                    707:  * indent-tabs-mode: nil
                    708:  * tab-width: 8
                    709:  * End:
                    710:  */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.