/*
 * Linux host USB redirector
 *
 * Copyright (c) 2005 Fabrice Bellard
 *
 * Copyright (c) 2008 Max Krasnyansky
 *      Support for host device auto connect & disconnect
 *      Major rewrite to support fully async operation
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include "qemu-common.h"
#include "qemu-timer.h"
#include "console.h"

#if defined(__linux__)
#include <dirent.h>
#include <sys/ioctl.h>
#include <signal.h>

#include <linux/usbdevice_fs.h>
#include <linux/version.h>
#include "hw/usb.h"

/* We redefine it to avoid version problems */
struct usb_ctrltransfer {
    uint8_t  bRequestType;
    uint8_t  bRequest;
    uint16_t wValue;
    uint16_t wIndex;
    uint16_t wLength;
    uint32_t timeout;
    void *data;
};

struct usb_ctrlrequest {
    uint8_t bRequestType;
    uint8_t bRequest;
    uint16_t wValue;
    uint16_t wIndex;
    uint16_t wLength;
};

typedef int USBScanFunc(void *opaque, int bus_num, int addr, int class_id,
                        int vendor_id, int product_id,
                        const char *product_name, int speed);
static int usb_host_find_device(int *pbus_num, int *paddr,
                                char *product_name, int product_name_size,
                                const char *devname);
//#define DEBUG

#ifdef DEBUG
#define dprintf printf
#else
#define dprintf(...)
#endif

#define USBDEVFS_PATH "/proc/bus/usb"
#define PRODUCT_NAME_SZ 32
#define MAX_ENDPOINTS 16

/* endpoint association data */
struct endp_data {
    uint8_t type;
    uint8_t halted;
};

enum {
    CTRL_STATE_IDLE = 0,
    CTRL_STATE_SETUP,
    CTRL_STATE_DATA,
    CTRL_STATE_ACK
};

/*
 * Control transfer state.
 * Note that 'buffer' _must_ follow 'req' field because 
 * we need contigious buffer when we submit control URB.
 */ 
struct ctrl_struct {
    uint16_t len;
    uint16_t offset;
    uint8_t  state;
    struct   usb_ctrlrequest req;
    uint8_t  buffer[1024];
};

typedef struct USBHostDevice {
    USBDevice dev;
    int       fd;

    uint8_t   descr[1024];
    int       descr_len;
    int       configuration;
    int       ninterfaces;
    int       closing;

    struct ctrl_struct ctrl;
    struct endp_data endp_table[MAX_ENDPOINTS];

    /* Host side address */
    int bus_num;
    int addr;

    struct USBHostDevice *next;
} USBHostDevice;

static int is_isoc(USBHostDevice *s, int ep)
{
    return s->endp_table[ep - 1].type == USBDEVFS_URB_TYPE_ISO;
}

static int is_halted(USBHostDevice *s, int ep)
{
    return s->endp_table[ep - 1].halted;
}

static void clear_halt(USBHostDevice *s, int ep)
{
    s->endp_table[ep - 1].halted = 0;
}

static void set_halt(USBHostDevice *s, int ep)
{
    s->endp_table[ep - 1].halted = 1;
}

static USBHostDevice *hostdev_list;

static void hostdev_link(USBHostDevice *dev)
{
    dev->next = hostdev_list;
    hostdev_list = dev;
}

static void hostdev_unlink(USBHostDevice *dev)
{
    USBHostDevice *pdev = hostdev_list;
    USBHostDevice **prev = &hostdev_list;

    while (pdev) {
	if (pdev == dev) {
            *prev = dev->next;
            return;
        }

        prev = &pdev->next;
        pdev = pdev->next;
    }
}

static USBHostDevice *hostdev_find(int bus_num, int addr)
{
    USBHostDevice *s = hostdev_list;
    while (s) {
        if (s->bus_num == bus_num && s->addr == addr)
            return s;
        s = s->next;
    }
    return NULL;
}

/* 
 * Async URB state.
 * We always allocate one isoc descriptor even for bulk transfers
 * to simplify allocation and casts. 
 */
typedef struct AsyncURB
{
    struct usbdevfs_urb urb;
    struct usbdevfs_iso_packet_desc isocpd;

    USBPacket     *packet;
    USBHostDevice *hdev;
} AsyncURB;

static AsyncURB *async_alloc(void)
{
    return (AsyncURB *) qemu_mallocz(sizeof(AsyncURB));
}

static void async_free(AsyncURB *aurb)
{
    qemu_free(aurb);
}

static void async_complete_ctrl(USBHostDevice *s, USBPacket *p)
{
    switch(s->ctrl.state) {
    case CTRL_STATE_SETUP:
        if (p->len < s->ctrl.len)
            s->ctrl.len = p->len;
        s->ctrl.state = CTRL_STATE_DATA;
        p->len = 8;
        break;

    case CTRL_STATE_ACK:
        s->ctrl.state = CTRL_STATE_IDLE;
        p->len = 0;
        break;

    default:
        break;
    }
}

