亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? scsi_tgt_if.c

?? linux 內核源代碼
?? C
字號:
/* * SCSI target kernel/user interface functions * * Copyright (C) 2005 FUJITA Tomonori <tomof@acm.org> * Copyright (C) 2005 Mike Christie <michaelc@cs.wisc.edu> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA */#include <linux/miscdevice.h>#include <linux/file.h>#include <net/tcp.h>#include <scsi/scsi.h>#include <scsi/scsi_cmnd.h>#include <scsi/scsi_device.h>#include <scsi/scsi_host.h>#include <scsi/scsi_tgt.h>#include <scsi/scsi_tgt_if.h>#include <asm/cacheflush.h>#include "scsi_tgt_priv.h"#if TGT_RING_SIZE < PAGE_SIZE#  define TGT_RING_SIZE PAGE_SIZE#endif#define TGT_RING_PAGES (TGT_RING_SIZE >> PAGE_SHIFT)#define TGT_EVENT_PER_PAGE (PAGE_SIZE / sizeof(struct tgt_event))#define TGT_MAX_EVENTS (TGT_EVENT_PER_PAGE * TGT_RING_PAGES)struct tgt_ring {	u32 tr_idx;	unsigned long tr_pages[TGT_RING_PAGES];	spinlock_t tr_lock;};/* tx_ring : kernel->user, rx_ring : user->kernel */static struct tgt_ring tx_ring, rx_ring;static DECLARE_WAIT_QUEUE_HEAD(tgt_poll_wait);static inline void tgt_ring_idx_inc(struct tgt_ring *ring){	if (ring->tr_idx == TGT_MAX_EVENTS - 1)		ring->tr_idx = 0;	else		ring->tr_idx++;}static struct tgt_event *tgt_head_event(struct tgt_ring *ring, u32 idx){	u32 pidx, off;	pidx = idx / TGT_EVENT_PER_PAGE;	off = idx % TGT_EVENT_PER_PAGE;	return (struct tgt_event *)		(ring->tr_pages[pidx] + sizeof(struct tgt_event) * off);}static int tgt_uspace_send_event(u32 type, struct tgt_event *p){	struct tgt_event *ev;	struct tgt_ring *ring = &tx_ring;	unsigned long flags;	int err = 0;	spin_lock_irqsave(&ring->tr_lock, flags);	ev = tgt_head_event(ring, ring->tr_idx);	if (!ev->hdr.status)		tgt_ring_idx_inc(ring);	else		err = -BUSY;	spin_unlock_irqrestore(&ring->tr_lock, flags);	if (err)		return err;	memcpy(ev, p, sizeof(*ev));	ev->hdr.type = type;	mb();	ev->hdr.status = 1;	flush_dcache_page(virt_to_page(ev));	wake_up_interruptible(&tgt_poll_wait);	return 0;}int scsi_tgt_uspace_send_cmd(struct scsi_cmnd *cmd, u64 itn_id,			     struct scsi_lun *lun, u64 tag){	struct Scsi_Host *shost = scsi_tgt_cmd_to_host(cmd);	struct tgt_event ev;	int err;	memset(&ev, 0, sizeof(ev));	ev.p.cmd_req.host_no = shost->host_no;	ev.p.cmd_req.itn_id = itn_id;	ev.p.cmd_req.data_len = cmd->request_bufflen;	memcpy(ev.p.cmd_req.scb, cmd->cmnd, sizeof(ev.p.cmd_req.scb));	memcpy(ev.p.cmd_req.lun, lun, sizeof(ev.p.cmd_req.lun));	ev.p.cmd_req.attribute = cmd->tag;	ev.p.cmd_req.tag = tag;	dprintk("%p %d %u %x %llx\n", cmd, shost->host_no,		ev.p.cmd_req.data_len, cmd->tag,		(unsigned long long) ev.p.cmd_req.tag);	err = tgt_uspace_send_event(TGT_KEVENT_CMD_REQ, &ev);	if (err)		eprintk("tx buf is full, could not send\n");	return err;}int scsi_tgt_uspace_send_status(struct scsi_cmnd *cmd, u64 itn_id, u64 tag){	struct Scsi_Host *shost = scsi_tgt_cmd_to_host(cmd);	struct tgt_event ev;	int err;	memset(&ev, 0, sizeof(ev));	ev.p.cmd_done.host_no = shost->host_no;	ev.p.cmd_done.itn_id = itn_id;	ev.p.cmd_done.tag = tag;	ev.p.cmd_done.result = cmd->result;	dprintk("%p %d %llu %u %x\n", cmd, shost->host_no,		(unsigned long long) ev.p.cmd_req.tag,		ev.p.cmd_req.data_len, cmd->tag);	err = tgt_uspace_send_event(TGT_KEVENT_CMD_DONE, &ev);	if (err)		eprintk("tx buf is full, could not send\n");	return err;}int scsi_tgt_uspace_send_tsk_mgmt(int host_no, u64 itn_id, int function,				  u64 tag, struct scsi_lun *scsilun, void *data){	struct tgt_event ev;	int err;	memset(&ev, 0, sizeof(ev));	ev.p.tsk_mgmt_req.host_no = host_no;	ev.p.tsk_mgmt_req.itn_id = itn_id;	ev.p.tsk_mgmt_req.function = function;	ev.p.tsk_mgmt_req.tag = tag;	memcpy(ev.p.tsk_mgmt_req.lun, scsilun, sizeof(ev.p.tsk_mgmt_req.lun));	ev.p.tsk_mgmt_req.mid = (u64) (unsigned long) data;	dprintk("%d %x %llx %llx\n", host_no, function, (unsigned long long) tag,		(unsigned long long) ev.p.tsk_mgmt_req.mid);	err = tgt_uspace_send_event(TGT_KEVENT_TSK_MGMT_REQ, &ev);	if (err)		eprintk("tx buf is full, could not send\n");	return err;}int scsi_tgt_uspace_send_it_nexus_request(int host_no, u64 itn_id,					  int function, char *initiator_id){	struct tgt_event ev;	int err;	memset(&ev, 0, sizeof(ev));	ev.p.it_nexus_req.host_no = host_no;	ev.p.it_nexus_req.function = function;	ev.p.it_nexus_req.itn_id = itn_id;	if (initiator_id)		strncpy(ev.p.it_nexus_req.initiator_id, initiator_id,			sizeof(ev.p.it_nexus_req.initiator_id));	dprintk("%d %x %llx\n", host_no, function, (unsigned long long)itn_id);	err = tgt_uspace_send_event(TGT_KEVENT_IT_NEXUS_REQ, &ev);	if (err)		eprintk("tx buf is full, could not send\n");	return err;}static int event_recv_msg(struct tgt_event *ev){	int err = 0;	switch (ev->hdr.type) {	case TGT_UEVENT_CMD_RSP:		err = scsi_tgt_kspace_exec(ev->p.cmd_rsp.host_no,					   ev->p.cmd_rsp.itn_id,					   ev->p.cmd_rsp.result,					   ev->p.cmd_rsp.tag,					   ev->p.cmd_rsp.uaddr,					   ev->p.cmd_rsp.len,					   ev->p.cmd_rsp.sense_uaddr,					   ev->p.cmd_rsp.sense_len,					   ev->p.cmd_rsp.rw);		break;	case TGT_UEVENT_TSK_MGMT_RSP:		err = scsi_tgt_kspace_tsk_mgmt(ev->p.tsk_mgmt_rsp.host_no,					       ev->p.tsk_mgmt_rsp.itn_id,					       ev->p.tsk_mgmt_rsp.mid,					       ev->p.tsk_mgmt_rsp.result);		break;	case TGT_UEVENT_IT_NEXUS_RSP:		err = scsi_tgt_kspace_it_nexus_rsp(ev->p.it_nexus_rsp.host_no,						   ev->p.it_nexus_rsp.itn_id,						   ev->p.it_nexus_rsp.result);		break;	default:		eprintk("unknown type %d\n", ev->hdr.type);		err = -EINVAL;	}	return err;}static ssize_t tgt_write(struct file *file, const char __user * buffer,			 size_t count, loff_t * ppos){	struct tgt_event *ev;	struct tgt_ring *ring = &rx_ring;	while (1) {		ev = tgt_head_event(ring, ring->tr_idx);		/* do we need this? */		flush_dcache_page(virt_to_page(ev));		if (!ev->hdr.status)			break;		tgt_ring_idx_inc(ring);		event_recv_msg(ev);		ev->hdr.status = 0;	};	return count;}static unsigned int tgt_poll(struct file * file, struct poll_table_struct *wait){	struct tgt_event *ev;	struct tgt_ring *ring = &tx_ring;	unsigned long flags;	unsigned int mask = 0;	u32 idx;	poll_wait(file, &tgt_poll_wait, wait);	spin_lock_irqsave(&ring->tr_lock, flags);	idx = ring->tr_idx ? ring->tr_idx - 1 : TGT_MAX_EVENTS - 1;	ev = tgt_head_event(ring, idx);	if (ev->hdr.status)		mask |= POLLIN | POLLRDNORM;	spin_unlock_irqrestore(&ring->tr_lock, flags);	return mask;}static int uspace_ring_map(struct vm_area_struct *vma, unsigned long addr,			   struct tgt_ring *ring){	int i, err;	for (i = 0; i < TGT_RING_PAGES; i++) {		struct page *page = virt_to_page(ring->tr_pages[i]);		err = vm_insert_page(vma, addr, page);		if (err)			return err;		addr += PAGE_SIZE;	}	return 0;}static int tgt_mmap(struct file *filp, struct vm_area_struct *vma){	unsigned long addr;	int err;	if (vma->vm_pgoff)		return -EINVAL;	if (vma->vm_end - vma->vm_start != TGT_RING_SIZE * 2) {		eprintk("mmap size must be %lu, not %lu \n",			TGT_RING_SIZE * 2, vma->vm_end - vma->vm_start);		return -EINVAL;	}	addr = vma->vm_start;	err = uspace_ring_map(vma, addr, &tx_ring);	if (err)		return err;	err = uspace_ring_map(vma, addr + TGT_RING_SIZE, &rx_ring);	return err;}static int tgt_open(struct inode *inode, struct file *file){	tx_ring.tr_idx = rx_ring.tr_idx = 0;	return 0;}static const struct file_operations tgt_fops = {	.owner		= THIS_MODULE,	.open		= tgt_open,	.poll		= tgt_poll,	.write		= tgt_write,	.mmap		= tgt_mmap,};static struct miscdevice tgt_miscdev = {	.minor = MISC_DYNAMIC_MINOR,	.name = "tgt",	.fops = &tgt_fops,};static void tgt_ring_exit(struct tgt_ring *ring){	int i;	for (i = 0; i < TGT_RING_PAGES; i++)		free_page(ring->tr_pages[i]);}static int tgt_ring_init(struct tgt_ring *ring){	int i;	spin_lock_init(&ring->tr_lock);	for (i = 0; i < TGT_RING_PAGES; i++) {		ring->tr_pages[i] = get_zeroed_page(GFP_KERNEL);		if (!ring->tr_pages[i]) {			eprintk("out of memory\n");			return -ENOMEM;		}	}	return 0;}void scsi_tgt_if_exit(void){	tgt_ring_exit(&tx_ring);	tgt_ring_exit(&rx_ring);	misc_deregister(&tgt_miscdev);}int scsi_tgt_if_init(void){	int err;	err = tgt_ring_init(&tx_ring);	if (err)		return err;	err = tgt_ring_init(&rx_ring);	if (err)		goto free_tx_ring;	err = misc_register(&tgt_miscdev);	if (err)		goto free_rx_ring;	return 0;free_rx_ring:	tgt_ring_exit(&rx_ring);free_tx_ring:	tgt_ring_exit(&tx_ring);	return err;}

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
日韩黄色片在线观看| 国产成人精品免费看| 玖玖九九国产精品| eeuss鲁片一区二区三区在线观看| 欧美性大战久久| 欧美国产一区在线| 日韩精彩视频在线观看| 99re在线精品| 久久色成人在线| 五月天激情小说综合| 91一区二区三区在线观看| 久久综合九色综合欧美亚洲| 视频一区二区欧美| 色综合久久天天| 亚洲午夜视频在线观看| www.在线欧美| 久久久久久久综合色一本| 五月天一区二区三区| 色天天综合久久久久综合片| 国产精品理论片| 国产精品一卡二卡| 精品国产一区二区三区av性色| 亚洲国产精品视频| 日本久久一区二区三区| 中文字幕一区二区三| 极品美女销魂一区二区三区 | 一区二区三区欧美亚洲| 国产成人在线色| 国产午夜精品福利| 韩国女主播成人在线观看| 日韩精品一区二区在线观看| 青青草原综合久久大伊人精品| 欧美日韩三级视频| 亚洲va韩国va欧美va精品| 欧美熟乱第一页| 午夜精品国产更新| 制服丝袜av成人在线看| 日本不卡中文字幕| 日韩精品一区在线| 国产一区二区三区久久悠悠色av| 欧美变态口味重另类| 国产一区二区主播在线| 国产亚洲精品资源在线26u| 国产精品自产自拍| 国产精品女上位| 色94色欧美sute亚洲13| 亚洲18影院在线观看| 91精品福利在线一区二区三区| 日韩av中文字幕一区二区三区| 91精品国产综合久久久久久久| 人人爽香蕉精品| 久久品道一品道久久精品| 成人黄色综合网站| 亚洲精选视频免费看| 欧美色窝79yyyycom| 韩国女主播一区| 亚洲欧洲韩国日本视频| 欧美精品久久天天躁| 久久99蜜桃精品| 中文字幕在线免费不卡| 欧美日韩一级黄| 国产精品一区二区久久不卡| 亚洲天天做日日做天天谢日日欢| 在线观看日产精品| 国产一区二区在线免费观看| 亚洲日本va午夜在线影院| 717成人午夜免费福利电影| 国产乱人伦精品一区二区在线观看| 国产日产欧产精品推荐色| 99久久国产综合精品麻豆| 日韩电影一二三区| 亚洲欧洲一区二区三区| 日韩三级高清在线| 91在线国产福利| 久久91精品国产91久久小草| 亚洲伦理在线精品| 日韩精品一区在线| 在线免费观看视频一区| 盗摄精品av一区二区三区| 天天综合天天综合色| 欧美国产精品久久| 日韩一区二区三| 色94色欧美sute亚洲线路二| 国产老妇另类xxxxx| 亚洲丰满少妇videoshd| 国产精品久久久久久久裸模| 欧美不卡在线视频| 欧美日韩午夜影院| 91美女在线观看| 国产精品自拍av| 久久99精品久久久久| 亚洲成人免费在线观看| 中文字幕中文在线不卡住| 欧美精品一区二区三区很污很色的| 欧美少妇一区二区| 91亚洲国产成人精品一区二三| 国产精品一区二区视频| 蜜臀av在线播放一区二区三区 | 欧美mv日韩mv国产| 欧美日韩五月天| 欧美唯美清纯偷拍| 91视视频在线观看入口直接观看www | 欧美午夜影院一区| 97se亚洲国产综合自在线观| 国产精品一级在线| 激情小说亚洲一区| 蜜臀久久99精品久久久画质超高清 | 九一久久久久久| 天天综合网天天综合色| 亚洲高清久久久| 亚洲一区二区三区四区中文字幕 | 久久久久久99精品| 久久久久久影视| 国产日韩欧美电影| 国产女人aaa级久久久级| 精品av久久707| 欧美成人三级电影在线| 精品成人a区在线观看| 久久蜜桃av一区二区天堂| 亚洲精品在线电影| 久久久国际精品| 国产精品狼人久久影院观看方式| 国产精品毛片久久久久久久| 中文字幕中文字幕在线一区| 亚洲免费看黄网站| 亚洲福利一区二区三区| 日韩电影免费一区| 精品一区二区三区免费观看| 国产成人综合自拍| 99精品国产视频| 欧美日韩高清一区| 精品久久国产字幕高潮| 国产亚洲女人久久久久毛片| 国产精品久久午夜夜伦鲁鲁| 亚洲精品成人悠悠色影视| 亚洲成av人片在线| 九九热在线视频观看这里只有精品| 久99久精品视频免费观看| 成人av在线播放网址| 欧美专区亚洲专区| 精品国产乱码91久久久久久网站| 久久精品一区二区三区不卡| 中文字幕一区二区三| 天堂va蜜桃一区二区三区漫画版| 精品一区二区三区在线播放视频| 国产成人自拍网| 欧美性受xxxx黑人xyx性爽| 日韩一区二区三| 中文字幕在线不卡一区二区三区| 亚洲最大色网站| 国产一区在线视频| 欧洲激情一区二区| 久久综合九色综合欧美98| 亚洲激情自拍偷拍| 精品亚洲国产成人av制服丝袜 | 亚洲图片另类小说| 日本午夜精品一区二区三区电影 | 欧美性猛交一区二区三区精品| 日韩精品在线一区| 亚洲综合精品久久| 国产91在线|亚洲| 6080亚洲精品一区二区| 国产精品免费久久| 麻豆视频一区二区| 91国偷自产一区二区使用方法| 日韩欧美一级片| 亚洲444eee在线观看| a亚洲天堂av| 精品日韩欧美在线| 日韩激情在线观看| 欧美性大战久久久| 国产精品不卡在线| 国产传媒一区在线| 精品国免费一区二区三区| 亚洲伊人伊色伊影伊综合网| 欧美在线一二三| 国产精品色哟哟网站| 蜜桃一区二区三区四区| 欧美色视频在线| 亚洲人xxxx| 99视频精品全部免费在线| 久久久三级国产网站| 蜜桃av噜噜一区| 日韩一区二区三区在线观看| 一区二区三区四区亚洲| 成人福利视频网站| 国产欧美一区二区在线| 久久成人综合网| 欧美一区中文字幕| 视频一区二区中文字幕| 欧美日韩一级黄| 性做久久久久久久免费看| 欧美体内she精高潮| 亚洲在线视频一区| 欧美色倩网站大全免费| 亚洲综合999| 欧美三级电影网| 亚洲成人777| 欧美一区二区私人影院日本| 五月婷婷久久综合|