/*
 * This file is part of the libpayload project.
 *
 * Copyright (C) 2008-2010 coresystems GmbH
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

//#define USB_DEBUG

#include <arch/virtual.h>
#include <usb/usb.h>
#include "uhci.h"
#include "uhci_private.h"

static void uhci_start (hci_t *controller);
static void uhci_stop (hci_t *controller);
static void uhci_reset (hci_t *controller);
static void uhci_shutdown (hci_t *controller);
static int uhci_bulk (endpoint_t *ep, int size, u8 *data, int finalize);
static int uhci_control (usbdev_t *dev, direction_t dir, int drlen, void *devreq,
			 int dalen, u8 *data);
static void* uhci_create_intr_queue (endpoint_t *ep, int reqsize, int reqcount, int reqtiming);
static void uhci_destroy_intr_queue (endpoint_t *ep, void *queue);
static u8* uhci_poll_intr_queue (void *queue);

#if 0
/* dump uhci */
static void
uhci_dump (hci_t *controller)
{
	usb_debug ("dump:\nUSBCMD: %x\n", uhci_reg_read16 (controller, USBCMD));
	usb_debug ("USBSTS: %x\n", uhci_reg_read16 (controller, USBSTS));
	usb_debug ("USBINTR: %x\n", uhci_reg_read16 (controller, USBINTR));
	usb_debug ("FRNUM: %x\n", uhci_reg_read16 (controller, FRNUM));
	usb_debug ("FLBASEADD: %x\n", uhci_reg_read32 (controller, FLBASEADD));
	usb_debug ("SOFMOD: %x\n", uhci_reg_read8 (controller, SOFMOD));
	usb_debug ("PORTSC1: %x\n", uhci_reg_read16 (controller, PORTSC1));
	usb_debug ("PORTSC2: %x\n", uhci_reg_read16 (controller, PORTSC2));
}
#endif

