/*
 * Most of this source has been derived from the Linux USB
 * project:
 * (C) Copyright Linus Torvalds 1999
 * (C) Copyright Johannes Erdfelt 1999-2001
 * (C) Copyright Andreas Gal 1999
 * (C) Copyright Gregory P. Smith 1999
 * (C) Copyright Deti Fliegl 1999 (new USB architecture)
 * (C) Copyright Randy Dunlap 2000
 * (C) Copyright David Brownell 2000 (kernel hotplug, usb_device_id)
 * (C) Copyright Yggdrasil Computing, Inc. 2000
 *     (usb_device_id matching changes by Adam J. Richter)
 *
 * Adapted for U-Boot:
 * (C) Copyright 2001 Denis Peter, MPL AG Switzerland
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */
#include "diag_common.h"
#include "diag_misc.h"
#include "usb_memmap.h"
#include "core.h"

#undef USB_MAX_HUB
#define USB_MAX_HUB (2)
#define USB_MAX_HUB_PORT (16)
//#define USB_CNTL_TIMEOUT (100)  // you can enlarge it

#define USB_BUFSIZ	512
#define HUB_SHORT_RESET_TIME	20
#define HUB_LONG_RESET_TIME	200

#define PORT_OVERCURRENT_MAX_SCAN_COUNT		3

#define msleep delay_1ms

/******************************************************************************
**
** Macros to swap between USB byte arrays and HOST types.
** Stack and applications should use the following API:
**
** READ functions
**	Parameters:
**	   "p"			Pointer to data stored in USB order byte array
**
**	Macros:
**	   utoh32(p)	  Read 32 bit number from "p", return HOST uint_32
**	   utoh16(p)	  Read 16 bit number from "p", return HOST uint_16
**	   utoh8(p)	   Read  8 bit number from "p", return HOST uint_8
**
** WRITE functions
**	Parameters:
**	   "p"			Array of bytes in which to store data in USB byte order
**	   "x"			A HOST data type to be converted into a byte array
**
**	Macros:
**	   htou32(p,x)	Store "x" (uint_32) into USB order byte array at "p"
**	   htou16(p,x)	Store "x" (uint_16) into USB order byte array at "p"
**	   htou8(p,x)	 Store "x" (uint_8) into USB order byte array at "p"
*/

typedef  unsigned short uint_16;

#define HOST_WRITE_OCT32(p,x,a,b,c,d) ((p)[a] = ((uint_32)(x)) >> 24 & 0xFF, \
									   (p)[b] = ((uint_32)(x)) >> 16 & 0xFF, \
									   (p)[c] = ((uint_32)(x)) >>  8 & 0xFF, \
									   (p)[d] = ((uint_32)(x))	   & 0xFF)

#define HOST_WRITE_OCT16(p,x,a,b)	 ((p)[a] = ((uint_16)(x)) >>  8 & 0xFF, \
									   (p)[b] = ((uint_16)(x))	   & 0xFF)

#define HOST_WRITE_OCT8(p,x)		  ((p)[0] = (( uint_8)(x))	   & 0xFF)

#define HOST_READ_OCT32(p,a,b,c,d)  ((((uint_32)(p)[a] & 0xFF) << 24) | \
									 (((uint_32)(p)[b] & 0xFF) << 16) | \
									 (((uint_32)(p)[c] & 0xFF) <<  8) | \
									 (((uint_32)(p)[d] & 0xFF)	  ))

#define HOST_READ_OCT16(p,a,b)	  ((((uint_16)(p)[a] & 0xFF) <<  8) | \
									 (((uint_16)(p)[b] & 0xFF)	  ))

#define HOST_READ_OCT8(p)			(((( uchar)(p)[0] & 0xFF)	  ))


#define HOST_WRITE_BEOCT_32(p,x)	HOST_WRITE_OCT32(p,x,0,1,2,3)
#define HOST_WRITE_LEOCT_32(p,x)	HOST_WRITE_OCT32(p,x,3,2,1,0)
#define HOST_WRITE_BEOCT_16(p,x)	HOST_WRITE_OCT16(p,x,0,1)
#define HOST_WRITE_LEOCT_16(p,x)	HOST_WRITE_OCT16(p,x,1,0)
#define HOST_WRITE_BEOCT_8(p,x)	 HOST_WRITE_OCT8(p,x)
#define HOST_WRITE_LEOCT_8(p,x)	 HOST_WRITE_OCT8(p,x)

