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

📄 sg.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 5 页
字号:
/* This function is a "bottom half" handler that is called by the * mid level when a command is completed (or has failed). */static void sg_cmd_done_bh(Scsi_Cmnd * SCpnt){    Scsi_Request * SRpnt = SCpnt->sc_request;    int dev = MINOR(SRpnt->sr_request.rq_dev);    Sg_device * sdp = NULL;    Sg_fd * sfp;    Sg_request * srp = NULL;    read_lock(&sg_dev_arr_lock);    if (sg_dev_arr && (dev >= 0)) {	if (dev < sg_template.dev_max)	    sdp = sg_dev_arr[dev];    }    if ((NULL == sdp) || sdp->detached) {	read_unlock(&sg_dev_arr_lock);	SCSI_LOG_TIMEOUT(1, printk("sg...bh: dev=%d gone\n", dev));        scsi_release_request(SRpnt);        SRpnt = NULL;        return;    }    sfp = sdp->headfp;    while (sfp) {	read_lock(&sfp->rq_list_lock);	for (srp = sfp->headrp; srp; srp = srp->nextrp) {            if (SRpnt == srp->my_cmdp)                break;        }	read_unlock(&sfp->rq_list_lock);        if (srp)            break;        sfp = sfp->nextfp;    }    if (! srp) {	read_unlock(&sg_dev_arr_lock);	SCSI_LOG_TIMEOUT(1, printk("sg...bh: req missing, dev=%d\n", dev));        scsi_release_request(SRpnt);        SRpnt = NULL;        return;    }    /* First transfer ownership of data buffers to sg_device object. */    srp->data.k_use_sg = SRpnt->sr_use_sg;    srp->data.sglist_len = SRpnt->sr_sglist_len;    srp->data.bufflen = SRpnt->sr_bufflen;    srp->data.buffer = SRpnt->sr_buffer;    /* now clear out request structure */    SRpnt->sr_use_sg = 0;    SRpnt->sr_sglist_len = 0;    SRpnt->sr_bufflen = 0;    SRpnt->sr_buffer = NULL;    SRpnt->sr_underflow = 0;    SRpnt->sr_request.rq_dev = MKDEV(0, 0);  /* "sg" _disowns_ request blk */    srp->my_cmdp = NULL;    srp->done = 1;    read_unlock(&sg_dev_arr_lock);    SCSI_LOG_TIMEOUT(4, printk("sg...bh: dev=%d, pack_id=%d, res=0x%x\n",		     dev, srp->header.pack_id, (int)SRpnt->sr_result));    srp->header.resid = SCpnt->resid;    /* sg_unmap_and(&srp->data, 0); */     /* unmap locked pages a.s.a.p. */    /* N.B. unit of duration changes here from jiffies to millisecs */    srp->header.duration = sg_jif_to_ms(jiffies - (int)srp->header.duration);    if (0 != SRpnt->sr_result) {	memcpy(srp->sense_b, SRpnt->sr_sense_buffer, sizeof(srp->sense_b));	srp->header.status = 0xff & SRpnt->sr_result;	srp->header.masked_status  = status_byte(SRpnt->sr_result);	srp->header.msg_status  = msg_byte(SRpnt->sr_result);	srp->header.host_status = host_byte(SRpnt->sr_result);	srp->header.driver_status = driver_byte(SRpnt->sr_result);	if ((sdp->sgdebug > 0) &&	    ((CHECK_CONDITION == srp->header.masked_status) ||	     (COMMAND_TERMINATED == srp->header.masked_status)))	    print_req_sense("sg_cmd_done_bh", SRpnt);	/* Following if statement is a patch supplied by Eric Youngdale */	if (driver_byte(SRpnt->sr_result) != 0	    && (SRpnt->sr_sense_buffer[0] & 0x7f) == 0x70	    && (SRpnt->sr_sense_buffer[2] & 0xf) == UNIT_ATTENTION	    && sdp->device->removable) {	    /* Detected disc change. Set the bit - this may be used if */	    /* there are filesystems using this device. */	    sdp->device->changed = 1;	}    }    /* Rely on write phase to clean out srp status values, so no "else" */    scsi_release_request(SRpnt);    SRpnt = NULL;    if (sfp->closed) { /* whoops this fd already released, cleanup */        SCSI_LOG_TIMEOUT(1,	       printk("sg...bh: already closed, freeing ...\n"));	sg_finish_rem_req(srp);	srp = NULL;	if (NULL == sfp->headrp) {            SCSI_LOG_TIMEOUT(1,		printk("sg...bh: already closed, final cleanup\n"));            if (0 == sg_remove_sfp(sdp, sfp)) { /* device still present */		sdp->device->access_count--;		if (sdp->device->host->hostt->module)		    __MOD_DEC_USE_COUNT(sdp->device->host->hostt->module);	    }	    if (sg_template.module)		    __MOD_DEC_USE_COUNT(sg_template.module);	    sfp = NULL;        }    }    else if (srp && srp->orphan) {	if (sfp->keep_orphan)	    srp->sg_io_owned = 0;	else {	    sg_finish_rem_req(srp);	    srp = NULL;        }    }    if (sfp && srp) {	/* Now wake up any sg_read() that is waiting for this packet. */	wake_up_interruptible(&sfp->read_wait);	kill_fasync(&sfp->async_qp, SIGPOLL, POLL_IN);    }}static struct file_operations sg_fops = {	owner:		THIS_MODULE,	read:		sg_read,	write:		sg_write,	poll:		sg_poll,	ioctl:		sg_ioctl,	open:		sg_open,	mmap:		sg_mmap,	release:	sg_release,	fasync:		sg_fasync,};static int sg_detect(Scsi_Device * scsidp){    sg_template.dev_noticed++;    return 1;}/* Driver initialization */static int sg_init(){    static int sg_registered = 0;    unsigned long iflags;    if ((sg_template.dev_noticed == 0) || sg_dev_arr)    	return 0;    write_lock_irqsave(&sg_dev_arr_lock, iflags);    if(!sg_registered) {	if (devfs_register_chrdev(SCSI_GENERIC_MAJOR,"sg",&sg_fops))        {            printk(KERN_ERR "Unable to get major %d for generic SCSI device\n",                   SCSI_GENERIC_MAJOR);	    write_unlock_irqrestore(&sg_dev_arr_lock, iflags);            sg_template.dev_noticed = 0;            return 1;        }        sg_registered++;    }    SCSI_LOG_TIMEOUT(3, printk("sg_init\n"));    sg_template.dev_max = sg_template.dev_noticed + SG_DEV_ARR_LUMP;    sg_dev_arr = (Sg_device **)kmalloc(sg_template.dev_max *     					sizeof(Sg_device *), GFP_ATOMIC);    if (NULL == sg_dev_arr) {        printk(KERN_ERR "sg_init: no space for sg_dev_arr\n");	write_unlock_irqrestore(&sg_dev_arr_lock, iflags);        sg_template.dev_noticed = 0;        return 1;    }    memset(sg_dev_arr, 0, sg_template.dev_max * sizeof(Sg_device *));    write_unlock_irqrestore(&sg_dev_arr_lock, iflags);#ifdef CONFIG_PROC_FS    sg_proc_init();#endif  /* CONFIG_PROC_FS */    return 0;}#ifndef MODULEstatic int __init sg_def_reserved_size_setup(char *str){    int tmp;    if (get_option(&str, &tmp) == 1) {	def_reserved_size = tmp;	if (tmp >= 0)	    sg_big_buff = tmp;	return 1;    } else {	printk(KERN_WARNING "sg_def_reserved_size : usage "	    "sg_def_reserved_size=n (n could be 65536, 131072 or 262144)\n");	return 0;    }}__setup("sg_def_reserved_size=", sg_def_reserved_size_setup);#endifstatic int sg_attach(Scsi_Device * scsidp){    Sg_device * sdp;    unsigned long iflags;    int k;    write_lock_irqsave(&sg_dev_arr_lock, iflags);    if (sg_template.nr_dev >= sg_template.dev_max) { /* try to resize */    	Sg_device ** tmp_da;	int tmp_dev_max = sg_template.nr_dev + SG_DEV_ARR_LUMP;	tmp_da = (Sg_device **)kmalloc(tmp_dev_max *     					sizeof(Sg_device *), GFP_ATOMIC);	if (NULL == tmp_da) {	    scsidp->attached--;	    write_unlock_irqrestore(&sg_dev_arr_lock, iflags);	    printk(KERN_ERR "sg_attach: device array cannot be resized\n");	    return 1;	}	memset(tmp_da, 0, tmp_dev_max * sizeof(Sg_device *));	memcpy(tmp_da, sg_dev_arr, sg_template.dev_max * sizeof(Sg_device *));	kfree((char *)sg_dev_arr);	sg_dev_arr = tmp_da;	sg_template.dev_max = tmp_dev_max;    }    for(k = 0; k < sg_template.dev_max; k++)        if(! sg_dev_arr[k]) break;    if (k > MINORMASK) {	scsidp->attached--;	write_unlock_irqrestore(&sg_dev_arr_lock, iflags);	printk(KERN_WARNING "Unable to attach sg device <%d, %d, %d, %d>"	       " type=%d, minor number exceed %d\n", scsidp->host->host_no, 	       scsidp->channel, scsidp->id, scsidp->lun, scsidp->type,	       MINORMASK);	return 1;    }    if(k < sg_template.dev_max)    	sdp = (Sg_device *)kmalloc(sizeof(Sg_device), GFP_ATOMIC);    else    	sdp = NULL;    if (NULL == sdp) {	scsidp->attached--;	write_unlock_irqrestore(&sg_dev_arr_lock, iflags);	printk(KERN_ERR "sg_attach: Sg_device cannot be allocated\n");	return 1;    }    SCSI_LOG_TIMEOUT(3, printk("sg_attach: dev=%d \n", k));    sdp->device = scsidp;    init_waitqueue_head(&sdp->o_excl_wait);    sdp->headfp= NULL;    sdp->exclude = 0;    sdp->sgdebug = 0;    sdp->detached = 0;    sdp->sg_tablesize = scsidp->host ? scsidp->host->sg_tablesize : 0;    sdp->i_rdev = MKDEV(SCSI_GENERIC_MAJOR, k);    sdp->de = devfs_register (scsidp->de, "generic", DEVFS_FL_DEFAULT,                             SCSI_GENERIC_MAJOR, k,                             S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP,                             &sg_fops, sdp);    sg_template.nr_dev++;    sg_dev_arr[k] = sdp;    write_unlock_irqrestore(&sg_dev_arr_lock, iflags);    switch (scsidp->type) {	case TYPE_DISK:	case TYPE_MOD:	case TYPE_ROM:	case TYPE_WORM:	case TYPE_TAPE: break;	default:	    printk(KERN_NOTICE "Attached scsi generic sg%d at scsi%d, channel"	    	   " %d, id %d, lun %d,  type %d\n", k, scsidp->host->host_no, 		   scsidp->channel, scsidp->id, scsidp->lun, scsidp->type);    }    return 0;}/* Called at 'finish' of init process, after all attaches */static void sg_finish(void){ }static void sg_detach(Scsi_Device * scsidp){    Sg_device * sdp;    unsigned long iflags;    Sg_fd * sfp;    Sg_fd * tsfp;    Sg_request * srp;    Sg_request * tsrp;    int k, delay;    if (NULL == sg_dev_arr)    	return;    delay = 0;    write_lock_irqsave(&sg_dev_arr_lock, iflags);    for (k = 0; k < sg_template.dev_max; k++) {    	sdp = sg_dev_arr[k];        if ((NULL == sdp) || (sdp->device != scsidp))            continue;   /* dirty but lowers nesting */        if (sdp->headfp) {	    sdp->detached = 1;	    for (sfp = sdp->headfp; sfp; sfp = tsfp) {	    	tsfp = sfp->nextfp;		for (srp = sfp->headrp; srp; srp = tsrp) {		    tsrp = srp->nextrp;		    if (sfp->closed || (0 == srp->done))			sg_finish_rem_req(srp);		}		if (sfp->closed) {		    sdp->device->access_count--;		    if (sg_template.module)			__MOD_DEC_USE_COUNT(sg_template.module);		    if (sdp->device->host->hostt->module)			__MOD_DEC_USE_COUNT(sdp->device->host->hostt->module);		    __sg_remove_sfp(sdp, sfp);		}		else {		    delay = 1;		    wake_up_interruptible(&sfp->read_wait);		    kill_fasync(&sfp->async_qp, SIGPOLL, POLL_HUP);		}            }	    SCSI_LOG_TIMEOUT(3, printk("sg_detach: dev=%d, dirty\n", k));	    devfs_unregister (sdp->de);	    sdp->de = NULL;	    if (NULL == sdp->headfp) {		kfree((char *)sdp);		sg_dev_arr[k] = NULL;	    }        }        else { /* nothing active, simple case */            SCSI_LOG_TIMEOUT(3, printk("sg_detach: dev=%d\n", k));	    devfs_unregister (sdp->de);	    kfree((char *)sdp);	    sg_dev_arr[k] = NULL;        }        scsidp->attached--;        sg_template.nr_dev--;        sg_template.dev_noticed--;	/* from <dan@lectra.fr> */        break;    }    write_unlock_irqrestore(&sg_dev_arr_lock, iflags);    if (delay)	scsi_sleep(2);	/* dirty detach so delay device destruction */}MODULE_AUTHOR("Douglas Gilbert");MODULE_DESCRIPTION("SCSI generic (sg) driver");#ifdef MODULE_LICENSEMODULE_LICENSE("GPL");#endifMODULE_PARM(def_reserved_size, "i");MODULE_PARM_DESC(def_reserved_size, "size of buffer reserved for each fd");static int __init init_sg(void) {    if (def_reserved_size >= 0)	sg_big_buff = def_reserved_size;    sg_template.module = THIS_MODULE;    return scsi_register_module(MODULE_SCSI_DEV, &sg_template);}static void __exit exit_sg( void){#ifdef CONFIG_PROC_FS    sg_proc_cleanup();#endif  /* CONFIG_PROC_FS */    scsi_unregister_module(MODULE_SCSI_DEV, &sg_template);    devfs_unregister_chrdev(SCSI_GENERIC_MAJOR, "sg");    if(sg_dev_arr != NULL) {	kfree((char *)sg_dev_arr);        sg_dev_arr = NULL;    }    sg_template.dev_max = 0;}static int sg_start_req(Sg_request * srp){    int res;    Sg_fd * sfp = srp->parentfp;    sg_io_hdr_t * hp = &srp->header;    int dxfer_len = (int)hp->dxfer_len;    int dxfer_dir = hp->dxfer_direction;    Sg_scatter_hold * req_schp = &srp->data;    Sg_scatter_hold * rsv_schp = &sfp->reserve;    SCSI_LOG_TIMEOUT(4, printk("sg_start_req: dxfer_len=%d\n", dxfer_len));    if ((dxfer_len <= 0) || (dxfer_dir == SG_DXFER_NONE))    	return 0;    if (sg_allow_dio && (hp->flags & SG_FLAG_DIRECT_IO) && 

⌨️ 快捷键说明

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