/*
 * (C) Copyright 2004
 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 *
 * This code is based on linux driver for sl811hs chip, source at
 * drivers/usb/host/sl811.c:
 *
 * SL811 Host Controller Interface driver for USB.
 *
 * Copyright (c) 2003/06, Courage Co., Ltd.
 *
 * Based on:
 *	1.uhci.c by Linus Torvalds, Johannes Erdfelt, Randy Dunlap,
 *	  Georg Acher, Deti Fliegl, Thomas Sailer, Roman Weissgaerber,
 *	  Adam Richter, Gregory P. Smith;
 *	2.Original SL811 driver (hc_sl811.o) by Pei Liu <pbl@cypress.com>
 *	3.Rewrited as sl811.o by Yin Aihua <yinah:couragetech.com.cn>
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

#include <common.h>
#ifdef CONFIG_USB_SL811HS
#include <mpc8xx.h>
#include <usb.h>
#include "sl811.h"

#include "../../board/kup/common/kup.h"

#ifdef __PPC__
# define EIEIO		__asm__ volatile ("eieio")
#else
# define EIEIO		/* nothing */
#endif

#define	 SL811_ADR (0x50000000)
#define	 SL811_DAT (0x50000001)

#define mdelay(n) ({unsigned long msec=(n); while (msec--) udelay(1000);})

#ifdef SL811_DEBUG
static int debug = 9;
#endif

static int root_hub_devnum = 0;
static struct usb_port_status rh_status = { 0 };/* root hub port status */

static int sl811_rh_submit_urb(struct usb_device *usb_dev, unsigned long pipe,
			       void *data, int buf_len, struct devrequest *cmd);

static void sl811_write (__u8 index, __u8 data)
{
	*(volatile unsigned char *) (SL811_ADR) = index;
	EIEIO;
	*(volatile unsigned char *) (SL811_DAT) = data;
	EIEIO;
}

static __u8 sl811_read (__u8 index)
{
	__u8 data;

	*(volatile unsigned char *) (SL811_ADR) = index;
	EIEIO;
	data = *(volatile unsigned char *) (SL811_DAT);
	EIEIO;
	return (data);
}

/*
 * Read consecutive bytes of data from the SL811H/SL11H buffer
 */
static void inline sl811_read_buf(__u8 offset, __u8 *buf, __u8 size)
{
	*(volatile unsigned char *) (SL811_ADR) = offset;
	EIEIO;
	while (size--) {
		*buf++ = *(volatile unsigned char *) (SL811_DAT);
		EIEIO;
	}
}

/*
 * Write consecutive bytes of data to the SL811H/SL11H buffer
 */
static void inline sl811_write_buf(__u8 offset, __u8 *buf, __u8 size)
{
	*(volatile unsigned char *) (SL811_ADR) = offset;
	EIEIO;
	while (size--) {
		*(volatile unsigned char *) (SL811_DAT) = *buf++;
		EIEIO;
	}
}

int usb_init_kup4x (void)
{
	volatile immap_t *immap = (immap_t *) CFG_IMMR;
	volatile memctl8xx_t *memctl = &immap->im_memctl;
	int i;
	unsigned char tmp;

	memctl = &immap->im_memctl;
	memctl->memc_or7 = 0xFFFF8726;
	memctl->memc_br7 = 0x50000401;	/* start at 0x50000000 */
	/* BP 14 low = USB ON */
	immap->im_cpm.cp_pbdat &= ~(BP_USB_VCC);
	/* PB 14 nomal port */
	immap->im_cpm.cp_pbpar &= ~(BP_USB_VCC);
	/* output */
	immap->im_cpm.cp_pbdir |= (BP_USB_VCC);

	puts ("USB:   ");

	for (i = 0x10; i < 0xff; i++) {
		sl811_write(i, i);
		tmp = (sl811_read(i));
		if (tmp != i) {
			printf ("SL811 compare error index=0x%02x read=0x%02x\n", i, tmp);
			return (-1);
		}
	}
	printf ("SL811 ready\n");
	return (0);
}

/*
 * This function resets SL811HS controller and detects the speed of
 * the connecting device
 *
 * Return: 0 = no device attached; 1 = USB device attached
 */
