/*
 * Virtio Console Device
 *
 * Copyright IBM, Corp. 2008
 *
 * Authors:
 *  Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
 *
 * This work is licensed under the terms of the GNU GPL, version 2.  See
 * the COPYING file in the top-level directory.
 *
 */

#include "hw.h"
#include "qemu-char.h"
#include "virtio.h"
#include "virtio-console.h"


typedef struct VirtIOConsole
{
    VirtIODevice vdev;
    VirtQueue *ivq, *dvq;
    CharDriverState *chr;
} VirtIOConsole;

static VirtIOConsole *to_virtio_console(VirtIODevice *vdev)
{
    return (VirtIOConsole *)vdev;
}

static void virtio_console_handle_output(VirtIODevice *vdev, VirtQueue *vq)
{
    VirtIOConsole *s = to_virtio_console(vdev);
    VirtQueueElement elem;

    while (virtqueue_pop(vq, &elem)) {
        ssize_t len = 0;
        int d;

        for (d=0; d < elem.out_num; d++)
            len += qemu_chr_write(s->chr, elem.out_sg[d].iov_base,elem.out_sg[d].iov_len);
        virtqueue_push(vq, &elem, len);
        virtio_notify(vdev, vq);
    }
}

static void virtio_console_handle_input(VirtIODevice *vdev, VirtQueue *vq)
{
}

static uint32_t virtio_console_get_features(VirtIODevice *vdev)
{
    return 0;
}

static int vcon_can_read(void *opaque)
{
    VirtIOConsole *s = (VirtIOConsole *) opaque;

    if (!virtio_queue_ready(s->ivq) ||
        !(s->vdev.status & VIRTIO_CONFIG_S_DRIVER_OK) ||
        virtio_queue_empty(s->ivq))
        return 0;

    /* current implementations have a page sized buffer.
     * We fall back to a one byte per read if there is not enough room.
     * It would be cool to have a function that returns the available byte
     * instead of checking for a limit */
    if (virtqueue_avail_bytes(s->ivq, TARGET_PAGE_SIZE, 0))
        return TARGET_PAGE_SIZE;
    if (virtqueue_avail_bytes(s->ivq, 1, 0))
        return 1;
    return 0;
}

static void vcon_read(void *opaque, const uint8_t *buf, int size)
{
    VirtIOConsole *s = (VirtIOConsole *) opaque;
    VirtQueueElement elem;
    int offset = 0;

    /* The current kernel implementation has only one outstanding input
     * buffer of PAGE_SIZE. Nevertheless, this function is prepared to
     * handle multiple buffers with multiple sg element for input */
    while (offset < size) {
        int i = 0;
        if (!virtqueue_pop(s->ivq, &elem))
                break;
        while (offset < size && i < elem.in_num) {
            int len = MIN(elem.in_sg[i].iov_len, size - offset);
            memcpy(elem.in_sg[i].iov_base, buf + offset, len);
            offset += len;
            i++;
        }
        virtqueue_push(s->ivq, &elem, size);
    }
    virtio_notify(&s->vdev, s->ivq);
}

static void vcon_event(void *opaque, int event)
{
    /* we will ignore any event for the time being */
}

static void virtio_console_save(QEMUFile *f, void *opaque)
{
    VirtIOConsole *s = opaque;

    virtio_save(&s->vdev, f);
}

static int virtio_console_load(QEMUFile *f, void *opaque, int version_id)
{
    VirtIOConsole *s = opaque;

    if (version_id != 1)
        return -EINVAL;

    virtio_load(&s->vdev, f);
    return 0;
}

void *virtio_console_init(PCIBus *bus, CharDriverState *chr)
{
    VirtIOConsole *s;

    s = (VirtIOConsole *)virtio_init_pci(bus, "virtio-console",
                                         PCI_VENDOR_ID_REDHAT_QUMRANET,
                                         PCI_DEVICE_ID_VIRTIO_CONSOLE,
                                         PCI_VENDOR_ID_REDHAT_QUMRANET,
                                         VIRTIO_ID_CONSOLE,
                                         PCI_CLASS_DISPLAY_OTHER, 0x00,
                                         0, sizeof(VirtIOConsole));
    if (s == NULL)
        return NULL;

    s->vdev.get_features = virtio_console_get_features;

    s->ivq = virtio_add_queue(&s->vdev, 128, virtio_console_handle_input);
    s->dvq = virtio_add_queue(&s->vdev, 128, virtio_console_handle_output);

    s->chr = chr;
    qemu_chr_add_handlers(chr, vcon_can_read, vcon_read, vcon_event, s);

    register_savevm("virtio-console", -1, 1, virtio_console_save, virtio_console_load, s);

    return &s->vdev;
}