static void async_complete(void *opaque)
{
    USBHostDevice *s = opaque;
    AsyncURB *aurb;

    while (1) {
    	USBPacket *p;

	int r = ioctl(s->fd, USBDEVFS_REAPURBNDELAY, &aurb);
        if (r < 0) {
            if (errno == EAGAIN)
                return;

            if (errno == ENODEV && !s->closing) {
                printf("husb: device %d.%d disconnected\n", s->bus_num, s->addr);
	        usb_device_del_addr(0, s->dev.addr);
                return;
            }

            dprintf("husb: async. reap urb failed errno %d\n", errno);
            return;
        }

        p = aurb->packet;

	dprintf("husb: async completed. aurb %p status %d alen %d\n", 
                aurb, aurb->urb.status, aurb->urb.actual_length);

	if (p) {
            switch (aurb->urb.status) {
            case 0:
                p->len = aurb->urb.actual_length;
                if (aurb->urb.type == USBDEVFS_URB_TYPE_CONTROL)
                    async_complete_ctrl(s, p);
                break;

            case -EPIPE:
                set_halt(s, p->devep);
                /* fall through */
            default:
                p->len = USB_RET_NAK;
                break;
            }

            usb_packet_complete(p);
	}

        async_free(aurb);
    }
}

static void async_cancel(USBPacket *unused, void *opaque)
{
    AsyncURB *aurb = opaque;
    USBHostDevice *s = aurb->hdev;

    dprintf("husb: async cancel. aurb %p\n", aurb);

    /* Mark it as dead (see async_complete above) */
    aurb->packet = NULL;

    int r = ioctl(s->fd, USBDEVFS_DISCARDURB, aurb);
    if (r < 0) {
        dprintf("husb: async. discard urb failed errno %d\n", errno);
    }
}

static int usb_host_claim_interfaces(USBHostDevice *dev, int configuration)
{
    int dev_descr_len, config_descr_len;
    int interface, nb_interfaces, nb_configurations;
    int ret, i;

    if (configuration == 0) /* address state - ignore */
        return 1;

    dprintf("husb: claiming interfaces. config %d\n", configuration);

    i = 0;
    dev_descr_len = dev->descr[0];
    if (dev_descr_len > dev->descr_len)
        goto fail;
    nb_configurations = dev->descr[17];

    i += dev_descr_len;
    while (i < dev->descr_len) {
        dprintf("husb: i is %d, descr_len is %d, dl %d, dt %d\n", i, dev->descr_len,
               dev->descr[i], dev->descr[i+1]);

        if (dev->descr[i+1] != USB_DT_CONFIG) {
            i += dev->descr[i];
            continue;
        }
        config_descr_len = dev->descr[i];

	printf("husb: config #%d need %d\n", dev->descr[i + 5], configuration); 

        if (configuration < 0 || configuration == dev->descr[i + 5]) {
            configuration = dev->descr[i + 5];
            break;
        }

        i += config_descr_len;
    }

    if (i >= dev->descr_len) {
        fprintf(stderr, "husb: update iface failed. no matching configuration\n");
        goto fail;
    }
    nb_interfaces = dev->descr[i + 4];

#ifdef USBDEVFS_DISCONNECT
    /* earlier Linux 2.4 do not support that */
    {
        struct usbdevfs_ioctl ctrl;
        for (interface = 0; interface < nb_interfaces; interface++) {
            ctrl.ioctl_code = USBDEVFS_DISCONNECT;
            ctrl.ifno = interface;
            ret = ioctl(dev->fd, USBDEVFS_IOCTL, &ctrl);
            if (ret < 0 && errno != ENODATA) {
                perror("USBDEVFS_DISCONNECT");
                goto fail;
            }
        }
    }
#endif

    /* XXX: only grab if all interfaces are free */
    for (interface = 0; interface < nb_interfaces; interface++) {
        ret = ioctl(dev->fd, USBDEVFS_CLAIMINTERFACE, &interface);
        if (ret < 0) {
            if (errno == EBUSY) {
                printf("husb: update iface. device already grabbed\n");
            } else {
                perror("husb: failed to claim interface");
            }
        fail:
            return 0;
        }
    }

    printf("husb: %d interfaces claimed for configuration %d\n",
           nb_interfaces, configuration);

    dev->ninterfaces   = nb_interfaces;
    dev->configuration = configuration;
    return 1;
}

static int usb_host_release_interfaces(USBHostDevice *s)
{
    int ret, i;

    dprintf("husb: releasing interfaces\n");

    for (i = 0; i < s->ninterfaces; i++) {
        ret = ioctl(s->fd, USBDEVFS_RELEASEINTERFACE, &i);
        if (ret < 0) {
            perror("husb: failed to release interface");
            return 0;
        }
    }

    return 1;
}

static void usb_host_handle_reset(USBDevice *dev)
{
    USBHostDevice *s = (USBHostDevice *) dev;

    dprintf("husb: reset device %u.%u\n", s->bus_num, s->addr);

    ioctl(s->fd, USBDEVFS_RESET);

    usb_host_claim_interfaces(s, s->configuration);
}

static void usb_host_handle_destroy(USBDevice *dev)
{
    USBHostDevice *s = (USBHostDevice *)dev;

    s->closing = 1;

    qemu_set_fd_handler(s->fd, NULL, NULL, NULL);

    hostdev_unlink(s);

    async_complete(s);

    if (s->fd >= 0)
        close(s->fd);

    qemu_free(s);
}

static int usb_linux_update_endp_table(USBHostDevice *s);

