virtio-keyboard: add keyboard event queue.
authorKitae Kim <kt920.kim@samsung.com>
Wed, 7 Nov 2012 13:40:07 +0000 (22:40 +0900)
committerKitae Kim <kt920.kim@samsung.com>
Thu, 8 Nov 2012 01:14:04 +0000 (10:14 +0900)
Changed a way to manager event handler and virtqueue notifier as increasing an eventqueue.

Signed-off-by: Kitae Kim <kt920.kim@samsung.com>
hw/virtio-pci.c
tizen/src/hw/maru_codec.c
tizen/src/hw/maru_virtio_keyboard.c
tizen/src/hw/maru_virtio_keyboard.h
tizen/src/skin/maruskin_operation.c

index 75ad478..579d05b 100644 (file)
@@ -943,6 +943,7 @@ static void virtio_keyboard_exit_pci(PCIDevice *pci_dev)
 {
     VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
 
+    mloop_evcmd_set_hostkbd(NULL);
     virtio_pci_stop_ioeventfd(proxy);
     virtio_keyboard_exit(proxy->vdev);
     virtio_exit_pci(pci_dev);
index 7fe4895..c5c6b19 100644 (file)
@@ -949,7 +949,8 @@ int qemu_avcodec_decode_audio(SVCodecState *s, int ctx_index)
 
     memcpy((uint8_t *)s->vaddr + offset, &avctx->bit_rate, sizeof(int));
     size = sizeof(int);
-    memcpy((uint8_t *)s->vaddr + offset + size, &avctx->sample_rate, sizeof(int));
+    memcpy((uint8_t *)s->vaddr + offset + size,
+                       &avctx->sample_rate, sizeof(int));
     size += sizeof(int);
     memcpy((uint8_t *)s->vaddr + offset + size, &avctx->channels, sizeof(int));
     size += sizeof(int);
index 4fb894a..9926a5f 100644 (file)
 MULTI_DEBUG_CHANNEL(qemu, virtio-kbd);
 
 #define VIRTIO_KBD_DEVICE_NAME "virtio-keyboard"
+#define VIRTIO_KBD_QUEUE_SIZE  10
 
-typedef struct EmulKbdEvent
-{
+typedef struct EmulKbdEvent {
     uint16_t code;
     uint16_t type;
 } EmulKbdEvent;
 
-typedef struct VirtIOKeyboard
-{
+typedef struct VirtIOKbdQueue {
+    EmulKbdEvent kbdevent[VIRTIO_KBD_QUEUE_SIZE];
+    int index;
+    int rptr, wptr;
+} VirtIOKbdQueue;
+
+typedef struct VirtIOKeyboard {
     VirtIODevice    vdev;
     VirtQueue       *vq;
     DeviceState     *qdev;
-    EmulKbdEvent    kbdevent;
-    short           extension_key;
+    uint16_t        extension_key;
+
+    VirtIOKbdQueue  kbdqueue;
+    QemuMutex       event_mutex;
 } VirtIOKeyboard;
 
 VirtQueueElement elem;
 
-static void virtio_keyboard_handle (VirtIODevice *vdev, VirtQueue *vq)
+static void virtio_keyboard_handle(VirtIODevice *vdev, VirtQueue *vq)
 {
     VirtIOKeyboard *vkbd = (VirtIOKeyboard *)vdev;
+    int index = 0;
 
     TRACE("virtqueue handler.\n");
     if (virtio_queue_empty(vkbd->vq)) {
-        INFO("virtio_keyboard: virtqueue is empty.\n");
+        INFO("virtqueue is empty.\n");
         return;
     }
 
     /* Get a queue buffer which is written by guest side. */
-    virtqueue_pop(vq, &elem);
+    do {
+        index = virtqueue_pop(vq, &elem);
+        TRACE("virtqueue pop. index: %d\n", index);
+    } while(index < VIRTIO_KBD_QUEUE_SIZE);
 }
 
-void virtio_keyboard_notify (void *opaque)
+void virtio_keyboard_notify(void *opaque)
 {
     VirtIOKeyboard *vkbd = (VirtIOKeyboard *)opaque;
-    int len = sizeof(EmulKbdEvent);
+    EmulKbdEvent *kbdevt;
+    int index = 0;
+    int written_cnt = 0;
+    int *rptr = NULL;
+
+    if (!vkbd) {
+        ERR("VirtIOKeyboard is NULL.\n");
+        return;
+    }
+
+    // TODO : need to lock??
+    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 0
-    TRACE("virtio_keyboard_notify: code:%d, type:%d\n",
-        vkbd->kbdevent.code, vkbd->kbdevent.type);
-#endif
-    TRACE("virtqueue notifier.\n");
     if (!virtio_queue_ready(vkbd->vq)) {
-        INFO("virtio_keyboard: virtqueue is not ready.\n");
+        INFO("virtqueue is not ready.\n");
         return;
     }
 
-    /* Copy keyboard data into guest side. */
-    memcpy(elem.in_sg[0].iov_base, &vkbd->kbdevent, len);
+    if (vkbd->kbdqueue.rptr == VIRTIO_KBD_QUEUE_SIZE) {
+        *rptr = 0;
+    }
+
+    while ((written_cnt--)) {
+        index = *rptr;
+        kbdevt = &vkbd->kbdqueue.kbdevent[index];
+
+        /* Copy keyboard data into guest side. */
+        TRACE("copy: keycode %d, type %d, index %d\n", kbdevt->code, kbdevt->type, index);
+        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--;
+        }
+        qemu_mutex_unlock(&vkbd->event_mutex);
+
+        (*rptr)++;
+        if (*rptr == VIRTIO_KBD_QUEUE_SIZE) {
+            *rptr = 0;
+        }
+    }
 
-    virtqueue_push(vkbd->vq, &elem, len);
+    virtqueue_push(vkbd->vq, &elem, sizeof(EmulKbdEvent));
     virtio_notify(&vkbd->vdev, vkbd->vq);
+
+    TRACE("[Leave] virtqueue notifier.\n");
 }
 
-static void virtio_keyboard_event (void *opaque, int keycode)
+static void virtio_keyboard_event(void *opaque, int keycode)
 {
+    EmulKbdEvent kbdevt;
+    int *index = NULL;
     VirtIOKeyboard *vkbd = (VirtIOKeyboard *)opaque;
 
-    TRACE("keyborad input_event handler.\n");
+    if (!vkbd) {
+        ERR("VirtIOKeyboard is NULL.\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 71:    // Home
-                    vkbd->kbdevent.code = 102;
-                    break;
-                case 72:    // Up
-                    vkbd->kbdevent.code = 103;
-                    break;
-                case 73:    // Page Up
-                    vkbd->kbdevent.code = 104;
-                    break;
-                case 75:    // Left
-                    vkbd->kbdevent.code = 105;
-                    break;
-                case 77:    // Right
-                    vkbd->kbdevent.code = 106;
-                    break;
-                case 79:    // End
-                    vkbd->kbdevent.code = 107;
-                    break;
-                case 80:    // Down
-                    vkbd->kbdevent.code = 108;
-                    break;
-                case 81:    // Page Down
-                    vkbd->kbdevent.code = 109;
-                    break;
-                case 82:    // Insert
-                    vkbd->kbdevent.code = 110;
-                    break;
-                case 83:    // Delete
-                    vkbd->kbdevent.code = 111;
-                    break;
-                default:
-                    WARN("There is no keymap for the keycode %d.\n", keycode);
+            switch (keycode & 0x7f) {
+            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 {
-            vkbd->kbdevent.code = keycode & 0x7f;
+            kbdevt.code = keycode & 0x7f;
         }
 
         if (!(keycode & 0x80)) {
-            vkbd->kbdevent.type = 1;    /* KEY_PRESSED */
+            kbdevt.type = 1;    /* KEY_PRESSED */
         } else {
-            vkbd->kbdevent.type = 0;    /* KEY_RELEASED */
+            kbdevt.type = 0;    /* KEY_RELEASED */
         }
     } else {
         TRACE("Extension key.\n");
-        vkbd->kbdevent.code = keycode;
+        kbdevt.code = keycode;
         vkbd->extension_key = 1;
     }
 
-#if 0
-    TRACE("virito_keycode_event: keycode:%d, type:%d\n",
-        vkbd->kbdevent.code, vkbd->kbdevent.type);
-#endif
+    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);
 }
 
-static uint32_t virtio_keyboard_get_features (VirtIODevice *vdev,
-                                              uint32_t request_feature)
+static uint32_t virtio_keyboard_get_features(VirtIODevice *vdev,
+                                            uint32_t request_feature)
 {
     TRACE("virtio_keyboard_get_features.\n");
     return 0;
@@ -170,13 +240,16 @@ VirtIODevice *virtio_keyboard_init(DeviceState *dev)
 
     vkbd = (VirtIOKeyboard *)virtio_common_init(VIRTIO_KBD_DEVICE_NAME,
             VIRTIO_ID_KEYBOARD, 0, sizeof(VirtIOKeyboard));
-
     if (vkbd == NULL) {
-        ERR("failed to initialize the virtio-keyboard device\n");
+        ERR("failed to initialize device\n");
         return NULL;
     }
 
+    memset(&vkbd->kbdqueue, 0x00, sizeof(vkbd->kbdqueue));
     vkbd->extension_key = 0;
+//    vkbd->attached = 1;
+    qemu_mutex_init(&vkbd->event_mutex);
+
 
     vkbd->vdev.get_features = virtio_keyboard_get_features;
     vkbd->vq = virtio_add_queue(&vkbd->vdev, 64, virtio_keyboard_handle);
@@ -190,6 +263,9 @@ VirtIODevice *virtio_keyboard_init(DeviceState *dev)
 
 void virtio_keyboard_exit(VirtIODevice *vdev)
 {
-    INFO("destroy virtio-keyboard device\n");
+    VirtIOKeyboard *vkbd = (VirtIOKeyboard *)vdev;
+    INFO("destroy device\n");
+
+//    vkbd->attached = 0;
     virtio_cleanup(vdev);
 }
index 0e4196e..6d3c441 100644 (file)
@@ -41,7 +41,7 @@ VirtIODevice *virtio_keyboard_init(DeviceState *dev);
 
 void virtio_keyboard_exit(VirtIODevice *vdev);
 
-void virtio_keyboard_notify (void *opaque);
+void virtio_keyboard_notify(void *opaque);
 
 #ifdef __cplusplus
 }
index 01a2f46..749320e 100644 (file)
@@ -189,11 +189,10 @@ void do_key_event(int event_type, int keycode, int state_mask, int key_location)
     }
 #endif
 
-#if 0
     if (!mloop_evcmd_get_usbkbd_status()) {
+        TRACE("ignore keyboard input because usb keyboard is dettached.\n");
         return;
     }
-#endif
 
     scancode = javakeycode_to_scancode(event_type, keycode, state_mask, key_location);
 
@@ -203,10 +202,10 @@ void do_key_event(int event_type, int keycode, int state_mask, int key_location)
     }
 
     if (KEY_PRESSED == event_type) {
-               TRACE("key pressed: %d\n", scancode);
+        TRACE("key pressed: %d\n", scancode);
         kbd_put_keycode(scancode);
     } else if (KEY_RELEASED == event_type) {
-               TRACE("key released: %d\n", scancode);
+        TRACE("key released: %d\n", scancode);
         kbd_put_keycode(scancode | 0x80);
     }
 }