/*
 * Part of this code has been derived from linux:
 * Universal Host Controller Interface driver for USB (take II).
 *
 * (c) 1999-2001 Georg Acher, acher@in.tum.de (executive slave) (base guitar)
 *               Deti Fliegl, deti@fliegl.de (executive slave) (lead voice)
 *               Thomas Sailer, sailer@ife.ee.ethz.ch (chief consultant) (cheer leader)
 *               Roman Weissgaerber, weissg@vienna.at (virt root hub) (studio porter)
 * (c) 2000      Yggdrasil Computing, Inc. (port of new PCI interface support
 *               from usb-ohci.c by Adam Richter, adam@yggdrasil.com).
 * (C) 2000      David Brownell, david-b@pacbell.net (usb-ohci.c)
 *
 * HW-initalization based on material of
 *
 * (C) Copyright 1999 Linus Torvalds
 * (C) Copyright 1999 Johannes Erdfelt
 * (C) Copyright 1999 Randy Dunlap
 * (C) Copyright 1999 Gregory P. Smith
 *
 *
 * Adapted for U-Boot:
 * (C) Copyright 2001 Denis Peter, MPL AG Switzerland
 *
 * 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
 *
 *
 */

/**********************************************************************
 * How it works:
 * -------------
 * The framelist / Transfer descriptor / Queue Heads are similar like
 * in the linux usb_uhci.c.
 *
 * During initialization, the following skeleton is allocated in init_skel:
 *
 *         framespecific           |           common chain
 *
 * framelist[]
 * [  0 ]-----> TD ---------\
 * [  1 ]-----> TD ----------> TD ------> QH -------> QH -------> QH ---> NULL
 *   ...        TD ---------/
 * [1023]-----> TD --------/
 *
 *              ^^             ^^         ^^          ^^          ^^
 *              7 TDs for      1 TD for   Start of    Start of    End Chain
 *              INT (2-128ms)  1ms-INT    CTRL Chain  BULK Chain
 *
 *
 * Since this is a bootloader, the isochronous transfer descriptor have been removed.
 *
 * Interrupt Transfers.
 * --------------------
 * For Interupt transfers USB_MAX_TEMP_INT_TD Transfer descriptor are available. They
 * will be inserted after the appropriate (depending the interval setting) skeleton TD.
 * If an interrupt has been detected the dev->irqhandler is called. The status and number
 * of transfered bytes is stored in dev->irq_status resp. dev->irq_act_len. If the
 * dev->irqhandler returns 0, the interrupt TD is removed and disabled. If an 1 is returned,
 * the interrupt TD will be reactivated.
 *
 * Control Transfers
 * -----------------
 * Control Transfers are issued by filling the tmp_td with the appropriate data and connect
 * them to the qh_cntrl queue header. Before other control/bulk transfers can be issued,
 * the programm has to wait for completion. This does not allows asynchronous data transfer.
 *
 * Bulk Transfers
 * --------------
 * Bulk Transfers are issued by filling the tmp_td with the appropriate data and connect
 * them to the qh_bulk queue header. Before other control/bulk transfers can be issued,
 * the programm has to wait for completion. This does not allows asynchronous data transfer.
 *
 *
 */

#include <common.h>
#include <pci.h>

#ifdef CONFIG_USB_UHCI

#include <usb.h>
#include "usb_uhci.h"

#define USB_MAX_TEMP_TD      128  /* number of temporary TDs for bulk and control transfers */
#define USB_MAX_TEMP_INT_TD  32   /* number of temporary TDs for Interrupt transfers */


#undef USB_UHCI_DEBUG

#ifdef	USB_UHCI_DEBUG
#define	USB_UHCI_PRINTF(fmt,args...)	printf (fmt ,##args)
#else
#define USB_UHCI_PRINTF(fmt,args...)
#endif


static int irqvec = -1;            /* irq vector, if -1 uhci is stopped / reseted */
unsigned int usb_base_addr;       /* base address */

static uhci_td_t td_int[8];        /* Interrupt Transfer descriptors */
static uhci_qh_t qh_cntrl;         /* control Queue Head */
static uhci_qh_t qh_bulk;          /*  bulk Queue Head */
static uhci_qh_t qh_end;           /* end Queue Head */
static uhci_td_t td_last;          /* last TD (linked with end chain) */

/* temporary tds */
static uhci_td_t tmp_td[USB_MAX_TEMP_TD];          /* temporary bulk/control td's  */
static uhci_td_t tmp_int_td[USB_MAX_TEMP_INT_TD];  /* temporary interrupt td's  */

static unsigned long framelist[1024] __attribute__ ((aligned (0x1000))); /* frame list */

static struct virt_root_hub rh;   /* struct for root hub */

/**********************************************************************
 * some forward decleration
 */
int uhci_submit_rh_msg(struct usb_device *dev, unsigned long pipe,
						void *buffer, int transfer_len,struct devrequest *setup);

/* fill a td with the approproiate data. Link, status, info and buffer
 * are used by the USB controller itselfes, dev is used to identify the
 * "connected" device
 */
void usb_fill_td(uhci_td_t* td,unsigned long link,unsigned long status,
					unsigned long info, unsigned long buffer, unsigned long dev)
{
	td->link=swap_32(link);
	td->status=swap_32(status);
	td->info=swap_32(info);
	td->buffer=swap_32(buffer);
	td->dev_ptr=dev;
}

/* fill a qh with the approproiate data. Head and element are used by the USB controller
 * itselfes. As soon as a valid dev_ptr is filled, a td chain is connected to the qh.
 * Please note, that after completion of the td chain, the entry element is removed /
 * marked invalid by the USB controller.
 */
