/*
 * BSD host USB redirector
 *
 * Copyright (c) 2006 Lonnie Mendez
 * Portions of code and concepts borrowed from
 * usb-linux.c and libusb's bsd.c and are copyright their respective owners.
 *
 * 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 "monitor/monitor.h"
#include "hw/usb.h"

/* usb.h declares these */
#undef USB_SPEED_HIGH
#undef USB_SPEED_FULL
#undef USB_SPEED_LOW

#include <sys/ioctl.h>
#ifndef __DragonFly__
#include <dev/usb/usb.h>
#else
#include <bus/usb/usb.h>
#endif

/* This value has maximum potential at 16.
 * You should also set hw.usb.debug to gain
 * more detailed view.
 */
//#define DEBUG
#define UGEN_DEBUG_LEVEL 0


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,
                                const char *devname);

typedef struct USBHostDevice {
    USBDevice dev;
    int ep_fd[USB_MAX_ENDPOINTS];
    int devfd;
    char devpath[32];
} USBHostDevice;


static int ensure_ep_open(USBHostDevice *dev, int ep, int mode)
{
    char buf[32];
    int fd;

    /* Get the address for this endpoint */
    ep = UE_GET_ADDR(ep);

    if (dev->ep_fd[ep] < 0) {
#if defined(__FreeBSD__) || defined(__DragonFly__)
        snprintf(buf, sizeof(buf) - 1, "%s.%d", dev->devpath, ep);
#else
        snprintf(buf, sizeof(buf) - 1, "%s.%02d", dev->devpath, ep);
#endif
        /* Try to open it O_RDWR first for those devices which have in and out
         * endpoints with the same address (eg 0x02 and 0x82)
         */
        fd = open(buf, O_RDWR);
        if (fd < 0 && errno == ENXIO)
            fd = open(buf, mode);
        if (fd < 0) {
#ifdef DEBUG
            printf("ensure_ep_open: failed to open device endpoint %s: %s\n",
                   buf, strerror(errno));
#endif
        }
        dev->ep_fd[ep] = fd;
    }

    return dev->ep_fd[ep];
}

static void ensure_eps_closed(USBHostDevice *dev)
{
    int epnum = 1;

    if (!dev)
        return;

    while (epnum < USB_MAX_ENDPOINTS) {
        if (dev->ep_fd[epnum] >= 0) {
            close(dev->ep_fd[epnum]);
            dev->ep_fd[epnum] = -1;
        }
        epnum++;
    }
}

static void usb_host_handle_reset(USBDevice *dev)
{
#if 0
    USBHostDevice *s = (USBHostDevice *)dev;
#endif
}

/* XXX:
 * -check device states against transfer requests
 *  and return appropriate response
 */