static int usb_host_handle_data(USBHostDevice *s, USBPacket *p)
{
    struct usbdevfs_urb *urb;
    AsyncURB *aurb;
    int ret;

    aurb = async_alloc();
    if (!aurb) {
        dprintf("husb: async malloc failed\n");
        return USB_RET_NAK;
    }
    aurb->hdev   = s;
    aurb->packet = p;

    urb = &aurb->urb;

    if (p->pid == USB_TOKEN_IN)
    	urb->endpoint = p->devep | 0x80;
    else
    	urb->endpoint = p->devep;

    if (is_halted(s, p->devep)) {
	ret = ioctl(s->fd, USBDEVFS_CLEAR_HALT, &urb->endpoint);
        if (ret < 0) {
            dprintf("husb: failed to clear halt. ep 0x%x errno %d\n", 
                   urb->endpoint, errno);
            return USB_RET_NAK;
        }
        clear_halt(s, p->devep);
    }

    urb->buffer        = p->data;
    urb->buffer_length = p->len;

    if (is_isoc(s, p->devep)) {
        /* Setup ISOC transfer */
        urb->type     = USBDEVFS_URB_TYPE_ISO;
        urb->flags    = USBDEVFS_URB_ISO_ASAP;
        urb->number_of_packets = 1;
        urb->iso_frame_desc[0].length = p->len;
    } else {
        /* Setup bulk transfer */
        urb->type     = USBDEVFS_URB_TYPE_BULK;
    }

    urb->usercontext = s;

    ret = ioctl(s->fd, USBDEVFS_SUBMITURB, urb);

    dprintf("husb: data submit. ep 0x%x len %u aurb %p\n", urb->endpoint, p->len, aurb);

    if (ret < 0) {
        dprintf("husb: submit failed. errno %d\n", errno);
        async_free(aurb);

        switch(errno) {
        case ETIMEDOUT:
            return USB_RET_NAK;
        case EPIPE:
        default:
            return USB_RET_STALL;
        }
    }

    usb_defer_packet(p, async_cancel, aurb);
    return USB_RET_ASYNC;
}

static int ctrl_error(void)
{
    if (errno == ETIMEDOUT)
        return USB_RET_NAK;
    else 
        return USB_RET_STALL;
}

static int usb_host_set_address(USBHostDevice *s, int addr)
{
    dprintf("husb: ctrl set addr %u\n", addr);
    s->dev.addr = addr;
    return 0;
}

static int usb_host_set_config(USBHostDevice *s, int config)
{
    usb_host_release_interfaces(s);

    int ret = ioctl(s->fd, USBDEVFS_SETCONFIGURATION, &config);
 
    dprintf("husb: ctrl set config %d ret %d errno %d\n", config, ret, errno);
    
    if (ret < 0)
        return ctrl_error();
 
    usb_host_claim_interfaces(s, config);
    return 0;
}

static int usb_host_set_interface(USBHostDevice *s, int iface, int alt)
{
    struct usbdevfs_setinterface si;
    int ret;

    si.interface  = iface;
    si.altsetting = alt;
    ret = ioctl(s->fd, USBDEVFS_SETINTERFACE, &si);
    
    dprintf("husb: ctrl set iface %d altset %d ret %d errno %d\n", 
    	iface, alt, ret, errno);
    
    if (ret < 0)
        return ctrl_error();

    usb_linux_update_endp_table(s);
    return 0;
}

static int usb_host_handle_control(USBHostDevice *s, USBPacket *p)
{
    struct usbdevfs_urb *urb;
    AsyncURB *aurb;
    int ret, value, index;

    /* 
     * Process certain standard device requests.
     * These are infrequent and are processed synchronously.
     */
    value = le16_to_cpu(s->ctrl.req.wValue);
    index = le16_to_cpu(s->ctrl.req.wIndex);

    dprintf("husb: ctrl type 0x%x req 0x%x val 0x%x index %u len %u\n",
        s->ctrl.req.bRequestType, s->ctrl.req.bRequest, value, index, 
        s->ctrl.len);

    if (s->ctrl.req.bRequestType == 0) {
        switch (s->ctrl.req.bRequest) {
        case USB_REQ_SET_ADDRESS:
            return usb_host_set_address(s, value);

        case USB_REQ_SET_CONFIGURATION:
            return usb_host_set_config(s, value & 0xff);
        }
    }

    if (s->ctrl.req.bRequestType == 1 &&
                  s->ctrl.req.bRequest == USB_REQ_SET_INTERFACE)
        return usb_host_set_interface(s, index, value);

    /* The rest are asynchronous */

    aurb = async_alloc();
    if (!aurb) {
        dprintf("husb: async malloc failed\n");
        return USB_RET_NAK;
    }
    aurb->hdev   = s;
    aurb->packet = p;

    /* 
     * Setup ctrl transfer.
     *
     * s->ctrl is layed out such that data buffer immediately follows
     * 'req' struct which is exactly what usbdevfs expects.
     */ 
    urb = &aurb->urb;

    urb->type     = USBDEVFS_URB_TYPE_CONTROL;
    urb->endpoint = p->devep;

    urb->buffer        = &s->ctrl.req;
    urb->buffer_length = 8 + s->ctrl.len;

    urb->usercontext = s;

    ret = ioctl(s->fd, USBDEVFS_SUBMITURB, urb);

    dprintf("husb: submit ctrl. len %u aurb %p\n", urb->buffer_length, aurb);

    if (ret < 0) {
        dprintf("husb: submit failed. errno %d\n", errno);
        async_free(aurb);

        switch(errno) {
        case ETIMEDOUT:
            return USB_RET_NAK;
        case EPIPE:
        default:
            return USB_RET_STALL;
        }
    }

    usb_defer_packet(p, async_cancel, aurb);
    return USB_RET_ASYNC;
}

