/*
 * Mentor USB OTG Core host controller driver.
 *
 * Copyright (c) 2008 Texas Instruments
 *
 * 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
 *
 * Author: Thomas Abraham t-abraham@ti.com, Texas Instruments
 */

#include <common.h>
#include "musb_hcd.h"

/* MSC control transfers */
#define USB_MSC_BBB_RESET 	0xFF
#define USB_MSC_BBB_GET_MAX_LUN	0xFE

/* Endpoint configuration information */
static struct musb_epinfo epinfo[3] = {
	{MUSB_BULK_EP, 1, 512}, /* EP1 - Bluk Out - 512 Bytes */
	{MUSB_BULK_EP, 0, 512}, /* EP1 - Bluk In  - 512 Bytes */
	{MUSB_INTR_EP, 0, 64}   /* EP2 - Interrupt IN - 64 Bytes */
};

/*
 * This function writes the data toggle value.
 */
static void write_toggle(struct usb_device *dev, u8 ep, u8 dir_out)
{
	u16 toggle = usb_gettoggle(dev, ep, dir_out);
	u16 csr;

	if (dir_out) {
		if (!toggle)
			writew(MUSB_TXCSR_CLRDATATOG, &musbr->txcsr);
		else {
			csr = readw(&musbr->txcsr);
			csr |= MUSB_TXCSR_H_WR_DATATOGGLE;
			writew(csr, &musbr->txcsr);
			csr |= (toggle << MUSB_TXCSR_H_DATATOGGLE_SHIFT);
			writew(csr, &musbr->txcsr);
		}
	} else {
		if (!toggle)
			writew(MUSB_RXCSR_CLRDATATOG, &musbr->rxcsr);
		else {
			csr = readw(&musbr->rxcsr);
			csr |= MUSB_RXCSR_H_WR_DATATOGGLE;
			writew(csr, &musbr->rxcsr);
			csr |= (toggle << MUSB_S_RXCSR_H_DATATOGGLE);
			writew(csr, &musbr->rxcsr);
		}
	}
}

/*
 * This function checks if RxStall has occured on the endpoint. If a RxStall
 * has occured, the RxStall is cleared and 1 is returned. If RxStall has
 * not occured, 0 is returned.
 */
static u8 check_stall(u8 ep, u8 dir_out)
{
	u16 csr;

	/* For endpoint 0 */
	if (!ep) {
		csr = readw(&musbr->txcsr);
		if (csr & MUSB_CSR0_H_RXSTALL) {
			csr &= ~MUSB_CSR0_H_RXSTALL;
			writew(csr, &musbr->txcsr);
			return 1;
		}
	} else { /* For non-ep0 */
		if (dir_out) { /* is it tx ep */
			csr = readw(&musbr->txcsr);
			if (csr & MUSB_TXCSR_H_RXSTALL) {
				csr &= ~MUSB_TXCSR_H_RXSTALL;
				writew(csr, &musbr->txcsr);
				return 1;
			}
		} else { /* is it rx ep */
			csr = readw(&musbr->rxcsr);
			if (csr & MUSB_RXCSR_H_RXSTALL) {
				csr &= ~MUSB_RXCSR_H_RXSTALL;
				writew(csr, &musbr->rxcsr);
				return 1;
			}
		}
	}
	return 0;
}

/*
 * waits until ep0 is ready. Returns 0 if ep is ready, -1 for timeout
 * error and -2 for stall.
 */