void usb_fill_qh(uhci_qh_t* qh,unsigned long head,unsigned long element)
{
	qh->head=swap_32(head);
	qh->element=swap_32(element);
	qh->dev_ptr=0L;
}

/* get the status of a td->status
 */
unsigned long usb_uhci_td_stat(unsigned long status)
{
	unsigned long result=0;
	result |= (status & TD_CTRL_NAK)      ? USB_ST_NAK_REC : 0;
	result |= (status & TD_CTRL_STALLED)  ? USB_ST_STALLED : 0;
	result |= (status & TD_CTRL_DBUFERR)  ? USB_ST_BUF_ERR : 0;
	result |= (status & TD_CTRL_BABBLE)   ? USB_ST_BABBLE_DET : 0;
	result |= (status & TD_CTRL_CRCTIMEO) ? USB_ST_CRC_ERR : 0;
	result |= (status & TD_CTRL_BITSTUFF) ? USB_ST_BIT_ERR : 0;
	result |= (status & TD_CTRL_ACTIVE)   ? USB_ST_NOT_PROC : 0;
	return result;
}

/* get the status and the transfered len of a td chain.
 * called from the completion handler
 */
int usb_get_td_status(uhci_td_t *td,struct usb_device *dev)
{
	unsigned long temp,info;
	unsigned long stat;
	uhci_td_t *mytd=td;

	if(dev->devnum==rh.devnum)
		return 0;
	dev->act_len=0;
	stat=0;
	do {
		temp=swap_32((unsigned long)mytd->status);
		stat=usb_uhci_td_stat(temp);
		info=swap_32((unsigned long)mytd->info);
		if(((info & 0xff)!= USB_PID_SETUP) &&
				(((info >> 21) & 0x7ff)!= 0x7ff) &&
				(temp & 0x7FF)!=0x7ff)
		{  /* if not setup and not null data pack */
			dev->act_len+=(temp & 0x7FF) + 1; /* the transfered len is act_len + 1 */
		}
		if(stat) {           /* status no ok */
			dev->status=stat;
			return -1;
		}
		temp=swap_32((unsigned long)mytd->link);
		mytd=(uhci_td_t *)(temp & 0xfffffff0);
	}while((temp & 0x1)==0); /* process all TDs */
	dev->status=stat;
	return 0; /* Ok */
}


/*-------------------------------------------------------------------
 *                         LOW LEVEL STUFF
 *          assembles QHs und TDs for control, bulk and iso
 *-------------------------------------------------------------------*/

/* Submits a control message. That is a Setup, Data and Status transfer.
 * Routine does not wait for completion.
 */
int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
										int transfer_len,struct devrequest *setup)
{
	unsigned long destination, status;
	int maxsze = usb_maxpacket(dev, pipe);
	unsigned long dataptr;
	int len;
	int pktsze;
	int i=0;

	if (!maxsze) {
		USB_UHCI_PRINTF("uhci_submit_control_urb: pipesize for pipe %lx is zero\n", pipe);
		return -1;
	}
	if(((pipe>>8)&0x7f)==rh.devnum) {
		/* this is the root hub -> redirect it */
		return uhci_submit_rh_msg(dev,pipe,buffer,transfer_len,setup);
	}
	USB_UHCI_PRINTF("uhci_submit_control start len %x, maxsize %x\n",transfer_len,maxsze);
	/* The "pipe" thing contains the destination in bits 8--18 */
	destination = (pipe & PIPE_DEVEP_MASK) | USB_PID_SETUP; /* Setup stage */
	/* 3 errors */
	status = (pipe & TD_CTRL_LS) | TD_CTRL_ACTIVE | (3 << 27);
	/* (urb->transfer_flags & USB_DISABLE_SPD ? 0 : TD_CTRL_SPD); */
	/*  Build the TD for the control request, try forever, 8 bytes of data */
	usb_fill_td(&tmp_td[i],UHCI_PTR_TERM ,status, destination | (7 << 21),(unsigned long)setup,(unsigned long)dev);
#if 0
	{
		char *sp=(char *)setup;
		printf("SETUP to pipe %lx: %x %x %x %x %x %x %x %x\n", pipe,
		    sp[0],sp[1],sp[2],sp[3],sp[4],sp[5],sp[6],sp[7]);
	}
#endif
	dataptr = (unsigned long)buffer;
	len=transfer_len;

	/* If direction is "send", change the frame from SETUP (0x2D)
	   to OUT (0xE1). Else change it from SETUP to IN (0x69). */
	destination = (pipe & PIPE_DEVEP_MASK) | ((pipe & USB_DIR_IN)==0 ? USB_PID_OUT : USB_PID_IN);
	while (len > 0) {
		/* data stage */
		pktsze = len;
		i++;
		if (pktsze > maxsze)
			pktsze = maxsze;
		destination ^= 1 << TD_TOKEN_TOGGLE;	/* toggle DATA0/1 */
		usb_fill_td(&tmp_td[i],UHCI_PTR_TERM, status, destination | ((pktsze - 1) << 21),dataptr,(unsigned long)dev);	/* Status, pktsze bytes of data */
		tmp_td[i-1].link=swap_32((unsigned long)&tmp_td[i]);

		dataptr += pktsze;
		len -= pktsze;
	}

	/*  Build the final TD for control status */
	/* It's only IN if the pipe is out AND we aren't expecting data */

	destination &= ~UHCI_PID;
	if (((pipe & USB_DIR_IN)==0) || (transfer_len == 0))
		destination |= USB_PID_IN;
	else
		destination |= USB_PID_OUT;
	destination |= 1 << TD_TOKEN_TOGGLE;	/* End in Data1 */
	i++;
	status &=~TD_CTRL_SPD;
	/* no limit on errors on final packet , 0 bytes of data */
	usb_fill_td(&tmp_td[i],UHCI_PTR_TERM, status | TD_CTRL_IOC, destination | (UHCI_NULL_DATA_SIZE << 21),0,(unsigned long)dev);
	tmp_td[i-1].link=swap_32((unsigned long)&tmp_td[i]);	/* queue status td */
	/*	usb_show_td(i+1);*/
	USB_UHCI_PRINTF("uhci_submit_control end (%d tmp_tds used)\n",i);
	/* first mark the control QH element terminated */
	qh_cntrl.element=0xffffffffL;
	/* set qh active */
	qh_cntrl.dev_ptr=(unsigned long)dev;
	/* fill in tmp_td_chain */
	qh_cntrl.element=swap_32((unsigned long)&tmp_td[0]);
	return 0;
}