static int do_token_setup(USBDevice *dev, USBPacket *p)
{
    USBHostDevice *s = (USBHostDevice *) dev;
    int ret = 0;

    if (p->len != 8)
        return USB_RET_STALL;
 
    memcpy(&s->ctrl.req, p->data, 8);
    s->ctrl.len    = le16_to_cpu(s->ctrl.req.wLength);
    s->ctrl.offset = 0;
    s->ctrl.state  = CTRL_STATE_SETUP;

    if (s->ctrl.req.bRequestType & USB_DIR_IN) {
        ret = usb_host_handle_control(s, p);
        if (ret < 0)
            return ret;

        if (ret < s->ctrl.len)
            s->ctrl.len = ret;
        s->ctrl.state = CTRL_STATE_DATA;
    } else {
        if (s->ctrl.len == 0)
            s->ctrl.state = CTRL_STATE_ACK;
        else
            s->ctrl.state = CTRL_STATE_DATA;
    }

    return ret;
}

static int do_token_in(USBDevice *dev, USBPacket *p)
{
    USBHostDevice *s = (USBHostDevice *) dev;
    int ret = 0;

    if (p->devep != 0)
        return usb_host_handle_data(s, p);

    switch(s->ctrl.state) {
    case CTRL_STATE_ACK:
        if (!(s->ctrl.req.bRequestType & USB_DIR_IN)) {
            ret = usb_host_handle_control(s, p);
            if (ret == USB_RET_ASYNC)
                return USB_RET_ASYNC;

            s->ctrl.state = CTRL_STATE_IDLE;
            return ret > 0 ? 0 : ret;
        }

        return 0;

    case CTRL_STATE_DATA:
        if (s->ctrl.req.bRequestType & USB_DIR_IN) {
            int len = s->ctrl.len - s->ctrl.offset;
            if (len > p->len)
                len = p->len;
            memcpy(p->data, s->ctrl.buffer + s->ctrl.offset, len);
            s->ctrl.offset += len;
            if (s->ctrl.offset >= s->ctrl.len)
                s->ctrl.state = CTRL_STATE_ACK;
            return len;
        }

        s->ctrl.state = CTRL_STATE_IDLE;
        return USB_RET_STALL;

    default:
        return USB_RET_STALL;
    }
}

static int do_token_out(USBDevice *dev, USBPacket *p)
{
    USBHostDevice *s = (USBHostDevice *) dev;

    if (p->devep != 0)
        return usb_host_handle_data(s, p);

    switch(s->ctrl.state) {
    case CTRL_STATE_ACK:
        if (s->ctrl.req.bRequestType & USB_DIR_IN) {
            s->ctrl.state = CTRL_STATE_IDLE;
            /* transfer OK */
        } else {
            /* ignore additional output */
        }
        return 0;

    case CTRL_STATE_DATA:
        if (!(s->ctrl.req.bRequestType & USB_DIR_IN)) {
            int len = s->ctrl.len - s->ctrl.offset;
            if (len > p->len)
                len = p->len;
            memcpy(s->ctrl.buffer + s->ctrl.offset, p->data, len);
            s->ctrl.offset += len;
            if (s->ctrl.offset >= s->ctrl.len)
                s->ctrl.state = CTRL_STATE_ACK;
            return len;
        }

        s->ctrl.state = CTRL_STATE_IDLE;
        return USB_RET_STALL;

    default:
        return USB_RET_STALL;
    }
}

/*
 * Packet handler.
 * Called by the HC (host controller).
 *
 * Returns length of the transaction or one of the USB_RET_XXX codes.
 */
static int usb_host_handle_packet(USBDevice *s, USBPacket *p)
{
    switch(p->pid) {
    case USB_MSG_ATTACH:
        s->state = USB_STATE_ATTACHED;
        return 0;

    case USB_MSG_DETACH:
        s->state = USB_STATE_NOTATTACHED;
        return 0;

    case USB_MSG_RESET:
        s->remote_wakeup = 0;
        s->addr = 0;
        s->state = USB_STATE_DEFAULT;
        s->handle_reset(s);
        return 0;
    }

    /* Rest of the PIDs must match our address */
    if (s->state < USB_STATE_DEFAULT || p->devaddr != s->addr)
        return USB_RET_NODEV;

    switch (p->pid) {
    case USB_TOKEN_SETUP:
        return do_token_setup(s, p);

    case USB_TOKEN_IN:
        return do_token_in(s, p);

    case USB_TOKEN_OUT:
        return do_token_out(s, p);
 
    default:
        return USB_RET_STALL;
    }
}

