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

? 歡迎來(lái)到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關(guān)于我們
? 蟲蟲下載站

?? streambuffer.c

?? ARM嵌入式應(yīng)用開發(fā)實(shí)例USB項(xiàng)目控制器的實(shí)現(xiàn)源代碼
?? C
字號(hào):
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/poll.h>
#include <linux/usb.h>
#include <linux/slab.h>

#include "streambuffer.h"

void dump_bin(char *Title,unsigned char *buf, int len);

#define	debug 0

#undef	dbg
#define dbg(format, arg...) \
	do { if (debug) printk(KERN_DEBUG __FILE__ ": [" __FUNCTION__ "] " format "\n" , ## arg); } while (0)

#define msg(format, arg...) \
	do { printk(KERN_DEBUG __FILE__ ": [" __FUNCTION__ "] " format "\n" , ## arg); } while (0)

/////////////////////////////////////////////////////////////
// private function

static inline unsigned int * sync_scan(unsigned int *addr, unsigned int syncword, int size)
{
	if(!size)
		return addr;
	
	__asm__ (
		"cld\n"
		"repnz; scasl\n\t"
		"jz 1f\n\t"
		"mov $0, %%edi\n"
		"1:"
		: "=D" (addr), "=c" (size)
		: "0" (addr), "1" (size), "a" (syncword));
	
	if(addr != NULL)
		addr--;

	return addr;
}

static int bufblk_alloc(PSTREAM_BUFFER psb)
{
	int i;

	dbg("Enter");

	dbg("bufblk_ready is %d", psb->bufblk_ready);
	if(psb->bufblk_ready) return 0;

/*
	psb->bufblk_cache = kmem_cache_create("Stream Buffer",
										  STREAMBUF_BLKSIZE + 96, 0,
										  0, NULL, NULL);
*/

	psb->bufblk_cache = kmem_cache_create(psb->cachename,
										  STREAMBUF_BLKSIZE + 96, 0,
										  0, NULL, NULL);

	if(psb->bufblk_cache == NULL)
	{
		dbg("ERROR: could not create cache");
		return -1;
	}

	for(i = 0; i < STREAMBUF_TOTAL_BLKS; i++)
	{
		psb->bufblk_pool[i]	= kmem_cache_alloc(psb->bufblk_cache, GFP_KERNEL);
		if(psb->bufblk_pool[i] == NULL)
		{
			dbg("ERROR: could not allocate block buffer for stream buffer");
			return -1;
		}
		else
		{
			dbg("SUCCESS: pointer is %p", psb->bufblk_pool[i]);
		}
	}

	psb->bufblk_ready = 1;

	dbg("Leave");

	return 0;
}

static void bufblk_free(PSTREAM_BUFFER psb)
{
	int i;

	psb->bufblk_ready = 0;

	if(psb->bufblk_cache == NULL)
	{
		dbg("ERROR: bufblk_cache is NULL");
		return;
	}

	for(i = 0; i < STREAMBUF_TOTAL_BLKS; i++)
	{
		if(psb->bufblk_pool[i] != NULL)
		{
			kmem_cache_free(psb->bufblk_cache, psb->bufblk_pool[i]);
			psb->bufblk_pool[i] = NULL;
		}
	}

	kmem_cache_destroy(psb->bufblk_cache);
	psb->bufblk_cache = NULL;
}

static int bufblk_calc_freespace(PSTREAM_BUFFER psb)
{
	int rv;

	rv = psb->buf_tail - psb->buf_head;
	if(rv < 0)
	{
		rv += STREAMBUF_TOTAL_SIZE;
	}

	rv = STREAMBUF_TOTAL_SIZE - rv;

	dbg("bufblk: freespace = %d (%d/%d)", rv,
		psb->buf_head, psb->buf_tail);

	return rv;
}

static int bufblk_copy_in(PSTREAM_BUFFER psb, void *buf, int len)
{
	int cur_off, count, total_len;
	int blknum;

	char *pblk, *pdata;

	count = 0;
	total_len = len;

	blknum	= (psb->buf_tail + 1) / STREAMBUF_BLKSIZE;
	cur_off	= psb->buf_tail % STREAMBUF_BLKSIZE;

	pdata = (char*) buf;

	dbg("bufblk_copy_in: blknum = %d, cur_off = %d, len = %d", blknum, cur_off, len);

	while(len > 0)
	{

		pblk = (char*) (psb->bufblk_pool[blknum]);
		dbg("pointer is %p", pblk);

		if((cur_off + len) <= STREAMBUF_BLKSIZE)
		{
			dbg("not cross block");

			if(cur_off < 0 || (cur_off + len) > STREAMBUF_BLKSIZE)
			{
				err("out of range: offset = %d, len = %d", cur_off, len);
			}

			memcpy(pblk + cur_off, pdata, len);

			dbg("Block number: 0x%X, offset: 0x%X, len: 0x%X", blknum, cur_off, len);

			pdata += len; count += len; len = 0;
		}
		else
		{
			int n;

			dbg("cross block, count = %d, len = %d, cur_off = %d", count, len, cur_off);

			n = STREAMBUF_BLKSIZE - cur_off;

			if(cur_off < 0 || (cur_off + n) > STREAMBUF_BLKSIZE)
			{
				err("out of range: offset = %d, len = %d", cur_off, len);
			}

			memcpy(pblk + cur_off, pdata, n);

			dbg("Block number: 0x%X, offset: 0x%X, len: 0x%X", blknum, cur_off, n);

			pdata += n; count += n; len -= n;
			cur_off = 0; blknum = (blknum + 1) % STREAMBUF_TOTAL_BLKS;
		}
	}

	psb->buf_tail = (psb->buf_tail + count) % STREAMBUF_TOTAL_SIZE;

	if(count != total_len)
	{
		err("ERROR: count != length (%d/%d)", count, total_len);
	}
	
	return count;
}

static int bufblk_copy_out(PSTREAM_BUFFER psb, int offset, void *buf, int len)
{
	int cur_off, count;
	int blknum;

	char *pblk, *pdst;

	dbg("Enter offset = 0x%X, len = 0x%X", offset, len);

	blknum	= (offset + 1) / STREAMBUF_BLKSIZE;
	cur_off	= offset % STREAMBUF_BLKSIZE;

	pdst = (char*) buf;
	count = 0;

	while(len > 0)
	{
		pblk = (char*) (psb->bufblk_pool[blknum]);
		if((cur_off + len) <= STREAMBUF_BLKSIZE)
		{
			copy_to_user(pdst, pblk + cur_off, len);

			dbg("Block number: 0x%X, offset: 0x%X, len: 0x%X", blknum, cur_off, len);

			pdst += len; count += len; len = 0;
		}
		else
		{
			int n;

			n = STREAMBUF_BLKSIZE - cur_off;
			copy_to_user(pdst, pblk + cur_off, n);

			dbg("Block number: 0x%X, offset: 0x%X, len: 0x%X", blknum, cur_off, n);

			pdst += n; count += n; len -= n;
			cur_off = 0; blknum = (blknum + 1) % STREAMBUF_TOTAL_BLKS;
		}
	}

	dbg("Leave");

	return count;
}

static int finfo_init(PSTREAM_BUFFER psb)
{
	psb->finfo_head = 0;
	psb->finfo_tail = 0;

	psb->buf_head	= 0;
	psb->buf_tail	= 0;

	psb->least_freespace = STREAMBUF_TOTAL_SIZE;

	return 0;
}

inline static int finfo_is_empty(PSTREAM_BUFFER psb)
{
	return (psb->finfo_head == psb->finfo_tail);
}

static void finfo_add_tail(PSTREAM_BUFFER psb, int offset)
{
	int new_tail;

	new_tail = (psb->finfo_tail + 1) % MAX_FRAMES;

	if(new_tail == psb->finfo_head)
	{
		err("ERROR: try to add tail when list is full");
		return;
	}

	psb->finfo_pool[psb->finfo_tail].offset = offset;
	psb->finfo_pool[psb->finfo_tail].len	 = 0;

	if(psb->finfo_tail != psb->finfo_head)
	{
		int frame_len;
		int prev;

		/* Calculate previous node position */
		prev = psb->finfo_tail - 1;

		if(prev < 0)
			prev += MAX_FRAMES;

		/* Calculate frame length */
		frame_len = offset - psb->finfo_pool[prev].offset;

		if(frame_len < 0)
			frame_len += STREAMBUF_TOTAL_SIZE;

		/* Assign frame length */
		psb->finfo_pool[prev].len = frame_len;
	}

	psb->finfo_tail = new_tail;
}

static void finfo_remove_head(PSTREAM_BUFFER psb)
{
	int new_head;

	/* List is empty*/
	if(psb->finfo_head == psb->finfo_tail)
		return;
	
	new_head 	= (psb->finfo_head + 1) % MAX_FRAMES;

	psb->buf_head	= psb->finfo_pool[new_head].offset;
	psb->finfo_head	= new_head;
}

/*
 * Original local functions
 */

static void InitLock(PSTREAM_BUFFER psb)
{
	spin_lock_init(&(psb->spinlock));
	// init_MUTEX(&(psb->mutex));
}

static void LockBuffer(PSTREAM_BUFFER psb)
{
	spin_lock_irqsave(&(psb->spinlock), psb->lock_flags);
	// down(&(psb->mutex));
}

static void UnlockBuffer(PSTREAM_BUFFER psb)
{
	spin_unlock_irqrestore(&(psb->spinlock), psb->lock_flags);
	// up(&(psb->mutex));
}

/////////////////////////////////////////////////////////////
// public function

int StreamBuffer_Init(PSTREAM_BUFFER psb)
{
	dbg("Enter");

#if 1
	if(bufblk_alloc(psb))
	{
		bufblk_free(psb);
		return -1;
	}
#endif

	finfo_init(psb);

	InitLock(psb);
	
	dbg("Leave Successfully");
	return 0;
}

int StreamBuffer_Reset(PSTREAM_BUFFER psb)
{
	dbg("Enter");

	finfo_init(psb);

	dbg("Leave Successfully");

	return 0;
}

void StreamBuffer_Uninit(PSTREAM_BUFFER psb)
{
	dbg("Enter");

#if 1
	bufblk_free(psb);
#endif

	dbg("Leave");
}

int StreamBuffer_AddBlock(PSTREAM_BUFFER psb, unsigned char *pblock, int size)
{
	int rv, cur_offset;
	int freespace;
	int cnt;

	dbg("Enter");

	if(size > 200000)
	{
		err("Strange things: size = %d", size);
	}

	if(!psb->bufblk_ready)
	{
		dbg("[" __FUNCTION__ "] " "Buffer block not initialized");
		return 0;
		return -1;
	}

	LockBuffer(psb);

	dbg("Add block at %p, size = %d", pblock, size);

	/* Drop frame until getting enough space */
	cnt = 10;
	do
	{
		freespace = bufblk_calc_freespace(psb);

		if(freespace < psb->least_freespace)
		{
			psb->least_freespace = freespace;
			msg("Least freespace for %p: %d (%d/%d)", psb, psb->least_freespace,
				 psb->buf_head, psb->buf_tail);
		}
		
		if(freespace > (size + 8))
			break;

		/* Discard first frame */
		finfo_remove_head(psb);
		msg("Drop frames! size required: %d", size);
		cnt--;
	}while(cnt>0);

	if(freespace <= (size + 8))
	{
		err("free space is not enough in stream buffer");
		err("finfo: (%d/%d)", psb->finfo_head, psb->finfo_tail);
		goto exit;
	}

	/* Add data to frame buffer */
	cur_offset = psb->buf_tail;
	rv = bufblk_copy_in(psb, pblock, size);

#if 0
	/* Search frame header */
	{
		int i;

		for(i = 0; i < rv; i++)
		{
			if(*((unsigned int *)(pblock+i)) == SYNCWORD)
			{
				int sync_offset = (cur_offset + i) % (STREAMBUF_TOTAL_SIZE);
				finfo_add_tail(psb, sync_offset);
				dbg("SYNCWORD at 0x%06X", sync_offset);
			}
		}
	}
#else
	/* Search frame header */
	{
		int offset, words;
		unsigned int *pcur, *pend;
		unsigned int *pdata = (unsigned int *) pblock;

		offset	= 0;
		words	= rv / 4;

		pcur	= pdata;
		pend	= (unsigned int*) (pblock + rv);

		// msg("bufstart/cur_offset: %p/0x%08x", pdata, cur_offset);
		while(pcur < pend) {
			pcur = sync_scan(pcur, SYNCWORD, pend - pcur);
			if(pcur == NULL)
				break;

			// msg("sync_scan: %p", pcur);
			// msg("data[-1, 0, 1]: 0x%08x, 0x%08x, 0x%08x", *(pcur-1), *pcur, *(pcur+1));

			if(*pcur == SYNCWORD) {
				int sync_offset;
				
				sync_offset = (cur_offset + (((char*)pcur) - ((char*)pdata))) % (STREAMBUF_TOTAL_SIZE);
				finfo_add_tail(psb, sync_offset);
				// msg("SYNCWORD at 0x%06X", sync_offset);
				pcur++;
			}
			else {
				break;
			}
		}
	}
#endif

exit:
	UnlockBuffer(psb);

	dbg("Leave Normally");

	return 0;
}

////////////////////////////////////////////////////////////////////////////////////////
//
// return:
//		0  -- success
//		1 -- buffer underflow
//		2 -- dest buffer size too small

int StreamBuffer_GetFrame(PSTREAM_BUFFER psb, unsigned char *pDstBuf, int *DstBufLen)
{
	int frame_len, frame_offset, rv;
	rv = 1;

	dbg("Enter");

	if(finfo_is_empty(psb))
	{
		dbg("Stream buffer is empty");
		rv = 1;
		goto empty;
	}
	
	if(spin_is_locked(&(psb->spinlock))) {
		rv = 1;
		goto empty;
	}

	LockBuffer(psb);

	frame_offset	= psb->finfo_pool[psb->finfo_head].offset;
	frame_len		= psb->finfo_pool[psb->finfo_head].len;

	dbg("[GetFrame] Current fame: offset %d, len %d", frame_offset, frame_len);

	if(frame_len <= 0)
	{
		rv = 1;
		goto exit;
	}

	if(*DstBufLen < frame_len)
	{
		dbg("[" __FUNCTION__ "] " "Dest buffer too small %d/%d", frame_len, *DstBufLen);
		rv = 2;
		goto exit;
	}

	bufblk_copy_out(psb, frame_offset, pDstBuf, frame_len);
	*DstBufLen = frame_len;

	finfo_remove_head(psb);

	rv = 0;

exit:
	UnlockBuffer(psb);

empty:
	dbg("Leave");

	return rv;
}

?? 快捷鍵說(shuō)明

復(fù)制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號(hào) Ctrl + =
減小字號(hào) Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
韩国毛片一区二区三区| 色素色在线综合| 亚洲老妇xxxxxx| 欧美大片在线观看一区二区| 91在线视频播放地址| 久久成人免费日本黄色| 夜夜夜精品看看| 亚洲国产精品黑人久久久| 91精品免费观看| 色综合久久久久综合| 国产精品乡下勾搭老头1| 日本麻豆一区二区三区视频| 亚洲免费看黄网站| 欧美韩国日本综合| 久久免费视频一区| 日韩欧美一区在线| 欧美夫妻性生活| 色丁香久综合在线久综合在线观看| 国产成人免费网站| 久久成人羞羞网站| 裸体健美xxxx欧美裸体表演| 午夜视频在线观看一区二区三区| 日韩理论片网站| 日本一区二区免费在线观看视频| 精品国产乱码久久久久久1区2区| 91精选在线观看| 欧美伦理电影网| 国产女人水真多18毛片18精品视频 | 在线精品视频小说1| 高清不卡在线观看| 国产盗摄一区二区三区| 精品亚洲欧美一区| 精品一区二区三区在线观看| 日本美女一区二区三区视频| 日韩1区2区3区| 蜜乳av一区二区| 久久精品国内一区二区三区| 日本在线播放一区二区三区| 青青草一区二区三区| 奇米色一区二区三区四区| 免费不卡在线视频| 激情综合色播激情啊| 激情五月婷婷综合| 国产最新精品免费| 东方欧美亚洲色图在线| 国产大片一区二区| 大陆成人av片| 99国内精品久久| 在线免费不卡视频| 欧美日韩情趣电影| 日韩欧美一级精品久久| 久久奇米777| 亚洲欧美在线高清| 一区二区三区鲁丝不卡| 香港成人在线视频| 久久精品国产77777蜜臀| 国产一区二三区| 成人av资源站| 在线视频一区二区三区| 欧美乱妇23p| 精品国产乱码久久久久久浪潮| 亚洲欧洲中文日韩久久av乱码| 国产免费久久精品| 国产精品国产三级国产aⅴ无密码 国产精品国产三级国产aⅴ原创 | 婷婷成人激情在线网| 美国毛片一区二区三区| 粉嫩一区二区三区在线看| 91理论电影在线观看| 56国语精品自产拍在线观看| 欧美成人一区二区三区片免费| 久久精品日产第一区二区三区高清版 | eeuss鲁片一区二区三区| 欧美视频中文一区二区三区在线观看 | 国产一区二区精品久久| 91亚洲男人天堂| 日韩精品在线网站| 日韩久久一区二区| 视频一区在线视频| 成人小视频在线| 555www色欧美视频| 国产精品美女久久久久高潮| 亚洲成人av中文| 成人午夜伦理影院| 91精品国产综合久久香蕉麻豆| 国产欧美一区二区精品婷婷 | 一区二区三区.www| 国产一区二区三区四| 在线免费观看视频一区| 久久久久久一二三区| 亚洲国产一区在线观看| 国产电影一区在线| 538在线一区二区精品国产| 国产欧美精品一区| 免费成人小视频| 色妞www精品视频| 国产亚洲一本大道中文在线| 午夜激情综合网| 91免费版在线| 久久久久久久综合狠狠综合| 亚洲国产cao| 成人国产精品免费观看视频| 欧美一区二区视频在线观看2022| 18成人在线观看| 高清视频一区二区| 日韩免费高清视频| 香蕉久久夜色精品国产使用方法| 99这里只有久久精品视频| 精品嫩草影院久久| 日韩成人午夜电影| 在线看国产一区| 亚洲男人的天堂在线aⅴ视频| 国产美女一区二区| 欧美不卡视频一区| 日韩精品电影在线| 欧美日韩在线播放一区| 一区二区三区国产| 色婷婷av一区二区三区软件 | 精品一区二区国语对白| 欧美日本乱大交xxxxx| 一区二区三区免费| 一本大道综合伊人精品热热| 国产精品美女久久久久aⅴ国产馆 国产精品美女久久久久av爽李琼 国产精品美女久久久久高潮 | 欧美大片日本大片免费观看| 亚洲成人一区二区| 欧美日韩在线一区二区| 一区二区激情视频| 91麻豆视频网站| 国产精品免费久久| 成人av第一页| 国产精品免费丝袜| 99re热视频精品| 国产精品灌醉下药二区| 99久免费精品视频在线观看| 中文一区二区完整视频在线观看| 国产毛片一区二区| 久久久精品人体av艺术| 国产成人免费在线观看不卡| 国产免费久久精品| 不卡av在线网| 亚洲色图20p| 欧洲人成人精品| 日韩电影在线免费看| 日韩亚洲欧美中文三级| 激情久久五月天| 国产午夜亚洲精品午夜鲁丝片| 国产99久久久国产精品潘金| 中文欧美字幕免费| 色婷婷综合五月| 午夜电影一区二区| 欧美岛国在线观看| 国产福利一区在线| 亚洲欧美另类在线| 欧美精选午夜久久久乱码6080| 奇米精品一区二区三区四区| 久久网站最新地址| 99热99精品| 亚洲高清免费一级二级三级| 日韩一区二区在线看片| 国产精品一区2区| 综合激情成人伊人| 欧美日韩视频一区二区| 久久99热99| 中文字幕五月欧美| 欧美日韩一区二区在线观看视频 | 亚洲自拍偷拍av| 3d成人h动漫网站入口| 国产美女精品一区二区三区| 亚洲日本在线a| 欧美精品日韩综合在线| 国产乱人伦偷精品视频不卡| 成人免费在线视频观看| 制服丝袜国产精品| 成人av电影观看| 日产精品久久久久久久性色| 国产欧美一区二区精品秋霞影院 | 不卡一卡二卡三乱码免费网站| 亚洲无线码一区二区三区| 精品久久99ma| 色综合久久久网| 激情五月婷婷综合| 亚洲一级片在线观看| 久久久久久久久久久电影| 欧美色爱综合网| 成人综合婷婷国产精品久久蜜臀 | 精品一区免费av| 亚洲老妇xxxxxx| 国产午夜精品在线观看| 在线欧美一区二区| 国产精品系列在线播放| 肉色丝袜一区二区| 中文字幕一区二区三区精华液 | 日本一区二区三区视频视频| 欧美精品自拍偷拍| 91视频精品在这里| 国内精品国产成人国产三级粉色 | 自拍偷拍亚洲激情| 日韩精品一区二区三区四区 | 欧美国产综合色视频| 日韩欧美另类在线| 欧美日韩国产大片|