/*
 * 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 <libpayload-config.h>
#include <usb/usb.h>

hci_t *usb_hcs = 0;

hci_t *
new_controller (void)
{
	hci_t *controller = malloc (sizeof (hci_t));

	if (controller) {
		/* atomic */
		controller->next = usb_hcs;
		usb_hcs = controller;
		/* atomic end */
	}

	return controller;
}

void
detach_controller (hci_t *controller)
{
	if (controller == NULL)
		return;
	if (usb_hcs == controller) {
		usb_hcs = controller->next;
	} else {
		hci_t *it = usb_hcs;
		while (it != NULL) {
			if (it->next == controller) {
				it->next = controller->next;
				return;
			}
			it = it->next;
		}
	}
}

/**
 * Shut down all controllers
 */
int
usb_exit (void)
{
	while (usb_hcs != NULL) {
		usb_hcs->shutdown(usb_hcs);
	}
	return 0;
}

/**
 * Polls all hubs on all USB controllers, to find out about device changes
 */
void
usb_poll (void)
{
	if (usb_hcs == 0)
		return;
	hci_t *controller = usb_hcs;
	while (controller != NULL) {
		int i;
		for (i = 0; i < 128; i++) {
			if (controller->devices[i] != 0) {
				controller->devices[i]->poll (controller->devices[i]);
			}
		}
		controller = controller->next;
	}
}

void
init_device_entry (hci_t *controller, int i)
{
	if (controller->devices[i] != 0)
		usb_debug("warning: device %d reassigned?\n", i);
	controller->devices[i] = malloc(sizeof(usbdev_t));
	controller->devices[i]->controller = controller;
	controller->devices[i]->address = -1;
	controller->devices[i]->hub = -1;
	controller->devices[i]->port = -1;
	controller->devices[i]->init = usb_nop_init;
	controller->devices[i]->init (controller->devices[i]);
}

void
set_feature (usbdev_t *dev, int endp, int feature, int rtype)
{
	dev_req_t dr;

	dr.bmRequestType = rtype;
	dr.data_dir = host_to_device;
	dr.bRequest = SET_FEATURE;
	dr.wValue = feature;
	dr.wIndex = endp;
	dr.wLength = 0;
	dev->controller->control (dev, OUT, sizeof (dr), &dr, 0, 0);
}

void
get_status (usbdev_t *dev, int intf, int rtype, int len, void *data)
{
	dev_req_t dr;

	dr.bmRequestType = rtype;
	dr.data_dir = device_to_host;
	dr.bRequest = GET_STATUS;
	dr.wValue = 0;
	dr.wIndex = intf;
	dr.wLength = len;
	dev->controller->control (dev, IN, sizeof (dr), &dr, len, data);
}

u8 *
get_descriptor (usbdev_t *dev, unsigned char bmRequestType, int descType,
		int descIdx, int langID)
{
	u8 buf[8];
	u8 *result;
	dev_req_t dr;
	int size;

	dr.bmRequestType = bmRequestType;
	dr.data_dir = device_to_host;	// always like this for descriptors
	dr.bRequest = GET_DESCRIPTOR;
	dr.wValue = (descType << 8) | descIdx;
	dr.wIndex = langID;
	dr.wLength = 8;
	if (dev->controller->control (dev, IN, sizeof (dr), &dr, 8, buf) < 0) {
		usb_debug ("getting descriptor size (type %x) failed\n",
			descType);
	}

	if (descType == 1) {
		device_descriptor_t *dd = (device_descriptor_t *) buf;
		usb_debug ("maxPacketSize0: %x\n", dd->bMaxPacketSize0);
		if (dd->bMaxPacketSize0 != 0)
			dev->endpoints[0].maxpacketsize = dd->bMaxPacketSize0;
	}

	/* special case for configuration descriptors: they carry all their
	   subsequent descriptors with them, and keep the entire size at a
	   different location */
	size = buf[0];
	if (buf[1] == 2) {
		int realsize = ((unsigned short *) (buf + 2))[0];
		size = realsize;
	}
	result = malloc (size);
	memset (result, 0, size);
	dr.wLength = size;
	if (dev->controller->
	    control (dev, IN, sizeof (dr), &dr, size, result) < 0) {
		usb_debug ("getting descriptor (type %x, size %x) failed\n",
			descType, size);
	}

	return result;
}

void
set_configuration (usbdev_t *dev)
{
	dev_req_t dr;

	dr.bmRequestType = 0;
	dr.bRequest = SET_CONFIGURATION;
	dr.wValue = dev->configuration[5];
	dr.wIndex = 0;
	dr.wLength = 0;
	dev->controller->control (dev, OUT, sizeof (dr), &dr, 0, 0);
}

int
clear_feature (usbdev_t *dev, int endp, int feature, int rtype)
{
	dev_req_t dr;

	dr.bmRequestType = rtype;
	dr.data_dir = host_to_device;
	dr.bRequest = CLEAR_FEATURE;
	dr.wValue = feature;
	dr.wIndex = endp;
	dr.wLength = 0;
	return dev->controller->control (dev, OUT, sizeof (dr), &dr, 0, 0) < 0;
}