/*-------------------------------------------------------------------
 * Prepare TDs for bulk transfers.
 */
int submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer,int transfer_len)
{
	unsigned long destination, status,info;
	unsigned long dataptr;
	int maxsze = usb_maxpacket(dev, pipe);
	int len;
	int i=0;

	if(transfer_len < 0) {
		printf("Negative transfer length in submit_bulk\n");
		return -1;
	}
	if (!maxsze)
		return -1;
	/* The "pipe" thing contains the destination in bits 8--18. */
	destination = (pipe & PIPE_DEVEP_MASK) | usb_packetid (pipe);
	/* 3 errors */
	status = (pipe & TD_CTRL_LS) | TD_CTRL_ACTIVE | (3 << 27);
	/*	((urb->transfer_flags & USB_DISABLE_SPD) ? 0 : TD_CTRL_SPD) | (3 << 27); */
	/* Build the TDs for the bulk request */
	len = transfer_len;
	dataptr = (unsigned long)buffer;
	do {
		int pktsze = len;
		if (pktsze > maxsze)
			pktsze = maxsze;
		/* pktsze bytes of data  */
		info = destination | (((pktsze - 1)&UHCI_NULL_DATA_SIZE) << 21) |
			(usb_gettoggle (dev, usb_pipeendpoint (pipe), usb_pipeout (pipe)) << TD_TOKEN_TOGGLE);

		if((len-pktsze)==0)
			status |= TD_CTRL_IOC;	/* last one generates INT */

		usb_fill_td(&tmp_td[i],UHCI_PTR_TERM, status, info,dataptr,(unsigned long)dev);	/* Status, pktsze bytes of data */
		if(i>0)
			tmp_td[i-1].link=swap_32((unsigned long)&tmp_td[i]);
		i++;
		dataptr += pktsze;
		len -= pktsze;
		usb_dotoggle (dev, usb_pipeendpoint (pipe), usb_pipeout (pipe));
	} while (len > 0);
	/* first mark the bulk QH element terminated */
	qh_bulk.element=0xffffffffL;
	/* set qh active */
	qh_bulk.dev_ptr=(unsigned long)dev;
	/* fill in tmp_td_chain */
	qh_bulk.element=swap_32((unsigned long)&tmp_td[0]);
	return 0;
}


/* search a free interrupt td
 */
uhci_td_t *uhci_alloc_int_td(void)
{
	int i;
	for(i=0;i<USB_MAX_TEMP_INT_TD;i++) {
		if(tmp_int_td[i].dev_ptr==0) /* no device assigned -> free TD */
			return &tmp_int_td[i];
	}
	return NULL;
}

#if 0
void uhci_show_temp_int_td(void)
{
	int i;
	for(i=0;i<USB_MAX_TEMP_INT_TD;i++) {
		if((tmp_int_td[i].dev_ptr&0x01)!=0x1L) /* no device assigned -> free TD */
			printf("temp_td %d is assigned to dev %lx\n",i,tmp_int_td[i].dev_ptr);
	}
	printf("all others temp_tds are free\n");
}
#endif
/*-------------------------------------------------------------------
 * submits USB interrupt (ie. polling ;-)
 */
int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,int transfer_len, int interval)
{
	int nint, n;
	unsigned long status, destination;
	unsigned long info,tmp;
	uhci_td_t *mytd;
	if (interval < 0 || interval >= 256)
		return -1;

	if (interval == 0)
		nint = 0;
	else {
		for (nint = 0, n = 1; nint <= 8; nint++, n += n)	/* round interval down to 2^n */
		 {
			if(interval < n) {
				interval = n / 2;
				break;
			}
		}
		nint--;
	}

	USB_UHCI_PRINTF("Rounded interval to %i, chain  %i\n", interval, nint);
	mytd=uhci_alloc_int_td();
	if(mytd==NULL) {
		printf("No free INT TDs found\n");
		return -1;
	}
	status = (pipe & TD_CTRL_LS) | TD_CTRL_ACTIVE | TD_CTRL_IOC | (3 << 27);
/*		(urb->transfer_flags & USB_DISABLE_SPD ? 0 : TD_CTRL_SPD) | (3 << 27);
*/

	destination =(pipe & PIPE_DEVEP_MASK) | usb_packetid (pipe) | (((transfer_len - 1) & 0x7ff) << 21);

	info = destination | (usb_gettoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe)) << TD_TOKEN_TOGGLE);
	tmp = swap_32(td_int[nint].link);
	usb_fill_td(mytd,tmp,status, info,(unsigned long)buffer,(unsigned long)dev);
	/* Link it */
	tmp = swap_32((unsigned long)mytd);
	td_int[nint].link=tmp;

	usb_dotoggle (dev, usb_pipeendpoint (pipe), usb_pipeout (pipe));

	return 0;
}

