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

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

?? otg_hub.c

?? philips公司ISP1362 USB OTG控制芯片的驅動
?? C
?? 第 1 頁 / 共 3 頁
字號:
/*
 * USB hub driver.
 *
 * (C) Copyright 1999 Linus Torvalds
 * (C) Copyright 1999 Johannes Erdfelt
 * (C) Copyright 1999 Gregory P. Smith
 * (C) Copyright 2001 Brad Hards (bhards@bigpond.net.au)
 *
 */

#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/completion.h>
#include <linux/sched.h>
#include <linux/list.h>
#include <linux/slab.h>
#include <linux/smp_lock.h>
#ifdef CONFIG_USB_DEBUG
	#define DEBUG
#else
	#undef DEBUG
#endif
#include <linux/usb.h>
#include <linux/usbdevice_fs.h>

#include <asm/semaphore.h>
#include <asm/uaccess.h>
#include <asm/byteorder.h>

#include "otg_hub.h"

/* Wakes up khubd */
static spinlock_t hub_event_lock = SPIN_LOCK_UNLOCKED;
static DECLARE_MUTEX(usb_address0_sem);

static LIST_HEAD(hub_event_list);	/* List of hubs needing servicing */
static LIST_HEAD(hub_list);		/* List containing all of the hubs (for cleanup) */

static DECLARE_WAIT_QUEUE_HEAD(khubd_wait);
static int khubd_pid = 0;			/* PID of khubd */
static DECLARE_COMPLETION(khubd_exited);

#ifdef	DEBUG
static inline char *portspeed (int portstatus)
{
	if (portstatus & (1 << USB_PORT_FEAT_HIGHSPEED))
    		return "480 Mb/s";
	else if (portstatus & (1 << USB_PORT_FEAT_LOWSPEED))
		return "1.5 Mb/s";
	else
		return "12 Mb/s";
}
#endif


/*-----------------------------------------------------------
 * Additional Functions for OTG-HUB 
 * ---------------------------------------------------------*/

/*_ Global variables */
static struct usb_driver * old_hub_driver = NULL;	/* driver that comes with USB CORE */
extern	struct list_head * usb_driver_get_list(void);	/* Exporting this function from USB CORE 
							   Requires CONFIG_PROC_FS support */
#define	OTG_HUB_RESET_TIME	50
#define	USB_OTG_HUB_SET_TIMEOUT	3

LIST_HEAD(otg_hub_bus_list);

/*-----------------------------------------------------------
 * This function registers the OTG BUS to the OTG HUB
 * returns 0 on success and -ve value on failure
 * puts the OTG bus in the linked list
 * ---------------------------------------------------------*/
int	otg_hub_register_otg_bus(struct usb_otg_bus *otg_bus) {

	list_add(&otg_bus->bus_list, &otg_hub_bus_list);

	return 0;
}

/*-----------------------------------------------------------
 * This function registers the OTG BUS to the OTG HUB
 * removes the OTG bus from the linked list
 * ---------------------------------------------------------*/
void 	otg_hub_deregister_otg_bus(struct usb_otg_bus *otg_bus) {

	list_del(&otg_bus->bus_list);
}

/*----------------------------------------------------------------
 * Get the OTG Bus data structure from the USB Bus data structure
 * this function returns the OTG-BUS for the corresponding
 * USB-BUS if it is present in the OTG-BUS list
 * otherwise returns NULL
 * --------------------------------------------------------------*/
struct usb_otg_bus *otg_hub_get_otg_bus(struct usb_bus *bus) {
	struct list_head *tmp;

	tmp = otg_hub_bus_list.next;
	while (tmp != &otg_hub_bus_list) {
		struct usb_otg_bus *otg_bus = list_entry(tmp,struct usb_otg_bus, bus_list);

		if(otg_bus->usb_bus == bus)	{
				return otg_bus;
		}
		tmp = tmp->next;
	}

	return NULL;
}