/* returns 1 on problem encountered or 0 for success */
static int usb_linux_update_endp_table(USBHostDevice *s)
{
    uint8_t *descriptors;
    uint8_t devep, type, configuration, alt_interface;
    struct usbdevfs_ctrltransfer ct;
    int interface, ret, length, i;

    ct.bRequestType = USB_DIR_IN;
    ct.bRequest = USB_REQ_GET_CONFIGURATION;
    ct.wValue = 0;
    ct.wIndex = 0;
    ct.wLength = 1;
    ct.data = &configuration;
    ct.timeout = 50;

    ret = ioctl(s->fd, USBDEVFS_CONTROL, &ct);
    if (ret < 0) {
        perror("usb_linux_update_endp_table");
        return 1;
    }

    /* in address state */
    if (configuration == 0)
        return 1;

    /* get the desired configuration, interface, and endpoint descriptors
     * from device description */
    descriptors = &s->descr[18];
    length = s->descr_len - 18;
    i = 0;

    if (descriptors[i + 1] != USB_DT_CONFIG ||
        descriptors[i + 5] != configuration) {
        dprintf("invalid descriptor data - configuration\n");
        return 1;
    }
    i += descriptors[i];

    while (i < length) {
        if (descriptors[i + 1] != USB_DT_INTERFACE ||
            (descriptors[i + 1] == USB_DT_INTERFACE &&
             descriptors[i + 4] == 0)) {
            i += descriptors[i];
            continue;
        }

        interface = descriptors[i + 2];

        ct.bRequestType = USB_DIR_IN | USB_RECIP_INTERFACE;
        ct.bRequest = USB_REQ_GET_INTERFACE;
        ct.wValue = 0;
        ct.wIndex = interface;
        ct.wLength = 1;
        ct.data = &alt_interface;
        ct.timeout = 50;

        ret = ioctl(s->fd, USBDEVFS_CONTROL, &ct);
        if (ret < 0) {
            perror("usb_linux_update_endp_table");
            return 1;
        }

        /* the current interface descriptor is the active interface
         * and has endpoints */
        if (descriptors[i + 3] != alt_interface) {
            i += descriptors[i];
            continue;
        }

        /* advance to the endpoints */
        while (i < length && descriptors[i +1] != USB_DT_ENDPOINT)
            i += descriptors[i];

        if (i >= length)
            break;

        while (i < length) {
            if (descriptors[i + 1] != USB_DT_ENDPOINT)
                break;

            devep = descriptors[i + 2];
            switch (descriptors[i + 3] & 0x3) {
            case 0x00:
                type = USBDEVFS_URB_TYPE_CONTROL;
                break;
            case 0x01:
                type = USBDEVFS_URB_TYPE_ISO;
                break;
            case 0x02:
                type = USBDEVFS_URB_TYPE_BULK;
                break;
            case 0x03:
                type = USBDEVFS_URB_TYPE_INTERRUPT;
                break;
            default:
                dprintf("usb_host: malformed endpoint type\n");
                type = USBDEVFS_URB_TYPE_BULK;
            }
            s->endp_table[(devep & 0xf) - 1].type = type;
            s->endp_table[(devep & 0xf) - 1].halted = 0;

            i += descriptors[i];
        }
    }
    return 0;
}

static USBDevice *usb_host_device_open_addr(int bus_num, int addr, const char *prod_name)
{
    int fd = -1, ret;
    USBHostDevice *dev = NULL;
    struct usbdevfs_connectinfo ci;
    char buf[1024];

    dev = qemu_mallocz(sizeof(USBHostDevice));
    if (!dev)
        goto fail;

    dev->bus_num = bus_num;
    dev->addr = addr;

    printf("husb: open device %d.%d\n", bus_num, addr);

    snprintf(buf, sizeof(buf), USBDEVFS_PATH "/%03d/%03d",
             bus_num, addr);
    fd = open(buf, O_RDWR | O_NONBLOCK);
    if (fd < 0) {
        perror(buf);
        goto fail;
    }

    /* read the device description */
    dev->descr_len = read(fd, dev->descr, sizeof(dev->descr));
    if (dev->descr_len <= 0) {
        perror("husb: reading device data failed");
        goto fail;
    }

#ifdef DEBUG
    {
        int x;
        printf("=== begin dumping device descriptor data ===\n");
        for (x = 0; x < dev->descr_len; x++)
            printf("%02x ", dev->descr[x]);
        printf("\n=== end dumping device descriptor data ===\n");
    }
#endif

    dev->fd = fd;

    /* 
     * Initial configuration is -1 which makes us claim first 
     * available config. We used to start with 1, which does not
     * always work. I've seen devices where first config starts 
     * with 2.
     */
    if (!usb_host_claim_interfaces(dev, -1))
        goto fail;

    ret = ioctl(fd, USBDEVFS_CONNECTINFO, &ci);
    if (ret < 0) {
        perror("usb_host_device_open: USBDEVFS_CONNECTINFO");
        goto fail;
    }

    printf("husb: grabbed usb device %d.%d\n", bus_num, addr);

    ret = usb_linux_update_endp_table(dev);
    if (ret)
        goto fail;

    if (ci.slow)
        dev->dev.speed = USB_SPEED_LOW;
    else
        dev->dev.speed = USB_SPEED_HIGH;

    dev->dev.handle_packet  = usb_host_handle_packet;
    dev->dev.handle_reset   = usb_host_handle_reset;
    dev->dev.handle_destroy = usb_host_handle_destroy;

    if (!prod_name || prod_name[0] == '\0')
        snprintf(dev->dev.devname, sizeof(dev->dev.devname),
                 "host:%d.%d", bus_num, addr);
    else
        pstrcpy(dev->dev.devname, sizeof(dev->dev.devname),
                prod_name);

    /* USB devio uses 'write' flag to check for async completions */
    qemu_set_fd_handler(dev->fd, NULL, async_complete, dev);

    hostdev_link(dev);

    return (USBDevice *) dev;

fail:
    if (dev)
        qemu_free(dev);

    close(fd);
    return NULL;
}