/**********************************************************************
 * Low Level functions
 */


void reset_hc(void)
{

	/* Global reset for 100ms */
	out16r( usb_base_addr + USBPORTSC1,0x0204);
	out16r( usb_base_addr + USBPORTSC2,0x0204);
	out16r( usb_base_addr + USBCMD,USBCMD_GRESET | USBCMD_RS);
	/* Turn off all interrupts */
	out16r(usb_base_addr + USBINTR,0);
	wait_ms(50);
	out16r( usb_base_addr + USBCMD,0);
	wait_ms(10);
}

void start_hc(void)
{
	int timeout = 1000;

	while(in16r(usb_base_addr + USBCMD) & USBCMD_HCRESET) {
		if (!--timeout) {
			printf("USBCMD_HCRESET timed out!\n");
			break;
		}
	}
	/* Turn on all interrupts */
	out16r(usb_base_addr + USBINTR,USBINTR_TIMEOUT | USBINTR_RESUME | USBINTR_IOC | USBINTR_SP);
	/* Start at frame 0 */
	out16r(usb_base_addr + USBFRNUM,0);
	/* set Framebuffer base address */
	out32r(usb_base_addr+USBFLBASEADD,(unsigned long)&framelist);
	/* Run and mark it configured with a 64-byte max packet */
	out16r(usb_base_addr + USBCMD,USBCMD_RS | USBCMD_CF | USBCMD_MAXP);
}

/* Initialize the skeleton
 */
void usb_init_skel(void)
{
	unsigned long temp;
	int n;

	for(n=0;n<USB_MAX_TEMP_INT_TD;n++)
		tmp_int_td[n].dev_ptr=0L; /* no devices connected */
	/* last td */
	usb_fill_td(&td_last,UHCI_PTR_TERM,TD_CTRL_IOC ,0,0,0L);
  /* usb_fill_td(&td_last,UHCI_PTR_TERM,0,0,0); */
	/* End Queue Header */
	usb_fill_qh(&qh_end,UHCI_PTR_TERM,(unsigned long)&td_last);
	/* Bulk Queue Header */
	temp=(unsigned long)&qh_end;
	usb_fill_qh(&qh_bulk,temp | UHCI_PTR_QH,UHCI_PTR_TERM);
	/* Control Queue Header */
	temp=(unsigned long)&qh_bulk;
	usb_fill_qh(&qh_cntrl, temp | UHCI_PTR_QH,UHCI_PTR_TERM);
	/* 1ms Interrupt td */
	temp=(unsigned long)&qh_cntrl;
	usb_fill_td(&td_int[0],temp | UHCI_PTR_QH,0,0,0,0L);
	temp=(unsigned long)&td_int[0];
	for(n=1; n<8; n++)
		usb_fill_td(&td_int[n],temp,0,0,0,0L);
	for (n = 0; n < 1024; n++) {
	/* link all framelist pointers to one of the interrupts */
		int m, o;
		if ((n&127)==127)
			framelist[n]= swap_32((unsigned long)&td_int[0]);
		else
			for (o = 1, m = 2; m <= 128; o++, m += m)
				if ((n & (m - 1)) == ((m - 1) / 2))
						framelist[n]= swap_32((unsigned long)&td_int[o]);
	}
}

/* check the common skeleton for completed transfers, and update the status
 * of the "connected" device. Called from the IRQ routine.
 */
void usb_check_skel(void)
{
	struct usb_device *dev;
	/* start with the control qh */
	if(qh_cntrl.dev_ptr!=0) /* it's a device assigned check if this caused IRQ */
	{
		dev=(struct usb_device *)qh_cntrl.dev_ptr;
		usb_get_td_status(&tmp_td[0],dev); /* update status */
		if(!(dev->status & USB_ST_NOT_PROC)) { /* is not active anymore, disconnect devices */
			qh_cntrl.dev_ptr=0;
		}
	}
	/* now process the bulk */
	if(qh_bulk.dev_ptr!=0) /* it's a device assigned check if this caused IRQ */
	{
		dev=(struct usb_device *)qh_bulk.dev_ptr;
		usb_get_td_status(&tmp_td[0],dev); /* update status */
		if(!(dev->status & USB_ST_NOT_PROC)) { /* is not active anymore, disconnect devices */
			qh_bulk.dev_ptr=0;
		}
	}
}

/* check the interrupt chain, ubdate the status of the appropriate device,
 * call the appropriate irqhandler and reactivate the TD if the irqhandler
 * returns with 1
 */
