/*
 * Copyright 2017, Data61
 * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
 * ABN 41 687 119 230.
 *
 * This software may be distributed and modified according to the terms of
 * the BSD 2-Clause license. Note that NO WARRANTY is provided.
 * See "LICENSE_BSD2.txt" for details.
 *
 * @TAG(DATA61_BSD)
 */
#include <stdio.h>
#include <stdint.h>

#include <usb/usb.h>
#include <usb/usb_host.h>
#include <usb/drivers/usbhub.h>
#include <usb/usb.h>
#include "services.h"
#include <string.h>
#include <utils/util.h>
#include <utils/sglib.h>

#define NUM_DEVICES 32

#define CLASS_RESERVED_STR "<Reserved>"

const char *usb_class_get_description(enum usb_class usb_class)
{
	switch (usb_class) {
		case USB_CLASS_UNSPECIFIED:
		return "Unspecified - See interface classes";
	case USB_CLASS_AUDIO:
		return "Audio";
	case USB_CLASS_COMM:
		return "Communication and CDC Control";
	case USB_CLASS_HID:
		return "Human interface device (HID)";
	case USB_CLASS_PID:
		return "Physical Interface Device (PID)";
	case USB_CLASS_IMAGE:
		return "Image";
	case USB_CLASS_PRINTER:
		return "Printer";
	case USB_CLASS_STORAGE:
		return "Mass storage";
	case USB_CLASS_HUB:
		return "USB hub";
	case USB_CLASS_CDCDATA:
		return "CDC-Data";
	case USB_CLASS_CARDREADER:
		return "Smart Card";
	case USB_CLASS_SECURITY:
		return "Content security";
	case USB_CLASS_VIDEO:
		return "Video";
	case USB_CLASS_HEALTH:
		return "Personal Healthcare Pulse monitor";
	case USB_CLASS_AV:
		return "Audio/Video (AV)";
	/* Some other sparse classes */
	case USB_CLASS_DIAGNOSTIC:
		return "Diagnostic Device";
	case USB_CLASS_WIRELESS:
		return "Wireless Controller";
	case USB_CLASS_MISC:
		return "Miscellaneous";
	case USB_CLASS_APPSPEC:
		return "Application specific";
	case USB_CLASS_VEND:
		return "Vendor specific";
	default:
		return CLASS_RESERVED_STR;
	}
}

/*****************
 **** Helpers ****
 *****************/

static inline struct usbreq __new_desc_req(enum DescriptorType t, int size)
{
	struct usbreq r = {
		.bmRequestType = (USB_DIR_IN | USB_TYPE_STD | USB_RCPT_DEVICE),
		.bRequest = GET_DESCRIPTOR,
		.wValue = t << 8,
		.wIndex = 0,
		.wLength = size
	};
	return r;
}

static inline struct usbreq __new_address_req(int addr)
{
	struct usbreq r = {
		.bmRequestType = (USB_DIR_OUT | USB_TYPE_STD | USB_RCPT_DEVICE),
		.bRequest = SET_ADDRESS,
		.wValue = addr,
		.wIndex = 0,
		.wLength = 0
	};
	return r;
}

/**** Device list ****/

/* Initialise the device list */
static void devlist_init(usb_t * host)
{
	host->devlist = NULL;
	host->addrbm = 1;
	host->next_addr = 1;
}

/* Insert a device into the list, return the index at which it was inserted */
static int devlist_insert(struct usb_dev *d)
{
	usb_t *host = d->host;
	int i = host->next_addr;
	/* Early exit */
	if (host->addrbm == (1ULL << NUM_DEVICES) - 1) {
		return -1;
	}
	/* cycle the list searching for a free address */
	while (host->addrbm & (1 << i)) {
		if (i == NUM_DEVICES) {
			/* Remember address 0 is a special case */
			i = 1;
		} else {
			i++;
		}
	}
	/* Add the device to the list */
	SGLIB_LIST_ADD(struct usb_dev, host->devlist, d, next);
	host->addrbm |= (1 << i);

	/* Update the next address for next insertion */
	if ((i + 1) == NUM_DEVICES) {
		host->next_addr = 1;
	} else {
		host->next_addr = i + 1;
	}

	/* return address */
	return i;
}

