/*
 * 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 "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 of all 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

/* 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);
}

/* completion function, fires on port status changes and various faults */
static void hub_irq(struct urb *urb)
{
	struct usb_hub *hub = (struct usb_hub *)urb->context;
	unsigned long flags;

	switch (urb->status) {
	case -ENOENT:		/* synchronous unlink */
	case -ECONNRESET:	/* async unlink */
	case -ESHUTDOWN:	/* hardware going away */
		return;

	default:		/* presumably an error */
		/* Cause a hub reset after 10 consecutive errors */
		dbg("hub '%s' status %d for interrupt transfer",
			urb->dev->devpath, urb->status);
		if ((++hub->nerrors < 10) || hub->error)
			return;
		hub->error = urb->status;
		/* FALL THROUGH */
	
	/* let khubd handle things */
	case 0:			/* we got data:  port status changed */
		break;
	}

	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.
	 * hub->descriptor can handle USB_MAXCHILDREN ports,
	 * but the hub can/will return fewer bytes here.
	 */
	ret = usb_get_hub_descriptor(dev, hub->descriptor,
			sizeof(*hub->descriptor));
	if (ret < 0) {
		err("Unable to get hub descriptor (err = %d)", ret);
		kfree(hub->descriptor);
		return -1;
	} else if (hub->descriptor->bNbrPorts > USB_MAXCHILDREN) {
		err("Hub is too big! %d children", hub->descriptor->bNbrPorts);
		kfree(hub->descriptor);
		return -1;
	}

	dev->maxchild = hub->descriptor->bNbrPorts;
	info("%d port%s detected", dev->maxchild,
		(dev->maxchild == 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) {
		case 0:
			break;
		case 1:
			dbg("Single TT");
			hub->tt.hub = dev;
			break;
		case 2:
			dbg("TT per port");
			hub->tt.hub = dev;
			hub->tt.multi = 1;
			break;
		default:
			dbg("Unrecognized hub protocol %d",
				dev->descriptor.bDeviceProtocol);
			break;
	}

	switch (hub->descriptor->wHubCharacteristics & HUB_CHAR_TTTT) {
		case 0x00:
			if (dev->descriptor.bDeviceProtocol != 0)
				dbg("TT requires at most 8 FS bit times");
			break;
		case 0x20:
			dbg("TT requires at most 16 FS bit times");
			break;
		case 0x40:
			dbg("TT requires at most 24 FS bit times");
			break;
		case 0x60:
			dbg("TT requires at most 32 FS bit times");
			break;
	}

	dbg("Port indicators are %s supported", 
	    (hub->descriptor->wHubCharacteristics & HUB_CHAR_PORTIND)
	    	? "" : "not");

	dbg("power on to power good time: %dms",
		hub->descriptor->bPwrOn2PwrGood * 2);
	dbg("hub controller current requirement: %dmA",
		hub->descriptor->bHubContrCurrent);

	for (i = 0; i < dev->maxchild; i++)
		portstr[i] = hub->descriptor->DeviceRemovable
			    [((i + 1) / 8)] & (1 << ((i + 1) % 8))
			? 'F' : 'R';
	portstr[dev->maxchild] = 0;

	dbg("port removable status: %s", portstr);

	ret = usb_get_hub_status(dev, &hubstatus);
	if (ret < 0) {
		err("Unable to get hub status (err = %d)", ret);
		kfree(hub->descriptor);
		return -1;
	}

	le16_to_cpus(&hubstatus.wHubStatus);

	dbg("local power source is %s",
		(hubstatus.wHubStatus & HUB_STATUS_LOCAL_POWER)
		? "lost (inactive)" : "good");

	dbg("%sover-current condition exists",
		(hubstatus.wHubStatus & HUB_STATUS_OVERCURRENT) ? "" : "no ");

	/* Start the interrupt endpoint */
	pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
	maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));

	if (maxp > sizeof(hub->buffer))
		maxp = sizeof(hub->buffer);

	hub->urb = usb_alloc_urb(0, GFP_KERNEL);
	if (!hub->urb) {
		err("couldn't allocate interrupt urb");
		kfree(hub->descriptor);
		return -1;
	}

	FILL_INT_URB(hub->urb, dev, pipe, hub->buffer, maxp, hub_irq,
		hub, endpoint->bInterval);
	ret = usb_submit_urb(hub->urb, GFP_KERNEL);
	if (ret) {
		err("usb_submit_urb failed (%d)", ret);
		kfree(hub->descriptor);
		return -1;
	}
		
	/* Wake up khubd */
	wake_up(&khubd_wait);

	usb_hub_power_on(hub);

	return 0;
}

