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

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

?? uhci-q.c

?? host usb 主設(shè)備程序 支持sd卡 mouse keyboard 的最單單的驅(qū)動(dòng)程序 gcc編譯
?? C
?? 第 1 頁 / 共 4 頁
字號(hào):
/* * Universal Host Controller Interface driver for USB. * * Maintainer: Alan Stern <stern@rowland.harvard.edu> * * (C) Copyright 1999 Linus Torvalds * (C) Copyright 1999-2002 Johannes Erdfelt, johannes@erdfelt.com * (C) Copyright 1999 Randy Dunlap * (C) Copyright 1999 Georg Acher, acher@in.tum.de * (C) Copyright 1999 Deti Fliegl, deti@fliegl.de * (C) Copyright 1999 Thomas Sailer, sailer@ife.ee.ethz.ch * (C) Copyright 1999 Roman Weissgaerber, weissg@vienna.at * (C) Copyright 2000 Yggdrasil Computing, Inc. (port of new PCI interface *               support from usb-ohci.c by Adam Richter, adam@yggdrasil.com). * (C) Copyright 1999 Gregory P. Smith (from usb-ohci.c) * (C) Copyright 2004-2007 Alan Stern, stern@rowland.harvard.edu *//* * Technically, updating td->status here is a race, but it's not really a * problem. The worst that can happen is that we set the IOC bit again * generating a spurious interrupt. We could fix this by creating another * QH and leaving the IOC bit always set, but then we would have to play * games with the FSBR code to make sure we get the correct order in all * the cases. I don't think it's worth the effort */static void uhci_set_next_interrupt(struct uhci_hcd *uhci){	if (uhci->is_stopped)		mod_timer(&uhci_to_hcd(uhci)->rh_timer, jiffies);	uhci->term_td->status |= cpu_to_le32(TD_CTRL_IOC); }static inline void uhci_clear_next_interrupt(struct uhci_hcd *uhci){	uhci->term_td->status &= ~cpu_to_le32(TD_CTRL_IOC);}/* * Full-Speed Bandwidth Reclamation (FSBR). * We turn on FSBR whenever a queue that wants it is advancing, * and leave it on for a short time thereafter. */static void uhci_fsbr_on(struct uhci_hcd *uhci){	struct uhci_qh *lqh;	/* The terminating skeleton QH always points back to the first	 * FSBR QH.  Make the last async QH point to the terminating	 * skeleton QH. */	uhci->fsbr_is_on = 1;	lqh = list_entry(uhci->skel_async_qh->node.prev,			struct uhci_qh, node);	lqh->link = LINK_TO_QH(uhci->skel_term_qh);}static void uhci_fsbr_off(struct uhci_hcd *uhci){	struct uhci_qh *lqh;	/* Remove the link from the last async QH to the terminating	 * skeleton QH. */	uhci->fsbr_is_on = 0;	lqh = list_entry(uhci->skel_async_qh->node.prev,			struct uhci_qh, node);	lqh->link = UHCI_PTR_TERM;}static void uhci_add_fsbr(struct uhci_hcd *uhci, struct urb *urb){	struct urb_priv *urbp = urb->hcpriv;	if (!(urb->transfer_flags & URB_NO_FSBR))		urbp->fsbr = 1;}static void uhci_urbp_wants_fsbr(struct uhci_hcd *uhci, struct urb_priv *urbp){	if (urbp->fsbr) {		uhci->fsbr_is_wanted = 1;		if (!uhci->fsbr_is_on)			uhci_fsbr_on(uhci);		else if (uhci->fsbr_expiring) {			uhci->fsbr_expiring = 0;			del_timer(&uhci->fsbr_timer);		}	}}static void uhci_fsbr_timeout(unsigned long _uhci){	struct uhci_hcd *uhci = (struct uhci_hcd *) _uhci;	unsigned long flags;	spin_lock_irqsave(&uhci->lock, flags);	if (uhci->fsbr_expiring) {		uhci->fsbr_expiring = 0;		uhci_fsbr_off(uhci);	}	spin_unlock_irqrestore(&uhci->lock, flags);}static struct uhci_td *uhci_alloc_td(struct uhci_hcd *uhci){	dma_addr_t dma_handle;	struct uhci_td *td;	td = dma_pool_alloc(uhci->td_pool, GFP_ATOMIC, &dma_handle);	if (!td)		return NULL;	td->dma_handle = dma_handle;	td->frame = -1;	INIT_LIST_HEAD(&td->list);	INIT_LIST_HEAD(&td->fl_list);	return td;}static void uhci_free_td(struct uhci_hcd *uhci, struct uhci_td *td){	if (!list_empty(&td->list))		dev_warn(uhci_dev(uhci), "td %p still in list!\n", td);	if (!list_empty(&td->fl_list))		dev_warn(uhci_dev(uhci), "td %p still in fl_list!\n", td);	dma_pool_free(uhci->td_pool, td, td->dma_handle);}static inline void uhci_fill_td(struct uhci_td *td, u32 status,		u32 token, u32 buffer){	td->status = cpu_to_le32(status);	td->token = cpu_to_le32(token);	td->buffer = cpu_to_le32(buffer);}static void uhci_add_td_to_urbp(struct uhci_td *td, struct urb_priv *urbp){	list_add_tail(&td->list, &urbp->td_list);}static void uhci_remove_td_from_urbp(struct uhci_td *td){	list_del_init(&td->list);}/* * We insert Isochronous URBs directly into the frame list at the beginning */static inline void uhci_insert_td_in_frame_list(struct uhci_hcd *uhci,		struct uhci_td *td, unsigned framenum){	framenum &= (UHCI_NUMFRAMES - 1);	td->frame = framenum;	/* Is there a TD already mapped there? */	if (uhci->frame_cpu[framenum]) {		struct uhci_td *ftd, *ltd;		ftd = uhci->frame_cpu[framenum];		ltd = list_entry(ftd->fl_list.prev, struct uhci_td, fl_list);		list_add_tail(&td->fl_list, &ftd->fl_list);		td->link = ltd->link;		wmb();		ltd->link = LINK_TO_TD(td);	} else {		td->link = uhci->frame[framenum];		wmb();		uhci->frame[framenum] = LINK_TO_TD(td);		uhci->frame_cpu[framenum] = td;	}}static inline void uhci_remove_td_from_frame_list(struct uhci_hcd *uhci,		struct uhci_td *td){	/* If it's not inserted, don't remove it */	if (td->frame == -1) {		WARN_ON(!list_empty(&td->fl_list));		return;	}	if (uhci->frame_cpu[td->frame] == td) {		if (list_empty(&td->fl_list)) {			uhci->frame[td->frame] = td->link;			uhci->frame_cpu[td->frame] = NULL;		} else {			struct uhci_td *ntd;			ntd = list_entry(td->fl_list.next, struct uhci_td, fl_list);			uhci->frame[td->frame] = LINK_TO_TD(ntd);			uhci->frame_cpu[td->frame] = ntd;		}	} else {		struct uhci_td *ptd;		ptd = list_entry(td->fl_list.prev, struct uhci_td, fl_list);		ptd->link = td->link;	}	list_del_init(&td->fl_list);	td->frame = -1;}static inline void uhci_remove_tds_from_frame(struct uhci_hcd *uhci,		unsigned int framenum){	struct uhci_td *ftd, *ltd;	framenum &= (UHCI_NUMFRAMES - 1);	ftd = uhci->frame_cpu[framenum];	if (ftd) {		ltd = list_entry(ftd->fl_list.prev, struct uhci_td, fl_list);		uhci->frame[framenum] = ltd->link;		uhci->frame_cpu[framenum] = NULL;		while (!list_empty(&ftd->fl_list))			list_del_init(ftd->fl_list.prev);	}}/* * Remove all the TDs for an Isochronous URB from the frame list */static void uhci_unlink_isochronous_tds(struct uhci_hcd *uhci, struct urb *urb){	struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv;	struct uhci_td *td;	list_for_each_entry(td, &urbp->td_list, list)		uhci_remove_td_from_frame_list(uhci, td);}static struct uhci_qh *uhci_alloc_qh(struct uhci_hcd *uhci,		struct usb_device *udev, struct usb_host_endpoint *hep){	dma_addr_t dma_handle;	struct uhci_qh *qh;	qh = dma_pool_alloc(uhci->qh_pool, GFP_ATOMIC, &dma_handle);	if (!qh)		return NULL;	memset(qh, 0, sizeof(*qh));	qh->dma_handle = dma_handle;	qh->element = UHCI_PTR_TERM;	qh->link = UHCI_PTR_TERM;	INIT_LIST_HEAD(&qh->queue);	INIT_LIST_HEAD(&qh->node);	if (udev) {		/* Normal QH */		qh->type = hep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;		if (qh->type != USB_ENDPOINT_XFER_ISOC) {			qh->dummy_td = uhci_alloc_td(uhci);			if (!qh->dummy_td) {				dma_pool_free(uhci->qh_pool, qh, dma_handle);				return NULL;			}		}		qh->state = QH_STATE_IDLE;		qh->hep = hep;		qh->udev = udev;		hep->hcpriv = qh;		if (qh->type == USB_ENDPOINT_XFER_INT ||				qh->type == USB_ENDPOINT_XFER_ISOC)			qh->load = usb_calc_bus_time(udev->speed,					usb_endpoint_dir_in(&hep->desc),					qh->type == USB_ENDPOINT_XFER_ISOC,					le16_to_cpu(hep->desc.wMaxPacketSize))				/ 1000 + 1;	} else {		/* Skeleton QH */		qh->state = QH_STATE_ACTIVE;		qh->type = -1;	}	return qh;}static void uhci_free_qh(struct uhci_hcd *uhci, struct uhci_qh *qh){	WARN_ON(qh->state != QH_STATE_IDLE && qh->udev);	if (!list_empty(&qh->queue))		dev_warn(uhci_dev(uhci), "qh %p list not empty!\n", qh);	list_del(&qh->node);	if (qh->udev) {		qh->hep->hcpriv = NULL;		if (qh->dummy_td)			uhci_free_td(uhci, qh->dummy_td);	}	dma_pool_free(uhci->qh_pool, qh, qh->dma_handle);}/* * When a queue is stopped and a dequeued URB is given back, adjust * the previous TD link (if the URB isn't first on the queue) or * save its toggle value (if it is first and is currently executing). * * Returns 0 if the URB should not yet be given back, 1 otherwise. */static int uhci_cleanup_queue(struct uhci_hcd *uhci, struct uhci_qh *qh,		struct urb *urb){	struct urb_priv *urbp = urb->hcpriv;	struct uhci_td *td;	int ret = 1;	/* Isochronous pipes don't use toggles and their TD link pointers	 * get adjusted during uhci_urb_dequeue().  But since their queues	 * cannot truly be stopped, we have to watch out for dequeues	 * occurring after the nominal unlink frame. */	if (qh->type == USB_ENDPOINT_XFER_ISOC) {		ret = (uhci->frame_number + uhci->is_stopped !=				qh->unlink_frame);		goto done;	}	/* If the URB isn't first on its queue, adjust the link pointer	 * of the last TD in the previous URB.  The toggle doesn't need	 * to be saved since this URB can't be executing yet. */	if (qh->queue.next != &urbp->node) {		struct urb_priv *purbp;		struct uhci_td *ptd;		purbp = list_entry(urbp->node.prev, struct urb_priv, node);		WARN_ON(list_empty(&purbp->td_list));		ptd = list_entry(purbp->td_list.prev, struct uhci_td,				list);		td = list_entry(urbp->td_list.prev, struct uhci_td,				list);		ptd->link = td->link;		goto done;	}	/* If the QH element pointer is UHCI_PTR_TERM then then currently	 * executing URB has already been unlinked, so this one isn't it. */	if (qh_element(qh) == UHCI_PTR_TERM)		goto done;	qh->element = UHCI_PTR_TERM;	/* Control pipes don't have to worry about toggles */	if (qh->type == USB_ENDPOINT_XFER_CONTROL)		goto done;	/* Save the next toggle value */	WARN_ON(list_empty(&urbp->td_list));	td = list_entry(urbp->td_list.next, struct uhci_td, list);	qh->needs_fixup = 1;	qh->initial_toggle = uhci_toggle(td_token(td));done:	return ret;}/* * Fix up the data toggles for URBs in a queue, when one of them * terminates early (short transfer, error, or dequeued). */static void uhci_fixup_toggles(struct uhci_qh *qh, int skip_first){	struct urb_priv *urbp = NULL;	struct uhci_td *td;	unsigned int toggle = qh->initial_toggle;	unsigned int pipe;	/* Fixups for a short transfer start with the second URB in the	 * queue (the short URB is the first). */	if (skip_first)		urbp = list_entry(qh->queue.next, struct urb_priv, node);	/* When starting with the first URB, if the QH element pointer is	 * still valid then we know the URB's toggles are okay. */	else if (qh_element(qh) != UHCI_PTR_TERM)		toggle = 2;	/* Fix up the toggle for the URBs in the queue.  Normally this	 * loop won't run more than once: When an error or short transfer	 * occurs, the queue usually gets emptied. */	urbp = list_prepare_entry(urbp, &qh->queue, node);	list_for_each_entry_continue(urbp, &qh->queue, node) {		/* If the first TD has the right toggle value, we don't		 * need to change any toggles in this URB */		td = list_entry(urbp->td_list.next, struct uhci_td, list);		if (toggle > 1 || uhci_toggle(td_token(td)) == toggle) {			td = list_entry(urbp->td_list.prev, struct uhci_td,					list);			toggle = uhci_toggle(td_token(td)) ^ 1;		/* Otherwise all the toggles in the URB have to be switched */		} else {			list_for_each_entry(td, &urbp->td_list, list) {				td->token ^= __constant_cpu_to_le32(							TD_TOKEN_TOGGLE);				toggle ^= 1;			}		}	}	wmb();	pipe = list_entry(qh->queue.next, struct urb_priv, node)->urb->pipe;	usb_settoggle(qh->udev, usb_pipeendpoint(pipe),			usb_pipeout(pipe), toggle);	qh->needs_fixup = 0;}/* * Link an Isochronous QH into its skeleton's list */static inline void link_iso(struct uhci_hcd *uhci, struct uhci_qh *qh){	list_add_tail(&qh->node, &uhci->skel_iso_qh->node);	/* Isochronous QHs aren't linked by the hardware */}/* * Link a high-period interrupt QH into the schedule at the end of its * skeleton's list */static void link_interrupt(struct uhci_hcd *uhci, struct uhci_qh *qh){	struct uhci_qh *pqh;	list_add_tail(&qh->node, &uhci->skelqh[qh->skel]->node);	pqh = list_entry(qh->node.prev, struct uhci_qh, node);

?? 快捷鍵說明

復(fù)制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號(hào) Ctrl + =
減小字號(hào) Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
国产精品不卡在线| 欧美草草影院在线视频| 一二三四社区欧美黄| 91麻豆产精品久久久久久| 一色屋精品亚洲香蕉网站| 91麻豆国产精品久久| 亚洲一区二区三区自拍| 337p亚洲精品色噜噜噜| 九九视频精品免费| 久久久久久久久久久久久夜| 成人美女在线观看| 亚洲男人都懂的| 欧美电影在哪看比较好| 国产激情一区二区三区四区| 亚洲欧洲99久久| 欧美日韩免费在线视频| 精品中文字幕一区二区小辣椒 | 亚洲va在线va天堂| 欧美一区二区三区精品| 国产成人免费视频 | 亚洲在线中文字幕| 日韩无一区二区| 国产麻豆成人精品| 一区二区三区视频在线看| 91麻豆精品国产91久久久资源速度| 麻豆精品在线看| 亚洲私人黄色宅男| 欧美一级片免费看| 99精品久久只有精品| 三级不卡在线观看| 中文字幕亚洲在| 日韩欧美中文字幕制服| 91免费国产在线| 激情综合亚洲精品| 亚洲丶国产丶欧美一区二区三区| 国产午夜精品美女毛片视频| 欧美日韩一区二区三区四区| 国产精品亚洲а∨天堂免在线| 亚洲大片一区二区三区| 中文字幕av不卡| 欧美一区国产二区| 色欲综合视频天天天| 国产一区二区三区在线观看免费视频 | 丝袜美腿亚洲一区| 国产精品视频一二三| 日韩限制级电影在线观看| 色婷婷久久久综合中文字幕 | 七七婷婷婷婷精品国产| 亚洲狠狠丁香婷婷综合久久久| 久久久综合激的五月天| 欧美美女视频在线观看| 99久久精品国产一区| 国产一区二区三区黄视频| 日韩在线播放一区二区| 亚洲精品国产精华液| 国产精品萝li| 久久精品欧美日韩精品| 欧美变态凌虐bdsm| 制服丝袜在线91| 在线观看免费一区| 色婷婷亚洲精品| 97精品国产露脸对白| 国产91在线观看| 国产主播一区二区| 精品一区二区三区久久| 免费av网站大全久久| 日产欧产美韩系列久久99| 亚洲大片一区二区三区| 亚洲高清久久久| 亚洲综合在线第一页| 一区二区三区四区在线免费观看 | 免费人成精品欧美精品| 日韩va欧美va亚洲va久久| 亚洲成a人片综合在线| 亚洲午夜激情av| 午夜精品久久久久| 亚洲国产乱码最新视频| 婷婷久久综合九色综合伊人色| 亚洲第一搞黄网站| 天堂一区二区在线| 日韩高清在线观看| 麻豆成人综合网| 国产一区二区三区高清播放| 黄网站免费久久| 成人免费毛片片v| 色哟哟在线观看一区二区三区| 色88888久久久久久影院按摩 | 91在线视频在线| 91麻豆福利精品推荐| 精品视频在线免费看| 欧美老肥妇做.爰bbww视频| 欧美日韩国产天堂| 日韩欧美国产三级电影视频| 2023国产精华国产精品| 国产欧美精品日韩区二区麻豆天美| 久久久蜜桃精品| 中文字幕一区二区在线观看 | 欧美成人aa大片| 国产欧美日本一区视频| 一区二区在线观看av| 亚洲成av人在线观看| 免费人成精品欧美精品| 国产不卡视频在线观看| 一本色道a无线码一区v| 欧美妇女性影城| 国产精品沙发午睡系列990531| 亚洲韩国一区二区三区| 理论片日本一区| 99re这里只有精品视频首页| 91麻豆精品久久久久蜜臀| 26uuu久久天堂性欧美| 日韩美女啊v在线免费观看| 亚洲国产成人tv| 国产成人av网站| 在线观看91视频| 2021久久国产精品不只是精品| 亚洲久草在线视频| 精品亚洲国内自在自线福利| 色综合久久综合| 久久综合九色综合久久久精品综合| 亚洲人成精品久久久久| 捆绑调教一区二区三区| 91麻豆6部合集magnet| 精品人在线二区三区| 亚洲综合色区另类av| 国产精品综合网| 欧美日韩免费观看一区三区| 国产精品国产三级国产普通话三级| 青青草97国产精品免费观看 | 另类中文字幕网| 日本韩国一区二区| 久久综合九色综合97_久久久| 亚洲一区视频在线| 成人视屏免费看| 亚洲精品在线观看网站| 亚洲伊人伊色伊影伊综合网| 成人av在线一区二区| 欧美成人免费网站| 亚洲福利视频三区| eeuss鲁一区二区三区| 337p粉嫩大胆色噜噜噜噜亚洲| 午夜天堂影视香蕉久久| 一道本成人在线| 国产精品黄色在线观看| 国产精品911| 日韩你懂的电影在线观看| 亚洲国产精品一区二区久久| 91在线无精精品入口| 国产精品久久久久久久久免费丝袜| 精品一区二区三区在线观看国产| 欧美日韩一区二区在线观看| 一区二区三区不卡视频| 一本一本大道香蕉久在线精品| 国产精品午夜久久| 国产成人亚洲综合a∨婷婷 | 亚洲成人av一区二区| 色综合久久久久综合体桃花网| 亚洲国产岛国毛片在线| 国产福利一区二区三区视频在线| 欧美va日韩va| 国产一区二区三区在线观看免费视频| 欧美一区二区高清| 美国一区二区三区在线播放| 日韩一卡二卡三卡四卡| 日本aⅴ亚洲精品中文乱码| 欧美精品丝袜久久久中文字幕| 亚洲在线观看免费| 欧美日韩二区三区| 青青草原综合久久大伊人精品| 777久久久精品| 日本vs亚洲vs韩国一区三区二区| 欧美一区二区在线视频| 男男视频亚洲欧美| 日韩精品自拍偷拍| 国产精品69毛片高清亚洲| 欧美国产日本视频| 972aa.com艺术欧美| 亚洲免费观看高清完整版在线观看熊| 91免费国产在线| 午夜电影网一区| 日韩亚洲欧美在线| 国产一区二区在线电影| 国产精品久久99| 91国产免费看| 日韩国产一区二| 精品处破学生在线二十三| 成人免费视频免费观看| 亚洲精品第一国产综合野| 欧美久久婷婷综合色| 六月丁香综合在线视频| 中文字幕高清不卡| 91精品1区2区| 免费精品99久久国产综合精品| 国产欧美一区视频| 色婷婷久久综合| 免费看黄色91| 综合在线观看色| 欧美欧美欧美欧美| 国产成人亚洲综合a∨婷婷 | 国产一区二区久久|