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

📄 scsi_debug.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 2 页
字号:
	}	*errstsp = 0;	do {		int resid, k, off, len, rem, blk;		unsigned char * bp;		/* If this is block 0, then we want to read the partition		 * table for this device.  Let's make one up */		if (scsi_debug_fake_blk0 && (block == 0) && (! made_block0)) {			scsi_debug_mkblock0(buff, bufflen, SCpnt);			*errstsp = 0;			break;		}		bp = buff;		blk = block;		for (resid = bufflen; resid > 0; resid -= len) {			k = blk / SECT_PER_ELEM; 			off = (blk % SECT_PER_ELEM) * SECT_SIZE;			rem = STORE_ELEM_SIZE - off;			len = (resid > rem) ? rem : resid;/* printk("sdr: blk=%d k=%d off=%d rem=%d resid"			       "=%d len=%d  sgcount=%d\n", blk, k, 				off, rem, resid, len, sgcount); */			memcpy(bp, store_arr[k].p + off, len);			bp += len;			blk += len / SECT_SIZE;		}#if 0		/* Simulate a disk change */		if (block == 0xfff0) {			sense_buffer[0] = 0x70;			sense_buffer[2] = UNIT_ATTENTION;			starts[0] += 10;			starts[1] += 10;			starts[2] += 10;			*errstsp = (COMMAND_COMPLETE << 8) | 				   (CHECK_CONDITION << 1);			read_unlock_irqrestore(&sdebug_atomic_rw, iflags);			return 1;		}	/* End phony disk change code */#endif		nbytes -= bufflen;		if (SCpnt->use_sg) {			block += bufflen >> POW2_SECT_SIZE;			sgcount++;			if (nbytes) {				buff = sgpnt[sgcount].address;				bufflen = sgpnt[sgcount].length;			}		}		else if (nbytes > 0)			printk("sdebug_read: unexpected nbytes=%d\n", nbytes);	} while (nbytes);	read_unlock_irqrestore(&sdebug_atomic_rw, iflags);	return 0;}static int scsi_debug_write(Scsi_Cmnd * SCpnt, int upper_blk, int block, 			    int num, int * errstsp, Sdebug_dev_info * devip){        unsigned char *buff = (unsigned char *) SCpnt->request_buffer;        int nbytes, sgcount;        struct scatterlist *sgpnt = NULL;        int bufflen = SCpnt->request_bufflen;	unsigned long iflags;	if (upper_blk || (block + num > CAPACITY)) {		*errstsp = (COMMAND_COMPLETE << 8) |			   (CHECK_CONDITION << 1);		mk_sense_buffer(devip, 1, ILLEGAL_REQUEST, 0x21, 0, 14);		return 1;	}	write_lock_irqsave(&sdebug_atomic_rw, iflags);        sgcount = 0;#ifdef SCSI_DUMP	if (block != *((unsigned long *) (buff + 60))) {		printk("%x %x :", block, *((unsigned long *) (buff + 60)));		scsi_dump(SCpnt, 1);		printk("Bad block written.\n");	}#endif	nbytes = bufflen;	if (SCpnt->use_sg) {		sgcount = 0;		sgpnt = (struct scatterlist *) buff;		buff = sgpnt[sgcount].address;		bufflen = sgpnt[sgcount].length;	}	*errstsp = 0;	do {		int resid, k, off, len, rem, blk;		unsigned char * bp;		bp = buff;		blk = block;		for (resid = bufflen; resid > 0; resid -= len) {			k = blk / SECT_PER_ELEM; 			off = (blk % SECT_PER_ELEM) * SECT_SIZE;			rem = STORE_ELEM_SIZE - off;			len = (resid > rem) ? rem : resid;			memcpy(store_arr[k].p + off, bp, len);			bp += len;			blk += len / SECT_SIZE;		}		nbytes -= bufflen;		if (SCpnt->use_sg) {			block += bufflen >> POW2_SECT_SIZE;			sgcount++;			if (nbytes) {				buff = sgpnt[sgcount].address;				bufflen = sgpnt[sgcount].length;			}		}		else if (nbytes > 0)			printk("sdebug_write: unexpected nbytes=%d\n", nbytes);	} while (nbytes);	write_unlock_irqrestore(&sdebug_atomic_rw, iflags);	return 0;}static void scsi_debug_send_self_command(struct Scsi_Host * shpnt){	static unsigned char cmd[6] =	{TEST_UNIT_READY, 0, 0, 0, 0, 0};        Scsi_Request  * scp;        Scsi_Device   * sdev;                printk("Allocating host dev\n");        sdev = scsi_get_host_dev(shpnt);        if(sdev==NULL)        {        	printk("Out of memory.\n");        	return;        }                printk("Got %p. Allocating command block\n", sdev);        scp  = scsi_allocate_request(sdev);        printk("Got %p\n", scp);                if(scp==NULL)        {        	printk("Out of memory.\n");        	goto bail;        }        scp->sr_cmd_len = 6;        scp->sr_use_sg = 0;                printk("Sending command\n");        scsi_wait_req (scp, (void *) cmd, (void *) NULL,                       0, 100, 3);                printk("Releasing command\n");        scsi_release_request(scp);bail:	printk("Freeing device\n");        scsi_free_host_dev(sdev);}/* 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 *);#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;	}#if 0	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);#if 0	printk("Called done.\n");#endif}static int initialized = 0;static int do_init(void){	int sz;	starts[3] = CAPACITY;	sz = sizeof(Sd_store_elem) * STORE_ELEMENTS;	store_arr = kmalloc(sz, GFP_ATOMIC);	if (NULL == store_arr)		return 1;	memset(store_arr, 0, sz);	sz = sizeof(done_fct_t) * SCSI_DEBUG_MAILBOXES;	do_done = kmalloc(sz, GFP_ATOMIC);	if (NULL == do_done) {		kfree(store_arr);		return 1;	}	memset((void *)do_done, 0, sz);	sz = sizeof(struct timer_list) * SCSI_DEBUG_MAILBOXES;	timeout = kmalloc(sz, GFP_ATOMIC);	if (NULL == timeout) {		kfree((void *)do_done);		kfree(store_arr);		return 1;	}	memset(timeout, 0, sz);	sz = sizeof(Scsi_Cmnd *) * SCSI_DEBUG_MAILBOXES;	SCint = kmalloc(sz, GFP_ATOMIC);	if (NULL == SCint) {		kfree(timeout);		kfree((void *)do_done);		kfree(store_arr);		return 1;	}	memset(SCint, 0, sz);	return 0;}static void do_end(void){	kfree(SCint);	kfree(timeout);	kfree((void *)do_done);	kfree(store_arr);}int scsi_debug_detect(Scsi_Host_Template * tpnt){	int k, num, sz;	if (0 == initialized) {		++initialized;		sz = sizeof(Sdebug_dev_info) * scsi_debug_num_devs;		devInfop = kmalloc(sz, GFP_ATOMIC);		if (NULL == devInfop) {			printk("scsi_debug_detect: out of memory, 0.5\n");			return 0;		}		memset(devInfop, 0, sz);		if (do_init()) {			printk("scsi_debug_detect: out of memory, 0\n");			return 0;		}		for (k = 0; k < STORE_ELEMENTS; ++k) {			store_arr[k].p = (unsigned char *)				__get_free_pages(GFP_ATOMIC, STORE_ELEM_ORDER);			if (0 == store_arr[k].p)				goto detect_err;			memset(store_arr[k].p, 0, STORE_ELEM_SIZE);		}		for (k = 0; k < NUM_SENSE_BUFFS; ++k)			sense_buffers[k][0] = 0x70;		for (k = 0; k < NR_HOSTS_PRESENT; k++) {			tpnt->proc_name = "scsi_debug";	/* In the loop??? */			scsi_register(tpnt, 0);		}		return NR_HOSTS_PRESENT;	}	else {		printk("scsi_debug_detect: called again\n");		return 0;	}detect_err:	num = k;	for (k = 0; k < STORE_ELEMENTS; ++k) {		if (0 != store_arr[k].p) {			free_pages((unsigned long)store_arr[k].p, 				   STORE_ELEM_ORDER);			store_arr[k].p = NULL;		}	}	printk("scsi_debug_detect: out of memory: %d out of %d bytes\n",	       (int)(num * STORE_ELEM_SIZE), 	       (int)(scsi_debug_dev_size_mb * 1024 * 1024));	return 0;}static int num_releases = 0;int scsi_debug_release(struct Scsi_Host * hpnt){	int k;		scsi_unregister(hpnt);	if (++num_releases != NR_HOSTS_PRESENT)		return 0;	for (k = 0; k < STORE_ELEMENTS; ++k) {		if (0 != store_arr[k].p) {			free_pages((unsigned long)store_arr[k].p, 				   STORE_ELEM_ORDER);			store_arr[k].p = NULL;		}	}	do_end();	kfree(devInfop);	return 0;}static Sdebug_dev_info * devInfoReg(Scsi_Device * sdp){	int k;	unsigned short host_no, id;	Sdebug_dev_info * devip;	host_no = sdp->host->host_no;	id = (unsigned short)sdp->id;	for (k = 0; k < scsi_debug_num_devs; ++k) {		devip = &devInfop[k];		if (devip->sdp && (host_no == devip->host_no) &&		    (id == devip->id)) {			devip->sdp = sdp; /* overwrite previous sdp */			return devip;		}		if (NULL == devip->sdp) {			devip->sdp = sdp;			devip->host_no = host_no;			devip->id = id;			devip->reset = 1;			devip->sb_index = 0;			return devip;		}	}	return NULL;}static void mk_sense_buffer(Sdebug_dev_info * devip, int index, int key, 			    int asc, int asq, int inbandLen){	char * sbuff;	if ((index < 0) || (index >= NUM_SENSE_BUFFS))		return;	if (devip)		devip->sb_index = index;	sbuff = &sense_buffers[index][0];	memset(sbuff, 0, SENSE_BUFF_LEN);	sbuff[0] = 0x70;	sbuff[2] = key;	sbuff[7] = (inbandLen > 7) ? (inbandLen - 8) : 0;	sbuff[12] = asc;	sbuff[13] = asq;}int scsi_debug_abort(Scsi_Cmnd * SCpnt){#if 1	++num_aborts;	return SUCCESS;#else	int j;	void (*my_done) (Scsi_Cmnd *);	unsigned long iflags;	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);			spin_lock_irqsave(&mailbox_lock, iflags);			timeout[j] = 0;			SCint[j] = NULL;			do_done[j] = NULL;			spin_unlock_irqrestore(&mailbox_lock, iflags);		}	}	return SCSI_ABORT_SNOOZE;#endif}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] = N_CYLINDER;	if (info[2] >= 1024)		info[2] = 1024;	return 0;}#if 0int scsi_debug_reset(Scsi_Cmnd * SCpnt, unsigned int why){	int i;	unsigned long iflags;	void (*my_done) (Scsi_Cmnd *);	printk("Bus unlocked by reset - %d\n", why);	scsi_debug_lockup = 0;	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]);		spin_lock_irqsave(&mailbox_lock, iflags);		SCint[i] = NULL;		do_done[i] = NULL;		timeout[i].function = NULL;		spin_unlock_irqrestore(&mailbox_lock, iflags);	}	return SCSI_RESET_SUCCESS;}#endifint scsi_debug_device_reset(Scsi_Cmnd * SCpnt){	Scsi_Device * sdp;	int k;	++num_dev_resets;	if (SCpnt && ((sdp = SCpnt->device))) {		for (k = 0; k < scsi_debug_num_devs; ++k) {			if (sdp->hostdata == (devInfop + k))				break;		}		if (k < scsi_debug_num_devs)			devInfop[k].reset = 1;	}	return SUCCESS;}int scsi_debug_bus_reset(Scsi_Cmnd * SCpnt){	Scsi_Device * sdp;	struct Scsi_Host * hp;	int k;	++num_bus_resets;	if (SCpnt && ((sdp = SCpnt->device)) && ((hp = sdp->host))) {		for (k = 0; k < scsi_debug_num_devs; ++k) {			if (hp == devInfop[k].sdp->host)				devInfop[k].reset = 1;		}	}	return SUCCESS;}int scsi_debug_host_reset(Scsi_Cmnd * SCpnt){	int k;	++num_host_resets;	for (k = 0; k < scsi_debug_num_devs; ++k)		devInfop[k].reset = 1;	return SUCCESS;}#ifndef MODULEstatic int __init scsi_debug_num_devs_setup(char *str){       int tmp;         if (get_option(&str, &tmp) == 1) {        if (tmp > 0)            scsi_debug_num_devs = tmp;        return 1;    } else {        printk("scsi_debug_num_devs: usage scsi_debug_num_devs=<n> "               "(<n> can be from 1 to around 2000)\n");        return 0;    }}__setup("scsi_debug_num_devs=", scsi_debug_num_devs_setup);static int __init scsi_debug_dev_size_mb_setup(char *str){       int tmp;         if (get_option(&str, &tmp) == 1) {        if (tmp > 0)            scsi_debug_dev_size_mb = tmp;        return 1;    } else {        printk("scsi_debug_dev_size_mb: usage scsi_debug_dev_size_mb=<n>\n"               "    (<n> is number of MB ram shared by all devs\n");        return 0;    }}__setup("scsi_debug_dev_size_mb=", scsi_debug_dev_size_mb_setup);#endifMODULE_AUTHOR("Eric Youngdale + Douglas Gilbert");MODULE_DESCRIPTION("SCSI debug adapter driver");MODULE_PARM(scsi_debug_num_devs, "i");MODULE_PARM_DESC(scsi_debug_num_devs, "number of SCSI devices to simulate");MODULE_PARM(scsi_debug_dev_size_mb, "i");MODULE_PARM_DESC(scsi_debug_dev_size_mb, "size in MB of ram shared by devs");#ifdef MODULE_LICENSEMODULE_LICENSE("GPL");#endifstatic char sdebug_info[256];const char * scsi_debug_info(struct Scsi_Host * shp){	sprintf(sdebug_info, "scsi_debug, %s, num_devs=%d, "		"dev_size_mb=%d\n", scsi_debug_version_str,		scsi_debug_num_devs, scsi_debug_dev_size_mb);	return sdebug_info;}/* 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 == 4 && strncmp(buffer, "test", length) == 0) {                                printk("Testing send self command %p\n", SHpnt);                                scsi_debug_send_self_command(SHpnt);                                return orig_length;                        }			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, "scsi_debug adapter driver, %s\n"	    "num_devs=%d, shared (ram) size=%d MB, sector_size=%d bytes\n" 	    "cylinders=%d, heads=%d, sectors=%d\n"	    "number of aborts=%d, device_reset=%d, bus_resets=%d, " 	    "host_resets=%d\n",	    scsi_debug_version_str, scsi_debug_num_devs, 	    scsi_debug_dev_size_mb, SECT_SIZE,	    N_CYLINDER, N_HEAD, N_SECTOR,	    num_aborts, num_dev_resets, num_bus_resets, num_host_resets);#if 0	 "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");#endif	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);}/* Eventually this will go into an include file, but this will be later */static Scsi_Host_Template driver_template = SCSI_DEBUG_TEMPLATE;#include "scsi_module.c"

⌨️ 快捷键说明

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