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

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

?? video-buf.c

?? 這是一個市場上常見電視卡的驅動程序源代碼
?? C
?? 第 1 頁 / 共 3 頁
字號:
/*
 * generic helper functions for video4linux capture buffers, to handle
 * memory management and PCI DMA.  Right now bttv + saa7134 use it.
 *
 * The functions expect the hardware being able to scatter gatter
 * (i.e. the buffers are not linear in physical memory, but fragmented
 * into PAGE_SIZE chunks).  They also assume the driver does not need
 * to touch the video data (thus it is probably not useful for USB as
 * data often must be uncompressed by the drivers).
 * 
 * (c) 2001,02 Gerd Knorr <kraxel@bytesex.org>
 *
 * 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.
 */

#include <linux/version.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/vmalloc.h>
#include <linux/pagemap.h>
#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/interrupt.h>
#include <asm/page.h>
#include <asm/pgtable.h>

#ifndef TryLockPage
# include "linux/page-flags.h"
# define TryLockPage TestSetPageLocked
#endif

#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,64)
#include "video-buf.h"
#else
#include <media/video-buf.h>
#endif

static int debug = 0;

MODULE_DESCRIPTION("helper module to manage video4linux pci dma buffers");
MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
MODULE_LICENSE("GPL");
MODULE_PARM(debug,"i");