void usb_check_int_chain(void)
{
	int i,res;
	unsigned long link,status;
	struct usb_device *dev;
	uhci_td_t *td,*prevtd;

	for(i=0;i<8;i++) {
		prevtd = &td_int[i]; /* the first previous td is the skeleton td */
		link=swap_32(td_int[i].link) & 0xfffffff0; /* next in chain */
		td=(uhci_td_t *)link; /* assign it */
		/* all interrupt TDs are finally linked to the td_int[0].
		 * so we process all until we find the td_int[0].
		 * if int0 chain points to a QH, we're also done
	   */
		while(((i>0) && (link != (unsigned long)&td_int[0])) ||
					((i==0) && !(swap_32(td->link) &  UHCI_PTR_QH)))
		{
			/* check if a device is assigned with this td */
			status=swap_32(td->status);
			if((td->dev_ptr!=0L) && !(status & TD_CTRL_ACTIVE)) {
				/* td is not active and a device is assigned -> call irqhandler */
				dev=(struct usb_device *)td->dev_ptr;
				dev->irq_act_len=((status & 0x7FF)==0x7FF) ? 0 : (status & 0x7FF) + 1; /* transfered length */
				dev->irq_status=usb_uhci_td_stat(status); /* get status */
				res=dev->irq_handle(dev); /* call irqhandler */
				if(res==1) {
					/* reactivate */
					status|=TD_CTRL_ACTIVE;
					td->status=swap_32(status);
					prevtd=td; /* previous td = this td */
				}
				else {
					prevtd->link=td->link; /* link previous td directly to the nex td -> unlinked */
					/* remove device pointer */
					td->dev_ptr=0L;
				}
			} /* if we call the irq handler */
			link=swap_32(td->link) & 0xfffffff0; /* next in chain */
			td=(uhci_td_t *)link; /* assign it */
		} /* process all td in this int chain */
	} /* next interrupt chain */
}


/* usb interrupt service routine.
 */
void handle_usb_interrupt(void)
{
	unsigned short status;

	/*
	 * Read the interrupt status, and write it back to clear the
	 * interrupt cause
	 */

	status = in16r(usb_base_addr + USBSTS);

	if (!status)		/* shared interrupt, not mine */
		return;
	if (status != 1) {
		/* remove host controller halted state */
		if ((status&0x20) && ((in16r(usb_base_addr+USBCMD) && USBCMD_RS)==0)) {
			out16r(usb_base_addr + USBCMD, USBCMD_RS | in16r(usb_base_addr + USBCMD));
		}
	}
	usb_check_int_chain(); /* call interrupt handlers for int tds */
	usb_check_skel(); /* call completion handler for common transfer routines */
	out16r(usb_base_addr+USBSTS,status);
}


/* init uhci
 */
int usb_lowlevel_init(void)
{
	unsigned char temp;
	int	busdevfunc;

	busdevfunc=pci_find_device(USB_UHCI_VEND_ID,USB_UHCI_DEV_ID,0); /* get PCI Device ID */
	if(busdevfunc==-1) {
		printf("Error USB UHCI (%04X,%04X) not found\n",USB_UHCI_VEND_ID,USB_UHCI_DEV_ID);
		return -1;
	}
	pci_read_config_byte(busdevfunc,PCI_INTERRUPT_LINE,&temp);
	irqvec = temp;
	irq_free_handler(irqvec);
	USB_UHCI_PRINTF("Interrupt Line = %d, is %d\n",irqvec);
	pci_read_config_byte(busdevfunc,PCI_INTERRUPT_PIN,&temp);
	USB_UHCI_PRINTF("Interrupt Pin = %ld\n",temp);
	pci_read_config_dword(busdevfunc,PCI_BASE_ADDRESS_4,&usb_base_addr);
	USB_UHCI_PRINTF("IO Base Address = 0x%lx\n",usb_base_addr);
	usb_base_addr&=0xFFFFFFF0;
	usb_base_addr+=CONFIG_SYS_ISA_IO_BASE_ADDRESS;
	rh.devnum = 0;
	usb_init_skel();
	reset_hc();
	start_hc();
	irq_install_handler(irqvec, (interrupt_handler_t *)handle_usb_interrupt, NULL);
	return 0;
}

/* stop uhci
 */
int usb_lowlevel_stop(void)
{
	if(irqvec==-1)
		return 1;
	irq_free_handler(irqvec);
	reset_hc();
	irqvec = -1;
	return 0;
}

/*******************************************************************************************
 * Virtual Root Hub
 * Since the uhci does not have a real HUB, we simulate one ;-)
 */
#undef	USB_RH_DEBUG

#ifdef	USB_RH_DEBUG
#define	USB_RH_PRINTF(fmt,args...)	printf (fmt ,##args)
static void usb_display_wValue(unsigned short wValue,unsigned short wIndex);
static void usb_display_Req(unsigned short req);
#else
#define USB_RH_PRINTF(fmt,args...)
static void usb_display_wValue(unsigned short wValue,unsigned short wIndex) {}
static void usb_display_Req(unsigned short req) {}
#endif

static unsigned char root_hub_dev_des[] =
{
	0x12,			/*  __u8  bLength; */
	0x01,			/*  __u8  bDescriptorType; Device */
	0x00,			/*  __u16 bcdUSB; v1.0 */
	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,
	0x01,			/*  __u8  iManufacturer; */
	0x00,			/*  __u8  iProduct; */
	0x00,			/*  __u8  iSerialNumber; */
	0x01			/*  __u8  bNumConfigurations; */
};


/* Configuration descriptor */
static unsigned char root_hub_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; 8 Bytes */
	0x00,
	0xff			/*  __u8  ep_bInterval; 255 ms */
};


static unsigned char root_hub_hub_des[] =
{
	0x09,			/*  __u8  bLength; */
	0x29,			/*  __u8  bDescriptorType; Hub-descriptor */
	0x02,			/*  __u8  bNbrPorts; */
	0x00,			/* __u16  wHubCharacteristics; */
	0x00,
	0x01,			/*  __u8  bPwrOn2pwrGood; 2ms */
	0x00,			/*  __u8  bHubContrCurrent; 0 mA */
	0x00,			/*  __u8  DeviceRemovable; *** 7 Ports max *** */
	0xff			/*  __u8  PortPwrCtrlMask; *** 7 ports max *** */
};

static unsigned char root_hub_str_index0[] =
{
	0x04,			/*  __u8  bLength; */
	0x03,			/*  __u8  bDescriptorType; String-descriptor */
	0x09,			/*  __u8  lang ID */
	0x04,			/*  __u8  lang ID */
};