static int sl811_hc_reset(void)
{
	int status ;

	sl811_write(SL811_CTRL2, SL811_CTL2_HOST | SL811_12M_HI);
	sl811_write(SL811_CTRL1, SL811_CTRL1_RESET);

	mdelay(20);

	/* Disable hardware SOF generation, clear all irq status. */
	sl811_write(SL811_CTRL1, 0);
	mdelay(2);
	sl811_write(SL811_INTRSTS, 0xff);
	status = sl811_read(SL811_INTRSTS);

	if (status & SL811_INTR_NOTPRESENT) {
		/* Device is not present */
		PDEBUG(0, "Device not present\n");
		rh_status.wPortStatus &= ~(USB_PORT_STAT_CONNECTION | USB_PORT_STAT_ENABLE);
		rh_status.wPortChange |= USB_PORT_STAT_C_CONNECTION;
		sl811_write(SL811_INTR, SL811_INTR_INSRMV);
		return 0;
	}

	/* Send SOF to address 0, endpoint 0. */
	sl811_write(SL811_LEN_B, 0);
	sl811_write(SL811_PIDEP_B, PIDEP(USB_PID_SOF, 0));
	sl811_write(SL811_DEV_B, 0x00);
	sl811_write(SL811_SOFLOW, SL811_12M_LOW);

	if (status & SL811_INTR_SPEED_FULL) {
		/* full speed device connect directly to root hub */
		PDEBUG (0, "Full speed Device attached\n");

		sl811_write(SL811_CTRL1, SL811_CTRL1_RESET);
		mdelay(20);
		sl811_write(SL811_CTRL2, SL811_CTL2_HOST | SL811_12M_HI);
		sl811_write(SL811_CTRL1, SL811_CTRL1_SOF);

		/* start the SOF or EOP */
		sl811_write(SL811_CTRL_B, SL811_USB_CTRL_ARM);
		rh_status.wPortStatus |= USB_PORT_STAT_CONNECTION;
		rh_status.wPortStatus &= ~USB_PORT_STAT_LOW_SPEED;
		mdelay(2);
		sl811_write(SL811_INTRSTS, 0xff);
	} else {
		/* slow speed device connect directly to root-hub */
		PDEBUG(0, "Low speed Device attached\n");

		sl811_write(SL811_CTRL1, SL811_CTRL1_RESET);
		mdelay(20);
		sl811_write(SL811_CTRL2, SL811_CTL2_HOST | SL811_CTL2_DSWAP | SL811_12M_HI);
		sl811_write(SL811_CTRL1, SL811_CTRL1_SPEED_LOW | SL811_CTRL1_SOF);

		/* start the SOF or EOP */
		sl811_write(SL811_CTRL_B, SL811_USB_CTRL_ARM);
		rh_status.wPortStatus |= USB_PORT_STAT_CONNECTION | USB_PORT_STAT_LOW_SPEED;
		mdelay(2);
		sl811_write(SL811_INTRSTS, 0xff);
	}

	rh_status.wPortChange |= USB_PORT_STAT_C_CONNECTION;
	sl811_write(SL811_INTR, /*SL811_INTR_INSRMV*/SL811_INTR_DONE_A);

	return 1;
}

int usb_lowlevel_init(void)
{
	root_hub_devnum = 0;
	sl811_hc_reset();
	return 0;
}

int usb_lowlevel_stop(void)
{
	sl811_hc_reset();
	return 0;
}

static int calc_needed_buswidth(int bytes, int need_preamble)
{
	return !need_preamble ? bytes * 8 + 256 : 8 * 8 * bytes + 2048;
}

