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

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

?? pxa2xx_udc.c

?? LINUX2.4.18內(nèi)核下的usb GADGET驅(qū)動(dòng)程序
?? C
?? 第 1 頁 / 共 5 頁
字號(hào):
/* * linux/drivers/usb/gadget/pxa2xx_udc.c * Intel PXA2xx and IXP4xx on-chip full speed USB device controllers * * Copyright (C) 2002 Intrinsyc, Inc. (Frank Becker) * Copyright (C) 2003 Robert Schwebel, Pengutronix * Copyright (C) 2003 Benedikt Spranger, Pengutronix * Copyright (C) 2003 David Brownell * * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA * */#define	DEBUG	1// #define	VERBOSE	DBG_VERBOSE#include <linux/config.h>#include <linux/module.h>#include <linux/kernel.h>#include <linux/ioport.h>#include <linux/types.h>#include <linux/version.h>#include <linux/errno.h>#include <linux/delay.h>#include <linux/sched.h>#include <linux/slab.h>#include <linux/init.h>#include <linux/timer.h>#include <linux/list.h>#include <linux/interrupt.h>#include <linux/proc_fs.h>#include <linux/mm.h>// #include <linux/device.h>#include <asm/byteorder.h>#include <asm/dma.h>#include <asm/io.h>#include <asm/irq.h>#include <asm/system.h>#include <asm/unaligned.h>#include <asm/proc/cache.h>#include <linux/usb_ch9.h>#include <linux/usb_gadget.h>/* * This driver handles the USB Device Controller (UDC) in Intel's PXA 2xx * series processors.  The UDC for the IXP 4xx series is very similar. * There are fifteen endpoints, in addition to ep0. * * Such controller drivers work with a gadget driver.  The gadget driver * returns descriptors, implements configuration and data protocols used * by the host to interact with this device, and allocates endpoints to * the different protocol interfaces.  The controller driver virtualizes * usb hardware so that the gadget drivers will be more portable. *  * This UDC hardware wants to implement a bit too much USB protocol, so * it constrains the sorts of USB configuration change events that work. * The errata for these chips are misleading; some "fixed" bugs from * pxa250 a0/a1 b0/b1/b2 sure act like they're still there. *//* NOTE:  the 2.6 driver is probably the most current version */#define	DRIVER_VERSION	"5-Jan-2004"#define	DRIVER_DESC	"PXA 2xx USB Device Controller driver"static const char driver_name [] = "pxa2xx_udc";static const char ep0name [] = "ep0";// #define	USE_DMA// #define	USE_OUT_DMA// #define	DISABLE_TEST_MODE#ifdef CONFIG_PROC_FS#define	UDC_PROC_FILE#endif#ifdef CONFIG_ARCH_IXP425#undef USE_DMA/* cpu-specific register addresses are compiled in to this code */#ifdef CONFIG_ARCH_PXA#error "Can't configure both IXP and PXA"#endif#endif#ifdef CONFIG_EMBEDDED/* few strings, and little code to use them */#undef	DEBUG#undef	UDC_PROC_FILE#endif#include "pxa2xx_udc.h"#ifdef	USE_DMAstatic int use_dma = 1;MODULE_PARM (use_dma, "i");MODULE_PARM_DESC (use_dma, "true to use dma");static void dma_nodesc_handler (int dmach, void *_ep, struct pt_regs *r);static void kick_dma(struct pxa2xx_ep *ep, struct pxa2xx_request *req);#ifdef USE_OUT_DMA#define	DMASTR " (dma support)"#else#define	DMASTR " (dma in)"#endif#else	/* !USE_DMA */#define	DMASTR " (pio only)"#undef	USE_OUT_DMA#endif#ifdef	CONFIG_USB_PXA2XX_SMALL#define SIZE_STR	" (small)"#else#define SIZE_STR	""#endif#ifdef DISABLE_TEST_MODE/* (mode == 0) == no undocumented chip tweaks * (mode & 1)  == double buffer bulk IN * (mode & 2)  == double buffer bulk OUT * ... so mode = 3 (or 7, 15, etc) does it for both */static ushort fifo_mode = 0;MODULE_PARM (fifo_mode, "h");MODULE_PARM_DESC (fifo_mode, "pxa2xx udc fifo mode");#endif/* --------------------------------------------------------------------------- * 	endpoint related parts of the api to the usb controller hardware, *	used by gadget driver; and the inner talker-to-hardware core. * --------------------------------------------------------------------------- */static void pxa2xx_ep_fifo_flush (struct usb_ep *ep);static void nuke (struct pxa2xx_ep *, int status);static void pio_irq_enable(int bEndpointAddress){        bEndpointAddress &= 0xf;        if (bEndpointAddress < 8)                UICR0 &= ~(1 << bEndpointAddress);        else {                bEndpointAddress -= 8;                UICR1 &= ~(1 << bEndpointAddress);	}}static void pio_irq_disable(int bEndpointAddress){        bEndpointAddress &= 0xf;        if (bEndpointAddress < 8)                UICR0 |= 1 << bEndpointAddress;        else {                bEndpointAddress -= 8;                UICR1 |= 1 << bEndpointAddress;        }}/* The UDCCR reg contains mask and interrupt status bits, * so using '|=' isn't safe as it may ack an interrupt. */#define UDCCR_MASK_BITS         (UDCCR_REM | UDCCR_SRM | UDCCR_UDE)static inline void udc_set_mask_UDCCR(int mask){	UDCCR = (UDCCR & UDCCR_MASK_BITS) | (mask & UDCCR_MASK_BITS);}static inline void udc_clear_mask_UDCCR(int mask){	UDCCR = (UDCCR & UDCCR_MASK_BITS) & ~(mask & UDCCR_MASK_BITS);}static inline void udc_ack_int_UDCCR(int mask){	/* udccr contains the bits we dont want to change */	__u32 udccr = UDCCR & UDCCR_MASK_BITS;	UDCCR = udccr | (mask & ~UDCCR_MASK_BITS);}/* * endpoint enable/disable * * we need to verify the descriptors used to enable endpoints.  since pxa2xx * endpoint configurations are fixed, and are pretty much always enabled, * there's not a lot to manage here. * * because pxa2xx can't selectively initialize bulk (or interrupt) endpoints, * (resetting endpoint halt and toggle), SET_INTERFACE is unusable except * for a single interface (with only the default altsetting) and for gadget * drivers that don't halt endpoints (not reset by set_interface).  that also * means that if you use ISO, you must violate the USB spec rule that all * iso endpoints must be in non-default altsettings. */static int pxa2xx_ep_enable (struct usb_ep *_ep,		const struct usb_endpoint_descriptor *desc){	struct pxa2xx_ep        *ep;	struct pxa2xx_udc       *dev;	ep = container_of (_ep, struct pxa2xx_ep, ep);	if (!_ep || !desc || ep->desc || _ep->name == ep0name			|| desc->bDescriptorType != USB_DT_ENDPOINT			|| ep->bEndpointAddress != desc->bEndpointAddress			|| ep->fifo_size < le16_to_cpu						(desc->wMaxPacketSize)) {		DMSG("%s, bad ep or descriptor\n", __FUNCTION__);		return -EINVAL;	}	/* xfer types must match, except that interrupt ~= bulk */	if (ep->bmAttributes != desc->bmAttributes			&& ep->bmAttributes != USB_ENDPOINT_XFER_BULK			&& desc->bmAttributes != USB_ENDPOINT_XFER_INT) {		DMSG("%s, %s type mismatch\n", __FUNCTION__, _ep->name);		return -EINVAL;	}	/* hardware _could_ do smaller, but driver doesn't */	if ((desc->bmAttributes == USB_ENDPOINT_XFER_BULK				&& le16_to_cpu (desc->wMaxPacketSize)						!= BULK_FIFO_SIZE)			|| !desc->wMaxPacketSize) {		DMSG("%s, bad %s maxpacket\n", __FUNCTION__, _ep->name);		return -ERANGE;	}	dev = ep->dev;	if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) {		DMSG("%s, bogus device state\n", __FUNCTION__);		return -ESHUTDOWN;	}	ep->desc = desc;	ep->dma = -1;	ep->stopped = 0;	ep->pio_irqs = ep->dma_irqs = 0;	ep->ep.maxpacket = le16_to_cpu (desc->wMaxPacketSize);	/* flush fifo (mostly for OUT buffers) */	pxa2xx_ep_fifo_flush (_ep);	/* ... reset halt state too, if we could ... */#ifdef	USE_DMA	/* for (some) bulk and ISO endpoints, try to get a DMA channel and	 * bind it to the endpoint.  otherwise use PIO. 	 */	switch (ep->bmAttributes) {	case USB_ENDPOINT_XFER_ISOC:		if (le16_to_cpu(desc->wMaxPacketSize) % 32)			break;		// fall through	case USB_ENDPOINT_XFER_BULK:		if (!use_dma || !ep->reg_drcmr)			break;		/* no bulk-out dma yet (pointless w/o descriptors) */		if ((ep->bmAttributes == USB_ENDPOINT_XFER_BULK)				&& (ep->bEndpointAddress & USB_DIR_IN) == 0) {			DMSG("%s dma-out NYI\n", _ep->name);			break;		}		ep->dma = pxa_request_dma ((char *)_ep->name,				(le16_to_cpu(desc->wMaxPacketSize) > 64)					? DMA_PRIO_MEDIUM /* some iso */					: DMA_PRIO_LOW,				// FIXME or ep_out_dma .. ..				dma_nodesc_handler, ep);		if (ep->dma >= 0) {			*ep->reg_drcmr = DRCMR_MAPVLD | ep->dma;			DMSG("%s using dma%d\n", _ep->name, ep->dma);		}	}#endif	DBG(DBG_VERBOSE, "enabled %s\n", _ep->name);	return 0;}static int pxa2xx_ep_disable (struct usb_ep *_ep){	struct pxa2xx_ep	*ep;	ep = container_of (_ep, struct pxa2xx_ep, ep);	if (!_ep || !ep->desc) {		DMSG("%s, %s not enabled\n", __FUNCTION__,			_ep ? ep->ep.name : NULL);		return -EINVAL;	}	nuke (ep, -ESHUTDOWN);#ifdef	USE_DMA	if (ep->dma >= 0) {		*ep->reg_drcmr = 0;		pxa_free_dma (ep->dma);		ep->dma = -1;	}#endif	/* flush fifo (mostly for IN buffers) */	pxa2xx_ep_fifo_flush (_ep);	ep->desc = 0;	ep->stopped = 1;	DBG(DBG_VERBOSE, "%s disabled\n", _ep->name);	return 0;}/*-------------------------------------------------------------------------*//* for the pxa2xx, these can just wrap kmalloc/kfree.  gadget drivers * must still pass correctly initialized endpoints, since other controller * drivers may care about how it's currently set up (dma issues etc). *//* * 	pxa2xx_ep_alloc_request - allocate a request data structure */static struct usb_request *pxa2xx_ep_alloc_request (struct usb_ep *_ep, int gfp_flags){	struct pxa2xx_request *req;	/* FIXME for bulk out-dma endpoints, preallocate a frame's worth of	 * (aligned) dma descriptors at the end of the request	 */	req = kmalloc (sizeof *req, gfp_flags);	if (!req)		return 0;	memset (req, 0, sizeof *req);	INIT_LIST_HEAD (&req->queue);	return &req->req;}/* * 	pxa2xx_ep_free_request - deallocate a request data structure */static voidpxa2xx_ep_free_request (struct usb_ep *_ep, struct usb_request *_req){	struct pxa2xx_request	*req;	req = container_of (_req, struct pxa2xx_request, req);	WARN_ON (!list_empty (&req->queue));	kfree(req);}/* PXA cache needs flushing with DMA I/O (it's dma-incoherent), but there's * no device-affinity and the heap works perfectly well for i/o buffers. */static void *pxa2xx_ep_alloc_buffer(struct usb_ep *_ep, unsigned bytes,	dma_addr_t *dma, int gfp_flags){	char			*retval;	retval = kmalloc (bytes, gfp_flags & ~(__GFP_DMA|__GFP_HIGHMEM));	if (retval)		*dma = virt_to_bus (retval);	return retval;}static voidpxa2xx_ep_free_buffer(struct usb_ep *_ep, void *buf, dma_addr_t dma,		unsigned bytes){	kfree (buf);}/*-------------------------------------------------------------------------*//* *	done - retire a request; caller blocked irqs */static void done(struct pxa2xx_ep *ep, struct pxa2xx_request *req, int status){	unsigned		stopped = ep->stopped;	list_del_init(&req->queue);	if (likely (req->req.status == -EINPROGRESS))		req->req.status = status;	else		status = req->req.status;	if (status && status != -ESHUTDOWN)		DBG(DBG_VERBOSE, "complete %s req %p stat %d len %u/%u\n",			ep->ep.name, &req->req, status,			req->req.actual, req->req.length);	/* don't modify queue heads during completion callback */	ep->stopped = 1;	req->req.complete(&ep->ep, &req->req);	ep->stopped = stopped;}static inline void ep0_idle (struct pxa2xx_udc *dev){	dev->ep0state = EP0_IDLE;	LED_EP0_OFF;}static intwrite_packet(volatile u32 *uddr, struct pxa2xx_request *req, unsigned max){	u8		*buf;	unsigned	length, count;	buf = req->req.buf + req->req.actual;	prefetch(buf);	/* how big will this packet be? */	length = min(req->req.length - req->req.actual, max);	req->req.actual += length;	count = length;	while (likely(count--))		*uddr = *buf++;	return length;}/* * write to an IN endpoint fifo, as many packets as possible. * irqs will use this to write the rest later. * caller guarantees at least one packet buffer is ready (or a zlp). */static intwrite_fifo (struct pxa2xx_ep *ep, struct pxa2xx_request *req){	unsigned		max;	max = le16_to_cpu(ep->desc->wMaxPacketSize);	do {		unsigned	count;		int		is_last, is_short;		count = write_packet(ep->reg_uddr, req, max);		/* last packet is usually short (or a zlp) */		if (unlikely (count != max))			is_last = is_short = 1;		else {			if (likely(req->req.length != req->req.actual)					|| req->req.zero)				is_last = 0;			else				is_last = 1;			/* interrupt/iso maxpacket may not fill the fifo */			is_short = unlikely (max < ep->fifo_size);		}		DBG(DBG_VERY_NOISY, "wrote %s %d bytes%s%s %d left %p\n",			ep->ep.name, count,			is_last ? "/L" : "", is_short ? "/S" : "",			req->req.length - req->req.actual, req);		/* let loose that packet. maybe try writing another one,		 * double buffering might work.  TSP, TPC, and TFS		 * bit values are the same for all normal IN endpoints.		 */		*ep->reg_udccs = UDCCS_BI_TPC;		if (is_short)			*ep->reg_udccs = UDCCS_BI_TSP;		/* requests complete when all IN data is in the FIFO */		if (is_last) {			done (ep, req, 0);			if (list_empty(&ep->queue) || unlikely(ep->dma >= 0))				pio_irq_disable (ep->bEndpointAddress);#ifdef USE_DMA