static int wait_until_ep0_ready(struct usb_device *dev, u32 bit_mask)
{
	u16 csr;
	int result = 1;

	while (result > 0) {
		csr = readw(&musbr->txcsr);
		if (csr & MUSB_CSR0_H_ERROR) {
			csr &= ~MUSB_CSR0_H_ERROR;
			writew(csr, &musbr->txcsr);
			dev->status = USB_ST_CRC_ERR;
			result = -1;
			break;
		}

		switch (bit_mask) {
		case MUSB_CSR0_TXPKTRDY:
			if (!(csr & MUSB_CSR0_TXPKTRDY)) {
				if (check_stall(MUSB_CONTROL_EP, 0)) {
					dev->status = USB_ST_STALLED;
					result = -2;
				} else
					result = 0;
			}
			break;

		case MUSB_CSR0_RXPKTRDY:
			if (check_stall(MUSB_CONTROL_EP, 0)) {
				dev->status = USB_ST_STALLED;
				result = -2;
			} else
				if (csr & MUSB_CSR0_RXPKTRDY)
					result = 0;
			break;

		case MUSB_CSR0_H_REQPKT:
			if (!(csr & MUSB_CSR0_H_REQPKT)) {
				if (check_stall(MUSB_CONTROL_EP, 0)) {
					dev->status = USB_ST_STALLED;
					result = -2;
				} else
					result = 0;
			}
			break;
		}
	}
	return result;
}

/*
 * waits until tx ep is ready. Returns 1 when ep is ready and 0 on error.
 */
static u8 wait_until_txep_ready(struct usb_device *dev, u8 ep)
{
	u16 csr;

	do {
		if (check_stall(ep, 1)) {
			dev->status = USB_ST_STALLED;
			return 0;
		}

		csr = readw(&musbr->txcsr);
		if (csr & MUSB_TXCSR_H_ERROR) {
			dev->status = USB_ST_CRC_ERR;
			return 0;
		}
	} while (csr & MUSB_TXCSR_TXPKTRDY);
	return 1;
}

/*
 * waits until rx ep is ready. Returns 1 when ep is ready and 0 on error.
 */
static u8 wait_until_rxep_ready(struct usb_device *dev, u8 ep)
{
	u16 csr;

	do {
		if (check_stall(ep, 0)) {
			dev->status = USB_ST_STALLED;
			return 0;
		}

		csr = readw(&musbr->rxcsr);
		if (csr & MUSB_RXCSR_H_ERROR) {
			dev->status = USB_ST_CRC_ERR;
			return 0;
		}
	} while (!(csr & MUSB_RXCSR_RXPKTRDY));
	return 1;
}

/*
 * This function performs the setup phase of the control transfer
 */
static int ctrlreq_setup_phase(struct usb_device *dev, struct devrequest *setup)
{
	int result;
	u16 csr;

	/* write the control request to ep0 fifo */
	write_fifo(MUSB_CONTROL_EP, sizeof(struct devrequest), (void *)setup);

	/* enable transfer of setup packet */
	csr = readw(&musbr->txcsr);
	csr |= (MUSB_CSR0_TXPKTRDY|MUSB_CSR0_H_SETUPPKT);
	writew(csr, &musbr->txcsr);

	/* wait until the setup packet is transmitted */
	result = wait_until_ep0_ready(dev, MUSB_CSR0_TXPKTRDY);
	dev->act_len = 0;
	return result;
}

/*
 * This function handles the control transfer in data phase
 */
static int ctrlreq_in_data_phase(struct usb_device *dev, u32 len, void *buffer)
{
	u16 csr;
	u32 rxlen = 0;
	u32 nextlen = 0;
	u8  maxpktsize = (1 << dev->maxpacketsize) * 8;
	u8  *rxbuff = (u8 *)buffer;
	u8  rxedlength;
	int result;

	while (rxlen < len) {
		/* Determine the next read length */
		nextlen = ((len-rxlen) > maxpktsize) ? maxpktsize : (len-rxlen);

		/* Set the ReqPkt bit */
		csr = readw(&musbr->txcsr);
		writew(csr | MUSB_CSR0_H_REQPKT, &musbr->txcsr);
		result = wait_until_ep0_ready(dev, MUSB_CSR0_RXPKTRDY);
		if (result < 0)
			return result;

		/* Actual number of bytes received by usb */
		rxedlength = readb(&musbr->rxcount);

		/* Read the data from the RxFIFO */
		read_fifo(MUSB_CONTROL_EP, rxedlength, &rxbuff[rxlen]);

		/* Clear the RxPktRdy Bit */
		csr = readw(&musbr->txcsr);
		csr &= ~MUSB_CSR0_RXPKTRDY;
		writew(csr, &musbr->txcsr);

		/* short packet? */
		if (rxedlength != nextlen) {
			dev->act_len += rxedlength;
			break;
		}
		rxlen += nextlen;
		dev->act_len = rxlen;
	}
	return 0;
}