#define HOST_READ_BEOCT_32(p)	   HOST_READ_OCT32(p,0,1,2,3)
#define HOST_READ_LEOCT_32(p)	   HOST_READ_OCT32(p,3,2,1,0)
#define HOST_READ_BEOCT_16(p)	   HOST_READ_OCT16(p,0,1)
#define HOST_READ_LEOCT_16(p)	   HOST_READ_OCT16(p,1,0)
#define HOST_READ_BEOCT_8(p)		HOST_READ_OCT8(p)
#define HOST_READ_LEOCT_8(p)		HOST_READ_OCT8(p)

#define utoh32(p)	HOST_READ_OCT32(p,3,2,1,0)
#define utoh16(p)	HOST_READ_OCT16(p,1,0)
#define utoh8(p)	 HOST_READ_OCT8(p)

#define htou32(p,x)  HOST_WRITE_OCT32(p,x,3,2,1,0)
#define htou16(p,x)  HOST_WRITE_OCT16(p,x,1,0)
#define htou8(p,x)   HOST_WRITE_OCT8(p,x)


struct usb_device_scan {
	struct usb_device *dev;		/* USB hub device to scan */
	struct usb_hub_device *hub;	/* USB hub struct */
	int port;			/* USB port to scan */
	int enable;
};

/* TODO(sjg@chromium.org): Remove this when CONFIG_DM_USB is defined */
static struct usb_hub_device hub_dev[USB_MAX_HUB];
static int usb_hub_index;
static struct usb_device *dev_on_hub = NULL;
static struct usb_device_scan usb_scan_list[USB_MAX_HUB_PORT];


unsigned usb2_specific_hub_port = 0;
extern unsigned int timer_cycle2us(unsigned int cycles);
extern unsigned int timer_get();

unsigned int num_scan_list;
unsigned int scanned_all_flag;

void usb_hub_reset_devices(int port)
{
	UNUSED(port);
	return;
}

static int hub_is_superspeed(struct usb_device *dev)
{
	return dev->descriptor.bDeviceProtocol == USB_HUB_PR_SS;
}

static int usb_get_hub_descriptor(struct usb_device *dev, void *data, int size)
{
	unsigned char dtype;
	if (hub_is_superspeed(dev)) {
		dtype = USB_DT_SS_HUB;
	} else {
		dtype = USB_DT_HUB;
	}

	return urb_control(dev, usb_rcvctrlpipe(dev, 0),
		USB_REQ_GET_DESCRIPTOR, USB_DIR_IN | USB_RT_HUB,
		dtype << 8, 0, data, size, USB_CNTL_TIMEOUT);
}

static int usb_clear_port_feature(struct usb_device *dev, int port, int feature)
{
	return urb_control(dev, usb_sndctrlpipe(dev, 0),
				USB_REQ_CLEAR_FEATURE, USB_RT_PORT, feature,
				port, NULL, 0, USB_CNTL_TIMEOUT);
}

static int usb_set_port_feature(struct usb_device *dev, int port, int feature)
{
	return urb_control(dev, usb_sndctrlpipe(dev, 0),
				USB_REQ_SET_FEATURE, USB_RT_PORT, feature,
				port, NULL, 0, USB_CNTL_TIMEOUT);
}

static int usb_get_hub_status(struct usb_device *dev, void *data)
{
	return urb_control(dev, usb_rcvctrlpipe(dev, 0),
			USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_HUB, 0, 0,
			data, sizeof(struct usb_hub_status), USB_CNTL_TIMEOUT);
}

int usb_get_port_status(struct usb_device *dev, int port, void *data)
{
	return urb_control(dev, usb_rcvctrlpipe(dev, 0),
			USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_PORT, 0, port,
			data, sizeof(struct usb_hub_status), USB_CNTL_TIMEOUT);
}


static void usb_hub_power_on(struct usb_hub_device *hub)
{
	int i;
	struct usb_device *dev;
	unsigned pgood_delay = hub->desc.bPwrOn2PwrGood * 2;

	dev = hub->pusb_dev;

	debug("enabling power on all ports\n");
	for (i = 0; i < dev->maxchild; i++) {
		usb_set_port_feature(dev, i + 1, USB_PORT_FEAT_POWER);
		debug("port %d returns %lX\n", i + 1, dev->status);
	}


	/*
	 * Do a minimum delay of the larger value of 100ms or pgood_delay
	 * so that the power can stablize before the devices are queried
	 */
	hub->query_delay = timer_cycle2us(timer_get())/1000 + max(100, (int)pgood_delay);

	/*
	 * Record the power-on timeout here. The max. delay (timeout)
	 * will be done based on this value in the USB port loop in
	 * usb_hub_configure() later.
	 */
	hub->connect_timeout = hub->query_delay + 1000;
	debug("devnum=%d poweron: query_delay=%d connect_timeout=%d\n",
		  dev->devnum, max(100, (int)pgood_delay),
		  max(100, (int)pgood_delay) + 1000);
}