static int usb_host_auto_add(const char *spec);
static int usb_host_auto_del(const char *spec);

USBDevice *usb_host_device_open(const char *devname)
{
    int bus_num, addr;
    char product_name[PRODUCT_NAME_SZ];

    if (strstr(devname, "auto:")) {
        usb_host_auto_add(devname);
        return NULL;
    }

    if (usb_host_find_device(&bus_num, &addr, product_name, sizeof(product_name),
                             devname) < 0)
        return NULL;

    if (hostdev_find(bus_num, addr)) {
       term_printf("husb: host usb device %d.%d is already open\n", bus_num, addr);
       return NULL;
    }

    return usb_host_device_open_addr(bus_num, addr, product_name);
}

int usb_host_device_close(const char *devname)
{
    char product_name[PRODUCT_NAME_SZ];
    int bus_num, addr;
    USBHostDevice *s;

    if (strstr(devname, "auto:"))
        return usb_host_auto_del(devname);

    if (usb_host_find_device(&bus_num, &addr, product_name, sizeof(product_name),
                             devname) < 0)
        return -1;
 
    s = hostdev_find(bus_num, addr);
    if (s) {
        usb_device_del_addr(0, s->dev.addr);
        return 0;
    }

    return -1;
}
 
static int get_tag_value(char *buf, int buf_size,
                         const char *str, const char *tag,
                         const char *stopchars)
{
    const char *p;
    char *q;
    p = strstr(str, tag);
    if (!p)
        return -1;
    p += strlen(tag);
    while (isspace(*p))
        p++;
    q = buf;
    while (*p != '\0' && !strchr(stopchars, *p)) {
        if ((q - buf) < (buf_size - 1))
            *q++ = *p;
        p++;
    }
    *q = '\0';
    return q - buf;
}

static int usb_host_scan(void *opaque, USBScanFunc *func)
{
    FILE *f;
    char line[1024];
    char buf[1024];
    int bus_num, addr, speed, device_count, class_id, product_id, vendor_id;
    int ret;
    char product_name[512];

    f = fopen(USBDEVFS_PATH "/devices", "r");
    if (!f) {
        term_printf("husb: could not open %s\n", USBDEVFS_PATH "/devices");
        return 0;
    }
    device_count = 0;
    bus_num = addr = speed = class_id = product_id = vendor_id = 0;
    ret = 0;
    for(;;) {
        if (fgets(line, sizeof(line), f) == NULL)
            break;
        if (strlen(line) > 0)
            line[strlen(line) - 1] = '\0';
        if (line[0] == 'T' && line[1] == ':') {
            if (device_count && (vendor_id || product_id)) {
                /* New device.  Add the previously discovered device.  */
                ret = func(opaque, bus_num, addr, class_id, vendor_id,
                           product_id, product_name, speed);
                if (ret)
                    goto the_end;
            }
            if (get_tag_value(buf, sizeof(buf), line, "Bus=", " ") < 0)
                goto fail;
            bus_num = atoi(buf);
            if (get_tag_value(buf, sizeof(buf), line, "Dev#=", " ") < 0)
                goto fail;
            addr = atoi(buf);
            if (get_tag_value(buf, sizeof(buf), line, "Spd=", " ") < 0)
                goto fail;
            if (!strcmp(buf, "480"))
                speed = USB_SPEED_HIGH;
            else if (!strcmp(buf, "1.5"))
                speed = USB_SPEED_LOW;
            else
                speed = USB_SPEED_FULL;
            product_name[0] = '\0';
            class_id = 0xff;
            device_count++;
            product_id = 0;
            vendor_id = 0;
        } else if (line[0] == 'P' && line[1] == ':') {
            if (get_tag_value(buf, sizeof(buf), line, "Vendor=", " ") < 0)
                goto fail;
            vendor_id = strtoul(buf, NULL, 16);
            if (get_tag_value(buf, sizeof(buf), line, "ProdID=", " ") < 0)
                goto fail;
            product_id = strtoul(buf, NULL, 16);
        } else if (line[0] == 'S' && line[1] == ':') {
            if (get_tag_value(buf, sizeof(buf), line, "Product=", "") < 0)
                goto fail;
            pstrcpy(product_name, sizeof(product_name), buf);
        } else if (line[0] == 'D' && line[1] == ':') {
            if (get_tag_value(buf, sizeof(buf), line, "Cls=", " (") < 0)
                goto fail;
            class_id = strtoul(buf, NULL, 16);
        }
    fail: ;
    }
    if (device_count && (vendor_id || product_id)) {
        /* Add the last device.  */
        ret = func(opaque, bus_num, addr, class_id, vendor_id,
                   product_id, product_name, speed);
    }
 the_end:
    fclose(f);
    return ret;
}

struct USBAutoFilter {
    struct USBAutoFilter *next;
    int bus_num;
    int addr;
    int vendor_id;
    int product_id;
};

static QEMUTimer *usb_auto_timer;
static struct USBAutoFilter *usb_auto_filter;

