/*
* Virtio Keyboard Device
*
- * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2011 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
*
* Contact:
- * SungMin Ha <sungmin82.ha@samsung.com>
- * Kitae Kim <kt920.kim@samsung.com>
- * GiWoong Kim <giwoong.kim@samsung.com>
* SeokYeon Hwang <syeon.hwang@samsung.com>
- * SangHo Park <sangho.p@samsung.com>
- * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
+ * SungMin Ha <sungmin82.ha@samsung.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
*
*/
+#include "qemu/iov.h"
#include "hw/maru_device_ids.h"
#include "maru_virtio_keyboard.h"
-#include "debug_ch.h"
+#include "debug_ch.h"
MULTI_DEBUG_CHANNEL(qemu, keyboard);
+#define VIRTIO_MARU_KEYBOARD(obj) \
+ OBJECT_CHECK(VirtIOKeyboard, (obj), TYPE_VIRTIO_MARU_KEYBOARD)
+
+#define MAX_EVENT_CNT 256
+
+typedef struct EmulKbdEvent {
+ uint16_t code;
+ uint16_t type;
+} EmulKbdEvent;
+
+typedef struct VirtIOKbdList {
+ VirtIOKeyboard *vkbd;
+ struct VirtIOKbdList *next;
+} VirtIOKbdList;
+
static VirtIOKbdList *head = NULL;
static VirtIOKbdList *curr = NULL;
-VirtQueueElement elem;
+
+
+typedef struct KeyboardEventEntry {
+ EmulKbdEvent event;
+
+ QTAILQ_ENTRY(KeyboardEventEntry) node;
+} KeyboardEventEntry;
+
+static KeyboardEventEntry events_buf[MAX_EVENT_CNT];
+static QTAILQ_HEAD(, KeyboardEventEntry) events_queue =
+ QTAILQ_HEAD_INITIALIZER(events_queue);
+
+
+void virtio_keyboard_event(int keycode)
+{
+ KeyboardEventEntry *entry = NULL;
+ VirtIOKeyboard *vkbd;
+ EmulKbdEvent *kbdevt;
+
+ if (unlikely(!curr || !(vkbd = curr->vkbd))) {
+ LOG_TRACE("The keyboard device is not realized.\n");
+ return;
+ }
+
+ if (unlikely(!virtio_queue_ready(vkbd->vq))) {
+ LOG_INFO("virtqueue is not ready, dropping event.\n");
+ return;
+ }
+
+ ++(vkbd->event_cnt);
+
+ if ((vkbd->avail_buf_cnt)-- == 0) {
+ LOG_SEVERE("event queue is not available, dropping event.\n");
+ ++(vkbd->avail_buf_cnt);
+ return;
+ }
+
+ entry = &(events_buf[vkbd->event_cnt % MAX_EVENT_CNT]);
+ kbdevt = &entry->event;
+
+ if (keycode < 0xe0) {
+ if (vkbd->extension_key) {
+ switch (keycode & 0x7f) {
+ case 28: /* KP_Enter */
+ kbdevt->code = 96;
+ break;
+ case 29: /* Right Ctrl */
+ kbdevt->code = 97;
+ break;
+ case 56: /* Right Alt */
+ kbdevt->code = 100;
+ break;
+ case 71: /* Home */
+ kbdevt->code = 102;
+ break;
+ case 72: /* Up */
+ kbdevt->code = 103;
+ break;
+ case 73: /* Page Up */
+ kbdevt->code = 104;
+ break;
+ case 75: /* Left */
+ kbdevt->code = 105;
+ break;
+ case 77: /* Right */
+ kbdevt->code = 106;
+ break;
+ case 79: /* End */
+ kbdevt->code = 107;
+ break;
+ case 80: /* Down */
+ kbdevt->code = 108;
+ break;
+ case 81: /* Page Down */
+ kbdevt->code = 109;
+ break;
+ case 82: /* Insert */
+ kbdevt->code = 110;
+ break;
+ case 83: /* Delete */
+ kbdevt->code = 111;
+ break;
+ default:
+ WARN("There is no keymap for this keycode %d.\n", keycode);
+ }
+ vkbd->extension_key = 0;
+ } else {
+ kbdevt->code = keycode & 0x7f;
+ }
+
+ if (!(keycode & 0x80)) {
+ kbdevt->type = 1; /* KEY_PRESSED */
+ } else {
+ kbdevt->type = 0; /* KEY_RELEASED */
+ }
+ } else {
+ TRACE("Extension key.\n");
+ kbdevt->code = keycode;
+ vkbd->extension_key = 1;
+ }
+
+ qemu_mutex_lock(&vkbd->event_mutex);
+
+ QTAILQ_INSERT_TAIL(&events_queue, entry, node);
+
+ qemu_mutex_unlock(&vkbd->event_mutex);
+
+ qemu_bh_schedule(vkbd->bh);
+}
static VirtIOKbdList* create_list(VirtIOKeyboard *vkbd)
{
static void virtio_keyboard_handle(VirtIODevice *vdev, VirtQueue *vq)
{
- VirtIOKeyboard *vkbd = (VirtIOKeyboard *)vdev;
-
- if (virtio_queue_empty(vkbd->vq)) {
- INFO("virtqueue is empty.\n");
- return;
- }
-
- /* Get a queue buffer which is written by guest side. */
- // Logics should be re-written soon
- while (virtqueue_pop(vq, &elem)) {
- TRACE("virtqueue pop.\n");
- };
+ // nothing to do
}
-void virtio_keyboard_notify(void *opaque)
+static void virtio_keyboard_send(void *opaque)
{
VirtIOKeyboard *vkbd = (VirtIOKeyboard *)opaque;
- EmulKbdEvent *kbdevt;
- int written_cnt = 0;
+ KeyboardEventEntry *entry = NULL;
+ int len = 0;
- if (!vkbd) {
- ERR("VirtIOKeyboard is NULL.\n");
- return;
- }
-
- TRACE("[Enter] virtqueue notifier.\n");
-
- if (!virtio_queue_ready(vkbd->vq)) {
- INFO("virtqueue is not ready.\n");
- return;
- }
-
- if (vkbd->kbdqueue.rptr == VIRTIO_KBD_QUEUE_SIZE) {
- vkbd->kbdqueue.rptr = 0;
- }
+ LOG_TRACE("%s\n", __func__);
qemu_mutex_lock(&vkbd->event_mutex);
- written_cnt = vkbd->kbdqueue.wptr;
-
- while ((written_cnt--)) {
- kbdevt = &vkbd->kbdqueue.kbdevent[vkbd->kbdqueue.rptr];
-
- if (((EmulKbdEvent*)(elem.in_sg[vkbd->kbdqueue.rptr].iov_base))->code != 0) {
- TRACE("FIXME: virtio queue is full.\n");
- }
-
- /* Copy keyboard data into guest side. */
- TRACE("copy: keycode %d, type %d, elem_index %d\n",
- kbdevt->code, kbdevt->type, vkbd->kbdqueue.rptr);
- memcpy(elem.in_sg[vkbd->kbdqueue.rptr].iov_base, kbdevt, sizeof(EmulKbdEvent));
- memset(kbdevt, 0x00, sizeof(EmulKbdEvent));
-
- if (vkbd->kbdqueue.wptr > 0) {
- vkbd->kbdqueue.wptr--;
- TRACE("written_cnt: %d, wptr: %d, qemu_index: %d\n",
- written_cnt, vkbd->kbdqueue.wptr, vkbd->kbdqueue.rptr);
- }
-
- vkbd->kbdqueue.rptr++;
- if (vkbd->kbdqueue.rptr == VIRTIO_KBD_QUEUE_SIZE) {
- vkbd->kbdqueue.rptr = 0;
- }
- }
- qemu_mutex_unlock(&vkbd->event_mutex);
-
- virtqueue_push(vkbd->vq, &elem, sizeof(EmulKbdEvent));
- virtio_notify(&vkbd->vdev, vkbd->vq);
-
- TRACE("[Leave] virtqueue notifier.\n");
-}
-
-void virtio_keyboard_event(int keycode)
-{
- EmulKbdEvent kbdevt = {0};
- int *index = NULL;
-
- if (!curr) {
- TRACE("The keyboard device is not realized.\n");
- return;
- }
-
- VirtIOKeyboard *vkbd = curr->vkbd;
- if (!vkbd) {
- ERR("VirtIOKeyboard is NULL.\n");
- return;
- }
-
- if (!virtio_queue_ready(vkbd->vq)) {
- INFO("virtqueue is not ready.\n");
- return;
- }
-
- index = &(vkbd->kbdqueue.index);
- TRACE("[Enter] input_event handler. cnt %d\n", vkbd->kbdqueue.wptr);
-
- if (*index < 0) {
- ERR("keyboard queue is overflow.\n");
- return;
- }
-
- if (*index == VIRTIO_KBD_QUEUE_SIZE) {
- *index = 0;
- }
-
- if (keycode < 0xe0) {
- if (vkbd->extension_key) {
- switch (keycode & 0x7f) {
- case 28: /* KP_Enter */
- kbdevt.code = 96;
- break;
- case 29: /* Right Ctrl */
- kbdevt.code = 97;
- break;
- case 56: /* Right Alt */
- kbdevt.code = 100;
- break;
- case 71: /* Home */
- kbdevt.code = 102;
- break;
- case 72: /* Up */
- kbdevt.code = 103;
- break;
- case 73: /* Page Up */
- kbdevt.code = 104;
- break;
- case 75: /* Left */
- kbdevt.code = 105;
- break;
- case 77: /* Right */
- kbdevt.code = 106;
- break;
- case 79: /* End */
- kbdevt.code = 107;
- break;
- case 80: /* Down */
- kbdevt.code = 108;
- break;
- case 81: /* Page Down */
- kbdevt.code = 109;
- break;
- case 82: /* Insert */
- kbdevt.code = 110;
- break;
- case 83: /* Delete */
- kbdevt.code = 111;
- break;
- default:
- WARN("There is no keymap for this keycode %d.\n", keycode);
- }
- vkbd->extension_key = 0;
+ QTAILQ_FOREACH(entry, &events_queue, node) {
+ VirtQueueElement element;
+ EmulKbdEvent *event = &entry->event;
+
+ if (virtqueue_pop(vkbd->vq, &element)) {
+ len = iov_from_buf(element.in_sg, element.in_num,
+ 0, event, sizeof(EmulKbdEvent));
+ virtqueue_push(vkbd->vq, &element, len);
} else {
- kbdevt.code = keycode & 0x7f;
+ ERR("virtqueue is not available, dropping event.\n");
+ break;
}
- if (!(keycode & 0x80)) {
- kbdevt.type = 1; /* KEY_PRESSED */
- } else {
- kbdevt.type = 0; /* KEY_RELEASED */
- }
- } else {
- TRACE("Extension key.\n");
- kbdevt.code = keycode;
- vkbd->extension_key = 1;
+ ++(vkbd->avail_buf_cnt);
}
-
- qemu_mutex_lock(&vkbd->event_mutex);
- memcpy(&vkbd->kbdqueue.kbdevent[(*index)++], &kbdevt, sizeof(kbdevt));
- TRACE("event: keycode %d, type %d, index %d.\n",
- kbdevt.code, kbdevt.type, ((*index) - 1));
-
- vkbd->kbdqueue.wptr++;
+ QTAILQ_INIT(&events_queue);
qemu_mutex_unlock(&vkbd->event_mutex);
- TRACE("[Leave] input_event handler. cnt:%d\n", vkbd->kbdqueue.wptr);
-
- qemu_bh_schedule(vkbd->bh);
+ virtio_notify(VIRTIO_DEVICE(vkbd), vkbd->vq);
}
static uint64_t virtio_keyboard_get_features(VirtIODevice *vdev,
static void virtio_keyboard_bh(void *opaque)
{
- virtio_keyboard_notify(opaque);
+ virtio_keyboard_send(opaque);
}
static void virtio_keyboard_device_realize(DeviceState *dev, Error **errp)
virtio_init(vdev, TYPE_VIRTIO_MARU_KEYBOARD, VIRTIO_ID_MARU_KEYBOARD, 0);
- memset(&vkbd->kbdqueue, 0x00, sizeof(vkbd->kbdqueue));
vkbd->extension_key = 0;
- qemu_mutex_init(&vkbd->event_mutex);
vkbd->vq = virtio_add_queue(vdev, 128, virtio_keyboard_handle);
vkbd->qdev = dev;
} else {
add_to_list(vkbd, true);
}
+
+ qemu_mutex_init(&vkbd->event_mutex);
}
static void virtio_keyboard_device_unrealize(DeviceState *dev, Error **errp)
static void virtio_keyboard_device_reset(VirtIODevice *vdev)
{
- VirtIOKeyboard *vkbd = curr->vkbd;
- vkbd = VIRTIO_MARU_KEYBOARD(vdev);
+ VirtIOKeyboard *vkbd = (VirtIOKeyboard *)vdev;
INFO("reset keyboard device\n");
- vkbd->kbdqueue.rptr = 0;
- vkbd->kbdqueue.index = 0;
+
+ qemu_mutex_lock(&vkbd->event_mutex);
+ vkbd->event_cnt = 0;
+ vkbd->avail_buf_cnt = MAX_EVENT_CNT;
+
+ QTAILQ_INIT(&events_queue);
+ qemu_mutex_unlock(&vkbd->event_mutex);
}
static void virtio_keyboard_class_init(ObjectClass *klass, void *data)
/*
* Maru Virtio Touchscreen Device
*
- * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2011 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
*
* Contact:
+ * SeokYeon Hwang <syeon.hwang@samsung.com>
* GiWoong Kim <giwoong.kim@samsung.com>
- * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
*/
-#include <pthread.h>
+#include "qemu/iov.h"
#include "maru_virtio_touchscreen.h"
#include "hw/maru_device_ids.h"
+
#include "debug_ch.h"
-MULTI_DEBUG_CHANNEL(qemu, tsp);
+DECLARE_DEBUG_CHANNEL(tsp);
#define DEVICE_NAME "virtio-touchscreen"
+#define VIRTIO_MARU_TOUCHSCREEN(obj) \
+ OBJECT_CHECK(VirtIOTouchscreen, (obj), TYPE_VIRTIO_MARU_TOUCHSCREEN)
+
+#define TOUCHSCREEN_OPTION_NAME "max_point"
+#define MAX_EVENT_CNT 256
+
+/* This structure must match the kernel definitions */
+typedef struct EmulTouchEvent {
+ uint16_t x, y, z;
+ uint8_t state;
+} EmulTouchEvent;
+
/*
* touch event queue
*/
typedef struct TouchEventEntry {
- unsigned int index;
- EmulTouchEvent touch;
+ EmulTouchEvent event;
QTAILQ_ENTRY(TouchEventEntry) node;
} TouchEventEntry;
-/* the maximum number of touch event that can be put into a queue */
-#define MAX_TOUCH_EVENT_CNT 256
-
-static TouchEventEntry _events_buf[MAX_TOUCH_EVENT_CNT];
+static TouchEventEntry events_buf[MAX_EVENT_CNT];
static QTAILQ_HEAD(, TouchEventEntry) events_queue =
QTAILQ_HEAD_INITIALIZER(events_queue);
-static unsigned int event_ringbuf_cnt; /* _events_buf */
-static unsigned int event_queue_cnt; /* events_queue */
-
-/*
- * VirtQueueElement queue
- */
-typedef struct ElementEntry {
- unsigned int el_index;
- unsigned int sg_index;
- VirtQueueElement elem;
-
- QTAILQ_ENTRY(ElementEntry) node;
-} ElementEntry;
-
-static ElementEntry _elem_buf[10];
-static QTAILQ_HEAD(, ElementEntry) elem_queue =
- QTAILQ_HEAD_INITIALIZER(elem_queue);
-
-static unsigned int elem_ringbuf_cnt; /* _elem_buf */
-static unsigned int elem_queue_cnt; /* elem_queue */
-
-
-VirtIOTouchscreen *ts;
-
-/* lock for between communication thread and IO thread */
-static pthread_mutex_t event_mutex = PTHREAD_MUTEX_INITIALIZER;
-static pthread_mutex_t elem_mutex = PTHREAD_MUTEX_INITIALIZER;
+static VirtIOTouchscreen *ts;
bool virtio_touchscreen_ready(void)
{
return virtio_queue_ready(ts->vq) != 0;
}
+int virtio_touchscreen_get_max_touch_point(void)
+{
+ if (ts) {
+ return ts->max_finger;
+ } else {
+ return 1;
+ }
+}
+
void virtio_touchscreen_event(int x, int y, int z, int buttons_state)
{
TouchEventEntry *entry = NULL;
if (unlikely(!virtio_queue_ready(ts->vq))) {
- ERR("virtio queue is not ready\n");
+ LOG_INFO("virtqueue is not ready, dropping event.\n");
return;
}
- if (unlikely(event_queue_cnt >= MAX_TOUCH_EVENT_CNT)) {
- INFO("full touch event queue, lose event\n", event_queue_cnt);
+ ++(ts->event_cnt);
- qemu_bh_schedule(ts->bh);
+ if ((ts->avail_buf_cnt)-- == 0) {
+ LOG_SEVERE("event queue is not available, dropping event.\n");
+ ++(ts->avail_buf_cnt);
return;
}
- entry = &(_events_buf[event_ringbuf_cnt % MAX_TOUCH_EVENT_CNT]);
- event_ringbuf_cnt++;
+ entry = &(events_buf[ts->event_cnt % MAX_EVENT_CNT]);
/* mouse event is copied into the queue */
- entry->touch.x = x;
- entry->touch.y = y;
- entry->touch.z = z;
- entry->touch.state = buttons_state;
+ entry->event.x = x;
+ entry->event.y = y;
+ entry->event.z = z;
+ entry->event.state = buttons_state;
- pthread_mutex_lock(&event_mutex);
-
- entry->index = ++event_queue_cnt; /* 1 ~ */
+ qemu_mutex_lock(&ts->event_mutex);
QTAILQ_INSERT_TAIL(&events_queue, entry, node);
- pthread_mutex_unlock(&event_mutex);
+ qemu_mutex_unlock(&ts->event_mutex);
- /* call maru_virtio_touchscreen_notify */
+ /* call maru_virtio_touchscreen_send */
qemu_bh_schedule(ts->bh);
- TRACE("touch event (%d) : x=%d, y=%d, z=%d, state=%d\n",
- entry->index, entry->touch.x, entry->touch.y,
- entry->touch.z, entry->touch.state);
+ LOG_TRACE("touch event: x=%d, y=%d, z=%d, state=%d\n",
+ entry->event.x, entry->event.y,
+ entry->event.z, entry->event.state);
}
static void maru_virtio_touchscreen_handle(VirtIODevice *vdev, VirtQueue *vq)
{
-#if 0 /* not used yet */
- if (ts->eh_entry == NULL) {
- void *vbuf = NULL;
- VirtQueueElement elem;
- int max_trkid = 0;
-
- virtqueue_pop(ts->vq, &elem);
- vbuf = elem.in_sg[0].iov_base;
- memcpy(&max_trkid, vbuf, sizeof(max_trkid));
-
- if (max_trkid > 0) {
- INFO("virtio touchscreen's maximum of tracking id = %d\n", max_trkid);
-
- /* register a event handler */
- ts->eh_entry = qemu_add_mouse_event_handler(
- virtio_touchscreen_event, ts, 1, "QEMU Virtio Touchscreen");
- qemu_activate_mouse_event_handler(ts->eh_entry);
-
- //TODO:
- virtqueue_push(ts->vq, &elem, 0);
- virtio_notify(&(ts->vdev), ts->vq);
- } else {
- INFO("virtio touchscreen is not added to qemu mouse event handler\n");
- }
- }
-#endif
-
- int virt_sg_index = 0;
- ElementEntry *elem_entry = NULL;
-
- TRACE("maru_virtio_touchscreen_handle\n");
-
- if (unlikely(virtio_queue_empty(ts->vq))) {
- TRACE("virtqueue is empty\n");
- return;
- }
-
- while (true) {
- elem_entry = &(_elem_buf[elem_ringbuf_cnt % 10]);
- elem_ringbuf_cnt++;
-
- virt_sg_index = virtqueue_pop(ts->vq, &elem_entry->elem);
- if (virt_sg_index == 0) {
- elem_ringbuf_cnt--;
- break;
- } else if (virt_sg_index < 0) {
- ERR("virtqueue is broken\n");
- elem_ringbuf_cnt--;
- return;
- }
-
- pthread_mutex_lock(&elem_mutex);
-
- elem_entry->el_index = ++elem_queue_cnt;
- elem_entry->sg_index = (unsigned int)virt_sg_index;
-
- /* save VirtQueueElement */
- QTAILQ_INSERT_TAIL(&elem_queue, elem_entry, node);
-
- if (ts->waitBuf == true) {
- ts->waitBuf = false;
-
- /* call maru_virtio_touchscreen_notify */
- qemu_bh_schedule(ts->bh);
- }
-
- pthread_mutex_unlock(&elem_mutex);
- }
+ // do nothing
}
-void maru_virtio_touchscreen_notify(void)
+static void maru_virtio_touchscreen_send(void *opaque)
{
- ElementEntry *elem_entry = NULL;
- unsigned int ii = 0;
+ VirtIOTouchscreen *ts = (VirtIOTouchscreen *)opaque;
+ TouchEventEntry *entry = NULL;
+ int len = 0;
- TRACE("maru_virtio_touchscreen_notify\n");
+ LOG_TRACE("%s\n", __func__);
- if (unlikely(!virtio_queue_ready(ts->vq))) {
- ERR("virtio queue is not ready\n");
- return;
- }
-
- while (true) {
- if (event_queue_cnt == 0) {
- TRACE("no event\n");
- break;
- } else if (elem_queue_cnt == 0) {
- TRACE("no buffer\n");
+ qemu_mutex_lock(&ts->event_mutex);
+ QTAILQ_FOREACH(entry, &events_queue, node) {
+ VirtQueueElement element;
+ EmulTouchEvent *event = &entry->event;
- pthread_mutex_lock(&elem_mutex);
- /* maybe next time */
- ts->waitBuf = true;
- pthread_mutex_unlock(&elem_mutex);
+ if (virtqueue_pop(ts->vq, &element)) {
+ len = iov_from_buf(element.in_sg, element.in_num,
+ 0, event, sizeof(EmulTouchEvent));
+ virtqueue_push(ts->vq, &element, len);
+ } else {
+ ERR("virtqueue is not available, dropping event.\n");
break;
}
- elem_entry = QTAILQ_FIRST(&elem_queue);
-
- if (elem_entry->sg_index > 0) {
- TouchEventEntry *event_entry = NULL;
- VirtQueueElement *element = NULL;
- void *vbuf = NULL;
-
- element = &elem_entry->elem;
- vbuf = element->in_sg[elem_entry->sg_index - 1].iov_base;
-
- /* get touch event from host queue */
- event_entry = QTAILQ_FIRST(&events_queue);
-
- TRACE("touch(%d) : x=%d, y=%d, z=%d, state=%d | \
- event_queue_cnt=%d, elem.index=%d, elem.in_num=%d, sg_index=%d\n",
- event_entry->index, event_entry->touch.x, event_entry->touch.y,
- event_entry->touch.z, event_entry->touch.state,
- event_queue_cnt, element->index, element->in_num,
- elem_entry->sg_index);
-
- /* copy event into virtio buffer */
- memcpy(vbuf, &(event_entry->touch), sizeof(event_entry->touch));
-
- pthread_mutex_lock(&event_mutex);
-
- /* remove host event */
- QTAILQ_REMOVE(&events_queue, event_entry, node);
- event_queue_cnt--;
-
- pthread_mutex_unlock(&event_mutex);
-
- /* put buffer into virtio queue */
- virtqueue_fill(ts->vq, element, sizeof(EmulTouchEvent), ii++);
- }
-
- pthread_mutex_lock(&elem_mutex);
-
- QTAILQ_REMOVE(&elem_queue, elem_entry, node);
- elem_queue_cnt--;
-
- pthread_mutex_unlock(&elem_mutex);
+ ++(ts->avail_buf_cnt);
}
+ QTAILQ_INIT(&events_queue);
+ qemu_mutex_unlock(&ts->event_mutex);
- if (ii != 0) {
- /* signal other side */
- virtqueue_flush(ts->vq, ii);
- /* notify to guest */
- virtio_notify(&(ts->vdev), ts->vq);
- }
+ virtio_notify(VIRTIO_DEVICE(ts), ts->vq);
}
static void virtio_touchscreen_get_config(
VirtIODevice *vdev, uint8_t *config_data)
{
int max_trkid = 10;
- INFO("virtio_touchscreen_get_config\n");
+
+ LOG_TRACE("%s\n", __func__);
max_trkid = ts->max_finger;
memcpy(config_data, &max_trkid, 4);
static void maru_touchscreen_bh(void *opaque)
{
- //TouchscreenState *ts = (TouchscreenState *)opaque;
-
- maru_virtio_touchscreen_notify();
+ maru_virtio_touchscreen_send(opaque);
}
static void virtio_touchscreen_device_realize(DeviceState *dev, Error **errp)
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
ts = VIRTIO_MARU_TOUCHSCREEN(dev);
- INFO("initialize touchscreen device : %d\n", ts->max_finger);
+ LOG_INFO("%s: %d\n", __func__, ts->max_finger);
virtio_init(vdev, DEVICE_NAME, VIRTIO_ID_MARU_TOUCHSCREEN, 4);
- /*if (ts == NULL) {
- ERR("failed to initialize the touchscreen device\n");
- return NULL;
- }*/
// TODO: reduce size
ts->vq = virtio_add_queue(&ts->vdev, 64, maru_virtio_touchscreen_handle);
/* bottom halves */
ts->bh = qemu_bh_new(maru_touchscreen_bh, ts);
+
+ qemu_mutex_init(&ts->event_mutex);
}
static void virtio_touchscreen_device_unrealize(DeviceState *dev, Error **errp)
{
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
+ VirtIOTouchscreen *ts = VIRTIO_MARU_TOUCHSCREEN(vdev);
- INFO("exit the touchscreen device\n");
+ LOG_INFO("%s\n", __func__);
if (ts->bh) {
qemu_bh_delete(ts->bh);
}
- virtio_cleanup(vdev);
+ qemu_mutex_destroy(&ts->event_mutex);
- pthread_mutex_destroy(&event_mutex);
- pthread_mutex_destroy(&elem_mutex);
+ virtio_cleanup(vdev);
}
static Property virtio_touchscreen_properties[] = {
static void virtio_touchscreen_device_reset(VirtIODevice *vdev)
{
- TouchEventEntry *event_entry = NULL;
- ElementEntry *elem_entry = NULL;
+ VirtIOTouchscreen *ts = VIRTIO_MARU_TOUCHSCREEN(vdev);
- INFO("reset the touchscreen device\n");
+ LOG_INFO("%s\n", __func__);
+ qemu_mutex_lock(&ts->event_mutex);
/* reset the counters */
- event_ringbuf_cnt = 0;
- elem_ringbuf_cnt = 0;
+ ts->event_cnt = 0;
+ ts->avail_buf_cnt = MAX_EVENT_CNT;
/* reset queue */
- pthread_mutex_lock(&event_mutex);
- while (event_queue_cnt > 0) {
- event_entry = QTAILQ_FIRST(&events_queue);
- QTAILQ_REMOVE(&events_queue, event_entry, node);
-
- event_queue_cnt--;
- }
- pthread_mutex_unlock(&event_mutex);
-
- pthread_mutex_lock(&elem_mutex);
- while (elem_queue_cnt > 0) {
- elem_entry = QTAILQ_FIRST(&elem_queue);
- QTAILQ_REMOVE(&elem_queue, elem_entry, node);
-
- elem_queue_cnt--;
- }
-
- ts->waitBuf = false;
- pthread_mutex_unlock(&elem_mutex);
+ QTAILQ_INIT(&events_queue);
+ qemu_mutex_unlock(&ts->event_mutex);
}
static void virtio_touchscreen_class_init(ObjectClass *klass, void *data)