void usb_hub_reset(void)
{
	usb_hub_index = 0;

	dev_on_hub = NULL;
	/* Zero out global hub_dev in case its re-used again */
	memset(hub_dev, 0, sizeof(struct usb_hub_device) * USB_MAX_HUB);
	//memset(usb_scan_list, 0, sizeof(struct usb_device_scan) * USB_MAX_HUB_PORT);
}

static struct usb_hub_device *usb_hub_allocate(void)
{
	if (usb_hub_index < USB_MAX_HUB)
		return &hub_dev[usb_hub_index++];

	printf("ERROR: USB_MAX_HUB (%d) reached\n", USB_MAX_HUB);
	return NULL;
}

#define MAX_TRIES 5

static inline char *portspeed(int portstatus)
{
	char *speed_str;

	switch (portstatus & USB_PORT_STAT_SPEED_MASK) {
	case USB_PORT_STAT_SUPER_SPEED:
		speed_str = "5 Gb/s";
		break;
	case USB_PORT_STAT_HIGH_SPEED:
		speed_str = "480 Mb/s";
		break;
	case USB_PORT_STAT_LOW_SPEED:
		speed_str = "1.5 Mb/s";
		break;
	default:
		speed_str = "12 Mb/s";
		break;
	}

	return speed_str;
}

int legacy_hub_port_reset(struct usb_device *dev, int port,
			unsigned short *portstat)
{
	int err, tries;
	struct usb_port_status *portsts = USB_memalloc(sizeof(struct usb_port_status));
	unsigned short portstatus, portchange;
	int delay = HUB_SHORT_RESET_TIME; /* start with short reset delay */

	debug("%s: resetting port %d...\n", __func__, port + 1);
	for (tries = 0; tries < MAX_TRIES; tries++) {
		err = usb_set_port_feature(dev, port + 1, USB_PORT_FEAT_RESET);
		if (err < 0)
			return err;

		msleep(delay);

		if (usb_get_port_status(dev, port + 1, portsts) < 0) {
			debug("get_port_status failed status %lX\n",
				  dev->status);
			return -1;
		}
		portstatus = le16_to_cpu(portsts->wPortStatus);
		portchange = le16_to_cpu(portsts->wPortChange);

		debug("portstatus %x, change %x, %s\n", portstatus, portchange,
							portspeed(portstatus));

		debug("STAT_C_CONNECTION = %d STAT_CONNECTION = %d" \
			  "  USB_PORT_STAT_ENABLE %d\n",
			  (portchange & USB_PORT_STAT_C_CONNECTION) ? 1 : 0,
			  (portstatus & USB_PORT_STAT_CONNECTION) ? 1 : 0,
			  (portstatus & USB_PORT_STAT_ENABLE) ? 1 : 0);

		/*
		 * Perhaps we should check for the following here:
		 * - C_CONNECTION hasn't been set.
		 * - CONNECTION is still set.
		 *
		 * Doing so would ensure that the device is still connected
		 * to the bus, and hasn't been unplugged or replaced while the
		 * USB bus reset was going on.
		 *
		 * However, if we do that, then (at least) a San Disk Ultra
		 * USB 3.0 16GB device fails to reset on (at least) an NVIDIA
		 * Tegra Jetson TK1 board. For some reason, the device appears
		 * to briefly drop off the bus when this second bus reset is
		 * executed, yet if we retry this loop, it'll eventually come
		 * back after another reset or two.
		 */

		if (portstatus & USB_PORT_STAT_ENABLE)
			break;

		/* Switch to long reset delay for the next round */
		delay = HUB_LONG_RESET_TIME;
	}

	if (tries == MAX_TRIES) {
		debug("Cannot enable port %i after %i retries, " \
			  "disabling port.\n", port + 1, MAX_TRIES);
		debug("Maybe the USB cable is bad?\n");
		return -1;
	}

	usb_clear_port_feature(dev, port + 1, USB_PORT_FEAT_C_RESET);
	*portstat = portstatus;
	return 0;
}