static int usb_host_auto_scan(void *opaque, int bus_num, int addr,
                     int class_id, int vendor_id, int product_id,
                     const char *product_name, int speed)
{
    struct USBAutoFilter *f;
    struct USBDevice *dev;

    /* Ignore hubs */
    if (class_id == 9)
        return 0;

    for (f = usb_auto_filter; f; f = f->next) {
	if (f->bus_num >= 0 && f->bus_num != bus_num)
            continue;

	if (f->addr >= 0 && f->addr != addr)
            continue;

	if (f->vendor_id >= 0 && f->vendor_id != vendor_id)
            continue;

	if (f->product_id >= 0 && f->product_id != product_id)
            continue;

        /* We got a match */

        /* Allredy attached ? */
        if (hostdev_find(bus_num, addr))
            return 0;

        dprintf("husb: auto open: bus_num %d addr %d\n", bus_num, addr);

	dev = usb_host_device_open_addr(bus_num, addr, product_name);
	if (dev)
	    usb_device_add_dev(dev);
    }

    return 0;
}

static void usb_host_auto_timer(void *unused)
{
    usb_host_scan(NULL, usb_host_auto_scan);
    qemu_mod_timer(usb_auto_timer, qemu_get_clock(rt_clock) + 2000);
}

/*
 * Autoconnect filter
 * Format:
 *    auto:bus:dev[:vid:pid]
 *    auto:bus.dev[:vid:pid]
 *
 *    bus  - bus number    (dec, * means any)
 *    dev  - device number (dec, * means any)
 *    vid  - vendor id     (hex, * means any)
 *    pid  - product id    (hex, * means any)
 *
 *    See 'lsusb' output.
 */
static int parse_filter(const char *spec, struct USBAutoFilter *f)
{
    enum { BUS, DEV, VID, PID, DONE };
    const char *p = spec;
    int i;

    f->bus_num    = -1;
    f->addr       = -1;
    f->vendor_id  = -1;
    f->product_id = -1;

    for (i = BUS; i < DONE; i++) {
    	p = strpbrk(p, ":.");
    	if (!p) break;
        p++;
 
    	if (*p == '*')
            continue;

        switch(i) {
        case BUS: f->bus_num = strtol(p, NULL, 10);    break;
        case DEV: f->addr    = strtol(p, NULL, 10);    break;
        case VID: f->vendor_id  = strtol(p, NULL, 16); break;
        case PID: f->product_id = strtol(p, NULL, 16); break;
        }
    }

    if (i < DEV) {
        fprintf(stderr, "husb: invalid auto filter spec %s\n", spec);
        return -1;
    }

    return 0;
}

static int match_filter(const struct USBAutoFilter *f1, 
                        const struct USBAutoFilter *f2)
{
    return f1->bus_num    == f2->bus_num &&
           f1->addr       == f2->addr &&
           f1->vendor_id  == f2->vendor_id &&
           f1->product_id == f2->product_id;
}

static int usb_host_auto_add(const char *spec)
{
    struct USBAutoFilter filter, *f;

    if (parse_filter(spec, &filter) < 0)
        return -1;

    f = qemu_mallocz(sizeof(*f));
    if (!f) {
        fprintf(stderr, "husb: failed to allocate auto filter\n");
        return -1;
    }

    *f = filter; 

    if (!usb_auto_filter) {
        /*
         * First entry. Init and start the monitor.
         * Right now we're using timer to check for new devices.
         * If this turns out to be too expensive we can move that into a 
         * separate thread.
         */
	usb_auto_timer = qemu_new_timer(rt_clock, usb_host_auto_timer, NULL);
	if (!usb_auto_timer) {
            fprintf(stderr, "husb: failed to allocate auto scan timer\n");
            qemu_free(f);
            return -1;
        }

        /* Check for new devices every two seconds */
        qemu_mod_timer(usb_auto_timer, qemu_get_clock(rt_clock) + 2000);
    }

    dprintf("husb: added auto filter: bus_num %d addr %d vid %d pid %d\n",
	f->bus_num, f->addr, f->vendor_id, f->product_id);

    f->next = usb_auto_filter;
    usb_auto_filter = f;

    return 0;
}

static int usb_host_auto_del(const char *spec)
{
    struct USBAutoFilter *pf = usb_auto_filter;
    struct USBAutoFilter **prev = &usb_auto_filter;
    struct USBAutoFilter filter;

    if (parse_filter(spec, &filter) < 0)
        return -1;

    while (pf) {
        if (match_filter(pf, &filter)) {
            dprintf("husb: removed auto filter: bus_num %d addr %d vid %d pid %d\n",
	             pf->bus_num, pf->addr, pf->vendor_id, pf->product_id);

            *prev = pf->next;

	    if (!usb_auto_filter) {
                /* No more filters. Stop scanning. */
                qemu_del_timer(usb_auto_timer);
                qemu_free_timer(usb_auto_timer);
            }

            return 0;
        }

        prev = &pf->next;
        pf   = pf->next;
    }

    return -1;
}

typedef struct FindDeviceState {
    int vendor_id;
    int product_id;
    int bus_num;
    int addr;
    char product_name[PRODUCT_NAME_SZ];
} FindDeviceState;