static unsigned char root_hub_str_index1[] =
{
	28,			/*  __u8  bLength; */
	0x03,			/*  __u8  bDescriptorType; String-descriptor */
	'U',			/*  __u8  Unicode */
	0,				/*  __u8  Unicode */
	'H',			/*  __u8  Unicode */
	0,				/*  __u8  Unicode */
	'C',			/*  __u8  Unicode */
	0,				/*  __u8  Unicode */
	'I',			/*  __u8  Unicode */
	0,				/*  __u8  Unicode */
	' ',			/*  __u8  Unicode */
	0,				/*  __u8  Unicode */
	'R',			/*  __u8  Unicode */
	0,				/*  __u8  Unicode */
	'o',			/*  __u8  Unicode */
	0,				/*  __u8  Unicode */
	'o',			/*  __u8  Unicode */
	0,				/*  __u8  Unicode */
	't',			/*  __u8  Unicode */
	0,				/*  __u8  Unicode */
	' ',			/*  __u8  Unicode */
	0,				/*  __u8  Unicode */
	'H',			/*  __u8  Unicode */
	0,				/*  __u8  Unicode */
	'u',			/*  __u8  Unicode */
	0,				/*  __u8  Unicode */
	'b',			/*  __u8  Unicode */
	0,				/*  __u8  Unicode */
};


/*
 * Root Hub Control Pipe (interrupt Pipes are not supported)
 */