static void td_dump(td_t *td)
{
	usb_debug("+---------------------------------------------------+\n");
	if ((td->token & TD_PID_MASK) == UHCI_SETUP)
		usb_debug("|..[SETUP]..........................................|\n");
	else if ((td->token & TD_PID_MASK) == UHCI_IN)
		usb_debug("|..[IN].............................................|\n");
	else if ((td->token & TD_PID_MASK) == UHCI_OUT)
		usb_debug("|..[OUT]............................................|\n");
	else
		usb_debug("|..[]...............................................|\n");
	usb_debug("|:|============ UHCI TD at [0x%08lx] ==========|:|\n", virt_to_phys(td));
	usb_debug("|:+-----------------------------------------------+:|\n");
	usb_debug("|:| Next  TD/QH     [0x%08lx]                  |:|\n", td->ptr & ~0xFUL);
	usb_debug("|:+-----------------------------------------------+:|\n");
	usb_debug("|:| Depth/Breath [%lx]  | QH/TD [%lx] | TERMINATE [%lx] |:|\n",
	(td->ptr & (1UL << 2)) >> 2, (td->ptr & (1UL << 1)) >> 1, td->ptr & 1UL);
	usb_debug("|:+-----------------------------------------------+:|\n");
	usb_debug("|:|   T   | Maximum Length               | [%04lx] |:|\n", (td->token & (0x7FFUL << 21)) >> 21);
	usb_debug("|:|   O   | PID CODE                     | [%04lx] |:|\n", td->token & 0xFF);
	usb_debug("|:|   K   | Endpoint                     | [%04lx] |:|\n", (td->token & TD_EP_MASK) >> TD_EP_SHIFT);
	usb_debug("|:|   E   | Device Address               | [%04lx] |:|\n", (td->token & (0x7FUL << 8)) >> 8);
	usb_debug("|:|   N   | Data Toggle                  |    [%lx] |:|\n", (td->token & (1UL << 19)) >> 19);
	usb_debug("|:+-----------------------------------------------+:|\n");
	usb_debug("|:|   C   | Short Packet Detector        |    [%lx] |:|\n", (td->ctrlsts & (1UL << 29)) >> 29);
	usb_debug("|:|   O   | Error Counter                |    [%lx] |:|\n",
		(td->ctrlsts & (3UL << TD_COUNTER_SHIFT)) >> TD_COUNTER_SHIFT);
	usb_debug("|:|   N   | Low Speed Device             |    [%lx] |:|\n", (td->ctrlsts & (1UL << 26)) >> 26);
	usb_debug("|:|   T   | Isochronous Select           |    [%lx] |:|\n", (td->ctrlsts & (1UL << 25)) >> 25);
	usb_debug("|:|   R   | Interrupt on Complete (IOC)  |    [%lx] |:|\n", (td->ctrlsts & (1UL << 24)) >> 24);
	usb_debug("|:+   O   ----------------------------------------+:|\n");
	usb_debug("|:|   L   | Active                       |    [%lx] |:|\n", (td->ctrlsts & (1UL << 23)) >> 23);
	usb_debug("|:|   &   | Stalled                      |    [%lx] |:|\n", (td->ctrlsts & (1UL << 22)) >> 22);
	usb_debug("|:|   S   | Data Buffer Error            |    [%lx] |:|\n", (td->ctrlsts & (1UL << 21)) >> 21);
	usb_debug("|:|   T   | Bubble Detected              |    [%lx] |:|\n", (td->ctrlsts & (1UL << 20)) >> 20);
	usb_debug("|:|   A   | NAK Received                 |    [%lx] |:|\n", (td->ctrlsts & (1UL << 19)) >> 19);
	usb_debug("|:|   T   | CRC/Timeout Error            |    [%lx] |:|\n", (td->ctrlsts & (1UL << 18)) >> 18);
	usb_debug("|:|   U   | Bitstuff Error               |    [%lx] |:|\n", (td->ctrlsts & (1UL << 17)) >> 17);
	usb_debug("|:|   S   ----------------------------------------|:|\n");
	usb_debug("|:|       | Actual Length                | [%04lx] |:|\n", td->ctrlsts & 0x7FFUL);
	usb_debug("|:+-----------------------------------------------+:|\n");
	usb_debug("|:| Buffer pointer  [0x%08lx]                  |:|\n", td->bufptr);
	usb_debug("|:|-----------------------------------------------|:|\n");
	usb_debug("|...................................................|\n");
	usb_debug("+---------------------------------------------------+\n");
}

static void
uhci_reset (hci_t *controller)
{
	/* reset */
	uhci_reg_write16 (controller, USBCMD, 4); /* Global Reset */
	mdelay (50); /* uhci spec 2.1.1: at least 10ms */
	uhci_reg_write16 (controller, USBCMD, 0);
	mdelay (10);
	uhci_reg_write16 (controller, USBCMD, 2); /* Host Controller Reset */
	/* wait for controller to finish reset */
	/* TOTEST: how long to wait? 100ms for now */
	int timeout = 200; /* time out after 200 * 500us == 100ms */
	while (((uhci_reg_read16 (controller, USBCMD) & 2) != 0) && timeout--)
		udelay (500);
	if (timeout < 0)
		usb_debug ("Warning: uhci: host controller reset timed out.\n");
}

static void
uhci_reinit (hci_t *controller)
{
	uhci_reg_write32 (controller, FLBASEADD,
			  (u32) virt_to_phys (UHCI_INST (controller)->
					      framelistptr));
	//usb_debug ("framelist at %p\n",UHCI_INST(controller)->framelistptr);

	/* disable irqs */
	uhci_reg_write16 (controller, USBINTR, 0);

	/* reset framelist index */
	uhci_reg_write16 (controller, FRNUM, 0);

	uhci_reg_write16(controller, USBCMD,
			 uhci_reg_read16(controller, USBCMD) | 0xc0);	// max packets, configure flag

	uhci_start (controller);
}

