亚洲欧美第一页_禁久久精品乱码_粉嫩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一区二区三区免费野_久草精品视频
欧美视频一区二区三区四区| 欧美一区二区二区| 天堂一区二区在线免费观看| 欧美国产视频在线| 欧美一区二区大片| 在线观看免费成人| 懂色av一区二区在线播放| 日韩和欧美的一区| 亚洲精品写真福利| 国产欧美一区二区三区在线老狼| 欧美日韩免费视频| 91视频在线观看| 国产精品一区二区果冻传媒| 日韩影院精彩在线| 亚洲一区二区在线观看视频| 久久精品一二三| 日韩一区二区麻豆国产| 欧美亚洲动漫另类| 94-欧美-setu| 成人美女在线视频| 国产精品一区在线| 久久超级碰视频| 日本成人在线视频网站| 午夜国产不卡在线观看视频| 亚洲柠檬福利资源导航| 国产精品久久久久9999吃药| 久久―日本道色综合久久| 日韩欧美国产精品一区| 欧美一区日本一区韩国一区| 欧美日韩午夜在线| 欧美性淫爽ww久久久久无| 色屁屁一区二区| 91福利精品视频| 91国偷自产一区二区三区观看 | 国产精品一线二线三线精华| 麻豆成人在线观看| 蜜桃av噜噜一区| 麻豆91精品视频| 精品一区二区影视| 国产麻豆91精品| 国产高清成人在线| 成人激情视频网站| av福利精品导航| 色偷偷88欧美精品久久久| 色天使久久综合网天天| 欧美体内she精视频| 欧美无人高清视频在线观看| 欧美性猛交xxxxxx富婆| 欧美猛男男办公室激情| 7777精品伊人久久久大香线蕉超级流畅 | 琪琪久久久久日韩精品| 久久精品国产99国产| 国产综合色在线视频区| 高清shemale亚洲人妖| 懂色av一区二区三区蜜臀| 成人福利视频在线看| 97久久精品人人爽人人爽蜜臀| 91亚洲精品久久久蜜桃| 欧美日韩一区二区三区在线看| 在线播放中文字幕一区| 日韩欧美激情在线| 中文字幕av一区 二区| 亚洲精品日韩专区silk| 日本91福利区| 国产mv日韩mv欧美| 日本精品一区二区三区高清| 欧美片在线播放| 精品女同一区二区| 成人欧美一区二区三区视频网页| 一区二区三区中文字幕在线观看| 日韩高清不卡一区二区三区| 国产一区二区不卡| 91成人在线免费观看| 欧美一级高清片在线观看| 国产精品婷婷午夜在线观看| 亚洲国产成人91porn| 国产福利一区二区| 欧美亚洲一区三区| 久久视频一区二区| 亚洲欧美一区二区视频| 日韩福利电影在线| 成人av动漫在线| 日韩视频免费观看高清完整版 | 图片区小说区区亚洲影院| 激情综合亚洲精品| 91尤物视频在线观看| 欧美一区二区啪啪| 亚洲免费看黄网站| 久久不见久久见中文字幕免费| aaa欧美大片| 欧美成人猛片aaaaaaa| 中文字幕在线播放不卡一区| 久久国产精品区| 在线观看精品一区| 国产午夜精品福利| 日韩二区三区四区| 色综合欧美在线视频区| 久久精品人人做人人爽人人| 风间由美一区二区av101| 欧美精品1区2区3区| 亚洲视频一区在线| 国产原创一区二区| 91精品国模一区二区三区| 亚洲另类春色校园小说| 成人午夜视频免费看| 精品久久一区二区| 午夜激情一区二区三区| 一本到三区不卡视频| 国产免费成人在线视频| 免费视频一区二区| 精品视频资源站| 一区二区三区日韩| 97久久精品人人爽人人爽蜜臀| 久久精品一区二区三区不卡牛牛 | 成人黄色小视频| 日韩精品一区二区三区视频播放 | 91视频你懂的| 亚洲国产精品成人综合色在线婷婷| 裸体一区二区三区| 欧美一区午夜视频在线观看| 亚洲大片精品永久免费| 91国偷自产一区二区三区观看| 中文字幕一区不卡| jlzzjlzz亚洲女人18| 国产片一区二区| 国产激情91久久精品导航| 日韩精品一区二区三区视频播放| 日产精品久久久久久久性色| 欧美日韩久久久一区| 亚洲一区二区三区爽爽爽爽爽| 972aa.com艺术欧美| ●精品国产综合乱码久久久久 | 色婷婷精品大在线视频| 亚洲美女少妇撒尿| 色又黄又爽网站www久久| 玉足女爽爽91| 欧美性大战xxxxx久久久| 亚洲综合网站在线观看| 在线视频一区二区三区| 一区二区三区精品视频在线| 在线观看欧美精品| 婷婷国产v国产偷v亚洲高清| 91麻豆精品国产91久久久更新时间| 亚洲成年人网站在线观看| 欧美精品第1页| 捆绑调教一区二区三区| 26uuu精品一区二区三区四区在线| 精彩视频一区二区三区| 国产亲近乱来精品视频| www.亚洲色图| 亚洲精品视频在线看| 欧美高清视频在线高清观看mv色露露十八 | 一区二区在线免费观看| 亚洲精品亚洲人成人网 | 久久综合给合久久狠狠狠97色69| 国产专区欧美精品| 国产精品欧美一级免费| 在线视频欧美精品| 日本欧美大码aⅴ在线播放| 日韩精品一区二区三区三区免费| 国产不卡视频一区| 亚洲欧美日韩中文播放| 91麻豆精品国产自产在线| 麻豆精品视频在线观看视频| 久久久久久久一区| 91原创在线视频| 免费在线看成人av| 欧美激情一区在线观看| 欧美视频一区二区三区四区 | 91精品国产综合久久久久久久| 久久精品av麻豆的观看方式| 中文字幕欧美激情| 欧美日韩视频在线观看一区二区三区 | 在线观看91视频| 蜜桃精品在线观看| 中文字幕一区二区三区不卡| 欧美日韩国产成人在线免费| 国产精品一区二区果冻传媒| 亚洲午夜一二三区视频| 久久蜜臀精品av| 欧美性猛交xxxx乱大交退制版 | 91在线看国产| 六月婷婷色综合| 一区二区三区不卡视频| 2020国产精品自拍| 欧美色手机在线观看| 国产大陆a不卡| 视频一区欧美日韩| 国产精品成人一区二区艾草 | 怡红院av一区二区三区| 亚洲精品一区二区三区福利 | 7777精品伊人久久久大香线蕉完整版| 国产精品综合在线视频| 亚洲成av人片在线| 国产精品电影一区二区三区| 5566中文字幕一区二区电影| 91麻豆自制传媒国产之光| 国产一区二区三区在线观看免费视频| 亚洲国产日韩精品| 国产精品久久久久久久午夜片|