/*--------------------------------------------------
 * Set FEATURE function whihc internally calls the 
 * USB control message with the reuired parameters
 * -----------------------------------------------*/
int	otg_hub_set_otg_feature(struct usb_device *dev, int	feature) {

	return usb_control_msg(	dev, usb_sndctrlpipe(dev,0), 
				USB_REQ_SET_FEATURE, 0, feature, 
				0, NULL, 0, HZ * USB_OTG_HUB_SET_TIMEOUT);
}

/*-----------------------------------------------------
 * This function checks the device configuration and
 * calls the OTG enumeration function. If successful
 * calls the USB new_device function
 * ---------------------------------------------------*/
int otg_hub_new_device(struct usb_device *otg_dev, int port)
{
	int err;
	struct usb_device *dev = NULL;
	struct usb_otg_bus *hub_bus = NULL;


	hub_bus = otg_hub_get_otg_bus(otg_dev->bus);

	/* If the new device is connected on the root port and if 
	 * the HCD OTG is enabled */
	if((otg_dev->parent) && (otg_dev->parent == otg_dev->bus->root_hub) && hub_bus) {

		dev = usb_alloc_dev(otg_dev->bus->root_hub, otg_dev->bus);

		if(dev == NULL)	return -1;

		/* Replace the device with the new data structure */
//		memcpy(dev, otg_dev, sizeof(struct usb_device));

		otg_dev->parent->children[port] = dev;

		dev->descriptor.bMaxPacketSize0 = 8;  /* Start off at 8 bytes  */
		dev->devnum = 0;

		dev->parent = otg_dev->parent;
		
		/* USB v1.1 5.5.3 */
		/* We read the first 8 bytes from the device descriptor to get to */
		/*  the bMaxPacketSize0 field. Then we set the maximum packet size */
		/*  for the control pipe, and retrieve the rest */
		dev->epmaxpacketin [0] = 8;
		dev->epmaxpacketout[0] = 8;

		wait_ms(10);	/* Let the SET_ADDRESS settle */
	
		/* Address is not set yet, all communication is on default pipe */
		dev->devnum = 0;

		err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, &dev->descriptor, 8);
		if (err < 8) {
			if (err < 0)
				err("USB device not responding, giving up (error=%d)", err);
			else
				err("USB device descriptor short read (expected %i, got %i)", 8, err);
			goto error;
		}

		dev->epmaxpacketin [0] = dev->descriptor.bMaxPacketSize0;
		dev->epmaxpacketout[0] = dev->descriptor.bMaxPacketSize0;
	
		err = usb_get_device_descriptor(dev);
		if (err < (signed)sizeof(dev->descriptor)) {
			if (err < 0)
				err("unable to get device descriptor (error=%d)", err);
			else
				err("USB device descriptor short read (expected %Zi, got %i)",
					sizeof(dev->descriptor), err);
		
			goto error;
		}
	
		err = usb_get_configuration(dev);
		if (err < 0) {
			err("unable to get device %d configuration (error=%d)",
				dev->devnum, err);
			goto error;
		}
	
		if(hub_bus->otg_new_device) {
			err = hub_bus->otg_new_device(hub_bus->otg_priv,dev);
			if (err < 0) {
//				err("unable to do OTG enumeration for %d dev , err = %d\n", dev->devnum, err);
				goto error;
			}
		}

		usb_free_dev(dev);

		/* Replace the original device structure */
		otg_dev->parent->children[port] = otg_dev;
	}

	/* Try to enumerate fresh */
	return usb_new_device(otg_dev);

error:
	clear_bit(otg_dev->devnum, &otg_dev->bus->devmap.devicemap);
	otg_dev->devnum = -1;
	otg_dev->parent->children[port] = otg_dev;
	usb_free_dev(dev);

	return 1;
}

/*----------End OTG-HUB new functions ---------------------------------*/