hci_t *
uhci_pci_init (pcidev_t addr)
{
	int i;
	u16 reg16;

	hci_t *controller = new_controller ();

	if (!controller)
		fatal("Could not create USB controller instance.\n");

	controller->instance = malloc (sizeof (uhci_t));
	if(!controller->instance)
		fatal("Not enough memory creating USB controller instance.\n");

	controller->type = UHCI;

	controller->start = uhci_start;
	controller->stop = uhci_stop;
	controller->reset = uhci_reset;
	controller->init = uhci_reinit;
	controller->shutdown = uhci_shutdown;
	controller->bulk = uhci_bulk;
	controller->control = uhci_control;
	controller->set_address = generic_set_address;
	controller->finish_device_config = NULL;
	controller->destroy_device = NULL;
	controller->create_intr_queue = uhci_create_intr_queue;
	controller->destroy_intr_queue = uhci_destroy_intr_queue;
	controller->poll_intr_queue = uhci_poll_intr_queue;
	for (i = 0; i < 128; i++) {
		controller->devices[i] = 0;
	}
	init_device_entry (controller, 0);
	UHCI_INST (controller)->roothub = controller->devices[0];

	/* ~1 clears the register type indicator that is set to 1
	 * for IO space */
	controller->reg_base = pci_read_config32 (addr, 0x20) & ~1;

	/* kill legacy support handler */
	uhci_stop (controller);
	mdelay (1);
	uhci_reg_write16 (controller, USBSTS, 0x3f);
	reg16 = pci_read_config16(addr, 0xc0);
	reg16 &= 0xdf80;
	pci_write_config16 (addr, 0xc0, reg16);

	UHCI_INST (controller)->framelistptr = memalign (0x1000, 1024 * sizeof (flistp_t));	/* 4kb aligned to 4kb */
	if (! UHCI_INST (controller)->framelistptr)
		fatal("Not enough memory for USB frame list pointer.\n");

	memset (UHCI_INST (controller)->framelistptr, 0,
		1024 * sizeof (flistp_t));

	/* According to the *BSD UHCI code, this one is needed on some
	   PIIX chips, because otherwise they misbehave. It must be
	   added to the last chain.

	   FIXME: this leaks, if the driver should ever be reinited
	          for some reason. Not a problem now.
	   */
	td_t *antiberserk = memalign(16, sizeof(td_t));
	if (!antiberserk)
		fatal("Not enough memory for chipset workaround.\n");
	memset(antiberserk, 0, sizeof(td_t));

	UHCI_INST (controller)->qh_prei = memalign (16, sizeof (qh_t));
	UHCI_INST (controller)->qh_intr = memalign (16, sizeof (qh_t));
	UHCI_INST (controller)->qh_data = memalign (16, sizeof (qh_t));
	UHCI_INST (controller)->qh_last = memalign (16, sizeof (qh_t));

	if (! UHCI_INST (controller)->qh_prei ||
	    ! UHCI_INST (controller)->qh_intr ||
	    ! UHCI_INST (controller)->qh_data ||
	    ! UHCI_INST (controller)->qh_last)
		fatal("Not enough memory for USB controller queues.\n");

	UHCI_INST (controller)->qh_prei->headlinkptr =
		virt_to_phys (UHCI_INST (controller)->qh_intr) | FLISTP_QH;
	UHCI_INST (controller)->qh_prei->elementlinkptr = 0 | FLISTP_TERMINATE;

	UHCI_INST (controller)->qh_intr->headlinkptr =
		virt_to_phys (UHCI_INST (controller)->qh_data) | FLISTP_QH;
	UHCI_INST (controller)->qh_intr->elementlinkptr = 0 | FLISTP_TERMINATE;

	UHCI_INST (controller)->qh_data->headlinkptr =
		virt_to_phys (UHCI_INST (controller)->qh_last) | FLISTP_QH;
	UHCI_INST (controller)->qh_data->elementlinkptr = 0 | FLISTP_TERMINATE;

	UHCI_INST (controller)->qh_last->headlinkptr = virt_to_phys (UHCI_INST (controller)->qh_data) | FLISTP_TERMINATE;
	UHCI_INST (controller)->qh_last->elementlinkptr = virt_to_phys (antiberserk) | FLISTP_TERMINATE;

	for (i = 0; i < 1024; i++) {
		UHCI_INST (controller)->framelistptr[i] =
			virt_to_phys (UHCI_INST (controller)->qh_prei) | FLISTP_QH;
	}
	controller->devices[0]->controller = controller;
	controller->devices[0]->init = uhci_rh_init;
	controller->devices[0]->init (controller->devices[0]);
	uhci_reset (controller);
	uhci_reinit (controller);
	return controller;
}