/* Remove the device from the list */
static void devlist_remove(struct usb_dev *d)
{
	usb_t *host = d->host;

	SGLIB_LIST_DELETE(struct usb_dev, host->devlist, d, next);

	d->next = NULL;
	host->addrbm &= ~(1 << d->addr);
	d->addr = -1;
}

/* Retrieve a device from the list */
static struct usb_dev *devlist_at(usb_t *host, int addr)
{
	struct usb_dev *d;
	if (addr < 0 || addr > NUM_DEVICES) {
		ZF_LOGW("USB: Device not found\n");
	}

	for (d = host->devlist; d != NULL; d = d->next) {
		if (d->addr == addr) {
			return d;
		}
	}

	return NULL;
}

/************************
 **** Debug printing ****
 ************************/

#define PFIELD(d, x) printf("\t0x%-4x : %s\n", (d)->x, #x)
#define PFIELD2(d, x) printf("\t0x%-4x : %-20s | ", (d)->x, #x)
static void usb_print_descriptor(struct anon_desc *desc, int index)
{
	int type = desc->bDescriptorType;
	switch (desc->bDescriptorType) {
	case DEVICE:{
		struct device_desc d;
		memcpy(&d, desc, desc->bLength);
		printf("Device descriptor:\n");
		PFIELD(&d, bLength);
		PFIELD(&d, bDescriptorType);
		PFIELD(&d, bcdUSB);
		PFIELD2(&d, bDeviceClass);
		printf("%s\n", usb_class_get_description(d.bDeviceClass));
		PFIELD2(&d, bDeviceSubClass);
		printf("%s\n", usb_class_get_description(d.bDeviceSubClass));
		PFIELD(&d, bDeviceProtocol);
		PFIELD(&d, bMaxPacketSize0);
		PFIELD(&d, idVendor);
		PFIELD(&d, idProduct);
		PFIELD(&d, bcdDevice);
		PFIELD(&d, iManufacturer);
		PFIELD(&d, iProduct);
		PFIELD(&d, iSerialNumber);
		PFIELD(&d, bNumConfigurations);
		break;}
	case CONFIGURATION:{
		struct config_desc d;
		memcpy(&d, desc, desc->bLength);
		if (index >= 0) {
			printf("Config descriptor %d\n", index);
		} else {
			printf("Config descriptor\n");
		}
		PFIELD(&d, bLength);
		PFIELD(&d, bDescriptorType);
		PFIELD(&d, wTotalLength);
		PFIELD(&d, bNumInterfaces);
		PFIELD(&d, bConfigurationValue);
		PFIELD(&d, iConfigurationIndex);
		PFIELD2(&d, bmAttributes);
		printf("%s ", (d.bmAttributes & (1 << 6)) ?
		       "Self powered" : "");
		printf("%s ", (d.bmAttributes & (1 << 5)) ?
		       "Remote wakeup" : "");
		printf("%s ", (d.bmAttributes & (1 << 7)) ?
		       "" : "Warning: bit 7 should be set");
		printf("%s ", (d.bmAttributes & (1 << 4)) ?
		       "Warning: bit 5 should not be set" : "");
		printf("\n");
		PFIELD2(&d, bMaxPower);
		printf("%dmA\n", d.bMaxPower * 2);
		break;}
	case INTERFACE:{
		struct iface_desc d;
		memcpy(&d, desc, desc->bLength);
		if (index >= 0) {
			printf("Interface descriptor %d\n", index);
		} else {
			printf("Interface descriptor\n");
		}
		PFIELD(&d, bLength);
		PFIELD(&d, bDescriptorType);
		PFIELD(&d, bInterfaceNumber);
		PFIELD(&d, bAlternateSetting);
		PFIELD(&d, bNumEndpoints);
		PFIELD2(&d, bInterfaceClass);
		printf("%s\n", usb_class_get_description(d.bInterfaceClass));
		PFIELD2(&d, bInterfaceSubClass);
		printf("%s\n", usb_class_get_description(d.bInterfaceSubClass));
		PFIELD(&d, bInterfaceProtocol);
		PFIELD(&d, iInterface);
		break;}
	case ENDPOINT:{
		struct endpoint_desc d;
		memcpy(&d, desc, desc->bLength);
		if (index >= 0) {
			printf("Endpoint descriptor %d\n", index);
		} else {
			printf("Endpoint descriptor\n");
		}
		PFIELD(&d, bLength);
		PFIELD(&d, bDescriptorType);
		PFIELD2(&d, bEndpointAddress);
		printf("%d-", d.bEndpointAddress & 0xf);
		if (d.bmAttributes & 0x3) {
			if (d.bEndpointAddress & (1 << 7)) {
				printf("IN");
			} else {
				printf("OUT");
			}
		}
		printf("\n");
		PFIELD2(&d, bmAttributes);
		switch (d.bmAttributes & 0x3) {
		case 0:
			printf("CONTROL");
			break;
		case 1:
			printf("ISOCH");
			break;
		case 2:
			printf("BULK");
			break;
		case 3:
			printf("INT");
			break;
		}
		printf(",");
		switch ((d.bmAttributes >> 2) & 0x3) {
		case 0:
			printf("No synch");
			break;
		case 1:
			printf("Asynchronous");
			break;
		case 2:
			printf("Adaptive");
			break;
		case 3:
			printf("Synchronous");
			break;
		}
		printf(",");
		switch ((d.bmAttributes >> 4) & 0x3) {
		case 0:
			printf("DATA");
			break;
		case 1:
			printf("Feedback");
			break;
		case 2:
			printf("Implicit feedback data");
			break;
		case 3:
			printf("<Reserved>");
			break;
		}
		printf("\n");
		PFIELD2(&d, wMaxPacketSize);
		printf("%d bytes, %d xacts per uFrame\n",
		       d.wMaxPacketSize & 0x7ff,
		       ((d.wMaxPacketSize >> 11) & 0x3) + 1);
		PFIELD(&d, bInterval);
		break;}
	case DEVICE_QUALIFIER:
	case OTHER_SPEED_CONFIGURATION:
	case INTERFACE_POWER:
	case STRING:
		printf("Descriptor type %d not implemented\n", type);
		break;
		/* Class specific types */
	case HID:{
		struct hid_desc d;
		memcpy(&d, desc, desc->bLength);
		printf("HID descriptor\n");
		PFIELD(&d, bLength);
		PFIELD(&d, bDescriptorType);
		PFIELD(&d, bcdHID);
		PFIELD(&d, bCountryCode);
		PFIELD(&d, bNumDescriptors);
		PFIELD(&d, bReportDescriptorType);
		PFIELD(&d, wReportDescriptorLength);
		break;}
	default:
		printf("Unknown descriptor type %d\n", type);
	}
}

