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

📄 scsi_target.c

📁 这个linux源代码是很全面的~基本完整了~使用c编译的~由于时间问题我没有亲自测试~但就算用来做参考资料也是非常好的
💻 C
📖 第 1 页 / 共 2 页
字号:
		kmalloc(SGS_SIZE(sizeof (inqdata)), GFP_ATOMIC|GFP_DMA);	    if (dp == NULL) {		printk("scsi_target_alloc: out of memory for inquiry data\n");		spin_lock_irqsave(&scsi_target_lock, flags);		add_sdata(ini, ifailure);		spin_unlock_irqrestore(&scsi_target_lock, flags);		tmd->cd_hflags |= CDFH_SNSVALID;	    } else {		dp->alt_address = NULL;		dp->address = SGS_PAYLOAD(dp, char *);		dp->length = min(sizeof(inqdata), tmd->cd_totlen);		tmd->cd_xfrlen = dp->length;		memcpy(dp->address, inqdata, sizeof (inqdata));		/*		 * If we're not here, say we aren't here.		 */		if (tmd->cd_lun >= MAX_LUN || tmd->cd_bus >= 2) {		    dp->address[0] = (3 << 5) | DEFAULT_DEVICE_TYPE;		} else if (bp->luns[tmd->cd_bus][tmd->cd_lun] == 0) {		    dp->address[0] = (1 << 5) | DEFAULT_DEVICE_TYPE;		}		tmd->cd_data = dp;		tmd->cd_hflags |= CDFH_DATA_IN|CDFH_STSVALID;		SDprintk2("scsi_target(%s%d): %p (%p) length %d byte0 0x%x\n",		    bp->h.r_name, bp->h.r_inst, dp->address, dp, dp->length,		    inqdata[0] & 0xff);		tmd->cd_hflags |= CDFH_PRIVATE_0;	    }	} else {	    SDprintk2("scsi_target(%s%d): illegal field for inquiry data\n",		bp->h.r_name, bp->h.r_inst);	    spin_lock_irqsave(&scsi_target_lock, flags);	    add_sdata(ini, illfld);	    spin_unlock_irqrestore(&scsi_target_lock, flags);	    tmd->cd_hflags |= CDFH_SNSVALID;	}	goto doit;    }#if	0    if (tmd->cd_lun != 0) {        spin_lock_irqsave(&scsi_target_lock, flags);	add_sdata(ini, notrdy);	spin_unlock_irqrestore(&scsi_target_lock, flags);	tmd->cd_hflags |= CDFH_SNSVALID;	goto doit;    }#endif    if (tmd->cd_cdb[0] == REQUEST_SENSE) {	struct scatterlist *dp = NULL;	if (tmd->cd_totlen == 0)	    tmd->cd_totlen = tmd->cd_cdb[4];	if (tmd->cd_totlen != 0) {	    dp = (struct scatterlist *)		kmalloc(SGS_SIZE(QLTM_SENSELEN), GFP_ATOMIC|GFP_DMA);	    if (dp == NULL) {		printk("scsi_target_alloc: out of memory for sense data\n");		spin_lock_irqsave(&scsi_target_lock, flags);		add_sdata(ini, ifailure);		spin_unlock_irqrestore(&scsi_target_lock, flags);		tmd->cd_hflags |= CDFH_SNSVALID;	    } else {		if (ini->ini_sdata == NULL) {		    spin_lock_irqsave(&scsi_target_lock, flags);		    add_sdata(ini, nosense);		    spin_unlock_irqrestore(&scsi_target_lock, flags);		}		dp->alt_address = NULL;		dp->address = SGS_PAYLOAD(dp, char *);		dp->length = min(QLTM_SENSELEN, tmd->cd_totlen);		tmd->cd_xfrlen = dp->length;		memcpy(dp->address, ini->ini_sdata->sdata, QLTM_SENSELEN);		tmd->cd_data = dp;		tmd->cd_hflags |= CDFH_DATA_IN;		SDprintk2("sense data in scsi_target for %s%d: %p (%p) len %d, "		    "key/asc/ascq 0x%x/0x%x/0x%x\n", bp->h.r_name,		    bp->h.r_inst, dp->address, dp, dp->length,		    dp->address[2]&0xf, dp->address[12]&0xff,		    dp->address[13]);		tmd->cd_hflags |= CDFH_PRIVATE_0;	    }	}	tmd->cd_hflags |= CDFH_STSVALID;    } else if (tmd->cd_cdb[0] == TEST_UNIT_READY) {	tmd->cd_hflags |= CDFH_STSVALID;	if (ini->ini_sdata)		tmd->cd_hflags |= CDFH_SNSVALID;    } else {	tmd->cd_hflags |= CDFH_SNSVALID;	spin_lock_irqsave(&scsi_target_lock, flags);	add_sdata(ini, nolun);	spin_unlock_irqrestore(&scsi_target_lock, flags);    }    if ((tmd->cd_hflags & CDFH_SNSVALID) == 0) {	if (ini->ini_sdata) {	    tmd->cd_hflags |= CDFH_SNSVALID;	}    }doit:    tmd->cd_resid =  tmd->cd_totlen;    if (tmd->cd_hflags & CDFH_SNSVALID) {	tmd->cd_scsi_status = SCSI_CHECK;	tmd->cd_hflags |= CDFH_STSVALID;	memcpy(tmd->cd_sense, ini->ini_sdata->sdata, QLTM_SENSELEN);    }    SDprintk("INI%d-Lun%d: tag0x%x cdb0=0x%x totlen=%d ssts=0x%x hflags 0x%x\n",	(int) tmd->cd_iid, (int) tmd->cd_lun, tmd->cd_tagval,	tmd->cd_cdb[0] & 0xff, tmd->cd_totlen, tmd->cd_scsi_status,	tmd->cd_hflags);    (*bp->h.r_action)(QIN_TMD_CONT, tmd);}static inline voidscsi_target_ldfree(tmd_cmd_t *tmd){    if (tmd->cd_hflags & CDFH_PRIVATE_0) {	SDprintk("scsi_target: freeing tmd->cd_data %p\n", tmd->cd_data);	kfree(tmd->cd_data);	tmd->cd_hflags &= ~0x80;	tmd->cd_data = NULL;    }}voidscsi_target_handler(qact_e action, void *arg){    unsigned long flags;    bus_t *bp;    switch (action) {    case QOUT_HBA_REG:    {	tmd_cmd_t local;	hba_register_t local1;	spin_lock_irqsave(&scsi_target_lock, flags);	for (bp = busses; bp < &busses[MAX_BUS]; bp++) {	   if (bp->h.r_action == NULL) {		break;	   }	}	if (bp == &busses[MAX_BUS]) {	    printk("scsi_target: cannot register any more SCSI busses\n");	    break;	}	bp->h = *(hba_register_t *) arg;	bp->h.r_name[6] = 0;	bp->h.r_name[7] = 0;	spin_unlock_irqrestore(&scsi_target_lock, flags);	printk("scsi_target: registering %s%d\n", bp->h.r_name, bp->h.r_inst);	local.cd_hba = bp->h.r_identity;	local.cd_data = &local1;	local1.r_identity = bp;	local1.r_action = (void (*)(int, void *)) scsi_target_handler;	(*bp->h.r_action)(QIN_HBA_REG, &local);	break;    }    case QOUT_TMD_START:    {	tmd_cmd_t *tmd = arg;	tmd->cd_private = NULL;	spin_lock_irqsave(&scsi_target_lock, flags);	bp = bus_from_tmd(arg, 0);	if (bp == NULL) {	    printk("scsi_target: bogus QOUT_TMD_START (%p)\n", arg);	    spin_unlock_irqrestore(&scsi_target_lock, flags);	    break;	}	SDprintk2("scsi_target: TMD_START from %s%d\n",	    bp->h.r_name, bp->h.r_inst);	if (p_front) {	    p_last->cd_private = tmd;	} else {	    p_front = tmd;	}	p_last = tmd;	if (scsi_target_thread_notified == 0) {	    up(&scsi_thread_sleep_semaphore);	    scsi_target_thread_notified++;	}	spin_unlock_irqrestore(&scsi_target_lock, flags);	break;    }    case QOUT_TMD_DONE:    {	tmd_cmd_t *tmd = arg;	ini_t *nptr;	spin_lock_irqsave(&scsi_target_lock, flags);	bp = bus_from_tmd(tmd, 1);	if (bp == NULL) {	    printk("scsi_target: bogus QOUT_TMD_DONE(%p)\n", arg);	    spin_unlock_irqrestore(&scsi_target_lock, flags);	    break;	}	nptr = ini_from_tmd(bp, tmd);	SDprintk2("scsi_target: TMD_DONE from %s%d (0x%x)\n",	    bp->h.r_name, bp->h.r_inst, tmd->cd_lflags);	if (tmd->cd_hflags & CDFH_STSVALID) {	    if ((tmd->cd_lflags & CDFL_SENTSTATUS) == 0) {		if (tmd->cd_xfrlen) {		    SDprintk("scsi_target: data done, now do status\n");		    scsi_target_ldfree(tmd);		    tmd->cd_xfrlen = 0;		    spin_unlock_irqrestore(&scsi_target_lock, flags);		    (*bp->h.r_action)(QIN_TMD_CONT, tmd);		    break;		}		printk("scsi_target: already tried to send status\n");	        scsi_target_ldfree(tmd);		spin_unlock_irqrestore(&scsi_target_lock, flags);		(*bp->h.r_action)(QIN_TMD_FIN, arg);		break;	    }	}	/*	 * Was sense valid? Do we know whom we were talking to?	 * If so, and we sent sense, remove the Sense Data that's	 * current for this initiator.	 */	if (tmd->cd_hflags & CDFH_SNSVALID) {	    if (nptr) {		if (tmd->cd_lflags & CDFL_SENTSENSE) {		    rem_sdata(nptr);		}	    }	}	/*	 * Was this a REQUEST SENSE command? If so,	 * remove any sense data for this initiator	 * which we might have sent.	 *	 * XXX: Actually, we should remove it once	 * XXX: we make it data we would actually	 * XXX: send.	 */	if (tmd->cd_cdb[0] == REQUEST_SENSE) {	    if (nptr) {		rem_sdata(nptr);	    }	}	scsi_target_ldfree(tmd);	spin_unlock_irqrestore(&scsi_target_lock, flags);	(*bp->h.r_action)(QIN_TMD_FIN, arg);	break;    }    case QOUT_TEVENT:	spin_lock_irqsave(&scsi_target_lock, flags);	bp = bus_from_tmd(arg, 1);	if (bp == NULL) {	    spin_unlock_irqrestore(&scsi_target_lock, flags);	    printk("scsi_target: bogus QOUT_TMD_EVENT (%p)\n", arg);	    break;	}	SDprintk("scsi_target: TEVENT from %s%d\n",	    bp->h.r_name, bp->h.r_inst);	spin_unlock_irqrestore(&scsi_target_lock, flags);	break;    case QOUT_TMSG:	spin_lock_irqsave(&scsi_target_lock, flags);	bp = bus_from_tmd(arg, 1);	if (bp == NULL) {	    spin_unlock_irqrestore(&scsi_target_lock, flags);	    printk("scsi_target: bogus QOUT_TMD_MSG (%p)\n", arg);	    break;	}	printk("scsi_target: XXXX TMSG from %s%d\n",	    bp->h.r_name, bp->h.r_inst);	spin_unlock_irqrestore(&scsi_target_lock, flags);	break;    case QOUT_HBA_UNREG:	spin_lock_irqsave(&scsi_target_lock, flags);	bp = bus_from_tmd(arg, 0);	if (bp == NULL) {	    spin_unlock_irqrestore(&scsi_target_lock, flags);	    printk("scsi_target: bogus QOUT_HBA_UNREG (%p)\n", arg);	    break;	}	printk("scsi_target: unregistering %s%d\n",	    bp->h.r_name, bp->h.r_inst);	memset(bp, 0, sizeof (*bp));	spin_unlock_irqrestore(&scsi_target_lock, flags);	break;    default:	printk("scsi_target: action code %d (0x%x)?\n", action, action);	break;    }}static intscsi_target_thread(void *arg){    unsigned long flags;    siginitsetinv(&current->blocked, 0);    lock_kernel();    daemonize();    sprintf(current->comm, "scsi_target_thread");    unlock_kernel();    up(&scsi_thread_entry_exit_semaphore);    SDprintk("scsi_target_thread starting\n");    while (scsi_target_thread_exit == 0) {	bus_t *bp;	tmd_cmd_t *tp;	SDprintk2("scsi_task_thread sleeping\n");	down(&scsi_thread_sleep_semaphore);	SDprintk2("scsi_task_thread running\n");	spin_lock_irqsave(&scsi_target_lock, flags);        scsi_target_thread_notified = 0;	if ((tp = p_front) != NULL) {		p_last = p_front = NULL;	}	spin_unlock_irqrestore(&scsi_target_lock, flags);	while (tp) {	    tmd_cmd_t *active;	    active = tp;	    tp = active->cd_private;	    active->cd_private = NULL;	    bp = bus_from_tmd(active, 1);	    if (bp == NULL) {		panic("Lost the Bus?");	    }	    scsi_target_start_cmd(active, bp);	}    }    SDprintk("scsi_target_thread exiting\n");    up(&scsi_thread_entry_exit_semaphore);    return(0);}static intscsi_target_endis(char *hba_name_unit, int channel, int target, int lun, int en){    tmd_cmd_t ec;    bus_t *bp;/* * XXX: yes, there is a race condition here where the bus can * XXX: go away. But in order to solve it, we have to make the * XXX: bus structure stay around while we call into the HBA * XXX: anyway, so fooey,. */    bp = bus_from_name(hba_name_unit);    if (bp == NULL) {	return (-ENXIO);    }    if (channel > 1 || channel < 0 || lun < 0 || lun >= MAX_LUN) {	return (-EINVAL);    }    memset(&ec, 0, sizeof (ec));    ec.cd_hba = bp->h.r_identity;    ec.cd_bus = channel;    ec.cd_iid = target;    ec.cd_lun = lun;    (*bp->h.r_action)(en? QIN_ENABLE : QIN_DISABLE, &ec);    if (ec.cd_lflags & CDFL_ERROR) {	return (ec.cd_error);    } else {	bp->luns[channel][lun] = (en != 0);	return (0);    }}#ifdef	MODULE#if	LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)EXPORT_SYMBOL_NOVERS(scsi_target_handler);MODULE_PARM(scsi_tdebug, "i");#endifint init_module(void){    int r = scsi_target_init();    if (r == 0) {	for (r = N_SENSE_BUFS; r > 0; r--) {	    sdata_t *t = kmalloc(sizeof (sdata_t), GFP_KERNEL);	    if (t) {		t->next = sdp;		sdp = t;	    }	}    }    return (r);}void cleanup_module(void){    int i;    scsi_target_thread_exit = 1;    up(&scsi_thread_sleep_semaphore);    down(&scsi_thread_entry_exit_semaphore);    for (i = 0; i < MAX_BUS; i++) {	if (busses[i].h.r_action) {	    int j;	    tmd_cmd_t tmd;	    tmd.cd_hba = busses[i].h.r_identity;	    (*busses[i].h.r_action)(QIN_HBA_UNREG, &tmd);	    busses[i].h.r_action = NULL;	    for (j = 0; j < HASH_WIDTH; j++) {		ini_t *nptr = busses[i].list[j];		while (nptr) {		    ini_t *next = nptr->ini_next;		    kfree(nptr);		    nptr = next;		}	    }	}    }    while (sdp) {	sdata_t *t = sdp->next;	kfree(sdp);	sdp = t;    }#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) && defined(CONFIG_PROC_FS)    if (st) {	remove_proc_entry("scsi/scsi_target", 0);    }#endif    if (misc_deregister(&scsi_target_dev)) {	printk("scsi_target: warning- could not deregister\n");    }}#endif/* * mode: c * 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 * End: */

⌨️ 快捷键说明

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