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

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

?? ehci-q.c

?? host usb 主設備程序 支持sd卡 mouse keyboard 的最單單的驅動程序 gcc編譯
?? C
?? 第 1 頁 / 共 3 頁
字號:
/* * Copyright (C) 2001-2004 by 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., 675 Mass Ave, Cambridge, MA 02139, USA. *//* this file is part of ehci-hcd.c *//*-------------------------------------------------------------------------*//* * EHCI hardware queue manipulation ... the core.  QH/QTD manipulation. * * Control, bulk, and interrupt traffic all use "qh" lists.  They list "qtd" * entries describing USB transactions, max 16-20kB/entry (with 4kB-aligned * buffers needed for the larger number).  We use one QH per endpoint, queue * multiple urbs (all three types) per endpoint.  URBs may need several qtds. * * ISO traffic uses "ISO TD" (itd, and sitd) records, and (along with * interrupts) needs careful scheduling.  Performance improvements can be * an ongoing challenge.  That's in "ehci-sched.c". * * USB 1.1 devices are handled (a) by "companion" OHCI or UHCI root hubs, * or otherwise through transaction translators (TTs) in USB 2.0 hubs using * (b) special fields in qh entries or (c) split iso entries.  TTs will * buffer low/full speed data so the host collects it at high speed. *//*-------------------------------------------------------------------------*//* fill a qtd, returning how much of the buffer we were able to queue up */static intqtd_fill (struct ehci_qtd *qtd, dma_addr_t buf, size_t len,		int token, int maxpacket){	int	i, count;	u64	addr = buf;	/* one buffer entry per 4K ... first might be short or unaligned */	qtd->hw_buf [0] = cpu_to_le32 ((u32)addr);	qtd->hw_buf_hi [0] = cpu_to_le32 ((u32)(addr >> 32));	count = 0x1000 - (buf & 0x0fff);	/* rest of that page */	if (likely (len < count))		/* ... iff needed */		count = len;	else {		buf +=  0x1000;		buf &= ~0x0fff;		/* per-qtd limit: from 16K to 20K (best alignment) */		for (i = 1; count < len && i < 5; i++) {			addr = buf;			qtd->hw_buf [i] = cpu_to_le32 ((u32)addr);			qtd->hw_buf_hi [i] = cpu_to_le32 ((u32)(addr >> 32));			buf += 0x1000;			if ((count + 0x1000) < len)				count += 0x1000;			else				count = len;		}		/* short packets may only terminate transfers */		if (count != len)			count -= (count % maxpacket);	}	qtd->hw_token = cpu_to_le32 ((count << 16) | token);	qtd->length = count;	return count;}/*-------------------------------------------------------------------------*/static inline voidqh_update (struct ehci_hcd *ehci, struct ehci_qh *qh, struct ehci_qtd *qtd){	/* writes to an active overlay are unsafe */	BUG_ON(qh->qh_state != QH_STATE_IDLE);	qh->hw_qtd_next = QTD_NEXT (qtd->qtd_dma);	qh->hw_alt_next = EHCI_LIST_END;	/* Except for control endpoints, we make hardware maintain data	 * toggle (like OHCI) ... here (re)initialize the toggle in the QH,	 * and set the pseudo-toggle in udev. Only usb_clear_halt() will	 * ever clear it.	 */	if (!(qh->hw_info1 & cpu_to_le32(1 << 14))) {		unsigned	is_out, epnum;		is_out = !(qtd->hw_token & cpu_to_le32(1 << 8));		epnum = (le32_to_cpup(&qh->hw_info1) >> 8) & 0x0f;		if (unlikely (!usb_gettoggle (qh->dev, epnum, is_out))) {			qh->hw_token &= ~__constant_cpu_to_le32 (QTD_TOGGLE);			usb_settoggle (qh->dev, epnum, is_out, 1);		}	}	/* HC must see latest qtd and qh data before we clear ACTIVE+HALT */	wmb ();	qh->hw_token &= __constant_cpu_to_le32 (QTD_TOGGLE | QTD_STS_PING);}/* if it weren't for a common silicon quirk (writing the dummy into the qh * overlay, so qh->hw_token wrongly becomes inactive/halted), only fault * recovery (including urb dequeue) would need software changes to a QH... */static voidqh_refresh (struct ehci_hcd *ehci, struct ehci_qh *qh){	struct ehci_qtd *qtd;	if (list_empty (&qh->qtd_list))		qtd = qh->dummy;	else {		qtd = list_entry (qh->qtd_list.next,				struct ehci_qtd, qtd_list);		/* first qtd may already be partially processed */		if (cpu_to_le32 (qtd->qtd_dma) == qh->hw_current)			qtd = NULL;	}	if (qtd)		qh_update (ehci, qh, qtd);}/*-------------------------------------------------------------------------*/static void qtd_copy_status (	struct ehci_hcd *ehci,	struct urb *urb,	size_t length,	u32 token){	/* count IN/OUT bytes, not SETUP (even short packets) */	if (likely (QTD_PID (token) != 2))		urb->actual_length += length - QTD_LENGTH (token);	/* don't modify error codes */	if (unlikely (urb->status != -EINPROGRESS))		return;	/* force cleanup after short read; not always an error */	if (unlikely (IS_SHORT_READ (token)))		urb->status = -EREMOTEIO;	/* serious "can't proceed" faults reported by the hardware */	if (token & QTD_STS_HALT) {		if (token & QTD_STS_BABBLE) {			/* FIXME "must" disable babbling device's port too */			urb->status = -EOVERFLOW;		} else if (token & QTD_STS_MMF) {			/* fs/ls interrupt xfer missed the complete-split */			urb->status = -EPROTO;		} else if (token & QTD_STS_DBE) {			urb->status = (QTD_PID (token) == 1) /* IN ? */				? -ENOSR  /* hc couldn't read data */				: -ECOMM; /* hc couldn't write data */		} else if (token & QTD_STS_XACT) {			/* timeout, bad crc, wrong PID, etc; retried */			if (QTD_CERR (token))				urb->status = -EPIPE;			else {				ehci_dbg (ehci, "devpath %s ep%d%s 3strikes\n",					urb->dev->devpath,					usb_pipeendpoint (urb->pipe),					usb_pipein (urb->pipe) ? "in" : "out");				urb->status = -EPROTO;			}		/* CERR nonzero + no errors + halt --> stall */		} else if (QTD_CERR (token))			urb->status = -EPIPE;		else	/* unknown */			urb->status = -EPROTO;		ehci_vdbg (ehci,			"dev%d ep%d%s qtd token %08x --> status %d\n",			usb_pipedevice (urb->pipe),			usb_pipeendpoint (urb->pipe),			usb_pipein (urb->pipe) ? "in" : "out",			token, urb->status);		/* if async CSPLIT failed, try cleaning out the TT buffer */		if (urb->status != -EPIPE				&& urb->dev->tt && !usb_pipeint (urb->pipe)				&& ((token & QTD_STS_MMF) != 0					|| QTD_CERR(token) == 0)				&& (!ehci_is_TDI(ehci)			                || urb->dev->tt->hub !=					   ehci_to_hcd(ehci)->self.root_hub)) {#ifdef DEBUG			struct usb_device *tt = urb->dev->tt->hub;			dev_dbg (&tt->dev,				"clear tt buffer port %d, a%d ep%d t%08x\n",				urb->dev->ttport, urb->dev->devnum,				usb_pipeendpoint (urb->pipe), token);#endif /* DEBUG */			usb_hub_tt_clear_buffer (urb->dev, urb->pipe);		}	}}static voidehci_urb_done (struct ehci_hcd *ehci, struct urb *urb)__releases(ehci->lock)__acquires(ehci->lock){	if (likely (urb->hcpriv != NULL)) {		struct ehci_qh	*qh = (struct ehci_qh *) urb->hcpriv;		/* S-mask in a QH means it's an interrupt urb */		if ((qh->hw_info2 & __constant_cpu_to_le32 (QH_SMASK)) != 0) {			/* ... update hc-wide periodic stats (for usbfs) */			ehci_to_hcd(ehci)->self.bandwidth_int_reqs--;		}		qh_put (qh);	}	spin_lock (&urb->lock);	urb->hcpriv = NULL;	switch (urb->status) {	case -EINPROGRESS:		/* success */		urb->status = 0;	default:			/* fault */		COUNT (ehci->stats.complete);		break;	case -EREMOTEIO:		/* fault or normal */		if (!(urb->transfer_flags & URB_SHORT_NOT_OK))			urb->status = 0;		COUNT (ehci->stats.complete);		break;	case -ECONNRESET:		/* canceled */	case -ENOENT:		COUNT (ehci->stats.unlink);		break;	}	spin_unlock (&urb->lock);#ifdef EHCI_URB_TRACE	ehci_dbg (ehci,		"%s %s urb %p ep%d%s status %d len %d/%d\n",		__FUNCTION__, urb->dev->devpath, urb,		usb_pipeendpoint (urb->pipe),		usb_pipein (urb->pipe) ? "in" : "out",		urb->status,		urb->actual_length, urb->transfer_buffer_length);#endif	/* complete() can reenter this HCD */	spin_unlock (&ehci->lock);	usb_hcd_giveback_urb (ehci_to_hcd(ehci), urb);	spin_lock (&ehci->lock);}static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh);static void unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh);static void intr_deschedule (struct ehci_hcd *ehci, struct ehci_qh *qh);static int qh_schedule (struct ehci_hcd *ehci, struct ehci_qh *qh);/* * Process and free completed qtds for a qh, returning URBs to drivers. * Chases up to qh->hw_current.  Returns number of completions called, * indicating how much "real" work we did. */#define HALT_BIT __constant_cpu_to_le32(QTD_STS_HALT)static unsignedqh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh){	struct ehci_qtd		*last = NULL, *end = qh->dummy;	struct list_head	*entry, *tmp;	int			stopped;	unsigned		count = 0;	int			do_status = 0;	u8			state;	if (unlikely (list_empty (&qh->qtd_list)))		return count;	/* completions (or tasks on other cpus) must never clobber HALT	 * till we've gone through and cleaned everything up, even when	 * they add urbs to this qh's queue or mark them for unlinking.	 *	 * NOTE:  unlinking expects to be done in queue order.	 */	state = qh->qh_state;	qh->qh_state = QH_STATE_COMPLETING;	stopped = (state == QH_STATE_IDLE);	/* remove de-activated QTDs from front of queue.	 * after faults (including short reads), cleanup this urb	 * then let the queue advance.	 * if queue is stopped, handles unlinks.	 */	list_for_each_safe (entry, tmp, &qh->qtd_list) {		struct ehci_qtd	*qtd;		struct urb	*urb;		u32		token = 0;		qtd = list_entry (entry, struct ehci_qtd, qtd_list);		urb = qtd->urb;		/* clean up any state from previous QTD ...*/		if (last) {			if (likely (last->urb != urb)) {				ehci_urb_done (ehci, last->urb);				count++;			}			ehci_qtd_free (ehci, last);			last = NULL;		}		/* ignore urbs submitted during completions we reported */		if (qtd == end)			break;		/* hardware copies qtd out of qh overlay */		rmb ();		token = le32_to_cpu (qtd->hw_token);		/* always clean up qtds the hc de-activated */		if ((token & QTD_STS_ACTIVE) == 0) {			if ((token & QTD_STS_HALT) != 0) {				stopped = 1;			/* magic dummy for some short reads; qh won't advance.			 * that silicon quirk can kick in with this dummy too.			 */			} else if (IS_SHORT_READ (token)					&& !(qtd->hw_alt_next & EHCI_LIST_END)) {				stopped = 1;				goto halt;			}		/* stop scanning when we reach qtds the hc is using */		} else if (likely (!stopped				&& HC_IS_RUNNING (ehci_to_hcd(ehci)->state))) {			break;		} else {			stopped = 1;			if (unlikely (!HC_IS_RUNNING (ehci_to_hcd(ehci)->state)))				urb->status = -ESHUTDOWN;			/* ignore active urbs unless some previous qtd			 * for the urb faulted (including short read) or			 * its urb was canceled.  we may patch qh or qtds.			 */			if (likely (urb->status == -EINPROGRESS))				continue;			/* issue status after short control reads */			if (unlikely (do_status != 0)					&& QTD_PID (token) == 0 /* OUT */) {				do_status = 0;				continue;			}

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
视频在线观看91| 亚洲人成精品久久久久| 麻豆精品久久精品色综合| 欧美日韩在线播放一区| 婷婷一区二区三区| 337p粉嫩大胆噜噜噜噜噜91av| 九色porny丨国产精品| 国产欧美日韩另类视频免费观看| 成人一区二区三区| 亚洲最大成人综合| 欧美变态口味重另类| 国产激情视频一区二区在线观看| 中文字幕色av一区二区三区| 色嗨嗨av一区二区三区| 日本v片在线高清不卡在线观看| 精品国产99国产精品| av一区二区三区| 日本伊人午夜精品| 国产蜜臀97一区二区三区| 欧美中文一区二区三区| 另类人妖一区二区av| 国产精品久久久久久福利一牛影视| 在线视频你懂得一区| 久久99精品一区二区三区| 中文字幕一区二区三区在线播放| 在线免费不卡视频| 精品一区二区三区在线播放| 亚洲人成影院在线观看| 7777女厕盗摄久久久| 成人精品视频一区二区三区尤物| 图片区日韩欧美亚洲| 国产日韩在线不卡| 欧美高清精品3d| 成人在线视频一区二区| 免费成人av在线| 亚洲久本草在线中文字幕| 久久久影视传媒| 91麻豆精品91久久久久久清纯| 成人h精品动漫一区二区三区| 亚洲成a人在线观看| 中文字幕一区二区5566日韩| 欧美一二区视频| 欧美三级日本三级少妇99| 成人免费高清在线观看| 经典一区二区三区| 日精品一区二区| 亚洲精品一二三| 国产精品麻豆久久久| 欧美成人欧美edvon| 欧美精品九九99久久| 91美女在线观看| 成人污视频在线观看| 狠狠色综合播放一区二区| 亚洲v中文字幕| 一区二区三区四区在线| 欧美国产精品一区二区三区| 欧美电视剧在线看免费| 欧美美女直播网站| 在线观看免费视频综合| 91麻豆精品在线观看| 国产91富婆露脸刺激对白| 国产一区二三区| 精品一区二区在线看| 蜜臀国产一区二区三区在线播放 | 一区二区三区在线视频免费| 欧美激情一区二区| 国产网红主播福利一区二区| 日韩欧美高清dvd碟片| 欧美一区二区国产| 欧美精品777| 777亚洲妇女| 日韩欧美国产1| 精品日产卡一卡二卡麻豆| 26uuu亚洲综合色欧美| 欧美一级午夜免费电影| 日韩午夜精品电影| 欧美videos大乳护士334| 精品精品欲导航| 久久日一线二线三线suv| 精品国产91久久久久久久妲己| 欧美成人乱码一区二区三区| 久久综合九色综合97_久久久 | 99re这里只有精品首页| 97久久超碰国产精品| 色综合天天天天做夜夜夜夜做| 91偷拍与自偷拍精品| 日本韩国欧美一区| 欧美日韩久久不卡| 日韩三级在线免费观看| 久久综合久色欧美综合狠狠| 久久免费视频一区| 中文字幕一区在线观看视频| 午夜精品久久久久久不卡8050| 免费观看在线综合| 国产成人在线视频网址| 色国产综合视频| 欧美一区午夜精品| 中文字幕欧美激情一区| 一区二区三区在线影院| 美女网站一区二区| 成人国产精品免费网站| 在线日韩一区二区| 欧美精品一区二区高清在线观看| 国产精品色眯眯| 亚洲一区av在线| 国产一区二区三区在线观看精品| 91在线观看视频| 欧美一级欧美一级在线播放| 国产视频一区在线播放| 亚洲一区二区在线免费看| 狠狠色丁香婷综合久久| 一本久道久久综合中文字幕| 日韩女优视频免费观看| 亚洲天天做日日做天天谢日日欢| 日本成人在线一区| 91丨九色丨黑人外教| 日韩区在线观看| 亚洲欧美日韩成人高清在线一区| 日本美女一区二区| 99久久久免费精品国产一区二区| 91精品国产高清一区二区三区| 中文字幕一区二区三区不卡在线 | 久久众筹精品私拍模特| 亚洲日韩欧美一区二区在线| 免费久久精品视频| 91蝌蚪porny九色| 久久嫩草精品久久久精品| 亚洲综合激情另类小说区| 懂色av一区二区三区免费观看| 欧美日韩一区二区三区在线| 国产精品免费视频网站| 韩国女主播一区二区三区| 欧美日本一道本在线视频| 国产精品电影一区二区三区| 精品一区二区精品| 欧美喷水一区二区| 亚洲已满18点击进入久久| 国产成+人+日韩+欧美+亚洲| 日韩精品专区在线影院观看| 一区二区三区四区av| 成人性生交大片免费| 欧美精品一区二区在线观看| 奇米色777欧美一区二区| 色婷婷久久99综合精品jk白丝| 国产欧美精品国产国产专区 | 国产欧美一区二区三区网站| 蜜桃av噜噜一区| 欧美三级日韩在线| 亚洲国产精品一区二区尤物区| www.在线欧美| 国产精品毛片大码女人| 丁香婷婷综合网| 久久久久亚洲综合| 国产在线精品免费av| 欧美大黄免费观看| 免费成人在线观看| 日韩欧美国产麻豆| 另类中文字幕网| 日韩欧美一级二级| 麻豆91精品91久久久的内涵| 欧美一区日韩一区| 久久99九九99精品| 久久久亚洲午夜电影| 国产成人免费网站| 中文在线资源观看网站视频免费不卡| 国产精品亚洲一区二区三区在线| 欧美精品一区二区在线播放| 国产一区二区影院| 中文字幕国产精品一区二区| 不卡av电影在线播放| 亚洲欧美日韩国产综合在线| 色欧美片视频在线观看| 亚洲高清不卡在线观看| 欧美日韩精品一区视频| 美女网站一区二区| 久久精品视频在线免费观看| 国产91精品露脸国语对白| 亚洲摸摸操操av| 欧美精品一二三| 久久爱www久久做| 中文字幕不卡在线| 91香蕉视频在线| 日本午夜精品视频在线观看 | 日本免费在线视频不卡一不卡二 | 国产视频一区在线观看| 成人午夜视频在线| 亚洲激情av在线| 日韩欧美一区二区免费| 国产精品一区二区你懂的| 国产精品久久久久三级| 欧美亚洲高清一区| 久久99国产精品尤物| 亚洲欧洲精品天堂一级| 欧美午夜宅男影院| 久久99国产精品尤物| 亚洲欧洲另类国产综合| 欧美一级黄色片| 91欧美激情一区二区三区成人| 日本强好片久久久久久aaa| 国产精品系列在线|