int uhci_submit_rh_msg(struct usb_device *dev, unsigned long pipe, void *buffer,int transfer_len,struct devrequest *cmd)
{
	void *data = buffer;
	int leni = transfer_len;
	int len = 0;
	int status = 0;
	int stat = 0;
	int i;

	unsigned short cstatus;

	unsigned short bmRType_bReq;
	unsigned short wValue;
	unsigned short wIndex;
	unsigned short wLength;

	if (usb_pipeint(pipe)) {
		printf("Root-Hub submit IRQ: NOT implemented\n");
#if 0
		uhci->rh.urb = urb;
		uhci->rh.send = 1;
		uhci->rh.interval = urb->interval;
		rh_init_int_timer (urb);
#endif
		return 0;
	}
	bmRType_bReq = cmd->requesttype | cmd->request << 8;
	wValue = swap_16(cmd->value);
	wIndex = swap_16(cmd->index);
	wLength = swap_16(cmd->length);
	usb_display_Req(bmRType_bReq);
	for (i = 0; i < 8; i++)
		rh.c_p_r[i] = 0;
	USB_RH_PRINTF("Root-Hub: adr: %2x cmd(%1x): %02x%02x %04x %04x %04x\n",
	     dev->devnum, 8, cmd->requesttype,cmd->request, wValue, wIndex, wLength);

	switch (bmRType_bReq) {
		/* Request Destination:
		   without flags: Device,
		   RH_INTERFACE: interface,
		   RH_ENDPOINT: endpoint,
		   RH_CLASS means HUB here,
		   RH_OTHER | RH_CLASS  almost ever means HUB_PORT here
		 */

	case RH_GET_STATUS:
		*(unsigned short *) data = swap_16(1);
		len=2;
		break;
	case RH_GET_STATUS | RH_INTERFACE:
		*(unsigned short *) data = swap_16(0);
		len=2;
		break;
	case RH_GET_STATUS | RH_ENDPOINT:
		*(unsigned short *) data = swap_16(0);
		len=2;
		break;
	case RH_GET_STATUS | RH_CLASS:
		*(unsigned long *) data = swap_32(0);
		len=4;
		break;	/* hub power ** */
	case RH_GET_STATUS | RH_OTHER | RH_CLASS:

		status = in16r(usb_base_addr + USBPORTSC1 + 2 * (wIndex - 1));
		cstatus = ((status & USBPORTSC_CSC) >> (1 - 0)) |
			((status & USBPORTSC_PEC) >> (3 - 1)) |
			(rh.c_p_r[wIndex - 1] << (0 + 4));
		status = (status & USBPORTSC_CCS) |
			((status & USBPORTSC_PE) >> (2 - 1)) |
			((status & USBPORTSC_SUSP) >> (12 - 2)) |
			((status & USBPORTSC_PR) >> (9 - 4)) |
			(1 << 8) |	/* power on ** */
			((status & USBPORTSC_LSDA) << (-8 + 9));

		*(unsigned short *) data = swap_16(status);
		*(unsigned short *) (data + 2) = swap_16(cstatus);
		len=4;
		break;
	case RH_CLEAR_FEATURE | RH_ENDPOINT:
		switch (wValue) {
		case (RH_ENDPOINT_STALL):
			len=0;
			break;
		}
		break;

	case RH_CLEAR_FEATURE | RH_CLASS:
		switch (wValue) {
		case (RH_C_HUB_OVER_CURRENT):
			len=0;	/* hub power over current ** */
			break;
		}
		break;

	case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS:
		usb_display_wValue(wValue,wIndex);
		switch (wValue) {
		case (RH_PORT_ENABLE):
			status = in16r(usb_base_addr+USBPORTSC1+2*(wIndex-1));
			status = (status & 0xfff5) & ~USBPORTSC_PE;
			out16r(usb_base_addr+USBPORTSC1+2*(wIndex-1),status);
			len=0;
			break;
		case (RH_PORT_SUSPEND):
			status = in16r(usb_base_addr+USBPORTSC1+2*(wIndex-1));
			status = (status & 0xfff5) & ~USBPORTSC_SUSP;
			out16r(usb_base_addr+USBPORTSC1+2*(wIndex-1),status);
			len=0;
			break;
		case (RH_PORT_POWER):
			len=0;	/* port power ** */
			break;
		case (RH_C_PORT_CONNECTION):
			status = in16r(usb_base_addr+USBPORTSC1+2*(wIndex-1));
			status = (status & 0xfff5) | USBPORTSC_CSC;
			out16r(usb_base_addr+USBPORTSC1+2*(wIndex-1),status);
			len=0;
			break;
		case (RH_C_PORT_ENABLE):
			status = in16r(usb_base_addr+USBPORTSC1+2*(wIndex-1));
			status = (status & 0xfff5) | USBPORTSC_PEC;
			out16r(usb_base_addr+USBPORTSC1+2*(wIndex-1),status);
			len=0;
			break;
		case (RH_C_PORT_SUSPEND):
/*** WR_RH_PORTSTAT(RH_PS_PSSC); */
			len=0;
			break;
		case (RH_C_PORT_OVER_CURRENT):
			len=0;
			break;
		case (RH_C_PORT_RESET):
			rh.c_p_r[wIndex - 1] = 0;
			len=0;
			break;
		}
		break;
	case RH_SET_FEATURE | RH_OTHER | RH_CLASS:
		usb_display_wValue(wValue,wIndex);
		switch (wValue) {
		case (RH_PORT_SUSPEND):
			status = in16r(usb_base_addr+USBPORTSC1+2*(wIndex-1));
			status = (status & 0xfff5) | USBPORTSC_SUSP;
			out16r(usb_base_addr+USBPORTSC1+2*(wIndex-1),status);
			len=0;
			break;
		case (RH_PORT_RESET):
			status = in16r(usb_base_addr+USBPORTSC1+2*(wIndex-1));
			status = (status & 0xfff5) | USBPORTSC_PR;
			out16r(usb_base_addr+USBPORTSC1+2*(wIndex-1),status);
			wait_ms(10);
			status = (status & 0xfff5) & ~USBPORTSC_PR;
			out16r(usb_base_addr+USBPORTSC1+2*(wIndex-1),status);
			udelay(10);
			status = (status & 0xfff5) | USBPORTSC_PE;
			out16r(usb_base_addr+USBPORTSC1+2*(wIndex-1),status);
			wait_ms(10);
			status = (status & 0xfff5) | 0xa;
			out16r(usb_base_addr+USBPORTSC1+2*(wIndex-1),status);
			len=0;
			break;
		case (RH_PORT_POWER):
			len=0;	/* port power ** */
			break;
		case (RH_PORT_ENABLE):
			status = in16r(usb_base_addr+USBPORTSC1+2*(wIndex-1));
			status = (status & 0xfff5) | USBPORTSC_PE;
			out16r(usb_base_addr+USBPORTSC1+2*(wIndex-1),status);
			len=0;
			break;
		}
		break;

	case RH_SET_ADDRESS:
		rh.devnum = wValue;
		len=0;
		break;
	case RH_GET_DESCRIPTOR:
		switch ((wValue & 0xff00) >> 8) {
		case (0x01):	/* device descriptor */
			i=sizeof(root_hub_config_des);
			status=i > wLength ? wLength : i;
			len = leni > status ? status : leni;
			memcpy (data, root_hub_dev_des, len);
			break;
		case (0x02):	/* configuration descriptor */
			i=sizeof(root_hub_config_des);
			status=i > wLength ? wLength : i;
			len = leni > status ? status : leni;
			memcpy (data, root_hub_config_des, len);
			break;
		case (0x03):	/*string descriptors */
			if(wValue==0x0300) {
				i=sizeof(root_hub_str_index0);
				status = i > wLength ? wLength : i;
				len = leni > status ? status : leni;
				memcpy (data, root_hub_str_index0, len);
				break;
			}
			if(wValue==0x0301) {
				i=sizeof(root_hub_str_index1);
				status = i > wLength ? wLength : i;
				len = leni > status ? status : leni;
				memcpy (data, root_hub_str_index1, len);
				break;
			}
			stat = USB_ST_STALLED;
		}
		break;

	case RH_GET_DESCRIPTOR | RH_CLASS:
		root_hub_hub_des[2] = 2;
		i=sizeof(root_hub_hub_des);
		status= i > wLength ? wLength : i;
		len = leni > status ? status : leni;
		memcpy (data, root_hub_hub_des, len);
		break;
	case RH_GET_CONFIGURATION:
		*(unsigned char *) data = 0x01;
		len = 1;
		break;
	case RH_SET_CONFIGURATION:
		len=0;
		break;
	default:
		stat = USB_ST_STALLED;
	}
	USB_RH_PRINTF("Root-Hub stat %lx port1: %x port2: %x\n\n",stat,
	     in16r(usb_base_addr + USBPORTSC1), in16r(usb_base_addr + USBPORTSC2));
	dev->act_len=len;
	dev->status=stat;
	return stat;

}

/********************************************************************************
 * Some Debug Routines
 */

#ifdef	USB_RH_DEBUG