static void usb_host_handle_control(USBDevice *dev,
                                   USBPacket *p,
                                   int request,
                                   int value,
                                   int index,
                                   int length,
                                   uint8_t *data)
{
    USBHostDevice *s = (USBHostDevice *)dev;
    struct usb_ctl_request req;
    struct usb_alt_interface aiface;
    int ret, timeout = 50;

    if ((request >> 8) == UT_WRITE_DEVICE &&
        (request & 0xff) == UR_SET_ADDRESS) {

        /* specific SET_ADDRESS support */
        dev->addr = value;
    } else if ((request >> 8) == UT_WRITE_DEVICE &&
               (request & 0xff) == UR_SET_CONFIG) {

        ensure_eps_closed(s); /* can't do this without all eps closed */

        ret = ioctl(s->devfd, USB_SET_CONFIG, &value);
        if (ret < 0) {
#ifdef DEBUG
            printf("handle_control: failed to set configuration - %s\n",
                   strerror(errno));
#endif
            p->status = USB_RET_STALL;
        }
    } else if ((request >> 8) == UT_WRITE_INTERFACE &&
               (request & 0xff) == UR_SET_INTERFACE) {

        aiface.uai_interface_index = index;
        aiface.uai_alt_no = value;

        ensure_eps_closed(s); /* can't do this without all eps closed */
        ret = ioctl(s->devfd, USB_SET_ALTINTERFACE, &aiface);
        if (ret < 0) {
#ifdef DEBUG
            printf("handle_control: failed to set alternate interface - %s\n",
                   strerror(errno));
#endif
            p->status = USB_RET_STALL;
        }
    } else {
        req.ucr_request.bmRequestType = request >> 8;
        req.ucr_request.bRequest = request & 0xff;
        USETW(req.ucr_request.wValue, value);
        USETW(req.ucr_request.wIndex, index);
        USETW(req.ucr_request.wLength, length);
        req.ucr_data = data;
        req.ucr_flags = USBD_SHORT_XFER_OK;

        ret = ioctl(s->devfd, USB_SET_TIMEOUT, &timeout);
#if defined(__NetBSD__) || defined(__OpenBSD__)
        if (ret < 0 && errno != EINVAL) {
#else
        if (ret < 0) {
#endif
#ifdef DEBUG
            printf("handle_control: setting timeout failed - %s\n",
                   strerror(errno));
#endif
        }

        ret = ioctl(s->devfd, USB_DO_REQUEST, &req);
        /* ugen returns EIO for usbd_do_request_ no matter what
         * happens with the transfer */
        if (ret < 0) {
#ifdef DEBUG
            printf("handle_control: error after request - %s\n",
                   strerror(errno));
#endif
            p->status = USB_RET_NAK; /* STALL */
        } else {
            p->actual_length = req.ucr_actlen;
        }
    }
}

static void usb_host_handle_data(USBDevice *dev, USBPacket *p)
{
    USBHostDevice *s = (USBHostDevice *)dev;
    int ret, fd, mode;
    int one = 1, shortpacket = 0, timeout = 50;
    sigset_t new_mask, old_mask;
    uint8_t devep = p->ep->nr;

    /* protect data transfers from SIGALRM signal */
    sigemptyset(&new_mask);
    sigaddset(&new_mask, SIGALRM);
    sigprocmask(SIG_BLOCK, &new_mask, &old_mask);

    if (p->pid == USB_TOKEN_IN) {
        devep |= 0x80;
        mode = O_RDONLY;
        shortpacket = 1;
    } else {
        mode = O_WRONLY;
    }

    fd = ensure_ep_open(s, devep, mode);
    if (fd < 0) {
        sigprocmask(SIG_SETMASK, &old_mask, NULL);
        p->status = USB_RET_NODEV;
        return;
    }

    if (ioctl(fd, USB_SET_TIMEOUT, &timeout) < 0) {
#ifdef DEBUG
        printf("handle_data: failed to set timeout - %s\n",
               strerror(errno));
#endif
    }

    if (shortpacket) {
        if (ioctl(fd, USB_SET_SHORT_XFER, &one) < 0) {
#ifdef DEBUG
            printf("handle_data: failed to set short xfer mode - %s\n",
                   strerror(errno));
#endif
            sigprocmask(SIG_SETMASK, &old_mask, NULL);
        }
    }

    if (p->pid == USB_TOKEN_IN)
        ret = readv(fd, p->iov.iov, p->iov.niov);
    else
        ret = writev(fd, p->iov.iov, p->iov.niov);

    sigprocmask(SIG_SETMASK, &old_mask, NULL);

    if (ret < 0) {
#ifdef DEBUG
        printf("handle_data: error after %s data - %s\n",
               pid == USB_TOKEN_IN ? "reading" : "writing", strerror(errno));
#endif
        switch(errno) {
        case ETIMEDOUT:
        case EINTR:
            p->status = USB_RET_NAK;
            break;
        default:
            p->status = USB_RET_STALL;
        }
    } else {
        p->actual_length = ret;
    }
}

static void usb_host_handle_destroy(USBDevice *opaque)
{
    USBHostDevice *s = (USBHostDevice *)opaque;
    int i;

    for (i = 0; i < USB_MAX_ENDPOINTS; i++)
        if (s->ep_fd[i] >= 0)
            close(s->ep_fd[i]);

    if (s->devfd < 0)
        return;

    close(s->devfd);

    g_free(s);
}

static int usb_host_initfn(USBDevice *dev)
{
    dev->flags |= (1 << USB_DEV_FLAG_IS_HOST);
    return 0;
}

USBDevice *usb_host_device_open(USBBus *guest_bus, const char *devname)
{
    struct usb_device_info bus_info, dev_info;
    USBDevice *d = NULL, *ret = NULL;
    USBHostDevice *dev;
    char ctlpath[PATH_MAX + 1];
    char buspath[PATH_MAX + 1];
    int bfd, dfd, bus, address, i;
    int ugendebug = UGEN_DEBUG_LEVEL;

    if (usb_host_find_device(&bus, &address, devname) < 0) {
        goto fail;
    }

    snprintf(buspath, PATH_MAX, "/dev/usb%d", bus);

    bfd = open(buspath, O_RDWR);
    if (bfd < 0) {
#ifdef DEBUG
        printf("usb_host_device_open: failed to open usb bus - %s\n",
               strerror(errno));
#endif
        goto fail;
    }

    bus_info.udi_addr = address;
    if (ioctl(bfd, USB_DEVICEINFO, &bus_info) < 0) {
#ifdef DEBUG
        printf("usb_host_device_open: failed to grab bus information - %s\n",
               strerror(errno));
#endif
        goto fail_bfd;
    }

#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
    snprintf(ctlpath, PATH_MAX, "/dev/%s", bus_info.udi_devnames[0]);
#else
    snprintf(ctlpath, PATH_MAX, "/dev/%s.00", bus_info.udi_devnames[0]);
#endif

    dfd  = open(ctlpath, O_RDWR);
    if (dfd < 0) {
        dfd = open(ctlpath, O_RDONLY);
        if (dfd < 0) {
#ifdef DEBUG
            printf("usb_host_device_open: failed to open usb device %s - %s\n",
                   ctlpath, strerror(errno));
#endif
        }
        goto fail_dfd;
    }

    if (ioctl(dfd, USB_GET_DEVICEINFO, &dev_info) < 0) {
#ifdef DEBUG
        printf("usb_host_device_open: failed to grab device info - %s\n",
               strerror(errno));
#endif
        goto fail_dfd;
    }

    d = usb_create(guest_bus, "usb-host");
    dev = DO_UPCAST(USBHostDevice, dev, d);

    if (dev_info.udi_speed == 1) {
        dev->dev.speed = USB_SPEED_LOW - 1;
        dev->dev.speedmask = USB_SPEED_MASK_LOW;
    } else {
        dev->dev.speed = USB_SPEED_FULL - 1;
        dev->dev.speedmask = USB_SPEED_MASK_FULL;
    }

    if (strncmp(dev_info.udi_product, "product", 7) != 0) {
        pstrcpy(dev->dev.product_desc, sizeof(dev->dev.product_desc),
                dev_info.udi_product);
    } else {
        snprintf(dev->dev.product_desc, sizeof(dev->dev.product_desc),
                 "host:%s", devname);
    }

    pstrcpy(dev->devpath, sizeof(dev->devpath), "/dev/");
    pstrcat(dev->devpath, sizeof(dev->devpath), dev_info.udi_devnames[0]);

    /* Mark the endpoints as not yet open */
    for (i = 0; i < USB_MAX_ENDPOINTS; i++) {
        dev->ep_fd[i] = -1;
    }

    ioctl(dfd, USB_SETDEBUG, &ugendebug);

    ret = (USBDevice *)dev;

fail_dfd:
    close(dfd);
fail_bfd:
    close(bfd);
fail:
    return ret;
}

static void usb_host_class_initfn(ObjectClass *klass, void *data)
{
    USBDeviceClass *uc = USB_DEVICE_CLASS(klass);

    uc->product_desc   = "USB Host Device";
    uc->init           = usb_host_initfn;
    uc->handle_reset   = usb_host_handle_reset;
    uc->handle_control = usb_host_handle_control;
    uc->handle_data    = usb_host_handle_data;
    uc->handle_destroy = usb_host_handle_destroy;
}

static const TypeInfo usb_host_dev_info = {
    .name          = "usb-host",
    .parent        = TYPE_USB_DEVICE,
    .instance_size = sizeof(USBHostDevice),
    .class_init    = usb_host_class_initfn,
};

static void usb_host_register_types(void)
{
    type_register_static(&usb_host_dev_info);
}

type_init(usb_host_register_types)

static int usb_host_scan(void *opaque, USBScanFunc *func)
{
    struct usb_device_info bus_info;
    struct usb_device_info dev_info;
    uint16_t vendor_id, product_id, class_id, speed;
    int bfd, dfd, bus, address;
    char busbuf[20], devbuf[20], product_name[256];
    int ret = 0;

    for (bus = 0; bus < 10; bus++) {

        snprintf(busbuf, sizeof(busbuf) - 1, "/dev/usb%d", bus);
        bfd = open(busbuf, O_RDWR);
        if (bfd < 0)
	    continue;

        for (address = 1; address < 127; address++) {

            bus_info.udi_addr = address;
            if (ioctl(bfd, USB_DEVICEINFO, &bus_info) < 0)
                continue;

            /* only list devices that can be used by generic layer */
            if (strncmp(bus_info.udi_devnames[0], "ugen", 4) != 0)
                continue;

#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
            snprintf(devbuf, sizeof(devbuf) - 1, "/dev/%s", bus_info.udi_devnames[0]);
#else
            snprintf(devbuf, sizeof(devbuf) - 1, "/dev/%s.00", bus_info.udi_devnames[0]);
#endif

            dfd = open(devbuf, O_RDONLY);
            if (dfd < 0) {
#ifdef DEBUG
                printf("usb_host_scan: couldn't open device %s - %s\n", devbuf,
                       strerror(errno));
#endif
                continue;
            }

            if (ioctl(dfd, USB_GET_DEVICEINFO, &dev_info) < 0)
                printf("usb_host_scan: couldn't get device information for %s - %s\n",
                       devbuf, strerror(errno));

            /* XXX: might need to fixup endianness of word values before copying over */

            vendor_id = dev_info.udi_vendorNo;
            product_id = dev_info.udi_productNo;
            class_id = dev_info.udi_class;
            speed = dev_info.udi_speed;

            if (strncmp(dev_info.udi_product, "product", 7) != 0)
                pstrcpy(product_name, sizeof(product_name),
                        dev_info.udi_product);
            else
                product_name[0] = '\0';

            ret = func(opaque, bus, address, class_id, vendor_id,
                       product_id, product_name, speed);

            close(dfd);

            if (ret)
                goto the_end;
        }

        close(bfd);
    }

the_end:
    return ret;
}

typedef struct FindDeviceState {
    int vendor_id;
    int product_id;
    int bus_num;
    int addr;
} 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) {
        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,
                                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);
        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;
            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(Monitor *mon, 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;
    }

    monitor_printf(mon, "  Device %d.%d, speed %s Mb/s\n",
                   bus_num, addr, speed_str);
    class_str = usb_class_str(class_id);
    if (class_str)
        monitor_printf(mon, "    %s:", class_str);
    else
        monitor_printf(mon, "    Class %02x:", class_id);
    monitor_printf(mon, " USB device %04x:%04x", vendor_id, product_id);
    if (product_name[0] != '\0')
        monitor_printf(mon, ", %s", product_name);
    monitor_printf(mon, "\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)
{
    Monitor *mon = opaque;

    usb_info_device(mon, bus_num, addr, class_id, vendor_id, product_id,
                    product_name, speed);
    return 0;
}

void usb_host_info(Monitor *mon, const QDict *qdict)
{
    usb_host_scan(mon, usb_host_info_device);
}