static void print_string_desc(struct string_desc *desc)
{
	if (!desc) {
		ZF_LOGF("USB: Invalid arguments\n");
	}

	for (int i = 0; i < desc->bLength - 2; i++) {
		printf("%c", desc->bString[i]);
	}
	printf("\n");
}

static void
usb_get_string_desc(struct usb_dev *udev, int index, struct string_desc *desc)
{
	int err;
	int lang;
	struct xact xact[2];
	struct usbreq *req;
	struct string_desc *sdesc;

	if (index == 0) {
		return;
	}

	/* XXX: xact allocation relies on the xact.len */
	xact[0].len = sizeof(struct usbreq);
	xact[1].len = sizeof(struct string_desc);

	/* Get memory for the request */
	err = usb_alloc_xact(udev->dman, xact,
			   sizeof(xact) / sizeof(struct xact));
	if (err) {
		ZF_LOGE("USB %d: Not enough DMA memory!\n", udev->addr);
		return;
	}

	/* Fill in the SETUP packet */
	xact[0].type = PID_SETUP;
	xact[1].type = PID_IN;
	req = xact_get_vaddr(&xact[0]);
	sdesc = (struct string_desc *)xact[1].vaddr;

	/* Get language ID */
	*req = __get_descriptor_req(STRING, 0, 0, sizeof(struct string_desc));
	err = usbdev_schedule_xact(udev, udev->ep_ctrl, xact, 2, NULL, NULL);

	if (err < 0) {
		ZF_LOGD("USB %d: USB request failed.\n", udev->addr);
		usb_destroy_xact(udev->dman, xact, 2);
		return;
	}

	lang = sdesc->bString[1] << 8 | sdesc->bString[0];

	/* Get the string descriptor */
	*req = __get_descriptor_req(STRING, index, lang,
				 sizeof(struct string_desc));
	err = usbdev_schedule_xact(udev, udev->ep_ctrl, xact, 2, NULL, NULL);

	if (err < 0) {
		ZF_LOGD("USB %d: USB request failed.\n", udev->addr);
		usb_destroy_xact(udev->dman, xact, 2);
		return;
	}

	if (desc) {
		memcpy(desc, sdesc, sdesc->bLength);
	}
	usb_destroy_xact(udev->dman, xact, 2);
}