int usb_hub_port_connect_change(struct usb_device *dev, int port)
{
	struct usb_port_status *portsts = USB_memalloc(sizeof(struct usb_port_status));
	unsigned short portstatus;
	//unsigned short portchange;
	int ret, speed;

	debug("enter %s\n", __func__);

	/* checka status */
	ret = usb_get_port_status(dev, port + 1, portsts);
	if (ret < 0) {
		debug("get_port_status failed\n");
		return ret;
	}

	portstatus = le16_to_cpu(portsts->wPortStatus);
	//portchange = le16_to_cpu(portsts->wPortChange);
	debug("portstatus %x, change %x, %s\n",
		  portstatus,
		  le16_to_cpu(portsts->wPortChange),
		  portspeed(portstatus));

	/* Clear the connection change status */
	usb_clear_port_feature(dev, port + 1, USB_PORT_FEAT_C_CONNECTION);

	/* Disconnect any existing devices under this port */
	if (((!(portstatus & USB_PORT_STAT_CONNECTION)) &&
		 (!(portstatus & USB_PORT_STAT_ENABLE))) ||
		usb_device_has_child_on_port(dev, port)) {
		debug("usb_disconnect(&hub->children[port]);\n");
		/* Return now if nothing is connected */
		if (!(portstatus & USB_PORT_STAT_CONNECTION))
			return -ENOTCONN;
	}

//	if (hub_is_superspeed(dev)){
//
//		speed = USB_SPEED_SUPER;
//		if (portchange & USB_PORT_STAT_C_RESET) {
//			usb_clear_port_feature(dev, port + 1, USB_PORT_FEAT_C_RESET);
//		}
//		if (portchange & USB_PORT_STAT_C_BH_RESET) {
//			usb_clear_port_feature(dev, port + 1, USB_PORT_FEAT_C_BH_PORT_RESET);
//		}
//
//	} else {
		/* Reset the port */
		ret = legacy_hub_port_reset(dev, port, &portstatus);
		if (ret < 0) {
			if (ret != -6)
				printf("cannot reset port %i!?\n", port + 1);
			return ret;
		}

#if 0 // XL,  the hub will translate hs to fs
				speed = USB_SPEED_HIGH;
#else

		switch (portstatus & USB_PORT_STAT_SPEED_MASK) {
			case USB_PORT_STAT_SUPER_SPEED:
				speed = USB_SPEED_SUPER;
				break;
			case USB_PORT_STAT_HIGH_SPEED:
				speed = USB_SPEED_HIGH;
				break;
			case USB_PORT_STAT_LOW_SPEED:
				speed = USB_SPEED_LOW;
				break;
			default:
				speed = USB_SPEED_FULL;
				break;
			}
#endif
	//   }

	struct usb_device *usb;
	ret = usb_device_data_init(&usb);
	if (ret) {
		printf("cannot create new device: ret=%d", ret);
		return ret;
	}

	dev->children[port] = usb;
	usb->speed = speed;
	usb->parent = dev;
	usb->portnr = port + 1;
	/* Run it through the hoops (find a driver, etc) */
	ret = usb_new_device(usb);
	if (ret < 0) {
		/* Woops, disable the port */
		printf("non-mass devices, usb free device\n");
		usb_free_device(dev->controller);
		dev->children[port] = NULL;
	}

	if (ret < 0) {
		debug("hub: disabling port %d\n", port + 1);
		usb_clear_port_feature(dev, port + 1, USB_PORT_FEAT_ENABLE);
	}

	debug("exit %s\n", __func__);
	return ret;
}

