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

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

?? pxa2xx_udc.c

?? LINUX2.4.18內(nèi)核下的usb GADGET驅(qū)動程序
?? C
?? 第 1 頁 / 共 5 頁
字號:
			if (unlikely(ep->dma >= 0) && !list_empty(&ep->queue)) {DMSG("%s pio2dma\n", ep->ep.name);				req = list_entry(ep->queue.next,						struct pxa2xx_request, queue);				kick_dma(ep,req);				return 0;			}#endif			return 1;		}		// TODO experiment: how robust can fifo mode tweaking be?		// the double buffering could speed up I/O a bunch.	} while (*ep->reg_udccs & UDCCS_BI_TFS);	return 0;}/* caller asserts req->pending (ep0 irq status nyet cleared); starts * ep0 data stage.  these chips want very simple state transitions. */static inlinevoid ep0start(struct pxa2xx_udc *dev, u32 flags, const char *tag){	UDCCS0 = flags|UDCCS0_SA|UDCCS0_OPR;	USIR0 = USIR0_IR0;	dev->req_pending = 0;	DBG(DBG_VERY_NOISY, "%s %s, %02x/%02x\n",		__FUNCTION__, tag, UDCCS0, flags);}static intwrite_ep0_fifo (struct pxa2xx_ep *ep, struct pxa2xx_request *req){	unsigned	count;	int		is_short;	count = write_packet(&UDDR0, req, EP0_FIFO_SIZE);	ep->dev->stats.write.bytes += count;	/* last packet "must be" short (or a zlp) */	is_short = (count != EP0_FIFO_SIZE);	DBG(DBG_VERY_NOISY, "ep0in %d bytes %d left %p\n", count,		req->req.length - req->req.actual, req);	if (unlikely (is_short)) {		if (ep->dev->req_pending)			ep0start(ep->dev, UDCCS0_IPR, "short IN");		else			UDCCS0 = UDCCS0_IPR;		count = req->req.length;		done (ep, req, 0);		ep0_idle(ep->dev);#if 1		/* This seems to get rid of lost status irqs in some cases:		 * host responds quickly, or next request involves config		 * change automagic, or should have been hidden, or ...		 *		 * FIXME get rid of all udelays possible...		 */		if (count >= EP0_FIFO_SIZE) {			count = 100;			do {				if ((UDCCS0 & UDCCS0_OPR) != 0) {					/* clear OPR, generate ack */					UDCCS0 = UDCCS0_OPR;					break;				}				count--;				udelay(1);			} while (count);		}#endif	} else if (ep->dev->req_pending)		ep0start(ep->dev, 0, "IN");	return is_short;}/* * read_fifo -  unload packet(s) from the fifo we use for usb OUT * transfers and put them into the request.  caller should have made * sure there's at least one packet ready. * * returns true if the request completed because of short packet or the * request buffer having filled (and maybe overran till end-of-packet). */static intread_fifo (struct pxa2xx_ep *ep, struct pxa2xx_request *req){	for (;;) {		u32		udccs;		u8		*buf;		unsigned	bufferspace, count, is_short;		/* make sure there's a packet in the FIFO.		 * UDCCS_{BO,IO}_RPC are all the same bit value.		 * UDCCS_{BO,IO}_RNE are all the same bit value.		 */		udccs = *ep->reg_udccs;		if (unlikely ((udccs & UDCCS_BO_RPC) == 0))			break;		buf = req->req.buf + req->req.actual;		prefetchw(buf);		bufferspace = req->req.length - req->req.actual;		/* read all bytes from this packet */		if (likely (udccs & UDCCS_BO_RNE)) {			count = 1 + (0x0ff & *ep->reg_ubcr);			req->req.actual += min (count, bufferspace);		} else /* zlp */			count = 0;		is_short = (count < ep->ep.maxpacket);		DBG(DBG_VERY_NOISY, "read %s %02x, %d bytes%s req %p %d/%d\n",			ep->ep.name, udccs, count,			is_short ? "/S" : "",			req, req->req.actual, req->req.length);		while (likely (count-- != 0)) {			u8	byte = (u8) *ep->reg_uddr;			if (unlikely (bufferspace == 0)) {				/* this happens when the driver's buffer				 * is smaller than what the host sent.				 * discard the extra data.				 */				if (req->req.status != -EOVERFLOW)					DMSG("%s overflow %d\n",						ep->ep.name, count);				req->req.status = -EOVERFLOW;			} else {				*buf++ = byte;				bufferspace--;			}		}		*ep->reg_udccs =  UDCCS_BO_RPC;		/* RPC/RSP/RNE could now reflect the other packet buffer */		/* iso is one request per packet */		if (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC) {			if (udccs & UDCCS_IO_ROF)				req->req.status = -EHOSTUNREACH;			/* more like "is_done" */			is_short = 1;		}		/* completion */		if (is_short || req->req.actual == req->req.length) {			done (ep, req, 0);			if (list_empty(&ep->queue))				pio_irq_disable (ep->bEndpointAddress);			return 1;		}		/* finished that packet.  the next one may be waiting... */	}	return 0;}/* * special ep0 version of the above.  no UBCR0 or double buffering; status * handshaking is magic.  most device protocols don't need control-OUT. * CDC vendor commands (and RNDIS), mass storage CB/CBI, and some other * protocols do use them. */static intread_ep0_fifo (struct pxa2xx_ep *ep, struct pxa2xx_request *req){	u8		*buf, byte;	unsigned	bufferspace;	buf = req->req.buf + req->req.actual;	bufferspace = req->req.length - req->req.actual;	while (UDCCS0 & UDCCS0_RNE) {		byte = (u8) UDDR0;		if (unlikely (bufferspace == 0)) {			/* this happens when the driver's buffer			 * is smaller than what the host sent.			 * discard the extra data.			 */			if (req->req.status != -EOVERFLOW)				DMSG("%s overflow\n", ep->ep.name);			req->req.status = -EOVERFLOW;		} else {			*buf++ = byte;			req->req.actual++;			bufferspace--;		}	}		UDCCS0 = UDCCS0_OPR | UDCCS0_IPR;		/* completion */	if (req->req.actual >= req->req.length)		return 1;		/* finished that packet.  the next one may be waiting... */	return 0;}#ifdef	USE_DMAstatic inline voidstart_dma_nodesc(struct pxa2xx_ep *ep, struct pxa2xx_request *req, int is_in){	u32	dcmd = req->req.length;	u32	buf = virt_to_bus (req->req.buf);	u32	fifo = io_v2p ((u32)ep->reg_uddr);	/* no-descriptor mode can be simple for bulk-in, iso-in, iso-out */	DCSR(ep->dma) = DCSR_NODESC;	dcmd |= DCMD_BURST32 | DCMD_ENDIRQEN | DCMD_WIDTH1;	if (is_in) {		DSADR(ep->dma) = buf;		DTADR(ep->dma) = fifo;		dcmd |= DCMD_FLOWTRG | DCMD_INCSRCADDR;	} else {		DSADR(ep->dma) = fifo;		DTADR(ep->dma) = buf;		dcmd |= DCMD_FLOWSRC | DCMD_INCTRGADDR;	}	DCMD(ep->dma) = dcmd;	DCSR(ep->dma) = DCSR_RUN | DCSR_STOPIRQEN | DCSR_NODESC;	/* and later the dma handler gets called */}static void kick_dma(struct pxa2xx_ep *ep, struct pxa2xx_request *req){	if (ep->bEndpointAddress & USB_DIR_IN) {		/* docs imply we can't preload with pio */		if ((((u32)req->req.buf) & 0x0f) != 0) {// VERBOSE			DMSG("%s bad DMA align %p\n",				ep->ep.name, req->req.buf);pio_in:// FIXME PIO fallback doesn't work right yet (recovery?)DMSG("%s dma2pio\n", ep->ep.name);			pio_irq_enable(ep->bEndpointAddress);			if ((*ep->reg_udccs & UDCCS_BI_TFS) != 0)				(void) write_fifo(ep, req);			return;		}		/* dmacount 0 means end-of-transfer */		if (unlikely((req->req.length - req->req.actual) == 0)) {// VERBOSE			DMSG("%s zlp dma write...\n", ep->ep.name);			goto pio_in;		}		start_dma_nodesc(ep, req, USB_DIR_IN);	} else {		// if ISO, use no-descriptor DMA		BUG();	}}static void cancel_dma(struct pxa2xx_ep *ep){	struct pxa2xx_request	*req;	u32			tmp;	if (DCSR(ep->dma) == 0 || list_empty(&ep->queue))		return;	DCSR(ep->dma) = 0;	while ((DCSR(ep->dma) & DCSR_STOPSTATE) == 0)		cpu_relax();	req = list_entry(ep->queue.next, struct pxa2xx_request, queue);	tmp = DCMD(ep->dma) & DCMD_LENGTH;	req->req.actual = req->req.length - (tmp & DCMD_LENGTH);	/* the last tx packet may be incomplete, so flush the fifo.	 * FIXME correct req.actual if we can	 */	if (ep->bEndpointAddress & USB_DIR_IN)		*ep->reg_udccs = UDCCS_BI_FTF;}static void dma_nodesc_handler(int dmach, void *_ep, struct pt_regs *r){	struct pxa2xx_ep	*ep = _ep;	struct pxa2xx_request	*req;	u32			tmp;	req = list_entry(ep->queue.next, struct pxa2xx_request, queue);	ep->dev->stats.irqs++;	HEX_DISPLAY(ep->dev->stats.irqs);	/* ack/clear */	tmp = DCSR(ep->dma);	DCSR(ep->dma) = tmp;	if ((tmp & DCSR_STOPSTATE) == 0			|| (DDADR(ep->dma) & DDADR_STOP) != 0) {		DBG(DBG_VERBOSE, "%s, dcsr %08x ddadr %08x\n",			ep->ep.name, DCSR(ep->dma), DDADR(ep->dma));		return;	}	DCSR(ep->dma) = 0;	/* clear DCSR_STOPSTATE */	/* wrap up the transfer, and collect status */	if (unlikely(tmp & DCSR_BUSERR))		req->req.status = -EIO;	tmp = DCMD(ep->dma);	req->req.actual = req->req.length - (tmp & DCMD_LENGTH);	tmp = 1;	/* normally this is the last packet */	if (ep->bEndpointAddress & USB_DIR_IN) {		/* maybe validate final short packet */		if ((ep->bmAttributes == USB_ENDPOINT_XFER_BULK					&& req->req.actual % BULK_FIFO_SIZE)				|| (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC					&& req->req.actual % ISO_FIFO_SIZE))			*ep->reg_udccs = UDCCS_BI_TSP /*|UDCCS_BI_TPC*/;		/* or force a zlp, with pio ... */		else if (ep->bmAttributes == USB_ENDPOINT_XFER_BULK				&& req->req.zero) {			tmp = 0;		}		// if iso, maybe report underrun (TUR)	} else {		BUG();	}	if (likely(tmp != 0))		done(ep, req, 0);	/* maybe re-activate after completion */	if (ep->stopped || list_empty(&ep->queue))		return;	req = list_entry(ep->queue.next, struct pxa2xx_request, queue);	kick_dma(ep, req);}#endif/*-------------------------------------------------------------------------*/static intpxa2xx_ep_queue(struct usb_ep *_ep, struct usb_request *_req, int gfp_flags){	struct pxa2xx_request	*req;	struct pxa2xx_ep	*ep;	struct pxa2xx_udc	*dev;	unsigned long		flags;	req = container_of(_req, struct pxa2xx_request, req);	if (unlikely (!_req || !_req->complete || !_req->buf			|| !list_empty(&req->queue))) {		DMSG("%s, bad params\n", __FUNCTION__);		return -EINVAL;	}	ep = container_of(_ep, struct pxa2xx_ep, ep);	if (unlikely (!_ep || (!ep->desc && ep->ep.name != ep0name))) {		DMSG("%s, bad ep\n", __FUNCTION__);		return -EINVAL;	}	dev = ep->dev;	if (unlikely (!dev->driver			|| dev->gadget.speed == USB_SPEED_UNKNOWN)) {		DMSG("%s, bogus device state\n", __FUNCTION__);		return -ESHUTDOWN;	}	/* iso is always one packet per request, that's the only way	 * we can report per-packet status.  that also helps with dma.	 */	if (unlikely (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC			&& req->req.length > le16_to_cpu						(ep->desc->wMaxPacketSize)))		return -EMSGSIZE;#ifdef	USE_DMA	if (ep->dma >= 0) {		unsigned long	start = (unsigned long) _req->buf;		clean_dcache_range(start, start + _req->length);		/* or for USB_DIR_OUT, invalidate_dcache_range (...) */	}#endif	DBG(DBG_NOISY, "%s queue req %p, len %d buf %p\n",	     _ep->name, _req, _req->length, _req->buf);	local_irq_save(flags);	_req->status = -EINPROGRESS;	_req->actual = 0;	/* kickstart this i/o queue? */	if (list_empty(&ep->queue) && !ep->stopped) {		if (ep->desc == 0 /* ep0 */) {			unsigned	length = _req->length;			switch (dev->ep0state) {			case EP0_IN_DATA_PHASE:				dev->stats.write.ops++;				if (write_ep0_fifo(ep, req))					req = 0;				break;			case EP0_OUT_DATA_PHASE:				dev->stats.read.ops++;				/* messy ... */				if (dev->req_config) {					DBG(DBG_VERBOSE, "ep0 config ack%s\n",						dev->has_cfr ?  "" : " raced");					if (dev->has_cfr)						UDCCFR = UDCCFR_AREN|UDCCFR_ACM;					done(ep, req, 0);					dev->ep0state = EP0_END_XFER;					local_irq_restore (flags);					return 0;				}				if (dev->req_pending)					ep0start(dev, UDCCS0_IPR, "OUT");				if (length == 0 || ((UDCCS0 & UDCCS0_RNE) != 0						&& read_ep0_fifo(ep, req))) {					ep0_idle(dev);					done(ep, req, 0);					req = 0;				}				break;			default:				DMSG("ep0 i/o, odd state %d\n", dev->ep0state);				local_irq_restore (flags);				return -EL2HLT;			}#ifdef	USE_DMA		/* either start dma or prime pio pump */		} else if (ep->dma >= 0) {			kick_dma(ep, req);#endif		/* can the FIFO can satisfy the request immediately? */		} else if ((ep->bEndpointAddress & USB_DIR_IN) != 0				&& (*ep->reg_udccs & UDCCS_BI_TFS) != 0				&& write_fifo(ep, req)) {			req = 0;		} else if ((*ep->reg_udccs & UDCCS_BO_RFS) != 0				&& read_fifo(ep, req)) {			req = 0;		}		if (likely (req && ep->desc) && ep->dma < 0)			pio_irq_enable(ep->bEndpointAddress);	}	/* pio or dma irq handler advances the queue. */	if (likely (req != 0))		list_add_tail(&req->queue, &ep->queue);	local_irq_restore(flags);	return 0;}/* * 	nuke - dequeue ALL requests */static void nuke(struct pxa2xx_ep *ep, int status){	struct pxa2xx_request *req;	/* called with irqs blocked */#ifdef	USE_DMA	if (ep->dma >= 0 && !ep->stopped)		cancel_dma(ep);#endif	while (!list_empty(&ep->queue)) {		req = list_entry(ep->queue.next,				struct pxa2xx_request,				queue);		done(ep, req, status);	}	if (ep->desc)		pio_irq_disable (ep->bEndpointAddress);}/* dequeue JUST ONE request */static int pxa2xx_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req){	struct pxa2xx_ep	*ep;	struct pxa2xx_request	*req;	unsigned long		flags;	ep = container_of(_ep, struct pxa2xx_ep, ep);	if (!_ep || ep->ep.name == ep0name)		return -EINVAL;	local_irq_save(flags);