#define dprintk(level, fmt, arg...)	if (debug >= level) \
	printk(KERN_DEBUG "vbuf: " fmt , ## arg)

struct scatterlist*
videobuf_vmalloc_to_sg(unsigned char *virt, int nr_pages)
{
	struct scatterlist *sglist;
	struct page *pg;
	int i;

	sglist = kmalloc(sizeof(struct scatterlist)*nr_pages, GFP_KERNEL);
	if (NULL == sglist)
		return NULL;
	memset(sglist,0,sizeof(struct scatterlist)*nr_pages);
	for (i = 0; i < nr_pages; i++, virt += PAGE_SIZE) {
		pg = vmalloc_to_page(virt);
		if (NULL == pg)
			goto err;
		if (PageHighMem(pg))
			BUG();
		sglist[i].page   = pg;
		sglist[i].length = PAGE_SIZE;
	}
	return sglist;
	
 err:
	kfree(sglist);
	return NULL;
}

struct scatterlist*
videobuf_pages_to_sg(struct page **pages, int nr_pages, int offset)
{
	struct scatterlist *sglist;
	int i = 0;

	if (NULL == pages[0])
		return NULL;
	sglist = kmalloc(sizeof(*sglist) * nr_pages, GFP_KERNEL);
	if (NULL == sglist)
		return NULL;
	memset(sglist, 0, sizeof(*sglist) * nr_pages);

	if (NULL == pages[0])
		goto nopage;
	if (PageHighMem(pages[0]))
		/* DMA to highmem pages might not work */
		goto highmem;
	sglist[0].page   = pages[0];
	sglist[0].offset = offset;
	sglist[0].length = PAGE_SIZE - offset;
	for (i = 1; i < nr_pages; i++) {
		if (NULL == pages[i])
			goto nopage;
		if (PageHighMem(pages[i]))
			goto highmem;
		sglist[i].page   = pages[i];
		sglist[i].length = PAGE_SIZE;
	}
	return sglist;

 nopage:
	dprintk(2,"sgl: oops - no page\n");
	kfree(sglist);
	return NULL;

 highmem:
	dprintk(2,"sgl: oops - highmem page\n");
	kfree(sglist);
	return NULL;
}

int videobuf_lock(struct page **pages, int nr_pages)
{
	int i;

	dprintk(2,"lock start ...\n");
	for (i = 0; i < nr_pages; i++)
		if (TryLockPage(pages[i]))
			goto err;
	dprintk(2,"lock ok [%d pages]\n",nr_pages);
	return 0;

 err:
	dprintk(2,"lock failed, unlock ...\n");
	while (i > 0)
		unlock_page(pages[--i]);
	dprintk(2,"lock quit\n");
	return -EINVAL;
}

int videobuf_unlock(struct page **pages, int nr_pages)
{
	int i;

	dprintk(2,"unlock start ...\n");
	for (i = 0; i < nr_pages; i++)
		unlock_page(pages[i]);
	dprintk(2,"unlock ok [%d pages]\n",nr_pages);
	return 0;
}

/* --------------------------------------------------------------------- */

int videobuf_dma_init_user(struct videobuf_dmabuf *dma, int direction,
			   unsigned long data, unsigned long size)
{
	unsigned long first,last;
	int err, rw = 0;

	dma->direction = direction;
	switch (dma->direction) {
	case PCI_DMA_FROMDEVICE: rw = READ;  break;
	case PCI_DMA_TODEVICE:   rw = WRITE; break;
	default:                 BUG();
	}

	first = (data          & PAGE_MASK) >> PAGE_SHIFT;
	last  = ((data+size-1) & PAGE_MASK) >> PAGE_SHIFT;
	dma->offset   = data & ~PAGE_MASK;
	dma->nr_pages = last-first+1;
	dma->pages = kmalloc(dma->nr_pages * sizeof(struct page*),
			     GFP_KERNEL);
	if (NULL == dma->pages)
		return -ENOMEM;
	dprintk(1,"init user [0x%lx+0x%lx => %d pages]\n",
		data,size,dma->nr_pages);

	down_read(&current->mm->mmap_sem);
        err = get_user_pages(current,current->mm,
			     data & PAGE_MASK, dma->nr_pages,
			     rw == READ, 1, /* force */
			     dma->pages, NULL);
	up_read(&current->mm->mmap_sem);
	if (err != dma->nr_pages) {
		dma->nr_pages = (err >= 0) ? err : 0;
		dprintk(1,"get_user_pages: err=%d [%d]\n",err,dma->nr_pages);
		return err < 0 ? err : -EINVAL;
	}
	return 0;
}

int videobuf_dma_init_kernel(struct videobuf_dmabuf *dma, int direction,
			     int nr_pages)
{
	dprintk(1,"init kernel [%d pages]\n",nr_pages);
	dma->direction = direction;
	dma->vmalloc = vmalloc_32(nr_pages << PAGE_SHIFT);
	if (NULL == dma->vmalloc) {
		dprintk(1,"vmalloc_32(%d pages) failed\n",nr_pages);
		return -ENOMEM;
	}
	memset(dma->vmalloc,0,nr_pages << PAGE_SHIFT);
	dma->nr_pages = nr_pages;
	return 0;
}

int videobuf_dma_init_overlay(struct videobuf_dmabuf *dma, int direction,
			      dma_addr_t addr, int nr_pages)
{
	dprintk(1,"init overlay [%d pages @ bus 0x%lx]\n",
		nr_pages,(unsigned long)addr);
	dma->direction = direction;
	if (0 == addr)
		return -EINVAL;

	dma->bus_addr = addr;
	dma->nr_pages = nr_pages;
	return 0;
}

int videobuf_dma_pci_map(struct pci_dev *dev, struct videobuf_dmabuf *dma)
{
	int err;

	if (0 == dma->nr_pages)
		BUG();
	
	if (dma->pages) {
		if (0 != (err = videobuf_lock(dma->pages, dma->nr_pages))) {
			dprintk(1,"videobuf_lock: %d\n",err);
			return err;
		}
		dma->sglist = videobuf_pages_to_sg(dma->pages, dma->nr_pages,
						   dma->offset);
		if (NULL == dma->sglist)
			videobuf_unlock(dma->pages, dma->nr_pages);
	}
	if (dma->vmalloc) {
		dma->sglist = videobuf_vmalloc_to_sg
			(dma->vmalloc,dma->nr_pages);
	}
	if (dma->bus_addr) {
		dma->sglist = kmalloc(sizeof(struct scatterlist), GFP_KERNEL);
		if (NULL != dma->sglist) {
			dma->sglen  = 1;
			sg_dma_address(&dma->sglist[0]) = dma->bus_addr & PAGE_MASK;
			dma->sglist[0].offset           = dma->bus_addr & ~PAGE_MASK;
			sg_dma_len(&dma->sglist[0])     = dma->nr_pages * PAGE_SIZE;
		}
	}
	if (NULL == dma->sglist) {
		dprintk(1,"scatterlist is NULL\n");
		return -ENOMEM;
	}

	if (!dma->bus_addr)
		dma->sglen = pci_map_sg(dev,dma->sglist,dma->nr_pages,
					dma->direction);
	return 0;
}

int videobuf_dma_pci_sync(struct pci_dev *dev, struct videobuf_dmabuf *dma)
{
	if (!dma->sglen)
		BUG();

	if (!dma->bus_addr)
		pci_dma_sync_sg(dev,dma->sglist,dma->nr_pages,dma->direction);
	return 0;
}

int videobuf_dma_pci_unmap(struct pci_dev *dev, struct videobuf_dmabuf *dma)
{
	if (!dma->sglen)
		return 0;

	if (!dma->bus_addr)
		pci_unmap_sg(dev,dma->sglist,dma->nr_pages,dma->direction);
	kfree(dma->sglist);
	dma->sglist = NULL;
	dma->sglen = 0;
	if (dma->pages)
		videobuf_unlock(dma->pages, dma->nr_pages);
	return 0;
}

int videobuf_dma_free(struct videobuf_dmabuf *dma)
{
	if (dma->sglen)
		BUG();

	if (dma->pages) {
		int i;
		for (i=0; i < dma->nr_pages; i++)
			page_cache_release(dma->pages[i]);
		kfree(dma->pages);
		dma->pages = NULL;
	}
	if (dma->vmalloc) {
		vfree(dma->vmalloc);
		dma->vmalloc = NULL;
	}
	if (dma->bus_addr) {
		dma->bus_addr = 0;
	}
	dma->direction = PCI_DMA_NONE;
	return 0;
}

/* --------------------------------------------------------------------- */

void* videobuf_alloc(unsigned int size)
{
	struct videobuf_buffer *vb;

	vb = kmalloc(size,GFP_KERNEL);
	if (NULL != vb) {
		memset(vb,0,size);
		init_waitqueue_head(&vb->done);
	}
	return vb;
}

int videobuf_waiton(struct videobuf_buffer *vb, int non_blocking, int intr)
{
	int retval = 0;
	DECLARE_WAITQUEUE(wait, current);
	
	add_wait_queue(&vb->done, &wait);
	while (vb->state == STATE_ACTIVE || vb->state == STATE_QUEUED) {
		if (non_blocking) {
			retval = -EAGAIN;
			break;
		}
		set_current_state(intr  ? TASK_INTERRUPTIBLE
					: TASK_UNINTERRUPTIBLE);
		if (vb->state == STATE_ACTIVE || vb->state == STATE_QUEUED)
			schedule();
		set_current_state(TASK_RUNNING);
		if (intr && signal_pending(current)) {
			dprintk(1,"buffer waiton: -EINTR\n");
			retval = -EINTR;
			break;
		}
	}
	remove_wait_queue(&vb->done, &wait);
	return retval;
}

int
videobuf_iolock(struct pci_dev *pci, struct videobuf_buffer *vb,
		struct v4l2_framebuffer *fbuf)
{
	int err,pages;
	dma_addr_t bus;

	switch (vb->memory) {
	case V4L2_MEMORY_MMAP:
	case V4L2_MEMORY_USERPTR:
		if (0 == vb->baddr) {
			/* no userspace addr -- kernel bounce buffer */
			pages = PAGE_ALIGN(vb->size) >> PAGE_SHIFT;
			err = videobuf_dma_init_kernel(&vb->dma,PCI_DMA_FROMDEVICE,
						       pages);
			if (0 != err)
				return err;
		} else {
			/* dma directly to userspace */
			err = videobuf_dma_init_user(&vb->dma,PCI_DMA_FROMDEVICE,
						     vb->baddr,vb->bsize);
			if (0 != err)
				return err;
		}
		break;
	case V4L2_MEMORY_OVERLAY:
		if (NULL == fbuf)
			return -EINVAL;
		/* FIXME: need sanity checks for vb->boff */
		bus   = (dma_addr_t)fbuf->base + vb->boff;
		pages = PAGE_ALIGN(vb->size) >> PAGE_SHIFT;
		err = videobuf_dma_init_overlay(&vb->dma,PCI_DMA_FROMDEVICE,
						bus, pages);
		if (0 != err)
			return err;
		break;
	default:
		BUG();
	}
	err = videobuf_dma_pci_map(pci,&vb->dma);
	if (0 != err)
		return err;
		
	return 0;
}

/* --------------------------------------------------------------------- */

void
videobuf_queue_init(struct videobuf_queue *q,
		    struct videobuf_queue_ops *ops,
		    struct pci_dev *pci,
		    spinlock_t *irqlock,
		    enum v4l2_buf_type type,
		    enum v4l2_field field,
		    unsigned int msize)
{
	memset(q,0,sizeof(*q));

	q->irqlock = irqlock;
	q->pci     = pci;
	q->type    = type;
	q->field   = field;
	q->msize   = msize;
	q->ops     = ops;

	init_MUTEX(&q->lock);
	INIT_LIST_HEAD(&q->stream);
}

int 
videobuf_queue_is_busy(struct videobuf_queue *q)
{
	int i;
	
	if (q->streaming) {
		dprintk(1,"busy: streaming active\n");
		return 1;
	}
	if (q->reading) {
		dprintk(1,"busy: pending read #1\n");
		return 1;
	}

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
国产精品18久久久久久久久久久久 | 欧美国产丝袜视频| 中文字幕日韩精品一区| 日韩成人一级片| jvid福利写真一区二区三区| 欧美精品v国产精品v日韩精品| 日本一区二区三区免费乱视频| 亚洲午夜久久久久| www.亚洲精品| 国产午夜精品一区二区| 香蕉影视欧美成人| 色婷婷狠狠综合| 亚洲成人免费影院| 成人av网址在线观看| 日韩欧美中文一区| 亚洲午夜国产一区99re久久| 99久久精品国产一区二区三区| 久久亚洲影视婷婷| 久久成人综合网| 91麻豆精品国产自产在线观看一区 | 一区二区三区不卡视频在线观看| 国产精品99久久久久久似苏梦涵| 日韩美女视频在线| 人人精品人人爱| 3751色影院一区二区三区| 亚洲国产毛片aaaaa无费看| 91麻豆蜜桃一区二区三区| 国产精品美女久久久久久久| 国产91丝袜在线播放| 久久久久久毛片| 国产精品99久久久| 久久精品夜色噜噜亚洲a∨| 韩国女主播一区| 久久综合九色综合久久久精品综合| 日韩中文字幕麻豆| 麻豆免费看一区二区三区| 成人禁用看黄a在线| 欧美激情在线观看视频免费| 国产精品自拍一区| 国产精品亲子伦对白| 床上的激情91.| 亚洲色图制服诱惑| 色婷婷精品大在线视频| 亚洲制服丝袜av| 欧美肥大bbwbbw高潮| 免费的国产精品| 久久精品亚洲一区二区三区浴池| 岛国一区二区三区| 一区二区三区视频在线看| 欧美性色综合网| 蓝色福利精品导航| 国产精品丝袜在线| 欧美午夜一区二区三区| 日韩精品视频网| 国产三区在线成人av| 色婷婷综合久久| 奇米影视在线99精品| 欧美精品一区二区三区视频| 成人午夜看片网址| 亚洲一区免费视频| 欧美xxxx在线观看| 国产不卡在线视频| 无吗不卡中文字幕| 久久精品夜色噜噜亚洲a∨| 色综合久久天天综合网| 蜜桃视频在线一区| 国产精品美女一区二区在线观看| 欧洲国内综合视频| 国产精品69久久久久水密桃| 亚洲美女屁股眼交| 久久免费视频一区| 欧美视频完全免费看| 国产99久久久国产精品潘金 | 91国产丝袜在线播放| 91色乱码一区二区三区| 五月综合激情婷婷六月色窝| 国产亚洲欧美日韩日本| 欧美视频一区二区三区四区 | 国产亚洲综合在线| 欧美在线观看视频一区二区| 国产一区999| 天天综合色天天| 亚洲视频在线一区二区| 久久综合色8888| 欧美日韩精品欧美日韩精品一 | 精品一区二区免费视频| 一区二区三区蜜桃| 国产人成一区二区三区影院| 欧美精品第1页| 欧日韩精品视频| 国产91精品精华液一区二区三区| 日韩精品色哟哟| 一区二区高清视频在线观看| 国产女人18毛片水真多成人如厕| 欧美日韩美少妇 | 成人免费视频caoporn| 青青草精品视频| 亚洲va欧美va人人爽| 中文字幕一区三区| 久久嫩草精品久久久久| 3d成人动漫网站| 欧美理论电影在线| 欧美色图免费看| 色婷婷精品久久二区二区蜜臂av| 成人深夜福利app| 国产伦精品一区二区三区免费| 日韩成人一级片| 午夜不卡在线视频| 午夜精品爽啪视频| 午夜视频一区在线观看| 亚洲一区二区三区四区中文字幕| 中文字幕在线一区| 国产精品久久久爽爽爽麻豆色哟哟 | 偷偷要91色婷婷| 亚洲午夜激情网站| 洋洋成人永久网站入口| 亚洲日本中文字幕区| 亚洲欧洲精品天堂一级| 亚洲天堂2014| 夜夜嗨av一区二区三区四季av| 亚洲综合一区二区三区| 亚洲综合丝袜美腿| 日韩国产精品久久久| 免费三级欧美电影| 国内精品视频666| 国产传媒欧美日韩成人| 成人免费毛片app| 成人av手机在线观看| 99热这里都是精品| 欧美视频一区二区在线观看| 欧美精品在线一区二区三区| 制服丝袜日韩国产| 久久一日本道色综合| 欧美激情中文字幕| 亚洲黄色片在线观看| 婷婷国产v国产偷v亚洲高清| 麻豆成人综合网| 粉嫩av一区二区三区| 色偷偷久久一区二区三区| 欧美精品久久99久久在免费线| 日韩欧美国产一区二区三区| 久久久亚洲高清| 亚洲欧美另类久久久精品2019| 成人一道本在线| 91黄色免费版| 欧美大片在线观看| 中文字幕一区二区视频| 午夜精品aaa| 国产福利不卡视频| 欧美亚洲国产怡红院影院| 日韩一级完整毛片| 亚洲色图清纯唯美| 麻豆精品视频在线观看免费 | 欧美午夜电影网| 精品欧美一区二区在线观看| 国产精品久久久久一区二区三区 | 国产成人自拍在线| 欧美三区在线视频| 久久精品亚洲乱码伦伦中文 | 欧美天堂一区二区三区| 精品免费国产一区二区三区四区| 中日韩av电影| 美女久久久精品| 色94色欧美sute亚洲线路一ni| 精品sm捆绑视频| 性感美女久久精品| 成人开心网精品视频| 日韩欧美国产综合| 午夜精品久久久久久久99樱桃| 成人亚洲精品久久久久软件| 91精品国产高清一区二区三区蜜臀| 中文在线一区二区| 久久99热国产| 欧美日韩在线三级| 1024精品合集| 国产激情一区二区三区| 欧美一区二区性放荡片| 亚洲天堂久久久久久久| 国产91精品免费| 久久影院午夜片一区| 强制捆绑调教一区二区| 欧美曰成人黄网| 伊人一区二区三区| aaa欧美色吧激情视频| 国产日韩欧美麻豆| 精品中文av资源站在线观看| 7777精品伊人久久久大香线蕉最新版| 国产精品日韩精品欧美在线| 国产一区二区导航在线播放| 欧美变态口味重另类| 麻豆91在线看| 欧美一区二区三区思思人| 亚洲丶国产丶欧美一区二区三区| 97久久精品人人澡人人爽| 国产精品三级电影| 国产不卡一区视频| 国产精品免费观看视频| 成人美女视频在线观看18| 中文字幕av资源一区| 不卡av在线网|