/*
 * This function handles the control transfer out data phase
 */
static int ctrlreq_out_data_phase(struct usb_device *dev, u32 len, void *buffer)
{
	u16 csr;
	u32 txlen = 0;
	u32 nextlen = 0;
	u8  maxpktsize = (1 << dev->maxpacketsize) * 8;
	u8  *txbuff = (u8 *)buffer;
	int result = 0;

	while (txlen < len) {
		/* Determine the next write length */
		nextlen = ((len-txlen) > maxpktsize) ? maxpktsize : (len-txlen);

		/* Load the data to send in FIFO */
		write_fifo(MUSB_CONTROL_EP, txlen, &txbuff[txlen]);

		/* Set TXPKTRDY bit */
		csr = readw(&musbr->txcsr);
		writew(csr | MUSB_CSR0_H_DIS_PING | MUSB_CSR0_TXPKTRDY,
					&musbr->txcsr);
		result = wait_until_ep0_ready(dev, MUSB_CSR0_TXPKTRDY);
		if (result < 0)
			break;

		txlen += nextlen;
		dev->act_len = txlen;
	}
	return result;
}

/*
 * This function handles the control transfer out status phase
 */
static int ctrlreq_out_status_phase(struct usb_device *dev)
{
	u16 csr;
	int result;

	/* Set the StatusPkt bit */
	csr = readw(&musbr->txcsr);
	csr |= (MUSB_CSR0_H_DIS_PING | MUSB_CSR0_TXPKTRDY |
			MUSB_CSR0_H_STATUSPKT);
	writew(csr, &musbr->txcsr);

	/* Wait until TXPKTRDY bit is cleared */
	result = wait_until_ep0_ready(dev, MUSB_CSR0_TXPKTRDY);
	return result;
}

/*
 * This function handles the control transfer in status phase
 */
static int ctrlreq_in_status_phase(struct usb_device *dev)
{
	u16 csr;
	int result;

	/* Set the StatusPkt bit and ReqPkt bit */
	csr = MUSB_CSR0_H_DIS_PING | MUSB_CSR0_H_REQPKT | MUSB_CSR0_H_STATUSPKT;
	writew(csr, &musbr->txcsr);
	result = wait_until_ep0_ready(dev, MUSB_CSR0_H_REQPKT);

	/* clear StatusPkt bit and RxPktRdy bit */
	csr = readw(&musbr->txcsr);
	csr &= ~(MUSB_CSR0_RXPKTRDY | MUSB_CSR0_H_STATUSPKT);
	writew(csr, &musbr->txcsr);
	return result;
}

/*
 * determines the speed of the device (High/Full/Slow)
 */
static u8 get_dev_speed(struct usb_device *dev)
{
	return (dev->speed & USB_SPEED_HIGH) ? MUSB_TYPE_SPEED_HIGH :
		((dev->speed & USB_SPEED_LOW) ? MUSB_TYPE_SPEED_LOW :
						MUSB_TYPE_SPEED_FULL);
}

/*
 * configure the hub address and the port address.
 */
static void config_hub_port(struct usb_device *dev, u8 ep)
{
	u8 chid;
	u8 hub;

	/* Find out the nearest parent which is high speed */
	while (dev->parent->parent != NULL)
		if (get_dev_speed(dev->parent) !=  MUSB_TYPE_SPEED_HIGH)
			dev = dev->parent;
		else
			break;

	/* determine the port address at that hub */
	hub = dev->parent->devnum;
	for (chid = 0; chid < USB_MAXCHILDREN; chid++)
		if (dev->parent->children[chid] == dev)
			break;

	/* configure the hub address and the port address */
	writeb(hub, &musbr->tar[ep].txhubaddr);
	writeb((chid + 1), &musbr->tar[ep].txhubport);
	writeb(hub, &musbr->tar[ep].rxhubaddr);
	writeb((chid + 1), &musbr->tar[ep].rxhubport);
}