static int sl811_send_packet(struct usb_device *dev, unsigned long pipe, __u8 *buffer, int len)
{
	__u8 ctrl = SL811_USB_CTRL_ARM | SL811_USB_CTRL_ENABLE;
	__u16 status = 0;
	int err = 0, time_start = get_timer(0);
	int need_preamble = !(rh_status.wPortStatus & USB_PORT_STAT_LOW_SPEED) &&
		usb_pipeslow(pipe);

	if (len > 239)
		return -1;

	if (usb_pipeout(pipe))
		ctrl |= SL811_USB_CTRL_DIR_OUT;
	if (usb_gettoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe)))
		ctrl |= SL811_USB_CTRL_TOGGLE_1;
	if (need_preamble)
		ctrl |= SL811_USB_CTRL_PREAMBLE;

	sl811_write(SL811_INTRSTS, 0xff);

	while (err < 3) {
		sl811_write(SL811_ADDR_A, 0x10);
		sl811_write(SL811_LEN_A, len);
		if (usb_pipeout(pipe) && len)
			sl811_write_buf(0x10, buffer, len);

		if (!(rh_status.wPortStatus & USB_PORT_STAT_LOW_SPEED) &&
		    sl811_read(SL811_SOFCNTDIV)*64 < calc_needed_buswidth(len, need_preamble))
			ctrl |= SL811_USB_CTRL_SOF;
		else
			ctrl &= ~SL811_USB_CTRL_SOF;

		sl811_write(SL811_CTRL_A, ctrl);
 		while (!(sl811_read(SL811_INTRSTS) & SL811_INTR_DONE_A)) {
			if (5*CFG_HZ < get_timer(time_start)) {
				printf("USB transmit timed out\n");
				return -USB_ST_CRC_ERR;
			}
		}

		sl811_write(SL811_INTRSTS, 0xff);
		status = sl811_read(SL811_STS_A);

		if (status & SL811_USB_STS_ACK) {
			int remainder = sl811_read(SL811_CNT_A);
			if (remainder) {
				PDEBUG(0, "usb transfer remainder = %d\n", remainder);
				len -= remainder;
			}
			if (usb_pipein(pipe) && len)
				sl811_read_buf(0x10, buffer, len);
			return len;
		}

		if ((status & SL811_USB_STS_NAK) == SL811_USB_STS_NAK)
			continue;

		PDEBUG(0, "usb transfer error %#x\n", (int)status);
		err++;
	}

	err = 0;

	if (status & SL811_USB_STS_ERROR)
		err |= USB_ST_BUF_ERR;
	if (status & SL811_USB_STS_TIMEOUT)
		err |= USB_ST_CRC_ERR;
	if (status & SL811_USB_STS_STALL)
		err |= USB_ST_STALLED;

	return -err;
}

int submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
		    int len)
{
	int dir_out = usb_pipeout(pipe);
	int ep = usb_pipeendpoint(pipe);
	int max = usb_maxpacket(dev, pipe);
	int done = 0;

	PDEBUG(7, "dev = %ld pipe = %ld buf = %p size = %d dir_out = %d\n",
	       usb_pipedevice(pipe), usb_pipeendpoint(pipe), buffer, len, dir_out);

	dev->status = 0;

	sl811_write(SL811_DEV_A, usb_pipedevice(pipe));
	sl811_write(SL811_PIDEP_A, PIDEP(!dir_out ? USB_PID_IN : USB_PID_OUT, ep));
	while (done < len) {
		int res = sl811_send_packet(dev, pipe, (__u8*)buffer+done,
					    max > len - done ? len - done : max);
		if (res < 0) {
			dev->status = -res;
			return res;
		}

		if (!dir_out && res < max) /* short packet */
			break;

		done += res;
		usb_dotoggle(dev, ep, dir_out);
	}

	dev->act_len = done;

	return 0;
}

int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
		       int len,struct devrequest *setup)
{
	int done = 0;
	int devnum = usb_pipedevice(pipe);
	int ep = usb_pipeendpoint(pipe);

	dev->status = 0;

	if (devnum == root_hub_devnum)
		return sl811_rh_submit_urb(dev, pipe, buffer, len, setup);

	PDEBUG(7, "dev = %d pipe = %ld buf = %p size = %d rt = %#x req = %#x bus = %i\n",
	       devnum, ep, buffer, len, (int)setup->requesttype,
	       (int)setup->request, sl811_read(SL811_SOFCNTDIV)*64);

	sl811_write(SL811_DEV_A, devnum);
	sl811_write(SL811_PIDEP_A, PIDEP(USB_PID_SETUP, ep));
	/* setup phase */
	usb_settoggle(dev, ep, 1, 0);
	if (sl811_send_packet(dev, usb_sndctrlpipe(dev, ep),
			      (__u8*)setup, sizeof(*setup)) == sizeof(*setup)) {
		int dir_in = usb_pipein(pipe);
		int max = usb_maxpacket(dev, pipe);

		/* data phase */
		sl811_write(SL811_PIDEP_A,
			    PIDEP(dir_in ? USB_PID_IN : USB_PID_OUT, ep));
		usb_settoggle(dev, ep, usb_pipeout(pipe), 1);
		while (done < len) {
			int res = sl811_send_packet(dev, pipe, (__u8*)buffer+done,
						    max > len - done ? len - done : max);
			if (res < 0) {
				PDEBUG(0, "status data failed!\n");
				dev->status = -res;
				return 0;
			}
			done += res;
			usb_dotoggle(dev, ep, usb_pipeout(pipe));
			if (dir_in && res < max) /* short packet */
				break;
		}

		/* status phase */
		sl811_write(SL811_PIDEP_A,
			    PIDEP(!dir_in ? USB_PID_IN : USB_PID_OUT, ep));
		usb_settoggle(dev, ep, !usb_pipeout(pipe), 1);
		if (sl811_send_packet(dev,
				      !dir_in ? usb_rcvctrlpipe(dev, ep) :
				      usb_sndctrlpipe(dev, ep),
				      0, 0) < 0) {
			PDEBUG(0, "status phase failed!\n");
			dev->status = -1;
		}
	} else {
		PDEBUG(0, "setup phase failed!\n");
		dev->status = -1;
	}

	dev->act_len = done;

	return done;
}