int usb_scan_port(struct usb_device_scan *usb_scan)
{

	struct usb_port_status  * portsts = USB_memalloc(sizeof(struct usb_port_status));
	unsigned short portstatus;
	unsigned short portchange;
	struct usb_device *dev;
	struct usb_hub_device *hub;
	int ret = 0;
	int i;

	debug("enter %s, port:%d\n", __func__, usb_scan->port);
	dev = usb_scan->dev;
	hub = usb_scan->hub;
	i = usb_scan->port;

	if (i + 1 > dev->maxchild)
		return 1;

	/*
	 * Don't talk to the device before the query delay is expired.
	 * This is needed for voltages to stabalize.
	 */
	if (timer_cycle2us(timer_get())/1000 < hub->query_delay) {
		USB_memfree(portsts);
		memset(portsts, 0, sizeof(portsts));
		return 0;
	}


	ret = usb_get_port_status(dev, i + 1, portsts);
	if (ret < 0) {
		dbg_printf(PRN_ERR, "get_port_status failed\n");
		if (timer_cycle2us(timer_get())/1000 >= hub->connect_timeout) {
			dbg_printf(PRN_RES, "devnum=%d port=%d: timeout\n",
				  dev->devnum, i + 1);
			/* Remove this device from scanning list */
			memset(usb_scan, 0, sizeof(usb_scan));
			USB_memfree(portsts);
			memset(portsts, 0, sizeof(portsts));
			return 1;
		}
		USB_memfree(portsts);
		memset(portsts, 0, sizeof(portsts));
		return 0;
	}

	portstatus = le16_to_cpu(portsts->wPortStatus);
	portchange = le16_to_cpu(portsts->wPortChange);
	debug("Port %d Status %X Change %X\n", i + 1, portstatus, portchange);

	/* No connection change happened, wait a bit more. */
	if(!hub_is_superspeed(dev)){
		if (!(portchange & USB_PORT_STAT_C_CONNECTION)) {
			if (timer_cycle2us(timer_get())/1000 >= hub->connect_timeout) {
				dbg_printf(PRN_RES, "devnum=%d port=%d: timeout\n",
						   dev->devnum, i + 1);
				/* Remove this device from scanning list */
				memset(usb_scan, 0, sizeof(usb_scan));
				USB_memfree(portsts);
				return 1;
			}
			USB_memfree(portsts);
			memset(portsts, 0, sizeof(portsts));
			return 0;
		}
	} else {
		if (!(portchange & USB_PORT_STAT_C_RESET)) {
			if (timer_cycle2us(timer_get())/1000 >= hub->connect_timeout) {
				dbg_printf(PRN_RES, "devnum=%d port=%d: timeout\n",
						   dev->devnum, i + 1);
				/* Remove this device from scanning list */
				memset(usb_scan, 0, sizeof(usb_scan));
				USB_memfree(portsts);
				memset(portsts, 0, sizeof(portsts));
				return 1;
			}
			USB_memfree(portsts);
			memset(portsts, 0, sizeof(portsts));
			return 0;
		}
	}

	/* Test if the connection came up, and if not exit */
	if (!(portstatus & USB_PORT_STAT_CONNECTION)) {
		USB_memfree(portsts);
		memset(portsts, 0, sizeof(portsts));
		return 0;
	}

	/* A new USB device is ready at this point */
	dbg_printf(PRN_RES, "devnum=%d port=%d: USB dev found\n", dev->devnum, i + 1);

	usb_hub_port_connect_change(dev, i);
	dev_on_hub = dev->children[i];


	ret = usb_get_port_status(dev, i + 1, portsts);
	portstatus = le16_to_cpu(portsts->wPortStatus);
	portchange = le16_to_cpu(portsts->wPortChange);

	debug("Port %d Status %X Change %X\n", i + 1, portstatus, portchange);
	if(!hub_is_superspeed(dev)){
		if (portchange & USB_PORT_STAT_C_ENABLE) {
			debug("port %d enable change, status %x\n", i + 1, portstatus);
			usb_clear_port_feature(dev, i + 1, USB_PORT_FEAT_C_ENABLE);
			/*
			* The following hack causes a ghost device problem
			* to Faraday EHCI
			*/
	#if 0
			/*
			* EM interference sometimes causes bad shielded USB
			* devices to be shutdown by the hub, this hack enables
			* them again. Works at least with mouse driver
			*/
			if (!(portstatus & USB_PORT_STAT_ENABLE) &&
				(portstatus & USB_PORT_STAT_CONNECTION) &&
				usb_device_has_child_on_port(dev, i)) {
				debug("already running port %i disabled by hub (EMI?), re-enabling...\n",
					i + 1);
				usb_hub_port_connect_change(dev, i);
			}
	#endif
		}
	}

	if (portstatus & USB_PORT_STAT_SUSPEND) {
		debug("port %d suspend change\n", i + 1);
		usb_clear_port_feature(dev, i + 1, USB_PORT_FEAT_SUSPEND);
	}

	if (portchange & USB_PORT_STAT_C_OVERCURRENT) {
		debug("port %d over-current change\n", i + 1);
		usb_clear_port_feature(dev, i + 1,
					   USB_PORT_FEAT_C_OVER_CURRENT);
		/* Only power-on this one port */
		usb_set_port_feature(dev, i + 1, USB_PORT_FEAT_POWER);
		hub->overcurrent_count[i]++;

		/*
		 * If the max-scan-count is not reached, return without removing
		 * the device from scan-list. This will re-issue a new scan.
		 */
		if (hub->overcurrent_count[i] <=
			PORT_OVERCURRENT_MAX_SCAN_COUNT) {
			USB_memfree(portsts);
			memset(portsts, 0, sizeof(portsts));
			return 0;
		}

		/* Otherwise the device will get removed */
		debug("Port %d over-current occurred %d times\n", i + 1,
			   hub->overcurrent_count[i]);
	}

	if (portchange & USB_PORT_STAT_C_RESET) {
		debug("port %d reset change\n", i + 1);
		usb_clear_port_feature(dev, i + 1, USB_PORT_FEAT_C_RESET);
	}

	/*
	 * We're done with this device, so let's remove this device from
	 * scanning list
	 */
	memset(usb_scan, 0, sizeof(usb_scan));
	USB_memfree(portsts);
	memset(portsts, 0, sizeof(portsts));

	debug("exit %s, port:%d\n", __func__, usb_scan->port);
	return 0;
}

