亚洲欧美第一页_禁久久精品乱码_粉嫩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一区二区三区免费野_久草精品视频
亚洲欧洲精品天堂一级| 国产综合久久久久久久久久久久| 视频一区中文字幕国产| 国产精品一区二区你懂的| 欧美日韩另类一区| 国产精品免费视频网站| 精品一区精品二区高清| 在线观看免费视频综合| 国产精品每日更新| 国内精品不卡在线| 日韩视频免费观看高清完整版在线观看 | 亚洲国产成人av网| 99亚偷拍自图区亚洲| 久久综合久久综合亚洲| 日韩av中文在线观看| 日本精品视频一区二区| 国产精品盗摄一区二区三区| 久久精品国产久精国产| 制服丝袜在线91| 亚洲一区二区美女| 在线看日本不卡| 最新国产精品久久精品| 国产 日韩 欧美大片| 精品国产乱码久久久久久闺蜜| 亚洲影院免费观看| 欧美亚洲图片小说| 亚洲综合精品久久| 欧美少妇xxx| 亚洲一二三区不卡| 欧美日韩黄视频| 午夜私人影院久久久久| 欧美日本在线播放| 丝袜a∨在线一区二区三区不卡| 欧美性极品少妇| 午夜欧美大尺度福利影院在线看| 欧美怡红院视频| 亚洲国产aⅴ天堂久久| 欧美日韩色一区| 天堂久久久久va久久久久| 欧美一区二区三区免费在线看 | 欧美日韩在线三区| 五月婷婷综合网| 在线综合视频播放| 精品一区二区久久久| 久久日韩精品一区二区五区| 国产精品系列在线播放| 一区在线中文字幕| 欧美视频在线观看一区二区| 天天色综合成人网| 精品国产一区二区三区不卡| 国产精品88av| 亚洲男同性恋视频| 欧美色图一区二区三区| 免费欧美高清视频| 欧美激情在线一区二区| 色婷婷综合激情| 丝袜亚洲精品中文字幕一区| 精品久久人人做人人爽| 成人永久免费视频| 亚洲高清免费视频| 亚洲精品一区二区三区福利| 国产成人一区在线| 亚洲午夜视频在线观看| 日韩三级在线观看| 99在线精品观看| 青草av.久久免费一区| 欧美经典一区二区三区| 色又黄又爽网站www久久| 日韩不卡手机在线v区| 国产精品久久久久久亚洲毛片| 欧美在线影院一区二区| 韩国精品主播一区二区在线观看 | 日本亚洲视频在线| 国产三级一区二区| 欧美综合亚洲图片综合区| 韩日av一区二区| 亚洲在线一区二区三区| 2023国产一二三区日本精品2022| 一本久道中文字幕精品亚洲嫩| 男人的j进女人的j一区| 一区二区三区中文字幕精品精品 | 国产不卡视频一区二区三区| 亚洲综合丁香婷婷六月香| 国产午夜精品理论片a级大结局| 欧美最新大片在线看| 懂色av一区二区夜夜嗨| 日本vs亚洲vs韩国一区三区二区 | 欧美色视频一区| eeuss影院一区二区三区| 精品在线观看免费| 污片在线观看一区二区| 一区在线播放视频| 亚洲国产高清不卡| 精品理论电影在线观看| 5858s免费视频成人| 色婷婷综合中文久久一本| 粉嫩av亚洲一区二区图片| 久久草av在线| 日韩黄色一级片| 亚洲福利视频一区二区| 亚洲欧美日韩国产一区二区三区| 久久精品在线免费观看| 久久综合久色欧美综合狠狠| 日韩一级大片在线观看| 91精品国产综合久久精品性色| 色综合色狠狠综合色| av中文一区二区三区| 国产精品一级黄| 国产超碰在线一区| 国产高清在线观看免费不卡| 黄网站免费久久| 精品一区免费av| 国产乱码精品1区2区3区| 男女男精品视频网| 另类的小说在线视频另类成人小视频在线| 亚洲与欧洲av电影| 亚洲一二三区不卡| 日韩精品乱码免费| 男女男精品网站| 激情图片小说一区| 国产99久久久久久免费看农村| 国产麻豆精品在线观看| 国产精品自拍一区| av高清不卡在线| 欧美亚洲丝袜传媒另类| 欧美无砖专区一中文字| 在线不卡免费欧美| 制服视频三区第一页精品| 日韩视频免费观看高清在线视频| 精品国产麻豆免费人成网站| 久久亚洲精精品中文字幕早川悠里 | 国产最新精品免费| 波多野结衣一区二区三区 | 国产成人综合在线观看| 成人sese在线| 欧美在线免费视屏| 日韩视频一区二区三区在线播放 | 亚洲成a人v欧美综合天堂下载| 三级欧美韩日大片在线看| 久久av老司机精品网站导航| 国产精品99久久久久久似苏梦涵 | 洋洋成人永久网站入口| 日韩精彩视频在线观看| 国产精品99久久久| 欧美性做爰猛烈叫床潮| 亚洲精品一区二区三区四区高清 | 久久综合一区二区| 亚洲精品成人天堂一二三| 日韩精品一二区| 成人精品gif动图一区| 欧美色倩网站大全免费| 欧美va亚洲va在线观看蝴蝶网| 欧美激情中文不卡| 丝袜美腿亚洲一区| 菠萝蜜视频在线观看一区| 欧美福利视频一区| 国产精品美日韩| 蜜臀av性久久久久蜜臀aⅴ| 成人av综合在线| 精品久久久久久久久久久久久久久久久| 国产精品剧情在线亚洲| 麻豆精品国产91久久久久久| 欧美日韩极品在线观看一区| 国产色综合久久| 热久久一区二区| 欧美在线影院一区二区| 国产欧美日韩一区二区三区在线观看| 亚洲成人黄色影院| 99久久国产综合色|国产精品| 日韩一区二区三| 一区二区三区影院| 成人午夜在线播放| 精品久久人人做人人爽| 麻豆免费精品视频| 在线中文字幕一区二区| 中文字幕av一区二区三区| 日韩国产欧美三级| 色婷婷精品久久二区二区蜜臂av| 久久久久久久久久看片| 免费国产亚洲视频| 欧美日韩国产综合一区二区 | 色综合色狠狠综合色| 国产亚洲成年网址在线观看| 秋霞国产午夜精品免费视频 | 一本久道久久综合中文字幕| 久久综合色天天久久综合图片| 五月天中文字幕一区二区| 色妞www精品视频| 国产精品女主播av| 成人小视频在线| 国产精品久久久久aaaa樱花| 国产精品乡下勾搭老头1| 欧美不卡激情三级在线观看| 亚洲成av人片一区二区| 欧美视频在线观看一区| 一区二区三区在线视频观看| 色综合久久久久综合体| 亚洲最大成人综合| 精品视频999| 日韩高清电影一区|