/*
 * do a control transfer
 */
int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
			int len, struct devrequest *setup)
{
	int devnum = usb_pipedevice(pipe);
	u16 csr;
	u8  devspeed;

	/* select control endpoint */
	writeb(MUSB_CONTROL_EP, &musbr->index);
	csr = readw(&musbr->txcsr);

	/* target addr and (for multipoint) hub addr/port */
	writeb(devnum, &musbr->tar[MUSB_CONTROL_EP].txfuncaddr);
	writeb(devnum, &musbr->tar[MUSB_CONTROL_EP].rxfuncaddr);

	/* configure the hub address and the port number as required */
	devspeed = get_dev_speed(dev);
	if ((musb_ishighspeed()) && (dev->parent != NULL) &&
		(devspeed != MUSB_TYPE_SPEED_HIGH)) {
		config_hub_port(dev, MUSB_CONTROL_EP);
		writeb(devspeed << 6, &musbr->txtype);
	} else {
		writeb(musb_cfg.musb_speed << 6, &musbr->txtype);
		writeb(0, &musbr->tar[MUSB_CONTROL_EP].txhubaddr);
		writeb(0, &musbr->tar[MUSB_CONTROL_EP].txhubport);
		writeb(0, &musbr->tar[MUSB_CONTROL_EP].rxhubaddr);
		writeb(0, &musbr->tar[MUSB_CONTROL_EP].rxhubport);
	}

	/* Control transfer setup phase */
	if (ctrlreq_setup_phase(dev, setup) < 0)
		return 0;

	switch (setup->request) {
	case USB_REQ_GET_DESCRIPTOR:
	case USB_REQ_GET_CONFIGURATION:
	case USB_REQ_GET_INTERFACE:
	case USB_REQ_GET_STATUS:
	case USB_MSC_BBB_GET_MAX_LUN:
		/* control transfer in-data-phase */
		if (ctrlreq_in_data_phase(dev, len, buffer) < 0)
			return 0;
		/* control transfer out-status-phase */
		if (ctrlreq_out_status_phase(dev) < 0)
			return 0;
		break;

	case USB_REQ_SET_ADDRESS:
	case USB_REQ_SET_CONFIGURATION:
	case USB_REQ_SET_FEATURE:
	case USB_REQ_SET_INTERFACE:
	case USB_REQ_CLEAR_FEATURE:
	case USB_MSC_BBB_RESET:
		/* control transfer in status phase */
		if (ctrlreq_in_status_phase(dev) < 0)
			return 0;
		break;

	case USB_REQ_SET_DESCRIPTOR:
		/* control transfer out data phase */
		if (ctrlreq_out_data_phase(dev, len, buffer) < 0)
			return 0;
		/* control transfer in status phase */
		if (ctrlreq_in_status_phase(dev) < 0)
			return 0;
		break;

	default:
		/* unhandled control transfer */
		return -1;
	}

	dev->status = 0;
	dev->act_len = len;
	return len;
}