static void
uhci_shutdown (hci_t *controller)
{
	if (controller == 0)
		return;
	detach_controller (controller);
	UHCI_INST (controller)->roothub->destroy (UHCI_INST (controller)->
						  roothub);
	uhci_reg_write16(controller, USBCMD,
			 uhci_reg_read16(controller, USBCMD) & 0);	// stop work
	free (UHCI_INST (controller)->framelistptr);
	free (UHCI_INST (controller)->qh_prei);
	free (UHCI_INST (controller)->qh_intr);
	free (UHCI_INST (controller)->qh_data);
	free (UHCI_INST (controller)->qh_last);
	free (UHCI_INST (controller));
	free (controller);
}

static void
uhci_start (hci_t *controller)
{
	uhci_reg_write16(controller, USBCMD,
			 uhci_reg_read16(controller, USBCMD) | 1);	// start work on schedule
}

static void
uhci_stop (hci_t *controller)
{
	uhci_reg_write16(controller, USBCMD,
			 uhci_reg_read16(controller, USBCMD) & ~1);	// stop work on schedule
}

#define GET_TD(x) ((void*)(((unsigned int)(x))&~0xf))

static td_t *
wait_for_completed_qh (hci_t *controller, qh_t *qh)
{
	int timeout = 1000;	/* max 30 ms. */
	void *current = GET_TD (qh->elementlinkptr);
	while (((qh->elementlinkptr & FLISTP_TERMINATE) == 0) && (timeout-- > 0)) {
		if (current != GET_TD (qh->elementlinkptr)) {
			current = GET_TD (qh->elementlinkptr);
			timeout = 1000;
		}
		uhci_reg_write16(controller, USBSTS,
				 uhci_reg_read16(controller, USBSTS) | 0);	// clear resettable registers
		udelay (30);
	}
	return (GET_TD (qh->elementlinkptr) ==
		0) ? 0 : GET_TD (phys_to_virt (qh->elementlinkptr));
}

static int
maxlen (int size)
{
	return (size - 1) & 0x7ff;
}

static int
min (int a, int b)
{
	if (a < b)
		return a;
	else
		return b;
}