int usb_device_list_scan(void)
{
	struct usb_device_scan *usb_scan;
	unsigned int i, j;
	int ret = 0;

	debug("enter %s\n", __func__);
	/* Only run this loop once for each controller */
	dbg_printf(PRN_RES, "\n");

	while (1) {
		dbg_printf(PRN_RES, ".");
		/* ensure no mass storage devices can exit normally */
		scanned_all_flag = 0;
		for(i = 0; i< num_scan_list;i++) {
			debug("(%d, %s), usb_scan_list[%d].enable = %d\n",
				__LINE__,__func__, i, usb_scan_list[i].enable);
			scanned_all_flag |= usb_scan_list[i].enable;
		}

		if (0 == scanned_all_flag)
			goto out;

		/* We're done, once the list is empty again */
		for (i = 0; i < USB_MAX_HUB_PORT; i++) {
			usb_scan = &usb_scan_list[i];
			if (usb_scan->enable == 0)
				continue;
			debug("(%d, %s), port:%d, bInterfaceClass = %x\n",
				__LINE__, __func__, i+1, dev_on_hub->config.if_desc[i].desc.bInterfaceClass);

			/* Scan this port */
			ret = usb_scan_port(usb_scan);
			debug("(%d, %s), ret:%d, port:%d, bInterfaceClass = %x\n",
				__LINE__, __func__, ret, i+1, dev_on_hub->config.if_desc[i].desc.bInterfaceClass);
			if (ret) {
				memset(&usb_scan_list[i], 0, sizeof(struct usb_device_scan));
				debug("%s, %d,usb_scan_list[%d].enable = %d\n",
					__func__,__LINE__, i, usb_scan_list[i].enable);
			}
			if (dev_on_hub) {
				if (dev_on_hub->config.if_desc[0].desc.bInterfaceClass == USB_CLASS_MASS_STORAGE) {
					for (j = i; j < USB_MAX_HUB_PORT; j++) {
						memset(&usb_scan_list[j], 0, sizeof(struct usb_device_scan));
						debug("(%d, %s),usb_scan_list[%d].enable = %d\n",
							__LINE__, __func__, j, usb_scan_list[i].enable);
					}
					goto out;
				} else {
					memset(&usb_scan_list[i], 0, sizeof(struct usb_device_scan));
					debug("%s, %d,usb_scan_list[%d].enable = %d\n",
						__func__,__LINE__, i, usb_scan_list[i].enable);
				}
			}
		}
	}

out:
	/*
	 * This USB controller has finished scanning all its connected
	 * USB devices. Set "running" back to 0, so that other USB controllers
	 * will scan their devices too.
	 */

	scanned_all_flag = 0;
	dbg_printf(PRN_RES, "\n");
	debug("exit %s\n", __func__);
	return ret;
}