static void usb_display_Req(unsigned short req)
{
	USB_RH_PRINTF("- Root-Hub Request: ");
	switch (req) {
	case RH_GET_STATUS:
		USB_RH_PRINTF("Get Status ");
		break;
	case RH_GET_STATUS | RH_INTERFACE:
		USB_RH_PRINTF("Get Status Interface ");
		break;
	case RH_GET_STATUS | RH_ENDPOINT:
		USB_RH_PRINTF("Get Status Endpoint ");
		break;
	case RH_GET_STATUS | RH_CLASS:
		USB_RH_PRINTF("Get Status Class");
		break;	/* hub power ** */
	case RH_GET_STATUS | RH_OTHER | RH_CLASS:
		USB_RH_PRINTF("Get Status Class Others");
		break;
	case RH_CLEAR_FEATURE | RH_ENDPOINT:
		USB_RH_PRINTF("Clear Feature Endpoint ");
		break;
	case RH_CLEAR_FEATURE | RH_CLASS:
		USB_RH_PRINTF("Clear Feature Class ");
		break;
	case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS:
		USB_RH_PRINTF("Clear Feature Other Class ");
		break;
	case RH_SET_FEATURE | RH_OTHER | RH_CLASS:
		USB_RH_PRINTF("Set Feature Other Class ");
		break;
	case RH_SET_ADDRESS:
		USB_RH_PRINTF("Set Address ");
		break;
	case RH_GET_DESCRIPTOR:
		USB_RH_PRINTF("Get Descriptor ");
		break;
	case RH_GET_DESCRIPTOR | RH_CLASS:
		USB_RH_PRINTF("Get Descriptor Class ");
		break;
	case RH_GET_CONFIGURATION:
		USB_RH_PRINTF("Get Configuration ");
		break;
	case RH_SET_CONFIGURATION:
		USB_RH_PRINTF("Get Configuration ");
		break;
	default:
		USB_RH_PRINTF("****UNKNOWN**** 0x%04X ",req);
	}
	USB_RH_PRINTF("\n");

}

static void usb_display_wValue(unsigned short wValue,unsigned short wIndex)
{
	switch (wValue) {
		case (RH_PORT_ENABLE):
			USB_RH_PRINTF("Root-Hub: Enable Port %d\n",wIndex);
			break;
		case (RH_PORT_SUSPEND):
			USB_RH_PRINTF("Root-Hub: Suspend Port %d\n",wIndex);
			break;
		case (RH_PORT_POWER):
			USB_RH_PRINTF("Root-Hub: Port Power %d\n",wIndex);
			break;
		case (RH_C_PORT_CONNECTION):
			USB_RH_PRINTF("Root-Hub: C Port Connection Port %d\n",wIndex);
			break;
		case (RH_C_PORT_ENABLE):
			USB_RH_PRINTF("Root-Hub: C Port Enable Port %d\n",wIndex);
			break;
		case (RH_C_PORT_SUSPEND):
			USB_RH_PRINTF("Root-Hub: C Port Suspend Port %d\n",wIndex);
			break;
		case (RH_C_PORT_OVER_CURRENT):
			USB_RH_PRINTF("Root-Hub: C Port Over Current Port %d\n",wIndex);
			break;
		case (RH_C_PORT_RESET):
			USB_RH_PRINTF("Root-Hub: C Port reset Port %d\n",wIndex);
			break;
		default:
			USB_RH_PRINTF("Root-Hub: unknown %x %x\n",wValue,wIndex);
			break;
	}
}

#endif


#ifdef	USB_UHCI_DEBUG

static int usb_display_td(uhci_td_t *td)
{
	unsigned long tmp;
	int valid;

	printf("TD at %p:\n",td);

	tmp=swap_32(td->link);
	printf("Link points to 0x%08lX, %s first, %s, %s\n",tmp&0xfffffff0,
		((tmp & 0x4)==0x4) ? "Depth" : "Breath",
		((tmp & 0x2)==0x2) ? "QH" : "TD",
		((tmp & 0x1)==0x1) ? "invalid" : "valid");
	valid=((tmp & 0x1)==0x0);
	tmp=swap_32(td->status);
	printf("     %s %ld Errors %s %s %s \n     %s %s %s %s %s %s\n     Len 0x%lX\n",
		(((tmp>>29)&0x1)==0x1) ? "SPD Enable" : "SPD Disable",
		((tmp>>28)&0x3),
		(((tmp>>26)&0x1)==0x1) ? "Low Speed" : "Full Speed",
		(((tmp>>25)&0x1)==0x1) ? "ISO " : "",
		(((tmp>>24)&0x1)==0x1) ? "IOC " : "",
		(((tmp>>23)&0x1)==0x1) ? "Active " : "Inactive ",
		(((tmp>>22)&0x1)==0x1) ? "Stalled" : "",
		(((tmp>>21)&0x1)==0x1) ? "Data Buffer Error" : "",
		(((tmp>>20)&0x1)==0x1) ? "Babble" : "",
		(((tmp>>19)&0x1)==0x1) ? "NAK" : "",
		(((tmp>>18)&0x1)==0x1) ? "Bitstuff Error" : "",
		(tmp&0x7ff));
	tmp=swap_32(td->info);
	printf("     MaxLen 0x%lX\n",((tmp>>21)&0x7FF));
	printf("     %s Endpoint 0x%lX Dev Addr 0x%lX PID 0x%lX\n",((tmp>>19)&0x1)==0x1 ? "TOGGLE" : "",
		((tmp>>15)&0xF),((tmp>>8)&0x7F),tmp&0xFF);
	tmp=swap_32(td->buffer);
	printf("     Buffer 0x%08lX\n",tmp);
	printf("     DEV %08lX\n",td->dev_ptr);
	return valid;
}


void usb_show_td(int max)
{
	int i;
	if(max>0) {
		for(i=0;i<max;i++) {
			usb_display_td(&tmp_td[i]);
		}
	}
	else {
		i=0;
		do {
			printf("tmp_td[%d]\n",i);
		}while(usb_display_td(&tmp_td[i++]));
	}
}


#endif
#endif /* CONFIG_USB_UHCI */

/* EOF */