/* USB 2.0 spec Section 11.24.4.5 */
static int usb_get_hub_descriptor(struct usb_device *dev, void *data, int size)
{
	return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
		USB_REQ_GET_DESCRIPTOR, USB_DIR_IN | USB_RT_HUB,
		USB_DT_HUB << 8, 0, data, size, HZ);
}

/*
 * USB 2.0 spec Section 11.24.2.1
 */
static int usb_clear_hub_feature(struct usb_device *dev, int feature)
{
	return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
		USB_REQ_CLEAR_FEATURE, USB_RT_HUB, feature, 0, NULL, 0, HZ);
}

/*
 * USB 2.0 spec Section 11.24.2.2
 * BUG: doesn't handle port indicator selector in high byte of wIndex
 */
static int usb_clear_port_feature(struct usb_device *dev, int port, int feature)
{
	return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
		USB_REQ_CLEAR_FEATURE, USB_RT_PORT, feature, port, NULL, 0, HZ);
}

/*
 * USB 2.0 spec Section 11.24.2.13
 * BUG: doesn't handle port indicator selector in high byte of wIndex
 */
static int usb_set_port_feature(struct usb_device *dev, int port, int feature)
{
	return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
		USB_REQ_SET_FEATURE, USB_RT_PORT, feature, port, NULL, 0, HZ);
}

/*
 * USB 2.0 spec Section 11.24.2.6
 */
static int usb_get_hub_status(struct usb_device *dev, void *data)
{
	return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
		USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_HUB, 0, 0,
		data, sizeof(struct usb_hub_status), HZ);
}

/*
 * USB 2.0 spec Section 11.24.2.7
 */
static int usb_get_port_status(struct usb_device *dev, int port, void *data)
{
	return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
		USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_PORT, 0, port,
		data, sizeof(struct usb_hub_status), HZ);
}

static void hub_irq(struct urb *urb)
{
	struct usb_hub *hub = (struct usb_hub *)urb->context;
	unsigned long flags;

	/* Cause a hub reset after 10 consecutive errors */
	if (urb->status) {
		if (urb->status == -ENOENT)
			return;

		dbg("nonzero status in irq %d", urb->status);

		if ((++hub->nerrors < 10) || hub->error)
			return;

		hub->error = urb->status;
	}

	hub->nerrors = 0;

	/* Something happened, let khubd figure it out */
	spin_lock_irqsave(&hub_event_lock, flags);
	if (list_empty(&hub->event_list)) {
		list_add(&hub->event_list, &hub_event_list);
		wake_up(&khubd_wait);
	}
	spin_unlock_irqrestore(&hub_event_lock, flags);
}

static void usb_hub_power_on(struct usb_hub *hub)
{
	int i;

	/* Enable power to the ports */
	dbg("enabling power on all ports");
	for (i = 0; i < hub->descriptor->bNbrPorts; i++)
		usb_set_port_feature(hub->dev, i + 1, USB_PORT_FEAT_POWER);

	/* Wait for power to be enabled */
	wait_ms(hub->descriptor->bPwrOn2PwrGood * 2);
}