?? 快捷鍵說明

復(fù)制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
久久国产精品一区二区| 色综合久久久久久久久久久| 99久久久精品免费观看国产蜜| 91福利在线看| 久久久综合精品| 天天av天天翘天天综合网色鬼国产| 国产成人精品www牛牛影视| 8v天堂国产在线一区二区| 国产精品国产自产拍高清av| 免费看日韩a级影片| 91行情网站电视在线观看高清版| 久久久久久久综合日本| 日本不卡一区二区三区 | 日韩精品一级二级 | 美女性感视频久久| 欧美午夜精品久久久久久孕妇 | 日韩欧美在线综合网| 夜夜嗨av一区二区三区四季av| 国产成人av一区二区| www国产成人| 久久99国产精品尤物| 欧美日韩成人综合在线一区二区 | 色婷婷综合久久久久中文| 国产午夜精品在线观看| 国内精品在线播放| 日韩欧美的一区二区| 丝袜a∨在线一区二区三区不卡| 91美女片黄在线观看91美女| 中文字幕第一区二区| 国产成人av电影| 国产校园另类小说区| 国产精品原创巨作av| 久久精品夜色噜噜亚洲aⅴ| 久久不见久久见中文字幕免费| 欧美日韩成人综合天天影院| 亚洲福利一区二区三区| 欧美在线999| 亚洲电影激情视频网站| 欧美四级电影在线观看| 天天爽夜夜爽夜夜爽精品视频| 精品婷婷伊人一区三区三| 亚洲国产一二三| 7777精品伊人久久久大香线蕉完整版 | 91麻豆精品久久久久蜜臀 | 蜜臀av亚洲一区中文字幕| 欧美另类z0zxhd电影| 奇米综合一区二区三区精品视频| 日韩三级av在线播放| 国产一区二区三区免费观看| 五月婷婷欧美视频| 欧美一区二区在线免费观看| 青青草伊人久久| 久久婷婷成人综合色| 99久久伊人久久99| 亚洲成av人片在线观看无码| 日韩一区二区三区免费观看| 国产白丝精品91爽爽久久| 亚洲视频免费看| 欧美色视频在线| 久久99久久久欧美国产| 中文字幕不卡一区| 精品视频在线免费观看| 国产麻豆91精品| 亚洲视频香蕉人妖| 91精品国产福利| 成人一区二区三区在线观看| 亚洲自拍欧美精品| 精品国产乱码久久| 91美女视频网站| 久久www免费人成看片高清| 国产精品乱码妇女bbbb| 欧美精品亚洲二区| 国产经典欧美精品| 天堂蜜桃一区二区三区 | 欧美一卡二卡在线观看| 国产69精品久久99不卡| 亚洲乱码一区二区三区在线观看| 日韩欧美视频在线 | 国产成人精品亚洲日本在线桃色 | 成人爽a毛片一区二区免费| 亚洲大片精品永久免费| 国产精品女主播在线观看| 欧美久久一二三四区| 99精品桃花视频在线观看| 久久疯狂做爰流白浆xx| 亚洲男人都懂的| 精品精品国产高清一毛片一天堂| 色狠狠色狠狠综合| 成人在线综合网站| 裸体一区二区三区| 一区二区三区色| 久久嫩草精品久久久精品| 在线播放中文字幕一区| 色婷婷综合久久| 成人av资源下载| 国产精品一区二区91| 美女国产一区二区| 亚洲一二三专区| 亚洲精品写真福利| 国产精品久久精品日日| 久久久久国产一区二区三区四区 | 日本二三区不卡| 国产成人aaaa| 国产.欧美.日韩| 国产精品伊人色| 国产一区二区不卡在线| 精品写真视频在线观看| 免费日韩伦理电影| 日韩黄色免费电影| 亚欧色一区w666天堂| 亚洲一区av在线| 一区二区三区在线观看视频| 亚洲欧美欧美一区二区三区| **欧美大码日韩| 日韩一区日韩二区| 亚洲精品免费一二三区| 一级中文字幕一区二区| 依依成人精品视频| 亚洲在线中文字幕| 午夜精品在线看| 热久久久久久久| 紧缚捆绑精品一区二区| 国产福利91精品| 国产成人亚洲综合a∨婷婷| 国产成人日日夜夜| 东方aⅴ免费观看久久av| 99久久亚洲一区二区三区青草| kk眼镜猥琐国模调教系列一区二区 | 一本色道久久综合亚洲91| 91浏览器在线视频| 欧美视频一区二区三区四区 | 成人avav影音| av欧美精品.com| 色婷婷久久一区二区三区麻豆| 色婷婷亚洲精品| 91精品国产色综合久久ai换脸 | 亚洲精品成a人| 亚洲欧美激情一区二区| 有坂深雪av一区二区精品| 日韩电影在线免费观看| 国产一区二区在线看| 成人黄色在线网站| 91美女片黄在线观看| 欧美羞羞免费网站| 日韩一卡二卡三卡四卡| 久久久精品蜜桃| 一区在线观看视频| 日本免费在线视频不卡一不卡二| 国产福利一区二区| 欧美亚洲国产一区在线观看网站| 91精品国产综合久久精品app| 国产亚洲成aⅴ人片在线观看| 自拍偷自拍亚洲精品播放| 亚洲大片精品永久免费| 国产米奇在线777精品观看| 日本高清不卡视频| 精品1区2区在线观看| 一区二区三区精品| 国产乱码精品一区二区三区av | 在线综合+亚洲+欧美中文字幕| 亚洲一区av在线| 久久99蜜桃精品| 欧美在线免费视屏| 中文字幕中文乱码欧美一区二区| 日日夜夜免费精品视频| av在线这里只有精品| 日韩午夜小视频| 亚洲夂夂婷婷色拍ww47| 懂色av一区二区三区免费观看| 91麻豆精品国产自产在线观看一区| 国产精品免费观看视频| 麻豆91在线观看| 欧美亚洲动漫另类| 国产精品不卡在线观看| 激情文学综合插| 777奇米四色成人影色区| 一区二区三区在线视频免费观看| 精品亚洲成a人| 欧美精品自拍偷拍动漫精品| 综合欧美亚洲日本| 丰满白嫩尤物一区二区| 久久综合久久综合久久综合| 日本最新不卡在线| 欧美视频第二页| 亚洲精品国产品国语在线app| 不卡的看片网站| 国产片一区二区三区| 国产综合色视频| 精品国产123| 久久99久久精品| 日韩欧美高清一区| 日本人妖一区二区| 在线综合+亚洲+欧美中文字幕| 偷拍日韩校园综合在线| 欧美曰成人黄网| 亚洲激情在线播放| 色域天天综合网| 亚洲精品日韩综合观看成人91| 色狠狠综合天天综合综合| 亚洲乱码国产乱码精品精的特点|