static void print_dev(struct usb_dev *d)
{
	if (d) {
		printf("USB@%02d: 0x%04x:0x%04x | %-40s\n",
		       d->addr, d->vend_id, d->prod_id,
		       usb_class_get_description(d->class));
	}
}

static int
usb_config_print_cb(void *token, int cfg, int iface, struct anon_desc *d)
{
	uint32_t *cnt = (uint32_t *) token;
	int v;
	if (d == NULL) {
		printf("\n");
		return 0;
	} else {
		switch (d->bDescriptorType) {
		case CONFIGURATION:
			cnt[0]++;
			cnt[1] = 0;
			cnt[2] = 0;
			v = cnt[0];
			break;
		case INTERFACE:
			cnt[1]++;
			cnt[2] = 0;
			v = cnt[1];
			break;
		case ENDPOINT:
			cnt[2]++;
			v = cnt[2];
			break;
		default:
			v = -1;
			break;
		}
		usb_print_descriptor(d, v);
		return 0;
	}
}

static void usbdev_config_print(struct usb_dev *udev)
{
	struct anon_desc *desc;
	struct usbreq *req;
	struct xact xact[2];
	int ret;
	uint32_t cnt[3] = { 0, 0, 0 };

	/* Device descriptor */
	xact[0].type = PID_SETUP;
	xact[0].len = sizeof(*req);
	xact[1].type = PID_IN;
	xact[1].len = sizeof(struct device_desc);
	ret = usb_alloc_xact(udev->dman, xact, 2);
	if (ret) {
		ZF_LOGF("USB: Out of DMA memory\n");
	}
	req = xact_get_vaddr(&xact[0]);
	*req = __get_descriptor_req(DEVICE, 0, 0, xact[1].len);
	ret = usbdev_schedule_xact(udev, udev->ep_ctrl, xact, 2, NULL, NULL);
	if (ret < 0) {
		ZF_LOGF("USB: Transaction error\n");
	}
	desc = (struct anon_desc *)xact_get_vaddr(&xact[1]);
	usb_print_descriptor(desc, -1);
	usb_destroy_xact(udev->dman, xact, sizeof(xact) / sizeof(*xact));
	/* Print config descriptors */
	usbdev_parse_config(udev, usb_config_print_cb, cnt);
}

static void print_dev_graph(usb_t * host, struct usb_dev *d, int depth)
{
	int i;
	if (d != NULL) {
		for (i = 0; i < depth; i++) {
			printf("    ");
		}
		print_dev(d);
	}
	/* Search for connected devices */
	for (i = 1; i < NUM_DEVICES; i++) {
		struct usb_dev *d2;
		d2 = devlist_at(host, i);
		if (d2 && d2->hub == d) {
			print_dev_graph(host, d2, depth + 1);
		}
	}
}