int
clear_stall (endpoint_t *ep)
{
	usbdev_t *dev = ep->dev;
	int endp = ep->endpoint;
	int rtype = gen_bmRequestType (host_to_device, standard_type,
					endp ? endp_recp : dev_recp);

	int ret = clear_feature (dev, endp, ENDPOINT_HALT, rtype);
	ep->toggle = 0;
	return ret;
}

/* returns free address or -1 */
static int
get_free_address (hci_t *controller)
{
	int i;
	for (i = 1; i < 128; i++) {
		if (controller->devices[i] == 0)
			return i;
	}
	usb_debug ("no free address found\n");
	return -1;		// no free address
}

static int
set_address (hci_t *controller, int speed, int hubport, int hubaddr)
{
	int adr = get_free_address (controller);	// address to set
	dev_req_t dr;
	configuration_descriptor_t *cd;
	device_descriptor_t *dd;

	memset (&dr, 0, sizeof (dr));
	dr.data_dir = host_to_device;
	dr.req_type = standard_type;
	dr.req_recp = dev_recp;
	dr.bRequest = SET_ADDRESS;
	dr.wValue = adr;
	dr.wIndex = 0;
	dr.wLength = 0;

	init_device_entry(controller, adr);
	usbdev_t *dev = controller->devices[adr];
	// dummy values for registering the address
	dev->address = 0;
	dev->hub = hubaddr;
	dev->port = hubport;
	dev->speed = speed;
	dev->endpoints[0].dev = dev;
	dev->endpoints[0].endpoint = 0;
	dev->endpoints[0].maxpacketsize = 8;
	dev->endpoints[0].toggle = 0;
	dev->endpoints[0].direction = SETUP;
	mdelay (50);
	if (dev->controller->control (dev, OUT, sizeof (dr), &dr, 0, 0) < 0) {
		usb_debug ("set_address failed\n");
		return -1;
	}
	mdelay (50);
	dev->address = adr;
	dev->descriptor = get_descriptor (dev, gen_bmRequestType
		(device_to_host, standard_type, dev_recp), 1, 0, 0);
	dd = (device_descriptor_t *) dev->descriptor;

	usb_debug ("* found device (0x%04x:0x%04x, USB %x.%x)",
		 dd->idVendor, dd->idProduct,
		 dd->bcdUSB >> 8, dd->bcdUSB & 0xff);
	dev->quirks = usb_quirk_check(dd->idVendor, dd->idProduct);

	usb_debug ("\ndevice has %x configurations\n", dd->bNumConfigurations);
	if (dd->bNumConfigurations == 0) {
		/* device isn't usable */
		usb_debug ("... no usable configuration!\n");
		dev->address = 0;
		return -1;
	}

	dev->configuration = get_descriptor (dev, gen_bmRequestType
		(device_to_host, standard_type, dev_recp), 2, 0, 0);
	cd = (configuration_descriptor_t *) dev->configuration;
	set_configuration (dev);
	interface_descriptor_t *interface =
		(interface_descriptor_t *) (((char *) cd) + cd->bLength);
	{
		int i;
		int num = cd->bNumInterfaces;
		interface_descriptor_t *current = interface;
		usb_debug ("device has %x interfaces\n", num);
		if (num > 1) {
			int interfaces = usb_interface_check(dd->idVendor, dd->idProduct);
			if (interfaces) {
				/* Well known device, don't warn */
				num = interfaces;
			} else {

				usb_debug ("\nNOTICE: This driver defaults to using the first interface.\n"
					"This might be the wrong choice and lead to limited functionality\n"
					"of the device. Please report such a case to coreboot@coreboot.org\n"
					"as you might be the first.\n");
				/* we limit to the first interface, as there was no need to
				 * implement something else for the time being. If you need
				 * it, see the SetInterface and GetInterface functions in
				 * the USB specification, and adapt appropriately.
				 */
				num = (num > 1) ? 1 : num;
			}
		}
		for (i = 0; i < num; i++) {
			int j;
			usb_debug (" #%x has %x endpoints, interface %x:%x, protocol %x\n",
					current->bInterfaceNumber, current->bNumEndpoints, current->bInterfaceClass, current->bInterfaceSubClass, current->bInterfaceProtocol);
			endpoint_descriptor_t *endp =
				(endpoint_descriptor_t *) (((char *) current)
							   + current->bLength);
			/* Skip any non-endpoint descriptor */
			if (endp->bDescriptorType != 0x05)
				endp = (endpoint_descriptor_t *)(((char *)endp) + ((char *)endp)[0]);

			memset (dev->endpoints, 0, sizeof (dev->endpoints));
			dev->num_endp = 1;	// 0 always exists
			dev->endpoints[0].dev = dev;
			dev->endpoints[0].maxpacketsize = dd->bMaxPacketSize0;
			dev->endpoints[0].direction = SETUP;
			dev->endpoints[0].type = CONTROL;
			for (j = 1; j <= current->bNumEndpoints; j++) {
#ifdef USB_DEBUG
				static const char *transfertypes[4] = {
					"control", "isochronous", "bulk", "interrupt"
				};
				usb_debug ("   #%x: Endpoint %x (%s), max packet size %x, type %s\n", j, endp->bEndpointAddress & 0x7f, ((endp->bEndpointAddress & 0x80) != 0) ? "in" : "out", endp->wMaxPacketSize, transfertypes[endp->bmAttributes]);
#endif
				endpoint_t *ep =
					&dev->endpoints[dev->num_endp++];
				ep->dev = dev;
				ep->endpoint = endp->bEndpointAddress;
				ep->toggle = 0;
				ep->maxpacketsize = endp->wMaxPacketSize;
				ep->direction =
					((endp->bEndpointAddress & 0x80) ==
					 0) ? OUT : IN;
				ep->type = endp->bmAttributes;
				endp = (endpoint_descriptor_t
					*) (((char *) endp) + endp->bLength);
			}
			current = (interface_descriptor_t *) endp;
		}
	}

	int class = dd->bDeviceClass;
	if (class == 0)
		class = interface->bInterfaceClass;

	enum {
		audio_device      = 0x01,
		comm_device       = 0x02,
		hid_device        = 0x03,
		physical_device   = 0x05,
		imaging_device    = 0x06,
		printer_device    = 0x07,
		msc_device        = 0x08,
		hub_device        = 0x09,
		cdc_device        = 0x0a,
		ccid_device       = 0x0b,
		security_device   = 0x0d,
		video_device      = 0x0e,
		healthcare_device = 0x0f,
		diagnostic_device = 0xdc,
		wireless_device   = 0xe0,
		misc_device       = 0xef,
	};
	usb_debug(", class: ");
	switch (class) {
	case audio_device:
		usb_debug("audio\n");
		break;
	case comm_device:
		usb_debug("communication\n");
		break;
	case hid_device:
		usb_debug ("HID\n");
#ifdef CONFIG_LP_USB_HID
		controller->devices[adr]->init = usb_hid_init;
		return adr;
#else
		usb_debug ("NOTICE: USB HID support not compiled in\n");
#endif
		break;
	case physical_device:
		usb_debug("physical\n");
		break;
	case imaging_device:
		usb_debug("camera\n");
		break;
	case printer_device:
		usb_debug("printer\n");
		break;
	case msc_device:
		usb_debug ("MSC\n");
#ifdef CONFIG_LP_USB_MSC
		controller->devices[adr]->init = usb_msc_init;
		return adr;
#else
		usb_debug ("NOTICE: USB MSC support not compiled in\n");
#endif
		break;
	case hub_device:
		usb_debug ("hub\n");
#ifdef CONFIG_LP_USB_HUB
		controller->devices[adr]->init = usb_hub_init;
		return adr;
#else
		usb_debug ("NOTICE: USB hub support not compiled in.\n");
#endif
		break;
	case cdc_device:
		usb_debug("CDC\n");
		break;
	case ccid_device:
		usb_debug("smartcard / CCID\n");
		break;
	case security_device:
		usb_debug("content security\n");
		break;
	case video_device:
		usb_debug("video\n");
		break;
	case healthcare_device:
		usb_debug("healthcare\n");
		break;
	case diagnostic_device:
		usb_debug("diagnostic\n");
		break;
	case wireless_device:
		usb_debug("wireless\n");
		break;
	default:
		usb_debug("unsupported class %x\n", class);
		break;
	}
	controller->devices[adr]->init = usb_generic_init;
	return adr;
}