/*
 * do a bulk transfer
 */
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 devnum = usb_pipedevice(pipe);
	u8  type;
	u16 csr;
	u32 txlen = 0;
	u32 nextlen = 0;
	u8  devspeed;

	/* select bulk endpoint */
	writeb(MUSB_BULK_EP, &musbr->index);

	/* write the address of the device */
	if (dir_out)
		writeb(devnum, &musbr->tar[MUSB_BULK_EP].txfuncaddr);
	else
		writeb(devnum, &musbr->tar[MUSB_BULK_EP].rxfuncaddr);

	/* configure the hub address and the port number as required */
	devspeed = get_dev_speed(dev);
	if ((musb_ishighspeed()) && (dev->parent != NULL) &&
		(devspeed != MUSB_TYPE_SPEED_HIGH)) {
		/*
		 * MUSB is in high speed and the destination device is full
		 * speed device. So configure the hub address and port
		 * address registers.
		 */
		config_hub_port(dev, MUSB_BULK_EP);
	} else {
		if (dir_out) {
			writeb(0, &musbr->tar[MUSB_BULK_EP].txhubaddr);
			writeb(0, &musbr->tar[MUSB_BULK_EP].txhubport);
		} else {
			writeb(0, &musbr->tar[MUSB_BULK_EP].rxhubaddr);
			writeb(0, &musbr->tar[MUSB_BULK_EP].rxhubport);
		}
		devspeed = musb_cfg.musb_speed;
	}

	/* Write the saved toggle bit value */
	write_toggle(dev, ep, dir_out);

	if (dir_out) { /* bulk-out transfer */
		/* Program the TxType register */
		type = (devspeed << MUSB_TYPE_SPEED_SHIFT) |
			   (MUSB_TYPE_PROTO_BULK << MUSB_TYPE_PROTO_SHIFT) |
			   (ep & MUSB_TYPE_REMOTE_END);
		writeb(type, &musbr->txtype);

		/* Write maximum packet size to the TxMaxp register */
		writew(dev->epmaxpacketout[ep], &musbr->txmaxp);
		while (txlen < len) {
			nextlen = ((len-txlen) < dev->epmaxpacketout[ep]) ?
					(len-txlen) : dev->epmaxpacketout[ep];

			/* Write the data to the FIFO */
			write_fifo(MUSB_BULK_EP, nextlen,
					(void *)(((u8 *)buffer) + txlen));

			/* Set the TxPktRdy bit */
			csr = readw(&musbr->txcsr);
			writew(csr | MUSB_TXCSR_TXPKTRDY, &musbr->txcsr);

			/* Wait until the TxPktRdy bit is cleared */
			if (!wait_until_txep_ready(dev, MUSB_BULK_EP)) {
				readw(&musbr->txcsr);
				usb_settoggle(dev, ep, dir_out,
				(csr >> MUSB_TXCSR_H_DATATOGGLE_SHIFT) & 1);
				dev->act_len = txlen;
				return 0;
			}
			txlen += nextlen;
		}

		/* Keep a copy of the data toggle bit */
		csr = readw(&musbr->txcsr);
		usb_settoggle(dev, ep, dir_out,
				(csr >> MUSB_TXCSR_H_DATATOGGLE_SHIFT) & 1);
	} else { /* bulk-in transfer */
		/* Write the saved toggle bit value */
		write_toggle(dev, ep, dir_out);

		/* Program the RxType register */
		type = (devspeed << MUSB_TYPE_SPEED_SHIFT) |
			   (MUSB_TYPE_PROTO_BULK << MUSB_TYPE_PROTO_SHIFT) |
			   (ep & MUSB_TYPE_REMOTE_END);
		writeb(type, &musbr->rxtype);

		/* Write the maximum packet size to the RxMaxp register */
		writew(dev->epmaxpacketin[ep], &musbr->rxmaxp);
		while (txlen < len) {
			nextlen = ((len-txlen) < dev->epmaxpacketin[ep]) ?
					(len-txlen) : dev->epmaxpacketin[ep];

			/* Set the ReqPkt bit */
			writew(MUSB_RXCSR_H_REQPKT, &musbr->rxcsr);

			/* Wait until the RxPktRdy bit is set */
			if (!wait_until_rxep_ready(dev, MUSB_BULK_EP)) {
				csr = readw(&musbr->rxcsr);
				usb_settoggle(dev, ep, dir_out,
				(csr >> MUSB_S_RXCSR_H_DATATOGGLE) & 1);
				csr &= ~MUSB_RXCSR_RXPKTRDY;
				writew(csr, &musbr->rxcsr);
				dev->act_len = txlen;
				return 0;
			}

			/* Read the data from the FIFO */
			read_fifo(MUSB_BULK_EP, nextlen,
					(void *)(((u8 *)buffer) + txlen));

			/* Clear the RxPktRdy bit */
			csr =  readw(&musbr->rxcsr);
			csr &= ~MUSB_RXCSR_RXPKTRDY;
			writew(csr, &musbr->rxcsr);
			txlen += nextlen;
		}

		/* Keep a copy of the data toggle bit */
		csr = readw(&musbr->rxcsr);
		usb_settoggle(dev, ep, dir_out,
				(csr >> MUSB_S_RXCSR_H_DATATOGGLE) & 1);
	}

	/* bulk transfer is complete */
	dev->status = 0;
	dev->act_len = len;
	return 0;
}