static int
parse_config(struct usb_dev *udev, struct anon_desc *d, int tot_len,
	     usb_config_cb cb, void *t)
{
	int cfg = -1;
	int iface = -1;
	struct anon_desc *usrd = NULL;
	struct endpoint_desc *edsc;
	struct endpoint *ep;
	int buf_len = 0;
	int cur_len = 0;
	int err = 0;
	int cnt = 0;

	/*
	 * FIXME: Not all devices report the total length of its descriptors
	 * correctly. We should always check the details of each descriptor.
	 */
	while (cur_len < tot_len) {
		if (!d->bLength) {
			break;
		}
		/* Copy in for the sake of alignment */
		if (buf_len < d->bLength) {
			if (usrd) {
				usb_free(usrd);
			}
			usrd = usb_malloc(d->bLength);
			if (usrd == NULL) {
				ZF_LOGE("USB: Out of memory\n");
				err = 1;
				break;
			}
			buf_len = d->bLength;
		}
		memcpy(usrd, d, d->bLength);
		/* Update our config/iface */
		switch (d->bDescriptorType) {
		case CONFIGURATION:
			cfg = ((struct config_desc *)usrd)->bConfigurationValue;
			iface = -1;
			break;
		case INTERFACE:
			iface = ((struct iface_desc *)usrd)->bInterfaceNumber;
			/* Device class defined at interface level */
			if (!udev->class) {
				udev->class =
				    ((struct iface_desc *)
				     usrd)->bInterfaceClass;
			}
			break;
		case ENDPOINT:
			edsc = (struct endpoint_desc *)usrd;
			ep = usb_malloc(sizeof(struct endpoint));
			if (!ep) {
				ZF_LOGF("Out of memory\n");
			}

			/* Fill in the endpoint structure, USB standard(9.6.6) */
			ep->type = edsc->bmAttributes & 0x3;
			ep->dir = edsc->bEndpointAddress >> 0x7;
			ep->num = edsc->bEndpointAddress & 0xF;
			ep->max_pkt = edsc->wMaxPacketSize;
			ep->interval = edsc->bInterval;

			udev->ep[cnt++] = ep;
			break;
		default:
			break;
		}
		/* Send to caller */
		if (cb && cb(t, cfg, iface, usrd)) {
			break;
		}
		/* Next */
		cur_len += d->bLength;
		d = (struct anon_desc *)((uintptr_t) d + d->bLength);
	}

	/* Report end of list */
	if (cb && cur_len == tot_len) {
		cb(t, cfg, iface, NULL);
	}
	/* Clean up */
	if (usrd == NULL) {
		usb_free(usrd);
	}
	return err;
}

static int
usb_new_device_with_host(struct usb_dev *hub, usb_t * host, int port,
			 enum usb_speed speed, struct usb_dev **d)
{
	struct usb_dev *udev = NULL;
	struct usb_dev *parent = NULL, *child = NULL;
	struct usbreq *req;
	struct device_desc *d_desc;
	struct string_desc s_desc;
	struct xact xact[2];
	int addr = 0;
	int err;

	ZF_LOGD("USB: New USB device!\n");
	udev = (struct usb_dev*)usb_malloc(sizeof(*udev));
	if (!udev) {
		ZF_LOGE("USB: No heap memory for new USB device\n");
		return -1;
	}
	udev->addr = 0;
	udev->tt_addr = 0;
	udev->tt_port = 0;
	udev->connect = NULL;
	udev->disconnect = NULL;
	udev->dev_data = NULL;
	udev->hub = hub;
	udev->port = port;
	udev->speed = speed;
	udev->host = host;
	udev->dman = host->hdev.dman;

	/*
	 * Work out the TT hub for full/low speed devices.
	 * Assuming all high speed hubs have TT.
	 */
	if (speed != USBSPEED_HIGH) {
		parent = hub;
		child = udev;
		while (parent) {
			if (parent->speed == USBSPEED_HIGH) {
				udev->tt_addr = parent->addr;
				udev->tt_port = child->port;
				break;
			} else {
				child = parent;
				parent = parent->hub;
			}
		}
	}

	/*
	 * Allocate control endpoint
	 * Every device should have one control endpoint, the endpoint number is
	 * always zero and we initialize the maximum packet size to 8 for sending
	 * the very first request.
	 */
	udev->ep_ctrl = (struct endpoint *)usb_malloc(sizeof(struct endpoint));
	if (!udev->ep_ctrl) {
		ZF_LOGE("USB: No heap memory for control endpoint\n");
		usb_free(udev);
		udev = NULL;
		return -1;
	}
	udev->ep_ctrl->type = EP_CONTROL;
	udev->ep_ctrl->num = 0;
	udev->ep_ctrl->max_pkt = 8;