static int
uhci_control (usbdev_t *dev, direction_t dir, int drlen, void *devreq, int dalen,
	      unsigned char *data)
{
	int endp = 0;		/* this is control: always 0 */
	int mlen = dev->endpoints[0].maxpacketsize;
	int count = (2 + (dalen + mlen - 1) / mlen);
	unsigned short req = ((unsigned short *) devreq)[0];
	int i;
	td_t *tds = memalign (16, sizeof (td_t) * count);
	memset (tds, 0, sizeof (td_t) * count);
	count--;		/* to compensate for 0-indexed array */
	for (i = 0; i < count; i++) {
		tds[i].ptr = virt_to_phys (&tds[i + 1]) | TD_DEPTH_FIRST;
	}
	tds[count].ptr = 0 | TD_DEPTH_FIRST | TD_TERMINATE;

	tds[0].token = UHCI_SETUP |
		dev->address << TD_DEVADDR_SHIFT |
		endp << TD_EP_SHIFT |
		TD_TOGGLE_DATA0 |
		maxlen(drlen) << TD_MAXLEN_SHIFT;
	tds[0].bufptr = virt_to_phys (devreq);
	tds[0].ctrlsts = (3 << TD_COUNTER_SHIFT) |
		(dev->speed?TD_LOWSPEED:0) |
		TD_STATUS_ACTIVE;

	int toggle = 1;
	for (i = 1; i < count; i++) {
		switch (dir) {
			case SETUP: tds[i].token = UHCI_SETUP; break;
			case IN:    tds[i].token = UHCI_IN;    break;
			case OUT:   tds[i].token = UHCI_OUT;   break;
		}
		tds[i].token |= dev->address << TD_DEVADDR_SHIFT |
			endp << TD_EP_SHIFT |
			maxlen (min (mlen, dalen)) << TD_MAXLEN_SHIFT |
			toggle << TD_TOGGLE_SHIFT;
		tds[i].bufptr = virt_to_phys (data);
		tds[i].ctrlsts = (3 << TD_COUNTER_SHIFT) |
			(dev->speed?TD_LOWSPEED:0) |
			TD_STATUS_ACTIVE;
		toggle ^= 1;
		dalen -= mlen;
		data += mlen;
	}

	tds[count].token = ((dir == OUT) ? UHCI_IN : UHCI_OUT) |
		dev->address << TD_DEVADDR_SHIFT |
		endp << TD_EP_SHIFT |
		maxlen(0) << TD_MAXLEN_SHIFT |
		TD_TOGGLE_DATA1;
	tds[count].bufptr = 0;
	tds[count].ctrlsts = (0 << TD_COUNTER_SHIFT) | /* as Linux 2.4.10 does */
		(dev->speed?TD_LOWSPEED:0) |
		TD_STATUS_ACTIVE;
	UHCI_INST (dev->controller)->qh_data->elementlinkptr =
		virt_to_phys (tds) & ~(FLISTP_QH | FLISTP_TERMINATE);
	td_t *td = wait_for_completed_qh (dev->controller,
					  UHCI_INST (dev->controller)->
					  qh_data);
	int result;
	if (td == 0) {
		result = 0;
	} else {
		usb_debug ("control packet, req %x\n", req);
		td_dump (td);
		result = -1;
	}
	free (tds);
	return result;
}

static td_t *
create_schedule (int numpackets)
{
	if (numpackets == 0)
		return 0;
	td_t *tds = memalign (16, sizeof (td_t) * numpackets);
	memset (tds, 0, sizeof (td_t) * numpackets);
	int i;
	for (i = 0; i < numpackets; i++) {
		tds[i].ptr = virt_to_phys (&tds[i + 1]) | TD_DEPTH_FIRST;
	}
	tds[numpackets - 1].ptr = 0 | TD_TERMINATE;
	return tds;
}

static void
fill_schedule (td_t *td, endpoint_t *ep, int length, unsigned char *data,
	       int *toggle)
{
	switch (ep->direction) {
		case IN: td->token = UHCI_IN; break;
		case OUT: td->token = UHCI_OUT; break;
		case SETUP: td->token = UHCI_SETUP; break;
	}
	td->token |= ep->dev->address << TD_DEVADDR_SHIFT |
		(ep->endpoint & 0xf) << TD_EP_SHIFT |
		maxlen (length) << TD_MAXLEN_SHIFT |
		(*toggle & 1) << TD_TOGGLE_SHIFT;
	td->bufptr = virt_to_phys (data);
	td->ctrlsts = ((ep->direction == SETUP?3:0) << TD_COUNTER_SHIFT) |
		(ep->dev->speed?TD_LOWSPEED:0) |
		TD_STATUS_ACTIVE;
	*toggle ^= 1;
}