/*
 * This function initializes the usb controller module.
 */
int usb_lowlevel_init(void)
{
	u8  power;
	u32 timeout;

	if (musb_platform_init() == -1)
		return -1;

	/* Configure all the endpoint FIFO's and start usb controller */
	musbr = musb_cfg.regs;
	musb_configure_ep(&epinfo[0],
			sizeof(epinfo) / sizeof(struct musb_epinfo));
	musb_start();

	/*
	 * Wait until musb is enabled in host mode with a timeout. There
	 * should be a usb device connected.
	 */
	timeout = musb_cfg.timeout;
	while (timeout--)
		if (readb(&musbr->devctl) & MUSB_DEVCTL_HM)
			break;

	/* if musb core is not in host mode, then return */
	if (!timeout)
		return -1;

	/* start usb bus reset */
	power = readb(&musbr->power);
	writeb(power | MUSB_POWER_RESET, &musbr->power);

	/* After initiating a usb reset, wait for about 20ms to 30ms */
	udelay(30000);

	/* stop usb bus reset */
	power = readb(&musbr->power);
	power &= ~MUSB_POWER_RESET;
	writeb(power, &musbr->power);

	/* Determine if the connected device is a high/full/low speed device */
	musb_cfg.musb_speed = (readb(&musbr->power) & MUSB_POWER_HSMODE) ?
			MUSB_TYPE_SPEED_HIGH :
			((readb(&musbr->devctl) & MUSB_DEVCTL_FSDEV) ?
			MUSB_TYPE_SPEED_FULL : MUSB_TYPE_SPEED_LOW);
	return 0;
}

/*
 * This function stops the operation of the davinci usb module.
 */
int usb_lowlevel_stop(void)
{
	/* Reset the USB module */
	musb_platform_deinit();
	writeb(0, &musbr->devctl);
	return 0;
}

/*
 * This function supports usb interrupt transfers. Currently, usb interrupt
 * transfers are not supported.
 */