	xact[0].type = PID_SETUP;
	xact[0].len = sizeof(*req);
	xact[1].type = PID_IN;
	xact[1].len = sizeof(*d_desc);
	err = usb_alloc_xact(udev->dman, xact, 2);
	if (err) {
		ZF_LOGE("USB: No DMA memory for new USB device\n");
		usb_free(udev);
		udev = NULL;
		return -1;
	}
	req = xact_get_vaddr(&xact[0]);
	d_desc = xact_get_vaddr(&xact[1]);

	/* USB transactions are O(n) when trying to bind a driver.
	 * This is a good time to at least cache
	 * a) Max packet size for EP 0
	 * b) product and vendor ID
	 * c) device class
	 */
	ZF_LOGD("USB: Determining maximum packet size on the control endpoint\n");
	/*
	 * We need the value of bMaxPacketSize in order to request
	 * the bMaxPacketSize. A work around to this circular
	 * dependency is to set the maximum packet size to 8 and
	 * limit the size of our packets to prevent splitting until
	 * we know what the correct value is NOTE: High speed
	 * devices must always have a MaxPacketSize of 64 on the
	 * control endpoint (see USB spec) but we do not consider
	 * special cases.
	 */
	xact[1].len = 8;
	*req = __new_desc_req(DEVICE, 8);
	err = usbdev_schedule_xact(udev, udev->ep_ctrl, xact, 2, NULL, NULL);
	if (err < 0) {
		usb_destroy_xact(udev->dman, xact, 2);
		usb_free(udev);
		udev = NULL;
		ZF_LOGE("USB: Transaction error");
		return -1;
	}

	udev->ep_ctrl->max_pkt = d_desc->bMaxPacketSize0;

	/* Find the next available address */
	addr = devlist_insert(udev);
	if (addr < 0) {
		ZF_LOGE("USB: Too many devices\n");
		usb_destroy_xact(udev->dman, xact,
				 sizeof(xact) / sizeof(*xact));
		usb_free(udev);
		udev = NULL;
		return -1;
	}

	/* Set the address */
	*req = __new_address_req(addr);
	ZF_LOGD("USB: Setting address to %d\n", addr);
	err = usbdev_schedule_xact(udev, udev->ep_ctrl, xact, 1, NULL, NULL);
	if (err < 0) {
		usb_destroy_xact(udev->dman, xact, 2);
		usb_free(udev);
		udev = NULL;
		return -1;
	}

	/* Device has 2ms to start responding to new address */
	ps_mdelay(2);
	udev->addr = addr;

	/* All settled, start processing standard USB descriptors */
	ZF_LOGD("USB %d: Retrieving device descriptor\n", udev->addr);
	xact[1].len = sizeof(*d_desc);
	*req = __new_desc_req(DEVICE, sizeof(*d_desc));
	err = usbdev_schedule_xact(udev, udev->ep_ctrl, xact, 2, NULL, NULL);
	if (err < 0) {
		usb_destroy_xact(udev->dman, xact, 2);
		usb_free(udev);
		udev = NULL;
		return -1;
	}

	udev->prod_id = d_desc->idProduct;
	udev->vend_id = d_desc->idVendor;
	udev->class = d_desc->bDeviceClass;
	printf("USB %d: idVendor  0x%04x | ", udev->addr, udev->vend_id);
	if (d_desc->iManufacturer) {
		usb_get_string_desc(udev, d_desc->iManufacturer, &s_desc);
		print_string_desc(&s_desc);
	} else {
		printf("\n");
	}
	printf("USB %d: idProduct 0x%04x | ", udev->addr, udev->prod_id);
	if (d_desc->iProduct) {
		usb_get_string_desc(udev, d_desc->iProduct, &s_desc);
		print_string_desc(&s_desc);
	} else {
		printf("\n");
	}

	*d = udev;
	usb_destroy_xact(udev->dman, xact, sizeof(xact) / sizeof(*xact));