static void *hub_probe(struct usb_device *dev, unsigned int i,
		       const struct usb_device_id *id)
{
	struct usb_interface_descriptor *interface;
	struct usb_endpoint_descriptor *endpoint;
	struct usb_hub *hub;
	unsigned long flags;

	interface = &dev->actconfig->interface[i].altsetting[0];

	/* Some hubs have a subclass of 1, which AFAICT according to the */
	/*  specs is not defined, but it works */
	if ((interface->bInterfaceSubClass != 0) &&
	    (interface->bInterfaceSubClass != 1)) {
		err("invalid subclass (%d) for USB hub device #%d",
			interface->bInterfaceSubClass, dev->devnum);
		return NULL;
	}

	/* Multiple endpoints? What kind of mutant ninja-hub is this? */
	if (interface->bNumEndpoints != 1) {
		err("invalid bNumEndpoints (%d) for USB hub device #%d",
			interface->bNumEndpoints, dev->devnum);
		return NULL;
	}

	endpoint = &interface->endpoint[0];

	/* Output endpoint? Curiousier and curiousier.. */
	if (!(endpoint->bEndpointAddress & USB_DIR_IN)) {
		err("Device #%d is hub class, but has output endpoint?",
			dev->devnum);
		return NULL;
	}

	/* If it's not an interrupt endpoint, we'd better punt! */
	if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
			!= USB_ENDPOINT_XFER_INT) {
		err("Device #%d is hub class, but endpoint is not interrupt?",
			dev->devnum);
		return NULL;
	}

	/* We found a hub */
	info("USB hub found at %s", dev->devpath);

	hub = kmalloc(sizeof(*hub), GFP_KERNEL);
	if (!hub) {
		err("couldn't kmalloc hub struct");
		return NULL;
	}

	memset(hub, 0, sizeof(*hub));

	INIT_LIST_HEAD(&hub->event_list);
	hub->dev = dev;
	init_MUTEX(&hub->khubd_sem);

	/* Record the new hub's existence */
	spin_lock_irqsave(&hub_event_lock, flags);
	INIT_LIST_HEAD(&hub->hub_list);
	list_add(&hub->hub_list, &hub_list);
	spin_unlock_irqrestore(&hub_event_lock, flags);

	if (usb_hub_configure(hub, endpoint) >= 0)
		return hub;

	err("hub configuration failed for device at %s", dev->devpath);

	/* free hub, but first clean up its list. */
	spin_lock_irqsave(&hub_event_lock, flags);

	/* Delete it and then reset it */
	list_del(&hub->event_list);
	INIT_LIST_HEAD(&hub->event_list);
	list_del(&hub->hub_list);
	INIT_LIST_HEAD(&hub->hub_list);

	spin_unlock_irqrestore(&hub_event_lock, flags);

	kfree(hub);

	return NULL;
}