static int usb_hub_configure(struct usb_device *dev)
{
	int length;
	unsigned int i;
	unsigned char * buffer = USB_memalloc(USB_BUFSIZ);
	short hubCharacteristics;
	struct usb_hub_descriptor *descriptor;
	struct usb_hub_device *hub;
	struct usb_hub_status *hubsts;
	int ret;

	debug("enter %s\n", __func__);

	/* "allocatea" Hub device */
	hub = usb_hub_allocate();
	if (hub == NULL)
		return -ENOMEM;
	hub->pusb_dev = dev;
	/* Get the the hub descriptor */
	ret = usb_get_hub_descriptor(dev, buffer, 4);
	if (ret < 0) {
		dbg_printf(PRN_ERR,"usb_hub_configure: failed to get hub "  \
			  "descriptor, giving up %lX\n", dev->status);
		return ret;
	}
	descriptor = (struct usb_hub_descriptor *)buffer;

//	if (hub_is_superspeed(dev)) {
//		length = USB_DT_SS_HUB_SIZE;
//	} else {
		length = min(((int)(descriptor->bLength)),
			   sizeof(struct usb_hub_descriptor));
//	}

	ret = usb_get_hub_descriptor(dev, buffer, length);
	if (ret < 0) {
		dbg_printf(PRN_RES, "usb_hub_configure: failed to get hub "  \
			  "descriptor 2nd giving up %lX\n", dev->status);
		return ret;
	}

	memcpy((unsigned char *)&hub->desc, buffer, length);

#if 0 //  XL, remove, super speed don't have it.
	/* set the bitmap */
	bitmap = (unsigned char *)&hub->desc.DeviceRemovable[0];
	/* devices not removable by default */
	memset(bitmap, 0xff, (USB_MAXCHILDREN+1+7)/8);
	bitmap = (unsigned char *)&hub->desc.PortPowerCtrlMask[0];
	memset(bitmap, 0xff, (USB_MAXCHILDREN+1+7)/8); /* PowerMask = 1B */

	for (i = 0; i < ((hub->desc.bNbrPorts + 1 + 7)/8); i++)
		hub->desc.DeviceRemovable[i] = descriptor->DeviceRemovable[i];

	for (i = 0; i < ((hub->desc.bNbrPorts + 1 + 7)/8); i++)
		hub->desc.PortPowerCtrlMask[i] = descriptor->PortPowerCtrlMask[i];
#endif
	dev->maxchild = descriptor->bNbrPorts;
	dbg_printf(PRN_RES, "%d ports detected\n", dev->maxchild);

	if (usb2_specific_hub_port  > (unsigned int)dev->maxchild) {
		dbg_printf(PRN_RES,"invalid parameter, specific hub port should equal or less than:%d", dev-> maxchild);
		usb2_specific_hub_port = 0;
	}

	hubCharacteristics = utoh16(&hub->desc.wHubCharacteristics);
	switch (hubCharacteristics & HUB_CHAR_LPSM) {
	case 0x00:
		debug("ganged power switching\n");
		break;
	case 0x01:
		debug("individual port power switching\n");
		break;
	case 0x02:
	case 0x03:
		debug("unknown reserved power switching mode\n");
		break;
	}

	if (hubCharacteristics & HUB_CHAR_COMPOUND)
		debug("part of a compound device\n");
	else
		debug("standalone hub\n");

	switch (hubCharacteristics & HUB_CHAR_OCPM) {
	case 0x00:
		debug("global over-current protection\n");
		break;
	case 0x08:
		debug("individual port over-current protection\n");
		break;
	case 0x10:
	case 0x18:
		debug("no over-current protection\n");
		break;
	}

	switch (dev->descriptor.bDeviceProtocol) {
	case USB_HUB_PR_FS:
		break;
	case USB_HUB_PR_HS_SINGLE_TT:
		debug("Single TT\n");
		break;
	case USB_HUB_PR_HS_MULTI_TT:
		ret = set_interface(dev, 0, 1);
		if (ret == 0) {
			debug("TT per port\n");
			hub->tt.multi = true;
		} else {
			debug("Using single TT (err %d)\n", ret);
		}
		break;
	case USB_HUB_PR_SS:
		/* USB 3.0 hubs don't have a TT */
		break;
	default:
		debug("Unrecognized hub protocol %d\n",
			  dev->descriptor.bDeviceProtocol);
		break;
	}

	/* Note 8 FS bit times == (8 bits / 12000000 bps) ~= 666ns */
	switch (hubCharacteristics & HUB_CHAR_TTTT) {
	case HUB_TTTT_8_BITS:
		if (dev->descriptor.bDeviceProtocol != 0) {
			hub->tt.think_time = 666;
			debug("TT requires at most %d FS bit times (%d ns)\n",
				  8, hub->tt.think_time);
		}
		break;
	case HUB_TTTT_16_BITS:
		hub->tt.think_time = 666 * 2;
		debug("TT requires at most %d FS bit times (%d ns)\n",
			  16, hub->tt.think_time);
		break;
	case HUB_TTTT_24_BITS:
		hub->tt.think_time = 666 * 3;
		debug("TT requires at most %d FS bit times (%d ns)\n",
			  24, hub->tt.think_time);
		break;
	case HUB_TTTT_32_BITS:
		hub->tt.think_time = 666 * 4;
		debug("TT requires at most %d FS bit times (%d ns)\n",
			  32, hub->tt.think_time);
		break;
	}
	debug("power on to power good time: %dms\n",
		  descriptor->bPwrOn2PwrGood * 2);
	debug("hub controller current requirement: %dmA\n",
		  descriptor->bHubContrCurrent);

	if (!hub_is_superspeed(dev)) {
	for (i = 0; i < (unsigned int)dev->maxchild; i++)
		debug("port %d is%s removable\n", i + 1,
			  hub->desc.u.hs.DeviceRemovable[(i + 1) / 8] & \
			  (1 << ((i + 1) % 8)) ? " not" : "");
	}

	if (sizeof(struct usb_hub_status) > USB_BUFSIZ) {
		debug("usb_hub_configure: failed to get Status - " \
			  "too long: %d\n", descriptor->bLength);
		return -1;
	}


//	if (hub_is_superspeed(dev)) {
//			ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
//					HUB_SET_DEPTH, USB_RT_HUB,
//								  //dev->level - 1, 0, NULL, 0,
//					0, 0, NULL, 0,
//					USB_CTRL_SET_TIMEOUT);
//			if (ret < 0)
//				dev_err(hub->intfdev,
//						"set hub depth failed\n");
//
//			for (i = 0; i < dev->maxchild; i++) {
//				usb_set_port_feature(dev, i + 1, USB_PORT_FEAT_PORT_REMOTE_WAKE_MASK);
//			}
//	}

	ret = usb_get_hub_status(dev, buffer);
	if (ret < 0) {
		debug("usb_hub_configure: failed to get Status %lX\n",
			  dev->status);
		return ret;
	}

	hubsts = (struct usb_hub_status *)buffer;

	debug("get_hub_status returned status %X, change %X\n",
		  le16_to_cpu(hubsts->wHubStatus),
		  le16_to_cpu(hubsts->wHubChange));
	debug("local power source is %s\n",
		  (le16_to_cpu(hubsts->wHubStatus) & HUB_STATUS_LOCAL_POWER) ? \
		  "lost (inactive)" : "good");
	debug("%sover-current condition exists\n",
		  (le16_to_cpu(hubsts->wHubStatus) & HUB_STATUS_OVERCURRENT) ? \
		  "" : "no ");
	usb_hub_power_on(hub);

	/*
	 * Reset any devices that may be in a bad state when applying
	 * the power.  This is a __weak function.  Resetting of the devices
	 * should occur in the board file of the device.
	 */
	for (i = 0; i < (unsigned int)dev->maxchild; i++)
		usb_hub_reset_devices(i + 1);

	/*
	 * Only add the connected USB devices, including potential hubs,
	 * to a scanning list. This list will get scanned and devices that
	 * are detected (either via port connected or via port timeout)
	 * will get removed from this list. Scanning of the devices on this
	 * list will continue until all devices are removed.
	 */

	for (i = 0; i < (unsigned int)dev->maxchild; i++) {

		if ((usb2_specific_hub_port != 0) && (usb2_specific_hub_port != (i + 1))){
			continue;
		}
		struct usb_device_scan *usb_scan = &usb_scan_list[i];

		usb_scan->dev = dev;
		usb_scan->hub = hub;
		usb_scan->port = i;
		usb_scan->enable = 1;
	}

	num_scan_list = i;
	/*
	 * And now call the scanning code which loops over the generated list
	 */
	ret = usb_device_list_scan();

	debug("exit %s\n", __func__);
	return ret;
}