	return 0;
}

/****************************
 **** Exported functions ****
 ****************************/
ps_malloc_ops_t *ps_malloc_ops = NULL;
int
usb_init(enum usb_host_id id, ps_io_ops_t * ioops, ps_mutex_ops_t * sync,
	 usb_t * host)
{
	usb_hub_t hub;
	struct usb_dev *udev;
	int err;

	ps_malloc_ops = &ioops->malloc_ops;

	/* Pre-fill the host structure */
	devlist_init(host);

	err = usb_host_init(id, ioops, sync, &host->hdev);
	if (err) {
		ZF_LOGE("USB: Platform error\n");
		return -1;
	}
	err = usb_new_device_with_host(NULL, host, 1, 0, &udev);
	if (err) {
		ZF_LOGE("USB: Host error\n");
		return -1;
	}

	err = usb_hub_driver_bind(udev, &hub);
	if (err) {
		ZF_LOGE("USB: Failed to bind a hub");
		return -1;
	}

	return 0;
}

int usb_new_device(usb_dev_t *hub, int port, enum usb_speed speed, usb_dev_t **d)
{
	return usb_new_device_with_host(hub, hub->host, port, speed, d);
}

usb_dev_t *usb_get_device(usb_t * host, int addr)
{
	if (addr <= 0 || addr >= NUM_DEVICES) {
		return NULL;
	} else {
		return devlist_at(host, addr);
	}
}

/*
 * Parsing standard USB descriptors.
 * We don't support multiple configurations, if the device has more than one
 * configurations, the first one will be activated.
 */
int usbdev_parse_config(usb_dev_t *udev, usb_config_cb cb, void *t)
{
	struct xact xact[2];
	struct usbreq *req;
	struct config_desc *cd;
	struct anon_desc *d;
	int tot_len;
	int err;

	/* First read to find the size of the descriptor table */
	xact[0].len = sizeof(*req);
	xact[0].type = PID_SETUP;
	xact[1].len = sizeof(*cd);
	xact[1].type = PID_IN;
	err = usb_alloc_xact(udev->dman, xact, 2);
	if (err) {
		ZF_LOGE("USB %d: Out of DMA memory", udev->addr);
		return -1;
	}
	req = xact_get_vaddr(&xact[0]);
	cd = xact_get_vaddr(&xact[1]);
	*req = __get_descriptor_req(CONFIGURATION, 0, 0, xact[1].len);
	err = usbdev_schedule_xact(udev, udev->ep_ctrl, xact, 2, NULL, NULL);
	if (err < 0) {
		usb_destroy_xact(udev->dman, xact, 2);
		return -1;
	}
	tot_len = cd->wTotalLength;

	/* Some devices need a pause during initialization */
	ps_mdelay(100);

	/* Next read for the entire descriptor table */
	xact[0].len = sizeof(*req);
	xact[0].type = PID_SETUP;
	xact[1].len = tot_len;
	xact[1].type = PID_IN;
	err = usb_alloc_xact(udev->dman, xact, 2);
	if (err) {
		ZF_LOGE("USB %d: Out of DMA memory", udev->addr);
		return -1;
	}
	req = xact_get_vaddr(&xact[0]);
	d = xact_get_vaddr(&xact[1]);
	*req = __get_descriptor_req(CONFIGURATION, 0, 0, tot_len);
	err = usbdev_schedule_xact(udev, udev->ep_ctrl, xact, 2, NULL, NULL);
	if (err < 0) {
		usb_destroy_xact(udev->dman, xact,
				 sizeof(xact) / sizeof(*xact));
		return -1;
	}
	/* Now loop through descriptors */
	err = parse_config(udev, d, tot_len, cb, t);
	usb_destroy_xact(udev->dman, xact, sizeof(xact) / sizeof(*xact));
	return err;
}