static void hub_disconnect(struct usb_device *dev, void *ptr)
{
	struct usb_hub *hub = (struct usb_hub *)ptr;
	unsigned long flags;

	spin_lock_irqsave(&hub_event_lock, flags);

	/* Delete it and then reset it */
	list_del(&hub->event_list);
	INIT_LIST_HEAD(&hub->event_list);
	list_del(&hub->hub_list);
	INIT_LIST_HEAD(&hub->hub_list);

	spin_unlock_irqrestore(&hub_event_lock, flags);

	down(&hub->khubd_sem); /* Wait for khubd to leave this hub alone. */
	up(&hub->khubd_sem);

	if (hub->urb) {
		usb_unlink_urb(hub->urb);
		usb_free_urb(hub->urb);
		hub->urb = NULL;
	}

	if (hub->descriptor) {
		kfree(hub->descriptor);
		hub->descriptor = NULL;
	}

	/* Free the memory */
	kfree(hub);
}

static int hub_ioctl(struct usb_device *hub, unsigned int code, void *user_data)
{
	/* assert ifno == 0 (part of hub spec) */
	switch (code) {
	case USBDEVFS_HUB_PORTINFO: {
		struct usbdevfs_hub_portinfo *info = user_data;
		unsigned long flags;
		int i;

		spin_lock_irqsave(&hub_event_lock, flags);
		if (hub->devnum <= 0)
			info->nports = 0;
		else {
			info->nports = hub->maxchild;
			for (i = 0; i < info->nports; i++) {
				if (hub->children[i] == NULL)
					info->port[i] = 0;
				else
					info->port[i] =
						hub->children[i]->devnum;
			}
		}
		spin_unlock_irqrestore(&hub_event_lock, flags);

		return info->nports + 1;
		}

	default:
		return -ENOSYS;
	}
}

static int usb_hub_reset(struct usb_hub *hub)
{
	struct usb_device *dev = hub->dev;
	int i;

	/* Disconnect any attached devices */
	for (i = 0; i < hub->descriptor->bNbrPorts; i++) {
		if (dev->children[i])
			usb_disconnect(&dev->children[i]);
	}

	/* Attempt to reset the hub */
	if (hub->urb)
		usb_unlink_urb(hub->urb);
	else
		return -1;

	if (usb_reset_device(dev))
		return -1;

	hub->urb->dev = dev;                                                    
	if (usb_submit_urb(hub->urb, GFP_KERNEL))
		return -1;

	usb_hub_power_on(hub);

	return 0;
}

static void usb_hub_disconnect(struct usb_device *dev)
{
	struct usb_device *parent = dev->parent;
	int i;

	/* Find the device pointer to disconnect */
	if (parent) {
		for (i = 0; i < parent->maxchild; i++) {
			if (parent->children[i] == dev) {
				usb_disconnect(&parent->children[i]);
				return;
			}
		}
	}

	err("cannot disconnect hub %s", dev->devpath);
}

static int usb_hub_port_status(struct usb_device *hub, int port,
			       u16 *status, u16 *change)
{
	struct usb_port_status *portsts;
	int ret = -ENOMEM;

	portsts = kmalloc(sizeof(*portsts), GFP_KERNEL);
	if (portsts) {
		ret = usb_get_port_status(hub, port + 1, portsts);
		if (ret < 0)
			err("%s(%s) failed (err = %d)", __FUNCTION__, hub->devpath, ret);
		else {
			*status = le16_to_cpu(portsts->wPortStatus);
			*change = le16_to_cpu(portsts->wPortChange); 
			dbg("port %d, portstatus %x, change %x, %s", port + 1,
				*status, *change, portspeed(*status));
			ret = 0;
		}
		kfree(portsts);
	}
	return ret;
}

#define HUB_RESET_TRIES		5
#define HUB_PROBE_TRIES		2
#define HUB_SHORT_RESET_TIME	10
#define HUB_LONG_RESET_TIME	200
#define HUB_RESET_TIMEOUT	500

/* return: -1 on error, 0 on success, 1 on disconnect.  */
static int usb_hub_port_wait_reset(struct usb_device *hub, int port,
				struct usb_device *dev, unsigned int delay)
{
	int delay_time, ret;
	u16 portstatus;
	u16 portchange;