static int
run_schedule (usbdev_t *dev, td_t *td)
{
	UHCI_INST (dev->controller)->qh_data->elementlinkptr =
		virt_to_phys (td) & ~(FLISTP_QH | FLISTP_TERMINATE);
	td = wait_for_completed_qh (dev->controller,
				    UHCI_INST (dev->controller)->qh_data);
	if (td == 0) {
		return 0;
	} else {
		td_dump (td);
		return 1;
	}
}

/* finalize == 1: if data is of packet aligned size, add a zero length packet */
static int
uhci_bulk (endpoint_t *ep, int size, u8 *data, int finalize)
{
	int maxpsize = ep->maxpacketsize;
	if (maxpsize == 0)
		fatal("MaxPacketSize == 0!!!");
	int numpackets = (size + maxpsize - 1) / maxpsize;
	if (finalize && ((size % maxpsize) == 0)) {
		numpackets++;
	}
	if (numpackets == 0)
		return 0;
	td_t *tds = create_schedule (numpackets);
	int i = 0, toggle = ep->toggle;
	while ((size > 0) || ((size == 0) && (finalize != 0))) {
		fill_schedule (&tds[i], ep, min (size, maxpsize), data,
			       &toggle);
		i++;
		data += maxpsize;
		size -= maxpsize;
	}
	if (run_schedule (ep->dev, tds) == 1) {
		usb_debug("Stalled. Trying to clean up.\n");
		clear_stall (ep);
		free (tds);
		return -1;
	}
	ep->toggle = toggle;
	free (tds);
	return 0;
}

typedef struct {
	qh_t *qh;
	td_t *tds;
	td_t *last_td;
	u8 *data;
	int lastread;
	int total;
	int reqsize;
} intr_q;

/* create and hook-up an intr queue into device schedule */
static void*
uhci_create_intr_queue (endpoint_t *ep, int reqsize, int reqcount, int reqtiming)
{
	u8 *data = malloc(reqsize*reqcount);
	td_t *tds = memalign(16, sizeof(td_t) * reqcount);
	qh_t *qh = memalign(16, sizeof(qh_t));

	if (!data || !tds || !qh)
		fatal("Not enough memory to create USB intr queue prerequisites.\n");

	qh->elementlinkptr = virt_to_phys(tds);

	intr_q *q = malloc(sizeof(intr_q));
	if (!q)
		fatal("Not enough memory to create USB intr queue.\n");
	q->qh = qh;
	q->tds = tds;
	q->data = data;
	q->lastread = 0;
	q->total = reqcount;
	q->reqsize = reqsize;
	q->last_td = &tds[reqcount - 1];

	memset (tds, 0, sizeof (td_t) * reqcount);
	int i;
	for (i = 0; i < reqcount; i++) {
		tds[i].ptr = virt_to_phys (&tds[i + 1]);

		switch (ep->direction) {
			case IN: tds[i].token = UHCI_IN; break;
			case OUT: tds[i].token = UHCI_OUT; break;
			case SETUP: tds[i].token = UHCI_SETUP; break;
		}
		tds[i].token |= ep->dev->address << TD_DEVADDR_SHIFT |
			(ep->endpoint & 0xf) << TD_EP_SHIFT |
			maxlen (reqsize) << TD_MAXLEN_SHIFT |
			(ep->toggle & 1) << TD_TOGGLE_SHIFT;
		tds[i].bufptr = virt_to_phys (data);
		tds[i].ctrlsts = (0 << TD_COUNTER_SHIFT) |
			(ep->dev->speed?TD_LOWSPEED:0) |
			TD_STATUS_ACTIVE;
		ep->toggle ^= 1;
		data += reqsize;
	}
	tds[reqcount - 1].ptr = 0 | TD_TERMINATE;

	/* insert QH into framelist */
	uhci_t *const uhcic = UHCI_INST(ep->dev->controller);
	const u32 def_ptr = virt_to_phys(uhcic->qh_prei) | FLISTP_QH;
	int nothing_placed = 1;
	qh->headlinkptr = def_ptr;
	for (i = 0; i < 1024; i += reqtiming) {
		/* advance to the next free position */
		while ((i < 1024) && (uhcic->framelistptr[i] != def_ptr)) ++i;
		if (i < 1024) {
			uhcic->framelistptr[i] = virt_to_phys(qh) | FLISTP_QH;
			nothing_placed = 0;
		}
	}
	if (nothing_placed) {
		usb_debug("Error: Failed to place UHCI interrupt queue "
			      "head into framelist: no space left\n");
		uhci_destroy_intr_queue(ep, q);
		return NULL;
	}

	return q;
}