void usbdev_disconnect(usb_dev_t *udev)
{
	UNUSED int err;
	usb_host_t *hdev;
	usb_hub_t hub;
	int cnt = 0;

	if (!udev || !udev->host) {
		ZF_LOGF("USB: Invalid arguments\n");
	}
	ZF_LOGD("USB %d: Disconnecting\n", udev->addr);

	hdev = &udev->host->hdev;
	if (udev->disconnect) {
		ZF_LOGD("USB %d: calling device disconnect 0x%x\n",
		       udev->addr, (uint32_t) udev->disconnect);
		udev->disconnect(udev);
	}

	/*
	 * Check if we are disconnecting a Hub, in which case we also need to
	 * disconnect all devices that connect to it.
	 */
	if (udev->class == USB_CLASS_HUB) {
		hub = (usb_hub_t) udev->dev_data;
		for (int i = 0; i < hub->nports; i++) {
			if (hub->port[i].udev) {
				usbdev_disconnect(hub->port[i].udev);
			}
		}
	}

	/* Remove control endpoint */
	err = hdev->cancel_xact(hdev, udev->ep_ctrl);

	/* Remove all other endpoints */
	while (udev->ep[cnt] && cnt < USB_MAX_EPS) {
		err = hdev->cancel_xact(hdev, udev->ep[cnt]);
		cnt++;
	}

	if (err) {
		ZF_LOGW("USB %d: Failed to cancel some of the transactions\n",
			udev->addr);
	}

	(void)hdev;
	devlist_remove(udev);
	/* destroy it */
	usb_free(udev->ep_ctrl);
	for (int i = 0; i < USB_MAX_EPS; i++) {
		if (udev->ep[i]) {
			usb_free(udev->ep[i]);
		}
	}
	usb_free(udev);
}

void usb_handle_irq(usb_t *host)
{
	usb_host_t *hdev;

	if (!host) {
		ZF_LOGF("Invalid arguments\n");
	}

	hdev = &host->hdev;
	hdev->handle_irq(hdev);
}

int
usbdev_schedule_xact(usb_dev_t *udev, struct endpoint *ep, struct xact *xact,
		     int nxact, usb_cb_t cb, void *token)
{
	int err;
	usb_host_t *hdev;
	uint8_t hub_addr;

	if (!udev) {
		ZF_LOGF("Invalid arguments\n");
	}

	hdev = &udev->host->hdev;
	if (udev->hub) {
		hub_addr = udev->tt_addr;
	} else {
		hub_addr = -1;
	}
	err =
	    usb_hcd_schedule(hdev, udev->addr, hub_addr, udev->tt_port,
			     udev->speed, ep, xact, nxact, cb, token);
	return err;
}

void usb_lsusb(usb_t * host, int v)
{
	int i;
	printf("\n");
	if (v == 0) {
		/* Print a simple list */
		for (i = 1; i < NUM_DEVICES; i++) {
			struct usb_dev *d = devlist_at(host, i);
			print_dev(d);
		}
	} else {
		/* Print by connection */
		print_dev_graph(host, NULL, -1);
	}
	/* Print out all the configs */
	if (v > 1) {
		printf("\n");
		for (i = 1; i < NUM_DEVICES; i++) {
			struct usb_dev *d = devlist_at(host, i);
			if (d) {
				print_dev(d);
				usbdev_config_print(d);
			}
		}
	}
	printf("\n");
}

void usb_probe_device(usb_dev_t *dev)
{
	usbdev_config_print(dev);
}

int usb_alloc_xact(ps_dma_man_t * dman, struct xact *xact, int nxact)
{
	int i;
	for (i = 0; i < nxact; i++) {
		if (xact[i].len) {
			xact[i].vaddr =
			    ps_dma_alloc_pinned(dman, xact[i].len, 32, 0,
						PS_MEM_NORMAL, &xact[i].paddr);
			if (xact[i].vaddr == NULL) {
				usb_destroy_xact(dman, xact, i);
				return -1;
			}
		} else {
			xact[i].vaddr = NULL;
		}
	}
	return 0;
}

void usb_destroy_xact(ps_dma_man_t * dman, struct xact *xact, int nxact)
{
	while (nxact-- > 0) {
		if (xact[nxact].vaddr) {
			ps_dma_free_pinned(dman, xact[nxact].vaddr,
					   xact[nxact].len);
		}
	}
}

enum usb_class usbdev_get_class(usb_dev_t *dev)
{
	return dev->class;
}