	for (delay_time = 0;
			delay_time < HUB_RESET_TIMEOUT;
			delay_time += delay) {
		/* wait to give the device a chance to reset */
		wait_ms(delay);

		/* read and decode port status */
		ret = usb_hub_port_status(hub, port, &portstatus, &portchange);
		if (ret < 0) {
			return -1;
		}

		/* Device went away? */
		if (!(portstatus & USB_PORT_STAT_CONNECTION))
			return 1;

		/* bomb out completely if something weird happened */
		if ((portchange & USB_PORT_STAT_C_CONNECTION))
			return -1;

		/* if we`ve finished resetting, then break out of the loop */
		if (!(portstatus & USB_PORT_STAT_RESET) &&
		    (portstatus & USB_PORT_STAT_ENABLE)) {
			if (portstatus & USB_PORT_STAT_HIGH_SPEED)
				dev->speed = USB_SPEED_HIGH;
			else if (portstatus & USB_PORT_STAT_LOW_SPEED)
				dev->speed = USB_SPEED_LOW;
			else
				dev->speed = USB_SPEED_FULL;
			return 0;
		}

		/* switch to the long delay after two short delay failures */
		if (delay_time >= 2 * HUB_SHORT_RESET_TIME)
			delay = HUB_LONG_RESET_TIME;

		dbg("port %d of hub %s not reset yet, waiting %dms", port + 1,
			hub->devpath, delay);
	}

	return -1;
}

/* return: -1 on error, 0 on success, 1 on disconnect.  */
static int usb_hub_port_reset(struct usb_device *hub, int port,
				struct usb_device *dev, unsigned int delay)
{
	int i, status;

	/* Reset the port */
	for (i = 0; i < HUB_RESET_TRIES; i++) {
		usb_set_port_feature(hub, port + 1, USB_PORT_FEAT_RESET);

		/* return on disconnect or reset */
		status = usb_hub_port_wait_reset(hub, port, dev, delay);
		if (status != -1) {
			usb_clear_port_feature(hub,
				port + 1, USB_PORT_FEAT_C_RESET);
			return status;
		}

		dbg("port %d of hub %s not enabled, trying reset again...",
			port + 1, hub->devpath);
		delay = HUB_LONG_RESET_TIME;
	}

	err("Cannot enable port %i of hub %s, disabling port.",
		port + 1, hub->devpath);
	err("Maybe the USB cable is bad?");

	return -1;
}

void usb_hub_port_disable(struct usb_device *hub, int port)
{
	int ret;

	ret = usb_clear_port_feature(hub, port + 1, USB_PORT_FEAT_ENABLE);
	if (ret)
		err("cannot disable port %d of hub %s (err = %d)",
			port + 1, hub->devpath, ret);
}

/* USB 2.0 spec, 7.1.7.3 / fig 7-29:
 *
 * Between connect detection and reset signaling there must be a delay
 * of 100ms at least for debounce and power-settling. The corresponding
 * timer shall restart whenever the downstream port detects a disconnect.
 * 
 * Apparently there are some bluetooth and irda-dongles and a number
 * of low-speed devices which require longer delays of about 200-400ms.
 * Not covered by the spec - but easy to deal with.
 *
 * This implementation uses 400ms minimum debounce timeout and checks
 * every 100ms for transient disconnects to restart the delay.
 */

#define HUB_DEBOUNCE_TIMEOUT	400
#define HUB_DEBOUNCE_STEP	100

