73 lines
1.3 KiB
C
73 lines
1.3 KiB
C
/*
|
|
* Copyright (C) 2014, Red Hat Inc, Andrew Jones <drjones@redhat.com>
|
|
*
|
|
* This work is licensed under the terms of the GNU LGPL, version 2.
|
|
*/
|
|
#include "libcflat.h"
|
|
#include "virtio.h"
|
|
#include "asm/spinlock.h"
|
|
|
|
#define TESTDEV_NAME "chr-testdev"
|
|
|
|
static struct virtio_device *vcon;
|
|
static struct virtqueue *in_vq, *out_vq;
|
|
static struct spinlock lock;
|
|
|
|
static void __testdev_send(char *buf, unsigned int len)
|
|
{
|
|
int ret;
|
|
|
|
ret = virtqueue_add_outbuf(out_vq, buf, len);
|
|
virtqueue_kick(out_vq);
|
|
|
|
if (ret < 0)
|
|
return;
|
|
|
|
while (!virtqueue_get_buf(out_vq, &len))
|
|
;
|
|
}
|
|
|
|
void chr_testdev_exit(int code)
|
|
{
|
|
unsigned int len;
|
|
char buf[8];
|
|
|
|
snprintf(buf, sizeof(buf), "%dq", code);
|
|
len = strlen(buf);
|
|
|
|
spin_lock(&lock);
|
|
|
|
if (!vcon)
|
|
goto out;
|
|
|
|
__testdev_send(buf, len);
|
|
|
|
out:
|
|
spin_unlock(&lock);
|
|
}
|
|
|
|
void chr_testdev_init(void)
|
|
{
|
|
const char *io_names[] = { "input", "output" };
|
|
struct virtqueue *vqs[2];
|
|
int ret;
|
|
|
|
vcon = virtio_bind(VIRTIO_ID_CONSOLE);
|
|
if (vcon == NULL) {
|
|
printf("%s: %s: can't find a virtio-console\n",
|
|
__func__, TESTDEV_NAME);
|
|
return;
|
|
}
|
|
|
|
ret = vcon->config->find_vqs(vcon, 2, vqs, NULL, io_names);
|
|
if (ret < 0) {
|
|
printf("%s: %s: can't init virtqueues\n",
|
|
__func__, TESTDEV_NAME);
|
|
vcon = NULL;
|
|
return;
|
|
}
|
|
|
|
in_vq = vqs[0];
|
|
out_vq = vqs[1];
|
|
}
|