int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
		   int len, int interval)
{
	PDEBUG(0, "dev = %p pipe = %#lx buf = %p size = %d int = %d\n", dev, pipe,
	       buffer, len, interval);
	return -1;
}

/*
 * SL811 Virtual Root Hub
 */

/* Device descriptor */
static __u8 sl811_rh_dev_des[] =
{
	0x12,	    /*	__u8  bLength; */
	0x01,	    /*	__u8  bDescriptorType; Device */
	0x10,	    /*	__u16 bcdUSB; v1.1 */
	0x01,
	0x09,	    /*	__u8  bDeviceClass; HUB_CLASSCODE */
	0x00,	    /*	__u8  bDeviceSubClass; */
	0x00,	    /*	__u8  bDeviceProtocol; */
	0x08,	    /*	__u8  bMaxPacketSize0; 8 Bytes */
	0x00,	    /*	__u16 idVendor; */
	0x00,
	0x00,	    /*	__u16 idProduct; */
	0x00,
	0x00,	    /*	__u16 bcdDevice; */
	0x00,
	0x00,	    /*	__u8  iManufacturer; */
	0x02,	    /*	__u8  iProduct; */
	0x01,	    /*	__u8  iSerialNumber; */
	0x01	    /*	__u8  bNumConfigurations; */
};

/* Configuration descriptor */
static __u8 sl811_rh_config_des[] =
{
	0x09,	    /*	__u8  bLength; */
	0x02,	    /*	__u8  bDescriptorType; Configuration */
	0x19,	    /*	__u16 wTotalLength; */
	0x00,
	0x01,	    /*	__u8  bNumInterfaces; */
	0x01,	    /*	__u8  bConfigurationValue; */
	0x00,	    /*	__u8  iConfiguration; */
	0x40,	    /*	__u8  bmAttributes;
		    Bit 7: Bus-powered, 6: Self-powered, 5 Remote-wakwup,
		    4..0: resvd */
	0x00,	    /*	__u8  MaxPower; */

	/* interface */
	0x09,	    /*	__u8  if_bLength; */
	0x04,	    /*	__u8  if_bDescriptorType; Interface */
	0x00,	    /*	__u8  if_bInterfaceNumber; */
	0x00,	    /*	__u8  if_bAlternateSetting; */
	0x01,	    /*	__u8  if_bNumEndpoints; */
	0x09,	    /*	__u8  if_bInterfaceClass; HUB_CLASSCODE */
	0x00,	    /*	__u8  if_bInterfaceSubClass; */
	0x00,	    /*	__u8  if_bInterfaceProtocol; */
	0x00,	    /*	__u8  if_iInterface; */

	/* endpoint */
	0x07,	    /*	__u8  ep_bLength; */
	0x05,	    /*	__u8  ep_bDescriptorType; Endpoint */
	0x81,	    /*	__u8  ep_bEndpointAddress; IN Endpoint 1 */
	0x03,	    /*	__u8  ep_bmAttributes; Interrupt */
	0x08,	    /*	__u16 ep_wMaxPacketSize; */
	0x00,
	0xff	    /*	__u8  ep_bInterval; 255 ms */
};

