update source for tizen_2.1
[sdk/emulator/qemu.git] / tizen / src / hw / maru_virtio_keyboard.c
index e331070..97f4d2a 100644 (file)
@@ -5,6 +5,7 @@
  *
  * Contact:
  *  Kitae Kim <kt920.kim@samsung.com>
+ *  GiWoong Kim <giwoong.kim@samsung.com>
  *  SeokYeon Hwang <syeon.hwang@samsung.com>
  *  YeongKyoon Lee <yeongkyoon.lee@samsung.com>
  *
  *
  */
 
-#include "mloop_event.h"
 #include "maru_device_ids.h"
 #include "maru_virtio_keyboard.h"
 #include "tizen/src/debug_ch.h"
 
+
 MULTI_DEBUG_CHANNEL(qemu, virtio-kbd);
 
 VirtQueueElement elem;
@@ -60,22 +61,13 @@ void virtio_keyboard_notify(void *opaque)
     EmulKbdEvent *kbdevt;
     int index = 0;
     int written_cnt = 0;
-    int *rptr = NULL;
 
     if (!vkbd) {
         ERR("VirtIOKeyboard is NULL.\n");
         return;
     }
 
-    qemu_mutex_lock(&vkbd->event_mutex);
-    written_cnt = vkbd->kbdqueue.wptr;
     TRACE("[Enter] virtqueue notifier. %d\n", written_cnt);
-    qemu_mutex_unlock(&vkbd->event_mutex);
-    if (written_cnt < 0) {
-        TRACE("there is no input data to copy to guest.\n");
-        return;
-    }
-    rptr = &vkbd->kbdqueue.rptr;
 
     if (!virtio_queue_ready(vkbd->vq)) {
         INFO("virtqueue is not ready.\n");
@@ -83,30 +75,32 @@ void virtio_keyboard_notify(void *opaque)
     }
 
     if (vkbd->kbdqueue.rptr == VIRTIO_KBD_QUEUE_SIZE) {
-        *rptr = 0;
+        vkbd->kbdqueue.rptr = 0;
     }
 
+    qemu_mutex_lock(&vkbd->event_mutex);
+    written_cnt = vkbd->kbdqueue.wptr;
+
     while ((written_cnt--)) {
-        index = *rptr;
-        kbdevt = &vkbd->kbdqueue.kbdevent[index];
+        kbdevt = &vkbd->kbdqueue.kbdevent[vkbd->kbdqueue.rptr];
 
         /* Copy keyboard data into guest side. */
-        TRACE("copy: keycode %d, type %d, index %d\n",
+        TRACE("copy: keycode %d, type %d, elem_index %d\n",
             kbdevt->code, kbdevt->type, index);
-        memcpy(elem.in_sg[index].iov_base, kbdevt, sizeof(EmulKbdEvent));
+        memcpy(elem.in_sg[index++].iov_base, kbdevt, sizeof(EmulKbdEvent));
         memset(kbdevt, 0x00, sizeof(EmulKbdEvent));
 
-        qemu_mutex_lock(&vkbd->event_mutex);
         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);
         }
-        qemu_mutex_unlock(&vkbd->event_mutex);
 
-        (*rptr)++;
-        if (*rptr == VIRTIO_KBD_QUEUE_SIZE) {
-            *rptr = 0;
+        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);
@@ -198,16 +192,17 @@ static void virtio_keyboard_event(void *opaque, int keycode)
         vkbd->extension_key = 1;
     }
 
+    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));
 
-    qemu_mutex_lock(&vkbd->event_mutex);
     vkbd->kbdqueue.wptr++;
     qemu_mutex_unlock(&vkbd->event_mutex);
 
     TRACE("[Leave] input_event handler. cnt:%d\n", vkbd->kbdqueue.wptr);
-    mloop_evcmd_keyboard(vkbd);
+
+    qemu_bh_schedule(vkbd->bh);
 }
 
 static uint32_t virtio_keyboard_get_features(VirtIODevice *vdev,
@@ -217,6 +212,11 @@ static uint32_t virtio_keyboard_get_features(VirtIODevice *vdev,
     return 0;
 }
 
+static void virtio_keyboard_bh(void *opaque)
+{
+    virtio_keyboard_notify(opaque);
+}
+
 VirtIODevice *virtio_keyboard_init(DeviceState *dev)
 {
     VirtIOKeyboard *vkbd;
@@ -238,6 +238,9 @@ VirtIODevice *virtio_keyboard_init(DeviceState *dev)
     vkbd->vq = virtio_add_queue(&vkbd->vdev, 64, virtio_keyboard_handle);
     vkbd->qdev = dev;
 
+    /* bottom half */
+    vkbd->bh = qemu_bh_new(virtio_keyboard_bh, vkbd);
+
     /* register keyboard handler */
     qemu_add_kbd_event_handler(virtio_keyboard_event, vkbd);
 
@@ -249,6 +252,12 @@ void virtio_keyboard_exit(VirtIODevice *vdev)
     VirtIOKeyboard *vkbd = (VirtIOKeyboard *)vdev;
     INFO("destroy device\n");
 
+    qemu_remove_kbd_event_handler();
+
+    if (vkbd->bh) {
+        qemu_bh_delete(vkbd->bh);
+    }
+
     qemu_mutex_destroy(&vkbd->event_mutex);
 
     virtio_cleanup(vdev);