/* remove queue from device schedule, dropping all data that came in */
static void
uhci_destroy_intr_queue (endpoint_t *ep, void *q_)
{
	intr_q *const q = (intr_q*)q_;

	/* remove QH from framelist */
	uhci_t *const uhcic = UHCI_INST(ep->dev->controller);
	const u32 qh_ptr = virt_to_phys(q->qh) | FLISTP_QH;
	const u32 def_ptr = virt_to_phys(uhcic->qh_prei) | FLISTP_QH;
	int i;
	for (i = 0; i < 1024; ++i) {
		if (uhcic->framelistptr[i] == qh_ptr)
			uhcic->framelistptr[i] = def_ptr;
	}

	free(q->data);
	free(q->tds);
	free(q->qh);
	free(q);
}

/* read one intr-packet from queue, if available. extend the queue for new input.
   return NULL if nothing new available.
   Recommended use: while (data=poll_intr_queue(q)) process(data);
 */
static u8*
uhci_poll_intr_queue (void *q_)
{
	intr_q *q = (intr_q*)q_;
	if ((q->tds[q->lastread].ctrlsts & TD_STATUS_ACTIVE) == 0) {
		int current = q->lastread;
		int previous;
		if (q->lastread == 0) {
			previous = q->total - 1;
		} else {
			previous = q->lastread - 1;
		}
		q->tds[previous].ctrlsts &= ~TD_STATUS_MASK;
		q->tds[previous].ptr = 0 | TD_TERMINATE;
		if (q->last_td != &q->tds[previous]) {
			q->last_td->ptr = virt_to_phys(&q->tds[previous]) & ~TD_TERMINATE;
			q->last_td = &q->tds[previous];
		}
		q->tds[previous].ctrlsts |= TD_STATUS_ACTIVE;
		q->lastread = (q->lastread + 1) % q->total;
		if (!(q->tds[current].ctrlsts & TD_STATUS_MASK))
			return &q->data[current*q->reqsize];
	}
	/* reset queue if we fully processed it after underrun */
	else if (q->qh->elementlinkptr & FLISTP_TERMINATE) {
		usb_debug("resetting underrun uhci interrupt queue.\n");
		q->qh->elementlinkptr = virt_to_phys(q->tds + q->lastread);
	}
	return NULL;
}

void
uhci_reg_write32 (hci_t *ctrl, usbreg reg, u32 value)
{
	outl (value, ctrl->reg_base + reg);
}

u32
uhci_reg_read32 (hci_t *ctrl, usbreg reg)
{
	return inl (ctrl->reg_base + reg);
}

void
uhci_reg_write16 (hci_t *ctrl, usbreg reg, u16 value)
{
	outw (value, ctrl->reg_base + reg);
}

u16
uhci_reg_read16 (hci_t *ctrl, usbreg reg)
{
	return inw (ctrl->reg_base + reg);
}

void
uhci_reg_write8 (hci_t *ctrl, usbreg reg, u8 value)
{
	outb (value, ctrl->reg_base + reg);
}

u8
uhci_reg_read8 (hci_t *ctrl, usbreg reg)
{
	return inb (ctrl->reg_base + reg);
}