/* root hub class descriptor*/
static __u8 sl811_rh_hub_des[] =
{
	0x09,			/*  __u8  bLength; */
	0x29,			/*  __u8  bDescriptorType; Hub-descriptor */
	0x01,			/*  __u8  bNbrPorts; */
	0x00,			/* __u16  wHubCharacteristics; */
	0x00,
	0x50,			/*  __u8  bPwrOn2pwrGood; 2ms */
	0x00,			/*  __u8  bHubContrCurrent; 0 mA */
	0xfc,			/*  __u8  DeviceRemovable; *** 7 Ports max *** */
	0xff			/*  __u8  PortPwrCtrlMask; *** 7 ports max *** */
};

/*
 * helper routine for returning string descriptors in UTF-16LE
 * input can actually be ISO-8859-1; ASCII is its 7-bit subset
 */
static int ascii2utf (char *s, u8 *utf, int utfmax)
{
	int retval;

	for (retval = 0; *s && utfmax > 1; utfmax -= 2, retval += 2) {
		*utf++ = *s++;
		*utf++ = 0;
	}
	return retval;
}

/*
 * root_hub_string is used by each host controller's root hub code,
 * so that they're identified consistently throughout the system.
 */
static int usb_root_hub_string (int id, int serial, char *type, __u8 *data, int len)
{
	char buf [30];

	/* assert (len > (2 * (sizeof (buf) + 1)));
	   assert (strlen (type) <= 8);*/

	/* language ids */
	if (id == 0) {
		*data++ = 4; *data++ = 3;	/* 4 bytes data */
		*data++ = 0; *data++ = 0;	/* some language id */
		return 4;

	/* serial number */
	} else if (id == 1) {
		sprintf (buf, "%#x", serial);

	/* product description */
	} else if (id == 2) {
		sprintf (buf, "USB %s Root Hub", type);

	/* id 3 == vendor description */

	/* unsupported IDs --> "stall" */
	} else
	    return 0;

	ascii2utf (buf, data + 2, len - 2);
	data [0] = 2 + strlen(buf) * 2;
	data [1] = 3;
	return data [0];
}

/* helper macro */
#define OK(x)	len = (x); break

/*
 * This function handles all USB request to the the virtual root hub
 */
