⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scsi_debug.c

📁 基于组件方式开发操作系统的OSKIT源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
		starts[1] += 10;		starts[2] += 10;		#ifdef DEBUG		{ 		    int i;		    printk("scsi_debug: Filling sense buffer:");		    for(i=0;i<12;i++) printk("%d ",sense_buffer[i]);		    printk("\n");		};#endif		scsi_debug_errsts = (COMMAND_COMPLETE << 8) | (CHECK_CONDITION << 1);		break;	    } /* End phony disk change code */#endif	    #ifdef CLEAR	    memcpy(buff, &target, sizeof(target));	    memcpy(buff+sizeof(target), cmd, 24);	    memcpy(buff+60, &block, sizeof(block));	    memcpy(buff+64, SCpnt, sizeof(Scsi_Cmnd));#endif	    nbytes -= bufflen;	    if(SCpnt->use_sg){#ifdef CLEAR		memcpy(buff+128, bh, sizeof(struct buffer_head));#endif		block += bufflen >> 9;		bh = bh->b_reqnext;		sgcount++;		if (nbytes) {		    if(!bh) panic("Too few blocks for linked request.");		    buff = sgpnt[sgcount].address;		    bufflen = sgpnt[sgcount].length;		};	    }	} while(nbytes);		SCpnt->result = 0;	(done)(SCpnt);	return 0;		if (SCpnt->use_sg && !scsi_debug_errsts)	    if(bh) scsi_dump(SCpnt, 0);	break;    case WRITE_10:    case WRITE_6:#ifdef DEBUG	printk("Write\n");#endif	if ((*cmd) == WRITE_10)	    block = cmd[5] + (cmd[4] << 8) + (cmd[3] << 16) + (cmd[2] << 24); 	else 	    block = cmd[3] + (cmd[2] << 8) + ((cmd[1] & 0x1f) << 16);	VERIFY_DEBUG(WRITE);	/*      printk("(w%d)",SCpnt->request.nr_sectors); */	if (SCpnt->use_sg){	    if ((bufflen >> 9) != SCpnt->request.nr_sectors)		panic ("Trying to write wrong number of blocks\n");	    sgpnt = (struct scatterlist *) buff;	    buff = sgpnt[sgcount].address;	};#if 0	if (block != *((unsigned long *) (buff+60))) {	    printk("%x %x :",block,  *((unsigned long *) (buff+60)));	    scsi_dump(SCpnt,1);	    panic("Bad block written.\n");	};#endif	scsi_debug_errsts = 0;	break;    case MODE_SENSE:        /*         * Used to detect write protected status.         */	scsi_debug_errsts = 0;        memset(buff, 0, 6);        break;    default:	SCSI_LOG_LLQUEUE(3,printk("Unknown command %d\n",*cmd));	SCpnt->result =  DID_NO_CONNECT << 16;	done(SCpnt);	return 0;    };        save_flags(flags);     cli();    for(i=0;i<SCSI_DEBUG_MAILBOXES; i++){        if( timeout[i].function == NULL ) break;    };        /*     * If all of the slots are full, just return 1.  The new error handling scheme     * allows this, and the mid-level should queue things.     */    if (i >= SCSI_DEBUG_MAILBOXES ||  timeout[i].function != 0)    {        SCSI_LOG_LLQUEUE(1,printk("Command rejected - host busy\n"));        restore_flags(flags);        return 1;    }    SCSI_LOG_LLQUEUE(1,printk("Command accepted - slot %d\n", i));    #ifdef IMMEDIATE    if( !scsi_debug_lockup )    {        SCpnt->result = scsi_debug_errsts;        scsi_debug_intr_handle(i);  /* No timer - do this one right away */    }    restore_flags(flags);#else            SCpnt->result = scsi_debug_errsts;    timeout[i].function = scsi_debug_intr_handle;    timeout[i].data     = i;    timeout[i].expires  = jiffies + DISK_SPEED;    SCint[i]   = SCpnt;    do_done[i] = done;        restore_flags(flags);    add_timer(&timeout[i]);    if (!done)	panic("scsi_debug_queuecommand: done can't be NULL\n");    #if 0    printk("Sending command (%d %x %d %d)...", i, done, timeout[i].expires,jiffies);#endif#endif        return 0;}volatile static int internal_done_flag = 0;volatile static int internal_done_errcode = 0;static void internal_done(Scsi_Cmnd * SCpnt){    internal_done_errcode = SCpnt->result;    ++internal_done_flag;}int scsi_debug_command(Scsi_Cmnd * SCpnt){    DEB(printk("scsi_debug_command: ..calling scsi_debug_queuecommand\n"));    scsi_debug_queuecommand(SCpnt, internal_done);        while (!internal_done_flag);    internal_done_flag = 0;    return internal_done_errcode;}/* A "high" level interrupt handler.  This should be called once per jiffy * to simulate a regular scsi disk.  We use a timer to do this. */static void scsi_debug_intr_handle(unsigned long indx){    Scsi_Cmnd * SCtmp;    void (*my_done)(Scsi_Cmnd *); #ifdef DEBUG    int to;#endif    #if 0    del_timer(&timeout[indx]);#endif        SCtmp                  = (Scsi_Cmnd *) SCint[indx];    my_done                = do_done[indx];    do_done[indx]          = NULL;    timeout[indx].function = NULL;    SCint[indx]            = NULL;        if (!my_done) {      printk("scsi_debug_intr_handle: Unexpected interrupt\n");       return;    }    #ifdef DEBUG    printk("In intr_handle...");    printk("...done %d %x %d %d\n",i , my_done, to, jiffies);    printk("In intr_handle: %d %x %x\n",i, SCtmp, my_done);#endif        my_done(SCtmp);#ifdef DEBUG    printk("Called done.\n");#endif}int scsi_debug_detect(Scsi_Host_Template * tpnt){    int i;    for(i=0; i < NR_HOSTS_PRESENT; i++)    {        tpnt->proc_dir = &proc_scsi_scsi_debug;        scsi_register(tpnt,0);    }    return NR_HOSTS_PRESENT;}int scsi_debug_abort(Scsi_Cmnd * SCpnt){#if 0    int j;    void (*my_done)(Scsi_Cmnd *);    unsigned long flags;#endif        DEB(printk("scsi_debug_abort\n"));#if 0    SCpnt->result = SCpnt->abort_reason << 16;    for(j=0;j<SCSI_DEBUG_MAILBOXES; j++) {	if(SCpnt == SCint[j]) {	    my_done = do_done[j];	    my_done(SCpnt);	    save_flags(flags);	    cli();	    timeout[j] = 0;	    SCint[j] = NULL;	    do_done[j] = NULL;	    restore_flags(flags);	};    };#endif    return SCSI_ABORT_SNOOZE;}int scsi_debug_biosparam(Disk * disk, kdev_t dev, int* info){    int size = disk->capacity;    info[0] = N_HEAD;    info[1] = N_SECTOR;    info[2] = (size + 2047) >> 11;    if (info[2] >= 1024) info[2] = 1024;    return 0;}int scsi_debug_reset(Scsi_Cmnd * SCpnt, unsigned int why){    int i;    unsigned long flags;        void (*my_done)(Scsi_Cmnd *);    printk("Bus unlocked by reset - %d\n", why);    scsi_debug_lockup = 0;    DEB(printk("scsi_debug_reset called\n"));    for(i=0;i<SCSI_DEBUG_MAILBOXES; i++) {        if (SCint[i] == NULL) continue;        SCint[i]->result = DID_RESET << 16;        my_done = do_done[i];        my_done(SCint[i]);        save_flags(flags);        cli();        SCint[i]            = NULL;        do_done[i]          = NULL;        timeout[i].function = NULL;        restore_flags(flags);    }    return SCSI_RESET_SUCCESS;}const char *scsi_debug_info(void){    static char buffer[] = " ";         /* looks nicer without anything here */    return buffer;}/* scsi_debug_proc_info * Used if the driver currently has no own support for /proc/scsi */int scsi_debug_proc_info(char *buffer, char **start, off_t offset, 		     int length, int inode, int inout){    int len, pos, begin;    int orig_length;    orig_length = length;    if(inout == 1)    {        /* First check for the Signature */        if (length >= 10 && strncmp(buffer, "scsi_debug", 10) == 0) {            buffer += 11;            length -= 11;            if( buffer[length - 1] == '\n' )            {                buffer[length-1] = '\0';                length--;            }            /*             * OK, we are getting some kind of command.  Figure out             * what we are supposed to do here.  Simulate bus lockups             * to test our reset capability.             */            if( length == 6 && strncmp(buffer, "lockup", length) == 0 )            {                scsi_debug_lockup = 1;                return orig_length;            }                         if( length == 6 && strncmp(buffer, "unlock", length) == 0 )            {                scsi_debug_lockup = 0;                return orig_length;            }                         printk("Unknown command:%s (%d)\n", buffer, length);        } else             printk("Wrong Signature:%10s\n", (char *) buffer);        return -EINVAL;            }        begin = 0;    pos = len = sprintf(buffer, 			"This driver is not a real scsi driver, but it plays one on TV.\n"                        "It is very handy for debugging specific problems because you\n"                        "can simulate a variety of error conditions\n");    if(pos < offset)    {	len = 0;	begin = pos;    }        *start = buffer + (offset - begin);   /* Start of wanted data */    len -= (offset - begin);    if(len > length)	len = length;        return(len);}#ifdef MODULE/* Eventually this will go into an include file, but this will be later */Scsi_Host_Template driver_template = SCSI_DEBUG;#include "scsi_module.c"#endif /* * Overrides for Emacs so that we almost follow Linus's tabbing style. * Emacs will notice this stuff at the end of the file and automatically * adjust the settings for this buffer only.  This must remain at the end * of the file. * --------------------------------------------------------------------------- * Local variables: * c-indent-level: 4 * c-brace-imaginary-offset: 0 * c-brace-offset: -4 * c-argdecl-indent: 4 * c-label-offset: -4 * c-continued-statement-offset: 4 * c-continued-brace-offset: 0 * indent-tabs-mode: nil * tab-width: 8 * End: */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -