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

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

?? sl811-hcd.c

?? host usb 主設備程序 支持sd卡 mouse keyboard 的最單單的驅動程序 gcc編譯
?? C
?? 第 1 頁 / 共 4 頁
字號:
/* * SL811HS HCD (Host Controller Driver) for USB. * * Copyright (C) 2004 Psion Teklogix (for NetBook PRO) * Copyright (C) 2004-2005 David Brownell * * Periodic scheduling is based on Roman's OHCI code * 	Copyright (C) 1999 Roman Weissgaerber * * The SL811HS controller handles host side USB (like the SL11H, but with * another register set and SOF generation) as well as peripheral side USB * (like the SL811S).  This driver version doesn't implement the Gadget API * for the peripheral role; or OTG (that'd need much external circuitry). * * For documentation, see the SL811HS spec and the "SL811HS Embedded Host" * document (providing significant pieces missing from that spec); plus * the SL811S spec if you want peripheral side info. *//* * Status:  Passed basic stress testing, works with hubs, mice, keyboards, * and usb-storage. * * TODO: * - usb suspend/resume triggered by sl811 (with USB_SUSPEND) * - various issues noted in the code * - performance work; use both register banks; ... * - use urb->iso_frame_desc[] with ISO transfers */#undef	VERBOSE#undef	PACKET_TRACE#include <linux/module.h>#include <linux/moduleparam.h>#include <linux/kernel.h>#include <linux/delay.h>#include <linux/ioport.h>#include <linux/sched.h>#include <linux/slab.h>#include <linux/smp_lock.h>#include <linux/errno.h>#include <linux/init.h>#include <linux/timer.h>#include <linux/list.h>#include <linux/interrupt.h>#include <linux/usb.h>#include <linux/usb/sl811.h>#include <linux/platform_device.h>#include <asm/io.h>#include <asm/irq.h>#include <asm/system.h>#include <asm/byteorder.h>#include "../core/hcd.h"#include "sl811.h"MODULE_DESCRIPTION("SL811HS USB Host Controller Driver");MODULE_LICENSE("GPL");#define DRIVER_VERSION	"19 May 2005"#ifndef DEBUG#	define	STUB_DEBUG_FILE#endif/* for now, use only one transfer register bank */#undef	USE_B/* this doesn't understand urb->iso_frame_desc[], but if you had a driver * that just queued one ISO frame per URB then iso transfers "should" work * using the normal urb status fields. */#define	DISABLE_ISO// #define	QUIRK2#define	QUIRK3static const char hcd_name[] = "sl811-hcd";/*-------------------------------------------------------------------------*/static void port_power(struct sl811 *sl811, int is_on){	struct usb_hcd	*hcd = sl811_to_hcd(sl811);	/* hub is inactive unless the port is powered */	if (is_on) {		if (sl811->port1 & (1 << USB_PORT_FEAT_POWER))			return;		sl811->port1 = (1 << USB_PORT_FEAT_POWER);		sl811->irq_enable = SL11H_INTMASK_INSRMV;		hcd->self.controller->power.power_state = PMSG_ON;	} else {		sl811->port1 = 0;		sl811->irq_enable = 0;		hcd->state = HC_STATE_HALT;		hcd->self.controller->power.power_state = PMSG_SUSPEND;	}	sl811->ctrl1 = 0;	sl811_write(sl811, SL11H_IRQ_ENABLE, 0);	sl811_write(sl811, SL11H_IRQ_STATUS, ~0);	if (sl811->board && sl811->board->port_power) {		/* switch VBUS, at 500mA unless hub power budget gets set */		DBG("power %s\n", is_on ? "on" : "off");		sl811->board->port_power(hcd->self.controller, is_on);	}	/* reset as thoroughly as we can */	if (sl811->board && sl811->board->reset)		sl811->board->reset(hcd->self.controller);	else {		sl811_write(sl811, SL11H_CTLREG1, SL11H_CTL1MASK_SE0);		mdelay(20);	}	sl811_write(sl811, SL11H_IRQ_ENABLE, 0);	sl811_write(sl811, SL11H_CTLREG1, sl811->ctrl1);	sl811_write(sl811, SL811HS_CTLREG2, SL811HS_CTL2_INIT);	sl811_write(sl811, SL11H_IRQ_ENABLE, sl811->irq_enable);	// if !is_on, put into lowpower mode now}/*-------------------------------------------------------------------------*//* This is a PIO-only HCD.  Queueing appends URBs to the endpoint's queue, * and may start I/O.  Endpoint queues are scanned during completion irq * handlers (one per packet: ACK, NAK, faults, etc) and urb cancellation. * * Using an external DMA engine to copy a packet at a time could work, * though setup/teardown costs may be too big to make it worthwhile. *//* SETUP starts a new control request.  Devices are not allowed to * STALL or NAK these; they must cancel any pending control requests. */static void setup_packet(	struct sl811		*sl811,	struct sl811h_ep	*ep,	struct urb		*urb,	u8			bank,	u8			control){	u8			addr;	u8			len;	void __iomem		*data_reg;	addr = SL811HS_PACKET_BUF(bank == 0);	len = sizeof(struct usb_ctrlrequest);	data_reg = sl811->data_reg;	sl811_write_buf(sl811, addr, urb->setup_packet, len);	/* autoincrementing */	sl811_write(sl811, bank + SL11H_BUFADDRREG, addr);	writeb(len, data_reg);	writeb(SL_SETUP /* | ep->epnum */, data_reg);	writeb(usb_pipedevice(urb->pipe), data_reg);	/* always OUT/data0 */ ;	sl811_write(sl811, bank + SL11H_HOSTCTLREG,			control | SL11H_HCTLMASK_OUT);	ep->length = 0;	PACKET("SETUP qh%p\n", ep);}/* STATUS finishes control requests, often after IN or OUT data packets */static void status_packet(	struct sl811		*sl811,	struct sl811h_ep	*ep,	struct urb		*urb,	u8			bank,	u8			control){	int			do_out;	void __iomem		*data_reg;	do_out = urb->transfer_buffer_length && usb_pipein(urb->pipe);	data_reg = sl811->data_reg;	/* autoincrementing */	sl811_write(sl811, bank + SL11H_BUFADDRREG, 0);	writeb(0, data_reg);	writeb((do_out ? SL_OUT : SL_IN) /* | ep->epnum */, data_reg);	writeb(usb_pipedevice(urb->pipe), data_reg);	/* always data1; sometimes IN */	control |= SL11H_HCTLMASK_TOGGLE;	if (do_out)		control |= SL11H_HCTLMASK_OUT;	sl811_write(sl811, bank + SL11H_HOSTCTLREG, control);	ep->length = 0;	PACKET("STATUS%s/%s qh%p\n", ep->nak_count ? "/retry" : "",			do_out ? "out" : "in", ep);}/* IN packets can be used with any type of endpoint. here we just * start the transfer, data from the peripheral may arrive later. * urb->iso_frame_desc is currently ignored here... */static void in_packet(	struct sl811		*sl811,	struct sl811h_ep	*ep,	struct urb		*urb,	u8			bank,	u8			control){	u8			addr;	u8			len;	void __iomem		*data_reg;	/* avoid losing data on overflow */	len = ep->maxpacket;	addr = SL811HS_PACKET_BUF(bank == 0);	if (!(control & SL11H_HCTLMASK_ISOCH)			&& usb_gettoggle(urb->dev, ep->epnum, 0))		control |= SL11H_HCTLMASK_TOGGLE;	data_reg = sl811->data_reg;	/* autoincrementing */	sl811_write(sl811, bank + SL11H_BUFADDRREG, addr);	writeb(len, data_reg);	writeb(SL_IN | ep->epnum, data_reg);	writeb(usb_pipedevice(urb->pipe), data_reg);	sl811_write(sl811, bank + SL11H_HOSTCTLREG, control);	ep->length = min((int)len,			urb->transfer_buffer_length - urb->actual_length);	PACKET("IN%s/%d qh%p len%d\n", ep->nak_count ? "/retry" : "",			!!usb_gettoggle(urb->dev, ep->epnum, 0), ep, len);}/* OUT packets can be used with any type of endpoint. * urb->iso_frame_desc is currently ignored here... */static void out_packet(	struct sl811		*sl811,	struct sl811h_ep	*ep,	struct urb		*urb,	u8			bank,	u8			control){	void			*buf;	u8			addr;	u8			len;	void __iomem		*data_reg;	buf = urb->transfer_buffer + urb->actual_length;	prefetch(buf);	len = min((int)ep->maxpacket,			urb->transfer_buffer_length - urb->actual_length);	if (!(control & SL11H_HCTLMASK_ISOCH)			&& usb_gettoggle(urb->dev, ep->epnum, 1))		control |= SL11H_HCTLMASK_TOGGLE;	addr = SL811HS_PACKET_BUF(bank == 0);	data_reg = sl811->data_reg;	sl811_write_buf(sl811, addr, buf, len);	/* autoincrementing */	sl811_write(sl811, bank + SL11H_BUFADDRREG, addr);	writeb(len, data_reg);	writeb(SL_OUT | ep->epnum, data_reg);	writeb(usb_pipedevice(urb->pipe), data_reg);	sl811_write(sl811, bank + SL11H_HOSTCTLREG,			control | SL11H_HCTLMASK_OUT);	ep->length = len;	PACKET("OUT%s/%d qh%p len%d\n", ep->nak_count ? "/retry" : "",			!!usb_gettoggle(urb->dev, ep->epnum, 1), ep, len);}/*-------------------------------------------------------------------------*//* caller updates on-chip enables later */static inline void sofirq_on(struct sl811 *sl811){	if (sl811->irq_enable & SL11H_INTMASK_SOFINTR)		return;	VDBG("sof irq on\n");	sl811->irq_enable |= SL11H_INTMASK_SOFINTR;}static inline void sofirq_off(struct sl811 *sl811){	if (!(sl811->irq_enable & SL11H_INTMASK_SOFINTR))		return;	VDBG("sof irq off\n");	sl811->irq_enable &= ~SL11H_INTMASK_SOFINTR;}/*-------------------------------------------------------------------------*//* pick the next endpoint for a transaction, and issue it. * frames start with periodic transfers (after whatever is pending * from the previous frame), and the rest of the time is async * transfers, scheduled round-robin. */static struct sl811h_ep	*start(struct sl811 *sl811, u8 bank){	struct sl811h_ep	*ep;	struct urb		*urb;	int			fclock;	u8			control;	/* use endpoint at schedule head */	if (sl811->next_periodic) {		ep = sl811->next_periodic;		sl811->next_periodic = ep->next;	} else {		if (sl811->next_async)			ep = sl811->next_async;		else if (!list_empty(&sl811->async))			ep = container_of(sl811->async.next,					struct sl811h_ep, schedule);		else {			/* could set up the first fullspeed periodic			 * transfer for the next frame ...			 */			return NULL;		}#ifdef USE_B		if ((bank && sl811->active_b == ep) || sl811->active_a == ep)			return NULL;#endif		if (ep->schedule.next == &sl811->async)			sl811->next_async = NULL;		else			sl811->next_async = container_of(ep->schedule.next,					struct sl811h_ep, schedule);	}	if (unlikely(list_empty(&ep->hep->urb_list))) {		DBG("empty %p queue?\n", ep);		return NULL;	}	urb = container_of(ep->hep->urb_list.next, struct urb, urb_list);	control = ep->defctrl;	/* if this frame doesn't have enough time left to transfer this	 * packet, wait till the next frame.  too-simple algorithm...	 */	fclock = sl811_read(sl811, SL11H_SOFTMRREG) << 6;	fclock -= 100;		/* setup takes not much time */	if (urb->dev->speed == USB_SPEED_LOW) {		if (control & SL11H_HCTLMASK_PREAMBLE) {			/* also note erratum 1: some hubs won't work */			fclock -= 800;		}		fclock -= ep->maxpacket << 8;		/* erratum 2: AFTERSOF only works for fullspeed */		if (fclock < 0) {			if (ep->period)				sl811->stat_overrun++;			sofirq_on(sl811);			return NULL;		}	} else {		fclock -= 12000 / 19;	/* 19 64byte packets/msec */		if (fclock < 0) {			if (ep->period)				sl811->stat_overrun++;			control |= SL11H_HCTLMASK_AFTERSOF;		/* throttle bulk/control irq noise */		} else if (ep->nak_count)			control |= SL11H_HCTLMASK_AFTERSOF;	}	switch (ep->nextpid) {	case USB_PID_IN:		in_packet(sl811, ep, urb, bank, control);		break;	case USB_PID_OUT:		out_packet(sl811, ep, urb, bank, control);		break;	case USB_PID_SETUP:		setup_packet(sl811, ep, urb, bank, control);		break;	case USB_PID_ACK:		/* for control status */		status_packet(sl811, ep, urb, bank, control);		break;	default:		DBG("bad ep%p pid %02x\n", ep, ep->nextpid);		ep = NULL;	}	return ep;}#define MIN_JIFFIES	((msecs_to_jiffies(2) > 1) ? msecs_to_jiffies(2) : 2)static inline void start_transfer(struct sl811 *sl811){	if (sl811->port1 & (1 << USB_PORT_FEAT_SUSPEND))		return;	if (sl811->active_a == NULL) {		sl811->active_a = start(sl811, SL811_EP_A(SL811_HOST_BUF));		if (sl811->active_a != NULL)			sl811->jiffies_a = jiffies + MIN_JIFFIES;	}#ifdef USE_B	if (sl811->active_b == NULL) {		sl811->active_b = start(sl811, SL811_EP_B(SL811_HOST_BUF));		if (sl811->active_b != NULL)			sl811->jiffies_b = jiffies + MIN_JIFFIES;	}#endif}static void finish_request(	struct sl811		*sl811,	struct sl811h_ep	*ep,	struct urb		*urb,	int			status) __releases(sl811->lock) __acquires(sl811->lock){	unsigned		i;	if (usb_pipecontrol(urb->pipe))		ep->nextpid = USB_PID_SETUP;	spin_lock(&urb->lock);	if (urb->status == -EINPROGRESS)		urb->status = status;	urb->hcpriv = NULL;	spin_unlock(&urb->lock);	spin_unlock(&sl811->lock);	usb_hcd_giveback_urb(sl811_to_hcd(sl811), urb);	spin_lock(&sl811->lock);	/* leave active endpoints in the schedule */	if (!list_empty(&ep->hep->urb_list))		return;	/* async deschedule? */	if (!list_empty(&ep->schedule)) {		list_del_init(&ep->schedule);		if (ep == sl811->next_async)			sl811->next_async = NULL;		return;	}	/* periodic deschedule */	DBG("deschedule qh%d/%p branch %d\n", ep->period, ep, ep->branch);	for (i = ep->branch; i < PERIODIC_SIZE; i += ep->period) {		struct sl811h_ep	*temp;		struct sl811h_ep	**prev = &sl811->periodic[i];

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
狠狠狠色丁香婷婷综合久久五月| 欧美在线小视频| 国产精品美女久久久久高潮| 色中色一区二区| 国产在线视频不卡二| 亚洲成人av资源| 国产日韩欧美精品电影三级在线| 777午夜精品视频在线播放| 99久久免费精品| 国产精品一区免费在线观看| 日韩精品国产精品| 亚洲小说春色综合另类电影| 亚洲人成网站精品片在线观看 | 亚洲综合色网站| 国产女同性恋一区二区| 亚洲欧洲日韩一区二区三区| 9人人澡人人爽人人精品| 国产精品伦理在线| 欧美国产综合色视频| 久久精品免费在线观看| 26uuuu精品一区二区| 精品免费一区二区三区| 精品国内二区三区| 欧美三级中文字幕| 91精品国产一区二区三区| 欧美理论电影在线| 欧美一级二级在线观看| 日韩午夜精品电影| 精品国产一区二区三区四区四 | 成人午夜在线视频| 国产激情91久久精品导航| 成人涩涩免费视频| 色婷婷亚洲精品| 日本免费新一区视频 | 麻豆精品久久精品色综合| 国产欧美久久久精品影院| 国产亚洲精品资源在线26u| 久久久蜜桃精品| 国产精品久久久久久久久免费桃花| 欧美激情一区二区| 亚洲激情综合网| 一区二区三区四区av| 亚洲成人福利片| 激情深爱一区二区| 成人国产精品免费观看动漫| 91久久免费观看| 精品久久五月天| 欧美国产精品久久| 日日噜噜夜夜狠狠视频欧美人| 伦理电影国产精品| 成人激情午夜影院| 欧美一区二区三区公司| 国产日韩欧美综合在线| 一区二区三区四区在线免费观看| 最新不卡av在线| 日韩av电影一区| 成人av午夜电影| 日韩一级片在线观看| 国产精品久久久久久久久免费樱桃 | 日韩精品一区二区三区视频| 国产成人亚洲综合a∨婷婷| 午夜日韩在线电影| 成人免费黄色在线| 精品动漫一区二区三区在线观看| 欧美极品少妇xxxxⅹ高跟鞋| 亚洲国产精品久久不卡毛片| 国内久久精品视频| 欧美视频精品在线观看| 中文字幕一区二区三区视频| 男女视频一区二区| 欧美中文字幕一二三区视频| 久久综合狠狠综合久久综合88| 国产精品成人一区二区三区夜夜夜| 日韩精品福利网| 成人国产电影网| 久久一二三国产| 亚洲成a人在线观看| 久久电影网电视剧免费观看| 色成年激情久久综合| 久久亚洲精品小早川怜子| 五月婷婷欧美视频| 91国模大尺度私拍在线视频 | 国产精品亲子伦对白| 蜜臀av性久久久久av蜜臀妖精| 99久久精品99国产精品| 欧美激情一区在线| 狂野欧美性猛交blacked| 91精品国产福利在线观看| 一区二区在线观看av| 99视频精品全部免费在线| 久久精品一区二区三区四区| 六月婷婷色综合| 精品国产成人系列| 国内欧美视频一区二区| 精品美女在线观看| 秋霞午夜av一区二区三区| 制服丝袜亚洲播放| 日本人妖一区二区| 欧美一区二区三区在线观看| 日韩黄色一级片| 欧美精品在线一区二区三区| 亚洲成av人片一区二区梦乃| 欧美精品v国产精品v日韩精品| 一区二区三区 在线观看视频| 亚洲黄色免费网站| 久久久国际精品| 亚洲午夜久久久久久久久电影院| 91香蕉视频mp4| 亚洲一区二区视频在线观看| 欧美性一级生活| 久久国产精品99精品国产 | 精品入口麻豆88视频| 懂色av一区二区三区免费观看 | 91精品国产欧美一区二区成人| 国产精品一区专区| 亚洲国产毛片aaaaa无费看| 精品国产一二三区| 欧美午夜在线观看| 高清beeg欧美| 日本最新不卡在线| 亚洲精品成人在线| 亚洲国产精品黑人久久久| 欧美日韩国产色站一区二区三区| 国产一区二区三区黄视频 | 色综合 综合色| 国产乱国产乱300精品| 亚洲精品欧美二区三区中文字幕| 久久综合久久综合亚洲| 欧美精品亚洲一区二区在线播放| 国产a视频精品免费观看| 日本不卡视频一二三区| 亚洲一区二区三区四区五区黄 | 久久久91精品国产一区二区精品 | 欧美r级在线观看| 在线免费亚洲电影| 波多野结衣中文字幕一区二区三区 | 精品一区二区三区免费播放| 亚洲午夜影视影院在线观看| 国产欧美日韩一区二区三区在线观看| 欧美日韩国产综合草草| 一本久久a久久精品亚洲| 成人午夜激情影院| 国产91丝袜在线观看| 韩国一区二区视频| 激情综合色综合久久| 裸体歌舞表演一区二区| 日韩av网站在线观看| 视频在线观看91| 婷婷丁香激情综合| 日韩av中文字幕一区二区三区| 亚洲v中文字幕| 亚洲 欧美综合在线网络| 亚洲成av人影院在线观看网| 亚洲午夜私人影院| 亚洲一区二区三区视频在线 | 337p粉嫩大胆色噜噜噜噜亚洲| 欧美一级夜夜爽| 日韩欧美一区二区视频| 欧美xxxxx牲另类人与| 这里只有精品电影| 精品国产精品网麻豆系列| 欧美xxxxxxxx| 国产欧美精品一区| 亚洲天堂av一区| 亚洲成va人在线观看| 精品综合免费视频观看| 国产一区二区福利| 成人99免费视频| 日本韩国精品在线| 337p亚洲精品色噜噜| 久久人人爽人人爽| 欧美国产日韩亚洲一区| 日韩码欧中文字| 亚洲福利一区二区三区| 丝袜亚洲另类欧美| 国产伦理精品不卡| 色av综合在线| 欧美少妇xxx| 欧美精品一区二区高清在线观看| 国产女同互慰高潮91漫画| 一区二区三区四区蜜桃| 免费成人性网站| 99久久精品久久久久久清纯| 在线看日韩精品电影| 欧美群妇大交群中文字幕| 欧美精品一区二区高清在线观看| 中文字幕亚洲精品在线观看 | 国产99久久久国产精品潘金| 91精品91久久久中77777| 日韩欧美国产精品一区| 欧美α欧美αv大片| 亚洲最大成人综合| 欧美优质美女网站| 国产亚洲欧洲997久久综合 | 精品在线免费观看| 成人黄色国产精品网站大全在线免费观看 | 日韩毛片视频在线看| 蜜臀精品一区二区三区在线观看 | 久久国产麻豆精品| 99精品1区2区|