int submit_int_msg(struct usb_device *dev, unsigned long pipe,
				void *buffer, int len, int interval)
{
	int dir_out = usb_pipeout(pipe);
	int ep = usb_pipeendpoint(pipe);
	int devnum = usb_pipedevice(pipe);
	u8  type;
	u16 csr;
	u32 txlen = 0;
	u32 nextlen = 0;
	u8  devspeed;

	/* select interrupt endpoint */
	writeb(MUSB_INTR_EP, &musbr->index);

	/* write the address of the device */
	if (dir_out)
		writeb(devnum, &musbr->tar[MUSB_INTR_EP].txfuncaddr);
	else
		writeb(devnum, &musbr->tar[MUSB_INTR_EP].rxfuncaddr);

	/* configure the hub address and the port number as required */
	devspeed = get_dev_speed(dev);
	if ((musb_ishighspeed()) && (dev->parent != NULL) &&
		(devspeed != MUSB_TYPE_SPEED_HIGH)) {
		/*
		 * MUSB is in high speed and the destination device is full
		 * speed device. So configure the hub address and port
		 * address registers.
		 */
		config_hub_port(dev, MUSB_INTR_EP);
	} else {
		if (dir_out) {
			writeb(0, &musbr->tar[MUSB_INTR_EP].txhubaddr);
			writeb(0, &musbr->tar[MUSB_INTR_EP].txhubport);
		} else {
			writeb(0, &musbr->tar[MUSB_INTR_EP].rxhubaddr);
			writeb(0, &musbr->tar[MUSB_INTR_EP].rxhubport);
		}
		devspeed = musb_cfg.musb_speed;
	}

	/* Write the saved toggle bit value */
	write_toggle(dev, ep, dir_out);

	if (!dir_out) { /* intrrupt-in transfer */
		/* Write the saved toggle bit value */
		write_toggle(dev, ep, dir_out);
		writeb(interval, &musbr->rxinterval);

		/* Program the RxType register */
		type = (devspeed << MUSB_TYPE_SPEED_SHIFT) |
			   (MUSB_TYPE_PROTO_INTR << MUSB_TYPE_PROTO_SHIFT) |
			   (ep & MUSB_TYPE_REMOTE_END);
		writeb(type, &musbr->rxtype);

		/* Write the maximum packet size to the RxMaxp register */
		writew(dev->epmaxpacketin[ep], &musbr->rxmaxp);

		while (txlen < len) {
			nextlen = ((len-txlen) < dev->epmaxpacketin[ep]) ?
					(len-txlen) : dev->epmaxpacketin[ep];

			/* Set the ReqPkt bit */
			writew(MUSB_RXCSR_H_REQPKT, &musbr->rxcsr);

			/* Wait until the RxPktRdy bit is set */
			if (!wait_until_rxep_ready(dev, MUSB_INTR_EP)) {
				csr = readw(&musbr->rxcsr);
				usb_settoggle(dev, ep, dir_out,
				(csr >> MUSB_S_RXCSR_H_DATATOGGLE) & 1);
				csr &= ~MUSB_RXCSR_RXPKTRDY;
				writew(csr, &musbr->rxcsr);
				dev->act_len = txlen;
				return 0;
			}

			/* Read the data from the FIFO */
			read_fifo(MUSB_INTR_EP, nextlen,
					(void *)(((u8 *)buffer) + txlen));

			/* Clear the RxPktRdy bit */
			csr =  readw(&musbr->rxcsr);
			csr &= ~MUSB_RXCSR_RXPKTRDY;
			writew(csr, &musbr->rxcsr);
			txlen += nextlen;
		}

		/* Keep a copy of the data toggle bit */
		csr = readw(&musbr->rxcsr);
		usb_settoggle(dev, ep, dir_out,
				(csr >> MUSB_S_RXCSR_H_DATATOGGLE) & 1);
	}

	/* interrupt transfer is complete */
	dev->irq_status = 0;
	dev->irq_act_len = len;
	dev->irq_handle(dev);
	dev->status = 0;
	dev->act_len = len;
	return 0;
}


#ifdef CONFIG_SYS_USB_EVENT_POLL
/*
 * This function polls for USB keyboard data.
 */
void usb_event_poll()
{
	device_t *dev;
	struct usb_device *usb_kbd_dev;
	struct usb_interface_descriptor *iface;
	struct usb_endpoint_descriptor *ep;
	int pipe;
	int maxp;

	/* Get the pointer to USB Keyboard device pointer */
	dev = device_get_by_name("usbkbd");
	usb_kbd_dev = (struct usb_device *)dev->priv;
	iface = &usb_kbd_dev->config.if_desc[0];
	ep = &iface->ep_desc[0];
	pipe = usb_rcvintpipe(usb_kbd_dev, ep->bEndpointAddress);

	/* Submit a interrupt transfer request */
	maxp = usb_maxpacket(usb_kbd_dev, pipe);
	usb_submit_int_msg(usb_kbd_dev, pipe, &new[0],
			maxp > 8 ? 8 : maxp, ep->bInterval);
}
#endif /* CONFIG_SYS_USB_EVENT_POLL */