static int sl811_rh_submit_urb(struct usb_device *usb_dev, unsigned long pipe,
			       void *data, int buf_len, struct devrequest *cmd)
{
	__u8 data_buf[16];
	__u8 *bufp = data_buf;
	int len = 0;
	int status = 0;

	__u16 bmRType_bReq;
	__u16 wValue;
	__u16 wIndex;
	__u16 wLength;

	if (usb_pipeint(pipe)) {
		PDEBUG(0, "interrupt transfer unimplemented!\n");
		return 0;
	}

	bmRType_bReq  = cmd->requesttype | (cmd->request << 8);
	wValue	      = le16_to_cpu (cmd->value);
	wIndex	      = le16_to_cpu (cmd->index);
	wLength	      = le16_to_cpu (cmd->length);

	PDEBUG(5, "submit rh urb, req = %d(%x) val = %#x index = %#x len=%d\n",
	       bmRType_bReq, bmRType_bReq, wValue, wIndex, wLength);

	/* Request Destination:
		   without flags: Device,
		   USB_RECIP_INTERFACE: interface,
		   USB_RECIP_ENDPOINT: endpoint,
		   USB_TYPE_CLASS means HUB here,
		   USB_RECIP_OTHER | USB_TYPE_CLASS  almost ever means HUB_PORT here
	*/
	switch (bmRType_bReq) {
	case RH_GET_STATUS:
		*(__u16 *)bufp = cpu_to_le16(1);
		OK(2);

	case RH_GET_STATUS | USB_RECIP_INTERFACE:
		*(__u16 *)bufp = cpu_to_le16(0);
		OK(2);

	case RH_GET_STATUS | USB_RECIP_ENDPOINT:
		*(__u16 *)bufp = cpu_to_le16(0);
		OK(2);

	case RH_GET_STATUS | USB_TYPE_CLASS:
		*(__u32 *)bufp = cpu_to_le32(0);
		OK(4);

	case RH_GET_STATUS | USB_RECIP_OTHER | USB_TYPE_CLASS:
		*(__u32 *)bufp = cpu_to_le32(rh_status.wPortChange<<16 | rh_status.wPortStatus);
		OK(4);

	case RH_CLEAR_FEATURE | USB_RECIP_ENDPOINT:
		switch (wValue) {
		case 1:
			OK(0);
		}
		break;

	case RH_CLEAR_FEATURE | USB_TYPE_CLASS:
		switch (wValue) {
		case C_HUB_LOCAL_POWER:
			OK(0);

		case C_HUB_OVER_CURRENT:
			OK(0);
		}
		break;

	case RH_CLEAR_FEATURE | USB_RECIP_OTHER | USB_TYPE_CLASS:
		switch (wValue) {
		case USB_PORT_FEAT_ENABLE:
			rh_status.wPortStatus &= ~USB_PORT_STAT_ENABLE;
			OK(0);

		case USB_PORT_FEAT_SUSPEND:
			rh_status.wPortStatus &= ~USB_PORT_STAT_SUSPEND;
			OK(0);

		case USB_PORT_FEAT_POWER:
			rh_status.wPortStatus &= ~USB_PORT_STAT_POWER;
			OK(0);

		case USB_PORT_FEAT_C_CONNECTION:
			rh_status.wPortChange &= ~USB_PORT_STAT_C_CONNECTION;
			OK(0);

		case USB_PORT_FEAT_C_ENABLE:
			rh_status.wPortChange &= ~USB_PORT_STAT_C_ENABLE;
			OK(0);

		case USB_PORT_FEAT_C_SUSPEND:
			rh_status.wPortChange &= ~USB_PORT_STAT_C_SUSPEND;
			OK(0);

		case USB_PORT_FEAT_C_OVER_CURRENT:
			rh_status.wPortChange &= ~USB_PORT_STAT_C_OVERCURRENT;
			OK(0);

		case USB_PORT_FEAT_C_RESET:
			rh_status.wPortChange &= ~USB_PORT_STAT_C_RESET;
			OK(0);
		}
		break;

	case RH_SET_FEATURE | USB_RECIP_OTHER | USB_TYPE_CLASS:
		switch (wValue) {
		case USB_PORT_FEAT_SUSPEND:
			rh_status.wPortStatus |= USB_PORT_STAT_SUSPEND;
			OK(0);

		case USB_PORT_FEAT_RESET:
			rh_status.wPortStatus |= USB_PORT_STAT_RESET;
			rh_status.wPortChange = 0;
			rh_status.wPortChange |= USB_PORT_STAT_C_RESET;
			rh_status.wPortStatus &= ~USB_PORT_STAT_RESET;
			rh_status.wPortStatus |= USB_PORT_STAT_ENABLE;
			OK(0);

		case USB_PORT_FEAT_POWER:
			rh_status.wPortStatus |= USB_PORT_STAT_POWER;
			OK(0);

		case USB_PORT_FEAT_ENABLE:
			rh_status.wPortStatus |= USB_PORT_STAT_ENABLE;
			OK(0);
		}
		break;

	case RH_SET_ADDRESS:
		root_hub_devnum = wValue;
		OK(0);

	case RH_GET_DESCRIPTOR:
		switch ((wValue & 0xff00) >> 8) {
		case USB_DT_DEVICE:
			len = sizeof(sl811_rh_dev_des);
			bufp = sl811_rh_dev_des;
			OK(len);

		case USB_DT_CONFIG:
			len = sizeof(sl811_rh_config_des);
			bufp = sl811_rh_config_des;
			OK(len);

		case USB_DT_STRING:
			len = usb_root_hub_string(wValue & 0xff, (int)(long)0,	"SL811HS", data, wLength);
			if (len > 0) {
				bufp = data;
				OK(len);
			}

		default:
			status = -32;
		}
		break;

	case RH_GET_DESCRIPTOR | USB_TYPE_CLASS:
		len = sizeof(sl811_rh_hub_des);
		bufp = sl811_rh_hub_des;
		OK(len);

	case RH_GET_CONFIGURATION:
		bufp[0] = 0x01;
		OK(1);

	case RH_SET_CONFIGURATION:
		OK(0);

	default:
		PDEBUG(1, "unsupported root hub command\n");
		status = -32;
	}

	len = min(len, buf_len);
	if (data != bufp)
		memcpy(data, bufp, len);

	PDEBUG(5, "len = %d, status = %d\n", len, status);

	usb_dev->status = status;
	usb_dev->act_len = len;

	return status == 0 ? len : status;
}

#endif	/* CONFIG_USB_SL811HS */