static int usb_hub_configure(struct usb_hub *hub, struct usb_endpoint_descriptor *endpoint)
{
	struct usb_device *dev = hub->dev;
	struct usb_hub_status hubstatus;
	char portstr[USB_MAXCHILDREN + 1];
	unsigned int pipe;
	int i, maxp, ret;

	hub->descriptor = kmalloc(sizeof(*hub->descriptor), GFP_KERNEL);
	if (!hub->descriptor) {
		err("Unable to kmalloc %Zd bytes for hub descriptor", sizeof(*hub->descriptor));
		return -1;
	}

	/* Request the entire hub descriptor. */
	ret = usb_get_hub_descriptor(dev, hub->descriptor, sizeof(*hub->descriptor));
		/* <hub->descriptor> is large enough for a hub with 127 ports;
		 * the hub can/will return fewer bytes here. */
	if (ret < 0) {
		err("Unable to get hub descriptor (err = %d)", ret);
		kfree(hub->descriptor);
		return -1;
	}

	dev->maxchild = hub->descriptor->bNbrPorts;
	info("%d port%s detected", hub->descriptor->bNbrPorts, (hub->descriptor->bNbrPorts == 1) ? "" : "s");

	le16_to_cpus(&hub->descriptor->wHubCharacteristics);

	if (hub->descriptor->wHubCharacteristics & HUB_CHAR_COMPOUND)
		dbg("part of a compound device");
	else
		dbg("standalone hub");

	switch (hub->descriptor->wHubCharacteristics & HUB_CHAR_LPSM) {
		case 0x00:
			dbg("ganged power switching");
			break;
		case 0x01:
			dbg("individual port power switching");
			break;
		case 0x02:
		case 0x03:
			dbg("unknown reserved power switching mode");
			break;
	}

	switch (hub->descriptor->wHubCharacteristics & HUB_CHAR_OCPM) {
		case 0x00:
			dbg("global over-current protection");
			break;
		case 0x08:
			dbg("individual port over-current protection");
			break;
		case 0x10:
		case 0x18:
			dbg("no over-current protection");
                        break;
	}

	switch (dev->descriptor.bDeviceProtocol) {

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
欧美精品一二三区| 国产欧美日产一区| 国产成人在线视频免费播放| 亚洲美女在线一区| 日韩欧美一二三四区| 99精品在线观看视频| 精品一区二区精品| 婷婷激情综合网| 亚洲人成网站影音先锋播放| 久久久精品2019中文字幕之3| 欧美色图片你懂的| av电影天堂一区二区在线观看| 久久国产精品色婷婷| 亚洲国产综合91精品麻豆| 国产精品久久福利| 国产日本欧洲亚洲| 久久先锋影音av鲁色资源网| 欧美日韩国产色站一区二区三区| 91视频在线观看免费| 国产成人a级片| 极品美女销魂一区二区三区免费 | 亚洲精品国产品国语在线app| 久久久久免费观看| 精品999在线播放| 日韩一区二区三区四区| 欧美日韩在线播| 欧美网站大全在线观看| 欧美亚洲综合色| 欧美综合色免费| 欧美色中文字幕| 欧美性生活久久| 欧美三区在线观看| 欧美高清www午色夜在线视频| 欧美三片在线视频观看| 欧美日韩一区三区| 91.麻豆视频| 日韩亚洲欧美成人一区| 欧美一区二区三区白人| 欧美一区二区久久| 欧美va亚洲va在线观看蝴蝶网| 91精品国产综合久久婷婷香蕉| 91精品国产丝袜白色高跟鞋| 91精品国产麻豆| 日韩一区二区三区视频| 精品sm在线观看| 国产精品毛片无遮挡高清| 国产精品视频第一区| 国产精品久久久久一区二区三区| 自拍偷拍亚洲综合| 夜夜操天天操亚洲| 午夜精品免费在线观看| 免费成人在线观看视频| 国产伦精品一区二区三区在线观看| 国产一区二区三区不卡在线观看| 精品一区二区精品| 成人黄色在线网站| 日本乱人伦一区| 欧美日韩成人激情| 久久一区二区三区国产精品| 日本一区二区三区电影| 亚洲欧美另类在线| 日韩高清国产一区在线| 狠狠狠色丁香婷婷综合激情| 国产91露脸合集magnet| 91福利在线播放| 欧美xxxx老人做受| 亚洲欧洲成人自拍| 日本在线播放一区二区三区| 国产一区二区三区四| 91色porny在线视频| 91精品免费在线观看| 国产女人水真多18毛片18精品视频| 亚洲欧美一区二区在线观看| 午夜精品免费在线观看| 国产成人综合亚洲91猫咪| 色悠久久久久综合欧美99| 欧美一区二区三区四区五区 | 喷白浆一区二区| 粉嫩久久99精品久久久久久夜 | 制服丝袜亚洲网站| 国产精品丝袜久久久久久app| 亚洲最大的成人av| 国产露脸91国语对白| 91久久人澡人人添人人爽欧美| 在线综合视频播放| 国产精品护士白丝一区av| 日韩黄色小视频| 成人国产在线观看| 欧美va日韩va| 亚洲国产婷婷综合在线精品| 国产九九视频一区二区三区| 欧美亚洲综合另类| 国产日韩欧美不卡在线| 日本大胆欧美人术艺术动态| av影院午夜一区| 欧美一级国产精品| 亚洲影院在线观看| 成人国产一区二区三区精品| 日韩视频一区二区在线观看| 亚洲精品免费播放| 国产成人综合精品三级| 欧美精品tushy高清| 亚洲人成小说网站色在线| 国产乱码一区二区三区| 欧美一卡二卡在线| 夜夜爽夜夜爽精品视频| av电影天堂一区二区在线| 久久久久久久久久久久久久久99| 亚洲电影视频在线| 91麻豆国产精品久久| 中文字幕成人av| 国产精品99久久久久久似苏梦涵| 日韩一区二区三区在线| 丝袜美腿亚洲色图| 欧美在线视频你懂得| 中文字幕精品在线不卡| 国产在线不卡视频| 日韩三级免费观看| 视频一区二区国产| 欧洲激情一区二区| 亚洲黄色小说网站| 99国产精品99久久久久久| 国产精品免费视频一区| 狠狠色狠狠色合久久伊人| 欧美一级免费观看| 日韩电影一区二区三区| 欧美久久一二三四区| 亚洲观看高清完整版在线观看| 日本乱人伦一区| 亚洲综合丝袜美腿| 欧美三级在线看| 日韩中文字幕亚洲一区二区va在线| 欧美在线观看一区二区| 亚洲黄色免费网站| 欧美在线观看视频在线| 一区二区三区美女| 欧美三级中文字| 日本成人在线电影网| 欧美一区二区人人喊爽| 琪琪久久久久日韩精品| 欧美一区二视频| 国模套图日韩精品一区二区| 久久久久免费观看| 成人不卡免费av| 亚洲免费观看在线观看| 在线观看91精品国产入口| 亚洲成人一区在线| 这里是久久伊人| 国产一区二区三区观看| 欧美激情一区在线观看| 99久久精品国产导航| 亚洲一区二区欧美日韩| 日韩一区二区在线观看视频播放| 麻豆精品国产传媒mv男同| 久久蜜桃av一区精品变态类天堂| 成人深夜在线观看| 一区二区欧美精品| 51精品国自产在线| 国产福利91精品一区| 中文字幕高清一区| 91福利精品第一导航| 免费高清视频精品| 中文av一区特黄| 欧美性一二三区| 另类中文字幕网| 亚洲欧美在线aaa| 日韩一级大片在线| 粉嫩在线一区二区三区视频| 亚洲永久免费视频| 久久久久久久久久久久电影| 色又黄又爽网站www久久| 日韩电影一二三区| 国产精品国产三级国产aⅴ无密码| 欧美伊人久久久久久午夜久久久久| 麻豆精品视频在线| 亚洲少妇中出一区| 日韩欧美国产高清| 99久久免费国产| 蜜臀精品久久久久久蜜臀 | 国产精品美女久久久久久久| 欧美日韩综合一区| 国产91高潮流白浆在线麻豆| 亚洲永久精品大片| 亚洲国产成人在线| 69p69国产精品| 99久久国产免费看| 久久国产精品99久久人人澡| 1024国产精品| 26uuuu精品一区二区| 在线看日本不卡| 国产.欧美.日韩| 免费精品99久久国产综合精品| 中文字幕日本不卡| 久久久久亚洲蜜桃| 日韩一区二区视频在线观看| 91最新地址在线播放| 国产激情视频一区二区在线观看 | 欧美tickling挠脚心丨vk| 在线精品视频一区二区三四| 国产福利一区在线|