From e7bb713c7d328f0726a1e40b8e045df314abc523 Mon Sep 17 00:00:00 2001 From: Kitae Kim Date: Wed, 7 Nov 2012 22:40:07 +0900 Subject: [PATCH] virtio-keyboard: add keyboard event queue. Changed a way to manager event handler and virtqueue notifier as increasing an eventqueue. Signed-off-by: Kitae Kim --- hw/virtio-pci.c | 1 + tizen/src/hw/maru_codec.c | 3 +- tizen/src/hw/maru_virtio_keyboard.c | 212 ++++++++++++++++++++++++------------ tizen/src/hw/maru_virtio_keyboard.h | 2 +- tizen/src/skin/maruskin_operation.c | 7 +- 5 files changed, 151 insertions(+), 74 deletions(-) diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c index 75ad478..579d05b 100644 --- a/hw/virtio-pci.c +++ b/hw/virtio-pci.c @@ -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); diff --git a/tizen/src/hw/maru_codec.c b/tizen/src/hw/maru_codec.c index 7fe4895..c5c6b19 100644 --- a/tizen/src/hw/maru_codec.c +++ b/tizen/src/hw/maru_codec.c @@ -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); diff --git a/tizen/src/hw/maru_virtio_keyboard.c b/tizen/src/hw/maru_virtio_keyboard.c index 4fb894a..9926a5f 100644 --- a/tizen/src/hw/maru_virtio_keyboard.c +++ b/tizen/src/hw/maru_virtio_keyboard.c @@ -36,128 +36,198 @@ 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); } diff --git a/tizen/src/hw/maru_virtio_keyboard.h b/tizen/src/hw/maru_virtio_keyboard.h index 0e4196e..6d3c441 100644 --- a/tizen/src/hw/maru_virtio_keyboard.h +++ b/tizen/src/hw/maru_virtio_keyboard.h @@ -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 } diff --git a/tizen/src/skin/maruskin_operation.c b/tizen/src/skin/maruskin_operation.c index 01a2f46..749320e 100644 --- a/tizen/src/skin/maruskin_operation.c +++ b/tizen/src/skin/maruskin_operation.c @@ -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); } } -- 2.7.4