/* return: -1 on error, 0 on success, 1 on disconnect.  */
static int usb_hub_port_debounce(struct usb_device *hub, int port)
{
	int ret;
	unsigned delay_time;
	u16 portchange, portstatus;

	for (delay_time = 0; delay_time < HUB_DEBOUNCE_TIMEOUT; /* empty */ ) {

		/* wait debounce step increment */
		wait_ms(HUB_DEBOUNCE_STEP);

		ret = usb_hub_port_status(hub, port, &portstatus, &portchange);
		if (ret < 0)
			return -1;

		if ((portchange & USB_PORT_STAT_C_CONNECTION)) {
			usb_clear_port_feature(hub, port+1, USB_PORT_FEAT_C_CONNECTION);
			delay_time = 0;
		}
		else
			delay_time += HUB_DEBOUNCE_STEP;
	}
	return ((portstatus&USB_PORT_STAT_CONNECTION)) ? 0 : 1;
}

static void usb_hub_port_connect_change(struct usb_hub *hubstate, int port,
					u16 portstatus, u16 portchange)
{
	struct usb_device *hub = hubstate->dev;
	struct usb_device *dev;
	unsigned int delay = HUB_SHORT_RESET_TIME;
	int i;

	dbg("hub %s port %d, portstatus %x, change %x, %s",
		hub->devpath, port + 1,
		portstatus, portchange, portspeed (portstatus));

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

	/* Disconnect any existing devices under this port */
	if (hub->children[port])
		usb_disconnect(&hub->children[port]);

	/* Return now if nothing is connected */
	if (!(portstatus & USB_PORT_STAT_CONNECTION)) {
		if (portstatus & USB_PORT_STAT_ENABLE)
			usb_hub_port_disable(hub, port);

		return;
	}

	if (usb_hub_port_debounce(hub, port)) {
		err("connect-debounce failed, port %d disabled", port+1);
		usb_hub_port_disable(hub, port);
		return;
	}

	/* Some low speed devices have problems with the quick delay, so */
	/*  be a bit pessimistic with those devices. RHbug #23670 */
	if (portstatus & USB_PORT_STAT_LOW_SPEED)
		delay = HUB_LONG_RESET_TIME;

	down(&usb_address0_sem);

	for (i = 0; i < HUB_PROBE_TRIES; i++) {
		struct usb_device *pdev;
		int	len;

		/* Allocate a new device struct */
		dev = usb_alloc_dev(hub, hub->bus);
		if (!dev) {
			err("couldn't allocate usb_device");
			break;
		}

		hub->children[port] = dev;

		/* Reset the device, and detect its speed */
		if (usb_hub_port_reset(hub, port, dev, delay)) {
			usb_free_dev(dev);
			break;
		}

		/* Find a new address for it */
		usb_connect(dev);

		/* Set up TT records, if needed  */
		if (hub->tt) {
			dev->tt = hub->tt;
			dev->ttport = hub->ttport;
		} else if (dev->speed != USB_SPEED_HIGH
				&& hub->speed == USB_SPEED_HIGH) {
			dev->tt = &hubstate->tt;
			dev->ttport = port + 1;
		}

		/* Save readable and stable topology id, distinguishing
		 * devices by location for diagnostics, tools, etc.  The
		 * string is a path along hub ports, from the root.  Each
		 * device's id will be stable until USB is re-cabled, and
		 * hubs are often labled with these port numbers.
		 *
		 * Initial size: "/NN" times five hubs + NUL = 16 bytes max
		 * (quite rare, since most hubs have 4-6 ports).
		 */
		pdev = dev->parent;
		if (pdev->devpath [1] != '\0')	/* parent not root */
			len = snprintf (dev->devpath, sizeof dev->devpath,
				"%s/%d", pdev->devpath, port + 1);
		else	/* root == "/", root port 2 == "/2" */
			len = snprintf (dev->devpath, sizeof dev->devpath,
				"/%d", port + 1);
		if (len == sizeof dev->devpath)
			warn ("devpath size! usb/%03d/%03d path %s",
				dev->bus->busnum, dev->devnum, dev->devpath);
		info("new USB device on bus %d path %s, assigned address %d",
			dev->bus->busnum, dev->devpath, dev->devnum);

		/* put the device in the global device tree */
		dev->dev.parent = &dev->parent->dev;
		sprintf (&dev->dev.name[0], "USB device %04x:%04x",
			 dev->descriptor.idVendor,
			 dev->descriptor.idProduct);
		/* find the number of the port this device is connected to */
		sprintf (&dev->dev.bus_id[0], "unknown_port_%03d", dev->devnum);
		for (i = 0; i < USB_MAXCHILDREN; ++i) {
			if (dev->parent->children[i] == dev) {
				sprintf (&dev->dev.bus_id[0], "%02d", i);
				break;
			}
		}

		/* Run it through the hoops (find a driver, etc) */
		if (!usb_new_device(dev))
			goto done;

		/* Free the configuration if there was an error */
		usb_free_dev(dev);

		/* Switch to a long reset time */
		delay = HUB_LONG_RESET_TIME;
	}

	hub->children[port] = NULL;
	usb_hub_port_disable(hub, port);
done:
	up(&usb_address0_sem);
}