static int usb_hub_check(struct usb_device *dev, int ifnum)
{
	struct usb_interface *iface;
	struct usb_endpoint_descriptor *ep = NULL;

	iface = &dev->config.if_desc[ifnum];
	/* Is it a hub? */
	if (iface->desc.bInterfaceClass != USB_CLASS_HUB)
		goto err;
	/* Some hubs have a subclass of 1, which AFAICT according to the */
	/*  specs is not defined, but it works */
	if ((iface->desc.bInterfaceSubClass != 0) &&
		(iface->desc.bInterfaceSubClass != 1))
		goto err;
	/* Multiple endpoints? What kind of mutant ninja-hub is this? */
	if (iface->desc.bNumEndpoints != 1)
		goto err;
	ep = &iface->ep_desc[0];
	/* Output endpoint? Curiousier and curiousier.. */
	if (!(ep->bEndpointAddress & USB_DIR_IN))
		goto err;
	/* If it's not an interrupt endpoint, we'd better punt! */
	if ((ep->bmAttributes & 3) != 3)
		goto err;
	/* We found a hub */
	dbg_printf(PRN_RES, "USB hub found\n");

	dbg_printf(PRN_DBG, "bInterfaceClass=%d, bInterfaceSubClass=%d, bNumEndpoints=%d\n",
		  iface->desc.bInterfaceClass, iface->desc.bInterfaceSubClass,
		  iface->desc.bNumEndpoints);
	if (ep) {
		dbg_printf(PRN_DBG,"   bEndpointAddress=%#x, bmAttributes=%d",
			  ep->bEndpointAddress, ep->bmAttributes);
	}
	return 0;

err:
	dbg_printf(PRN_INFO, "It is not USB hub\n");

	return -ENOENT;
}

int usb_hub_probe(struct usb_device *dev, int ifnum)
{
	int ret;

	dbg_printf(PRN_ERR, "enter %s\n", __func__);

	usb_hub_reset();

	ret = usb_hub_check(dev, ifnum);
	if (ret)
		return 0;
	ret = usb_hub_configure(dev);
	return ret;
}