/*
 * Should be called by the hub drivers whenever a physical detach occurs
 * and can be called by usb class drivers if they are unsatisfied with a
 * malfunctioning device.
 */
void
usb_detach_device(hci_t *controller, int devno)
{
	/* check if device exists, as we may have
	   been called yet by the usb class driver */
	if (controller->devices[devno]) {
		controller->devices[devno]->destroy (controller->devices[devno]);
		free(controller->devices[devno]);
		controller->devices[devno] = NULL;
	}
}

int
usb_attach_device(hci_t *controller, int hubaddress, int port, int speed)
{
	static const char* speeds[] = { "full", "low", "high" };
	usb_debug ("%sspeed device\n", (speed <= 2) ? speeds[speed] : "invalid value - no");
	int newdev = set_address (controller, speed, port, hubaddress);
	if (newdev == -1)
		return -1;
	usbdev_t *newdev_t = controller->devices[newdev];
	// determine responsible driver - current done in set_address
	newdev_t->init (newdev_t);
	/* init() may have called usb_detach_device() yet, so check */
	return controller->devices[newdev] ? newdev : -1;
}

static void
usb_generic_destroy (usbdev_t *dev)
{
	if (usb_generic_remove)
		usb_generic_remove(dev);
}

void
usb_generic_init (usbdev_t *dev)
{
	dev->data = NULL;
	dev->destroy = usb_generic_destroy;

	if (usb_generic_create)
		usb_generic_create(dev);
}