static int usb_host_find_device_scan(void *opaque, int bus_num, int addr,
                                     int class_id,
                                     int vendor_id, int product_id,
                                     const char *product_name, int speed)
{
    FindDeviceState *s = opaque;
    if ((vendor_id == s->vendor_id &&
        product_id == s->product_id) ||
        (bus_num == s->bus_num &&
        addr == s->addr)) {
        pstrcpy(s->product_name, PRODUCT_NAME_SZ, product_name);
        s->bus_num = bus_num;
        s->addr = addr;
        return 1;
    } else {
        return 0;
    }
}

/* the syntax is :
   'bus.addr' (decimal numbers) or
   'vendor_id:product_id' (hexa numbers) */
static int usb_host_find_device(int *pbus_num, int *paddr,
                                char *product_name, int product_name_size,
                                const char *devname)
{
    const char *p;
    int ret;
    FindDeviceState fs;

    p = strchr(devname, '.');
    if (p) {
        *pbus_num = strtoul(devname, NULL, 0);
        *paddr = strtoul(p + 1, NULL, 0);
        fs.bus_num = *pbus_num;
        fs.addr = *paddr;
        ret = usb_host_scan(&fs, usb_host_find_device_scan);
        if (ret)
            pstrcpy(product_name, product_name_size, fs.product_name);
        return 0;
    }

    p = strchr(devname, ':');
    if (p) {
        fs.vendor_id = strtoul(devname, NULL, 16);
        fs.product_id = strtoul(p + 1, NULL, 16);
        ret = usb_host_scan(&fs, usb_host_find_device_scan);
        if (ret) {
            *pbus_num = fs.bus_num;
            *paddr = fs.addr;
            pstrcpy(product_name, product_name_size, fs.product_name);
            return 0;
        }
    }
    return -1;
}

/**********************/
/* USB host device info */

struct usb_class_info {
    int class;
    const char *class_name;
};

static const struct usb_class_info usb_class_info[] = {
    { USB_CLASS_AUDIO, "Audio"},
    { USB_CLASS_COMM, "Communication"},
    { USB_CLASS_HID, "HID"},
    { USB_CLASS_HUB, "Hub" },
    { USB_CLASS_PHYSICAL, "Physical" },
    { USB_CLASS_PRINTER, "Printer" },
    { USB_CLASS_MASS_STORAGE, "Storage" },
    { USB_CLASS_CDC_DATA, "Data" },
    { USB_CLASS_APP_SPEC, "Application Specific" },
    { USB_CLASS_VENDOR_SPEC, "Vendor Specific" },
    { USB_CLASS_STILL_IMAGE, "Still Image" },
    { USB_CLASS_CSCID, "Smart Card" },
    { USB_CLASS_CONTENT_SEC, "Content Security" },
    { -1, NULL }
};

static const char *usb_class_str(uint8_t class)
{
    const struct usb_class_info *p;
    for(p = usb_class_info; p->class != -1; p++) {
        if (p->class == class)
            break;
    }
    return p->class_name;
}

static void usb_info_device(int bus_num, int addr, int class_id,
                            int vendor_id, int product_id,
                            const char *product_name,
                            int speed)
{
    const char *class_str, *speed_str;

    switch(speed) {
    case USB_SPEED_LOW:
        speed_str = "1.5";
        break;
    case USB_SPEED_FULL:
        speed_str = "12";
        break;
    case USB_SPEED_HIGH:
        speed_str = "480";
        break;
    default:
        speed_str = "?";
        break;
    }

    term_printf("  Device %d.%d, speed %s Mb/s\n",
                bus_num, addr, speed_str);
    class_str = usb_class_str(class_id);
    if (class_str)
        term_printf("    %s:", class_str);
    else
        term_printf("    Class %02x:", class_id);
    term_printf(" USB device %04x:%04x", vendor_id, product_id);
    if (product_name[0] != '\0')
        term_printf(", %s", product_name);
    term_printf("\n");
}

static int usb_host_info_device(void *opaque, int bus_num, int addr,
                                int class_id,
                                int vendor_id, int product_id,
                                const char *product_name,
                                int speed)
{
    usb_info_device(bus_num, addr, class_id, vendor_id, product_id,
                    product_name, speed);
    return 0;
}

static void dec2str(int val, char *str)
{
    if (val == -1)
        strcpy(str, "*");
    else
        sprintf(str, "%d", val); 
}

static void hex2str(int val, char *str)
{
    if (val == -1)
        strcpy(str, "*");
    else
        sprintf(str, "%x", val);
}

void usb_host_info(void)
{
    struct USBAutoFilter *f;

    usb_host_scan(NULL, usb_host_info_device);

    if (usb_auto_filter)
        term_printf("  Auto filters:\n");
    for (f = usb_auto_filter; f; f = f->next) {
        char bus[10], addr[10], vid[10], pid[10];
        dec2str(f->bus_num, bus);
        dec2str(f->addr, addr);
        hex2str(f->vendor_id, vid);
        hex2str(f->product_id, pid);
    	term_printf("    Device %s.%s ID %s:%s\n", bus, addr, vid, pid);
    }
}

#else

#include "hw/usb.h"

void usb_host_info(void)
{
    term_printf("USB host devices not supported\n");
}

/* XXX: modify configure to compile the right host driver */
USBDevice *usb_host_device_open(const char *devname)
{
    return NULL;
}

int usb_host_device_close(const char *devname)
{
    return 0;
}

#endif