static void usb_hub_events(void)
{
	unsigned long flags;
	struct list_head *tmp;
	struct usb_device *dev;
	struct usb_hub *hub;
	struct usb_hub_status hubsts;
	u16 hubstatus;
	u16 hubchange;
	u16 portstatus;
	u16 portchange;
	int i, ret;

	/*
	 *  We restart the list everytime to avoid a deadlock with
	 * deleting hubs downstream from this one. This should be
	 * safe since we delete the hub from the event list.
	 * Not the most efficient, but avoids deadlocks.
	 */
	while (1) {
		spin_lock_irqsave(&hub_event_lock, flags);

		if (list_empty(&hub_event_list))
			break;

		/* Grab the next entry from the beginning of the list */
		tmp = hub_event_list.next;

		hub = list_entry(tmp, struct usb_hub, event_list);
		dev = hub->dev;

		list_del(tmp);
		INIT_LIST_HEAD(tmp);

		down(&hub->khubd_sem); /* never blocks, we were on list */
		spin_unlock_irqrestore(&hub_event_lock, flags);

		if (hub->error) {
			dbg("resetting hub %s for error %d",
				dev->devpath, hub->error);

			if (usb_hub_reset(hub)) {
				err("error resetting hub %s - disconnecting",
					dev->devpath);
				up(&hub->khubd_sem);
				usb_hub_disconnect(dev);
				continue;
			}

			hub->nerrors = 0;
			hub->error = 0;
		}

		for (i = 0; i < hub->descriptor->bNbrPorts; i++) {
			ret = usb_hub_port_status(dev, i, &portstatus, &portchange);
			if (ret < 0) {
				continue;
			}

			if (portchange & USB_PORT_STAT_C_CONNECTION) {
				dbg("hub %s port %d connection change",
					dev->devpath, i + 1);
				usb_hub_port_connect_change(hub, i, portstatus, portchange);
			} else if (portchange & USB_PORT_STAT_C_ENABLE) {
				dbg("hub %s port %d enable change, status %x",
					dev->devpath, i + 1, portstatus);
				usb_clear_port_feature(dev,
					i + 1, USB_PORT_FEAT_C_ENABLE);

				/*
				 * EM interference sometimes causes badly
				 * 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)
				    && (dev->children[i])) {
					err("already running hub %s port %i "
					    "disabled by hub (EMI?), "
					    "re-enabling...",
						dev->devpath, i + 1);
					usb_hub_port_connect_change(hub,
						i, portstatus, portchange);
				}
			}

			if (portchange & USB_PORT_STAT_C_SUSPEND) {
				dbg("hub %s port %d suspend change",
					dev->devpath, i + 1);
				usb_clear_port_feature(dev,
					i + 1,  USB_PORT_FEAT_C_SUSPEND);
			}
			
			if (portchange & USB_PORT_STAT_C_OVERCURRENT) {
				err("hub %s port %d over-current change",
					dev->devpath, i + 1);
				usb_clear_port_feature(dev,
					i + 1, USB_PORT_FEAT_C_OVER_CURRENT);
				usb_hub_power_on(hub);
			}

			if (portchange & USB_PORT_STAT_C_RESET) {
				dbg("hub %s port %d reset change",
					dev->devpath, i + 1);
				usb_clear_port_feature(dev,
					i + 1, USB_PORT_FEAT_C_RESET);
			}
		} /* end for i */

		/* deal with hub status changes */
		if (usb_get_hub_status(dev, &hubsts) < 0)
			err("get_hub_status %s failed", dev->devpath);
		else {
			hubstatus = le16_to_cpup(&hubsts.wHubStatus);
			hubchange = le16_to_cpup(&hubsts.wHubChange);
			if (hubchange & HUB_CHANGE_LOCAL_POWER) {
				dbg("hub %s power change", dev->devpath);
				usb_clear_hub_feature(dev, C_HUB_LOCAL_POWER);
			}
			if (hubchange & HUB_CHANGE_OVERCURRENT) {
				dbg("hub %s overcurrent change", dev->devpath);
				wait_ms(500);	/* Cool down */
				usb_clear_hub_feature(dev, C_HUB_OVER_CURRENT);
                        	usb_hub_power_on(hub);
			}
		}
		up(&hub->khubd_sem);
        } /* end while (1) */

	spin_unlock_irqrestore(&hub_event_lock, flags);
}

static int usb_hub_thread(void *__hub)
{
	lock_kernel();

	/*
	 * This thread doesn't need any user-level access,
	 * so get rid of all our resources
	 */

	daemonize();

	/* Setup a nice name */
	strcpy(current->comm, "khubd");

	/* Send me a signal to get me die (for debugging) */
	do {
		usb_hub_events();
		interruptible_sleep_on(&khubd_wait);
	} while (!signal_pending(current));

	dbg("usb_hub_thread exiting");

	unlock_kernel();
	complete_and_exit(&khubd_exited, 0);
}

static struct usb_device_id hub_id_table [] = {
    { match_flags: USB_DEVICE_ID_MATCH_DEV_CLASS,
      bDeviceClass: USB_CLASS_HUB},
    { match_flags: USB_DEVICE_ID_MATCH_INT_CLASS,
      bInterfaceClass: USB_CLASS_HUB},
    { }						/* Terminating entry */
};

MODULE_DEVICE_TABLE (usb, hub_id_table);

static struct usb_driver hub_driver = {
	name:		"hub",
	probe:		hub_probe,
	ioctl:		hub_ioctl,
	disconnect:	hub_disconnect,
	id_table:	hub_id_table,
};

/*
 * This should be a separate module.
 */
int usb_hub_init(void)
{
	int pid;

	if (usb_register(&hub_driver) < 0) {
		err("Unable to register USB hub driver");
		return -1;
	}

	pid = kernel_thread(usb_hub_thread, NULL,
		CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
	if (pid >= 0) {
		khubd_pid = pid;

		return 0;
	}

	/* Fall through if kernel_thread failed */
	usb_deregister(&hub_driver);
	err("failed to start usb_hub_thread");

	return -1;
}

void usb_hub_cleanup(void)
{
	int ret;

	/* Kill the thread */
	ret = kill_proc(khubd_pid, SIGTERM, 1);

	wait_for_completion(&khubd_exited);

	/*
	 * Hub resources are freed for us by usb_deregister. It calls
	 * usb_driver_purge on every device which in turn calls that
	 * devices disconnect function if it is using this driver.
	 * The hub_disconnect function takes care of releasing the
	 * individual hub resources. -greg
	 */
	usb_deregister(&hub_driver);
} /* usb_hub_cleanup() */

/*
 * WARNING - If a driver calls usb_reset_device, you should simulate a
 * disconnect() and probe() for other interfaces you doesn't claim. This
 * is left up to the driver writer right now. This insures other drivers
 * have a chance to re-setup their interface.
 *
 * Take a look at proc_resetdevice in devio.c for some sample code to
 * do this.
 */
int usb_reset_device(struct usb_device *dev)
{
	struct usb_device *parent = dev->parent;
	struct usb_device_descriptor descriptor;
	int i, ret, port = -1;

	if (!parent) {
		err("attempting to reset root hub!");
		return -EINVAL;
	}

	for (i = 0; i < parent->maxchild; i++)
		if (parent->children[i] == dev) {
			port = i;
			break;
		}

	if (port < 0)
		return -ENOENT;

	down(&usb_address0_sem);

	/* Send a reset to the device */
	if (usb_hub_port_reset(parent, port, dev, HUB_SHORT_RESET_TIME)) {
		usb_hub_port_disable(parent, port);
		up(&usb_address0_sem);
		return(-ENODEV);
	}

	/* Reprogram the Address */
	ret = usb_set_address(dev);
	if (ret < 0) {
		err("USB device not accepting new address (error=%d)", ret);
		usb_hub_port_disable(parent, port);
		up(&usb_address0_sem);
		return ret;
	}

	/* Let the SET_ADDRESS settle */
	wait_ms(10);

	up(&usb_address0_sem);

	/*
	 * Now we fetch the configuration descriptors for the device and
	 * see if anything has changed. If it has, we dump the current
	 * parsed descriptors and reparse from scratch. Then we leave
	 * the device alone for the caller to finish setting up.
	 *
	 * If nothing changed, we reprogram the configuration and then
	 * the alternate settings.
	 */
	ret = usb_get_descriptor(dev, USB_DT_DEVICE, 0, &descriptor,
			sizeof(descriptor));
	if (ret < 0)
		return ret;

	le16_to_cpus(&descriptor.bcdUSB);
	le16_to_cpus(&descriptor.idVendor);
	le16_to_cpus(&descriptor.idProduct);
	le16_to_cpus(&descriptor.bcdDevice);

	if (memcmp(&dev->descriptor, &descriptor, sizeof(descriptor))) {
		usb_destroy_configuration(dev);

		ret = usb_get_device_descriptor(dev);
		if (ret < sizeof(dev->descriptor)) {
			if (ret < 0)
				err("unable to get device %s descriptor "
					"(error=%d)", dev->devpath, ret);
			else
				err("USB device %s descriptor short read "
					"(expected %Zi, got %i)",
					dev->devpath,
					sizeof(dev->descriptor), ret);
        
			clear_bit(dev->devnum, &dev->bus->devmap.devicemap);
			dev->devnum = -1;
			return -EIO;
		}

		ret = usb_get_configuration(dev);
		if (ret < 0) {
			err("unable to get configuration (error=%d)", ret);
			usb_destroy_configuration(dev);
			clear_bit(dev->devnum, &dev->bus->devmap.devicemap);
			dev->devnum = -1;
			return 1;
		}

		dev->actconfig = dev->config;
		usb_set_maxpacket(dev);

		return 1;
	}

	ret = usb_set_configuration(dev, dev->actconfig->bConfigurationValue);
	if (ret < 0) {
		err("failed to set dev %s active configuration (error=%d)",
			dev->devpath, ret);
		return ret;
	}

	for (i = 0; i < dev->actconfig->bNumInterfaces; i++) {
		struct usb_interface *intf = &dev->actconfig->interface[i];
		struct usb_interface_descriptor *as;

		as = &intf->altsetting[intf->act_altsetting];
		ret = usb_set_interface(dev, as->bInterfaceNumber,
			as->bAlternateSetting);
		if (ret < 0) {
			err("failed to set active alternate setting "
				"for dev %s interface %d (error=%d)",
				dev->devpath, i, ret);
			return ret;
		}
	}

	return 0;
}