?? 快捷鍵說明

復(fù)制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號(hào) Ctrl + =
減小字號(hào) Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
成人小视频在线| 色综合久久久久综合体| 国产精品对白交换视频| 欧美性猛片xxxx免费看久爱| 国产乱子伦视频一区二区三区| 亚洲丝袜另类动漫二区| 日韩一级在线观看| 在线欧美一区二区| 国产原创一区二区三区| 天天色天天爱天天射综合| 国产日韩欧美亚洲| 777xxx欧美| 在线一区二区三区做爰视频网站| 国产一区二区在线观看免费| 水蜜桃久久夜色精品一区的特点 | 一区二区三区高清在线| 久久精品欧美一区二区三区不卡 | 一区二区三区.www| 国产亚洲精品免费| 日韩一区二区视频| 欧美日韩亚洲综合| 色综合中文字幕国产 | 精品电影一区二区| 5858s免费视频成人| 色诱亚洲精品久久久久久| 国产成人在线影院| 久久精品国产99久久6| 亚洲一区二区三区美女| 国产精品毛片高清在线完整版| 欧美成人r级一区二区三区| 欧美日本一区二区| 欧美唯美清纯偷拍| 色屁屁一区二区| 99vv1com这只有精品| 大尺度一区二区| 国产精品一卡二卡| 狠狠狠色丁香婷婷综合久久五月| 石原莉奈在线亚洲三区| 亚洲国产一区视频| 一区二区三区不卡视频| 亚洲综合精品自拍| 一区二区三区四区不卡视频 | 亚洲天堂免费看| 最近中文字幕一区二区三区| 中文文精品字幕一区二区| 精品国产乱码久久久久久免费| 欧美成人在线直播| 精品久久久久99| 久久你懂得1024| 久久久www成人免费毛片麻豆| 日韩午夜电影av| 欧美www视频| 国产欧美一区二区精品仙草咪| 国产午夜精品福利| 国产精品你懂的在线| 亚洲婷婷在线视频| 亚洲大片精品永久免费| 免费精品视频最新在线| 国产永久精品大片wwwapp| 国产一区91精品张津瑜| 波多野结衣91| 色8久久精品久久久久久蜜| 欧美日韩在线三级| 日韩一级片在线播放| 精品裸体舞一区二区三区| 久久女同精品一区二区| 国产精品乱码久久久久久| 一区二区三区免费观看| 日韩国产精品久久| 国产剧情av麻豆香蕉精品| 成人福利视频在线看| 色噜噜夜夜夜综合网| 欧美精选午夜久久久乱码6080| 日韩女优制服丝袜电影| 国产精品久久久久9999吃药| 亚洲中国最大av网站| 日韩电影免费在线看| 国产成人三级在线观看| 在线免费观看一区| 精品国产乱码久久久久久1区2区| 国产亚洲欧美日韩在线一区| 亚洲美女少妇撒尿| 喷水一区二区三区| 成人激情av网| 制服.丝袜.亚洲.另类.中文| 国产欧美一区二区在线观看| 亚洲福利视频一区二区| 欧美性xxxxx极品少妇| 日韩一级高清毛片| 日韩理论片一区二区| 久久精品国产秦先生| 91在线视频播放| 日韩视频一区二区三区| 综合婷婷亚洲小说| 久久99久久久欧美国产| 91福利在线播放| 欧美高清在线一区| 男男成人高潮片免费网站| 99久久伊人网影院| 日韩免费一区二区| 一区二区欧美国产| 懂色av一区二区夜夜嗨| 9191国产精品| 亚洲精品菠萝久久久久久久| 黄色小说综合网站| 欧美精品在线观看播放| 日韩美女精品在线| 国产成人免费高清| 精品国产成人在线影院| 亚洲成a人v欧美综合天堂| 成人免费毛片aaaaa**| 欧美va在线播放| 日韩高清不卡一区二区三区| 色婷婷一区二区| 国产精品视频一二三| 精品一区二区在线观看| 欧美乱妇20p| 亚洲精品一卡二卡| jiyouzz国产精品久久| 久久婷婷一区二区三区| 蜜乳av一区二区| 欧美人与禽zozo性伦| 夜夜嗨av一区二区三区中文字幕 | 久久99国产精品免费网站| 欧美日韩精品一区二区天天拍小说 | 99久久精品国产麻豆演员表| 久久久久久久久一| 狠狠色丁香婷婷综合| 欧美videos大乳护士334| 欧美aaa在线| 91精品国产91久久综合桃花 | 青草国产精品久久久久久| 欧美性色欧美a在线播放| 依依成人综合视频| 91搞黄在线观看| 亚洲精品中文在线观看| 色婷婷综合久久久久中文一区二区| 中文字幕第一页久久| 国产激情一区二区三区四区 | 欧美日精品一区视频| 一区二区三区免费看视频| 在线一区二区视频| 亚洲成人免费看| 9191精品国产综合久久久久久| 石原莉奈在线亚洲二区| 日韩视频在线一区二区| 激情六月婷婷综合| 久久久久久久久99精品| 国产成人av电影在线| 国产精品久久久久久亚洲毛片| 成人动漫av在线| 亚洲欧美一区二区三区极速播放| 91麻豆高清视频| 亚洲成人精品一区| 欧美一区二区三区白人| 久国产精品韩国三级视频| 久久亚洲一级片| 99久久国产免费看| 亚洲韩国精品一区| 日韩欧美国产一二三区| 国产高清精品在线| 日韩理论片网站| 欧美精品电影在线播放| 黄色精品一二区| 国产精品久久久久天堂| 欧美综合天天夜夜久久| 日本亚洲视频在线| 日本一区二区三区四区| 91久久免费观看| 免费欧美日韩国产三级电影| 久久这里都是精品| 91视频观看免费| 日本人妖一区二区| 日本成人在线网站| 国产欧美日韩精品在线| 91国偷自产一区二区三区观看| 日韩影院在线观看| 国产视频一区不卡| 在线看国产日韩| 激情文学综合网| 亚洲免费高清视频在线| 欧美一区二区高清| 国产ts人妖一区二区| 亚洲福利一区二区| 中文字幕精品一区二区三区精品| 在线亚洲免费视频| 国模大尺度一区二区三区| 樱桃视频在线观看一区| 日韩女优制服丝袜电影| 91丨porny丨户外露出| 美女视频免费一区| 亚洲精品菠萝久久久久久久| 精品福利一二区| 欧美亚洲国产一区在线观看网站 | 久久久激情视频| 欧美自拍偷拍午夜视频| 国产一区二区精品久久91| 亚洲v日本v欧美v久久精品| 亚洲国产精品av| 日韩亚洲欧美中文三级|