From: SeokYeon Hwang Date: Tue, 1 Jul 2014 01:13:58 +0000 (+0900) Subject: hotplug: new device hotplug system is introduced X-Git-Tag: Tizen_Studio_1.3_Release_p2.3.1~228^2^2~100^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F26%2F23626%2F5;p=sdk%2Femulator%2Fqemu.git hotplug: new device hotplug system is introduced Do not use old hotplug logic anymore. "Hotplug logic" becomes independent of legacy mloop. "mloop" will be removed. Change-Id: Ib1c40cb9bb65e6f2d8a2310ad5a0c761184b6321 Signed-off-by: SeokYeon Hwang --- diff --git a/hw/pci/pci-hotplug-old.c b/hw/pci/pci-hotplug-old.c index 555cf72b49..cf2caebfb1 100644 --- a/hw/pci/pci-hotplug-old.c +++ b/hw/pci/pci-hotplug-old.c @@ -261,52 +261,7 @@ static PCIDevice *qemu_pci_hot_add_storage(Monitor *mon, return dev; } -#ifdef CONFIG_MARU -static PCIDevice *qemu_pci_hot_add_keyboard(Monitor *mon, - const char *devaddr, - const char *opts) -{ - PCIDevice *dev; - PCIBus *root = pci_find_primary_bus(); - PCIBus *bus; - int devfn; - - if (!root) { - monitor_printf(mon, "no primary PCI bus (if there are multiple" - " PCI roots, you must use device_add instead)"); - return NULL; - } - - bus = pci_get_bus_devfn(&devfn, root, devaddr); - if (!bus) { - monitor_printf(mon, "Invalid PCI device address %s\n", devaddr); - return NULL; - } - - if (!((BusState*)bus)->allow_hotplug) { - monitor_printf(mon, "PCI bus doesn't support hotplug\n"); - return NULL; - } - - dev = pci_create(bus, devfn, "virtio-keyboard-pci"); - if (qdev_init(&dev->qdev) < 0) { - dev = NULL; - } - - return dev; -} -#endif /* CONFIG_MARU */ - -#ifdef CONFIG_MARU -void pci_device_hot_add(Monitor *mon, const QDict *qdict) -{ - do_pci_device_hot_add(mon, qdict); -} - -PCIDevice *do_pci_device_hot_add(Monitor *mon, const QDict *qdict) -#else void pci_device_hot_add(Monitor *mon, const QDict *qdict) -#endif { PCIDevice *dev = NULL; const char *pci_addr = qdict_get_str(qdict, "pci_addr"); @@ -329,10 +284,6 @@ void pci_device_hot_add(Monitor *mon, const QDict *qdict) dev = qemu_pci_hot_add_nic(mon, pci_addr, opts); } else if (strcmp(type, "storage") == 0) { dev = qemu_pci_hot_add_storage(mon, pci_addr, opts); -#ifdef CONFIG_MARU - } else if (strcmp(type, "keyboard") == 0) { - dev = qemu_pci_hot_add_keyboard(mon, pci_addr, opts); -#endif } else { monitor_printf(mon, "invalid type: %s\n", type); } @@ -344,9 +295,6 @@ void pci_device_hot_add(Monitor *mon, const QDict *qdict) PCI_FUNC(dev->devfn)); } else monitor_printf(mon, "failed to add %s\n", opts); -#ifdef CONFIG_MARU - return dev; -#endif } static int pci_device_hot_remove(Monitor *mon, const char *pci_addr) diff --git a/tizen/src/ecs/ecs_msg.c b/tizen/src/ecs/ecs_msg.c index 227cab975d..04f93274be 100644 --- a/tizen/src/ecs/ecs_msg.c +++ b/tizen/src/ecs/ecs_msg.c @@ -67,6 +67,7 @@ #include "hw/maru_virtio_vmodem.h" #include "skin/maruskin_operation.h" #include "skin/maruskin_server.h" +#include "util/maru_device_hotplug.h" #include "emulator.h" #include "emul_state.h" @@ -509,7 +510,7 @@ bool msgproc_device_req(ECS_Client* ccli, ECS__DeviceReq* msg) } } else if (!strncmp(cmd, "HKeyboard", 8)) { if (group == MSG_GROUP_STATUS) { - send_host_keyboard_ntf(mloop_evcmd_get_hostkbd_status()); + send_host_keyboard_ntf(is_host_keyboard_attached()); } else { if (data == NULL) { ERR("HKeyboard data is NULL\n"); @@ -897,6 +898,7 @@ bool send_nfc_ntf(struct nfc_msg_info* msg) return true; } + static void handle_sdcard(char* dataBuf, size_t dataLen) { @@ -907,8 +909,7 @@ static void handle_sdcard(char* dataBuf, size_t dataLen) if (ret == '0' ) { /* umount sdcard */ - //mloop_evcmd_usbdisk(NULL); - mloop_evcmd_sdcard(NULL); + do_hotplug(DETACH_SDCARD, NULL, 0); } else if (ret == '1') { /* mount sdcard */ char sdcard_img_path[256]; @@ -930,8 +931,7 @@ static void handle_sdcard(char* dataBuf, size_t dataLen) g_strlcat(sdcard_img_path, sdcard_img_name, sizeof(sdcard_img_path)); TRACE("sdcard path: [%s]\n", sdcard_img_path); - //mloop_evcmd_usbdisk(sdcard_img_path); - mloop_evcmd_sdcard(sdcard_img_path); + do_hotplug(ATTACH_SDCARD, sdcard_img_path, strlen(sdcard_img_path) + 1); /*if using strndup than free string*/ if(pLinechange != NULL && sdcard_img_name!= NULL){ diff --git a/tizen/src/emulator.c b/tizen/src/emulator.c index b921ec8a09..b0b467a239 100644 --- a/tizen/src/emulator.c +++ b/tizen/src/emulator.c @@ -47,6 +47,7 @@ #include "skin/maruskin_server.h" #include "debug_ch.h" #include "ecs/ecs.h" +#include "util/maru_device_hotplug.h" #ifdef CONFIG_SDL #include @@ -248,6 +249,8 @@ static void prepare_basic_features(gchar * const kernel_cmdline) check_vm_lock(); make_vm_lock(); + maru_device_hotplug_init(); + qemu_add_opts(&qemu_ecs_opts); start_ecs(); diff --git a/tizen/src/mloop_event.c b/tizen/src/mloop_event.c index a341d2062c..464e295053 100644 --- a/tizen/src/mloop_event.c +++ b/tizen/src/mloop_event.c @@ -81,12 +81,7 @@ struct mloop_evpack { #define MLOOP_EVTYPE_INTR_UP 3 #define MLOOP_EVTYPE_INTR_DOWN 4 #define MLOOP_EVTYPE_TOUCH 6 -#define MLOOP_EVTYPE_KBD_ADD 8 -#define MLOOP_EVTYPE_KBD_DEL 9 #define MLOOP_EVTYPE_RAMDUMP 10 -#define MLOOP_EVTYPE_SDCARD_ATTACH 11 -#define MLOOP_EVTYPE_SDCARD_DETACH 12 - static struct mloop_evsock mloop = {-1, 0, 0}; @@ -236,10 +231,6 @@ static int mloop_evsock_send(struct mloop_evsock *ev, struct mloop_evpack *p) } static USBDevice *usbdisk = NULL; -#ifdef TARGET_I386 -static PCIDevice *hostkbd = NULL; -static PCIDevice *virtio_sdcard = NULL; -#endif static void mloop_evhandle_usb_add(char *name) { @@ -296,137 +287,6 @@ static void mloop_evhandle_touch(struct mloop_evpack* pack) maru_virtio_touchscreen_notify(); } -#ifdef TARGET_I386 -static void mloop_evhandle_kbd_add(char *name) -{ - QDict *qdict; - - TRACE("try to add a keyboard device.\n"); - - if (name == NULL) { - ERR("packet data is NULL.\n"); - return; - } - - if (hostkbd) { - INFO("virtio-keyboard has already been added.\n"); - return; - } - - qdict = qdict_new(); - qdict_put(qdict, "pci_addr", qstring_from_str("auto")); - qdict_put(qdict, "type", qstring_from_str(name)); - - hostkbd = do_pci_device_hot_add(cur_mon, qdict); - if (hostkbd) { - TRACE("virtio-keyboard device: root_bus_path %s, bus %d, slot %d, function %d\n", - pci_root_bus_path(hostkbd), pci_bus_num(hostkbd->bus), - PCI_SLOT(hostkbd->devfn), PCI_FUNC(hostkbd->devfn)); - } else { - ERR("failed to hot_add keyboard device.\n"); - } - - QDECREF(qdict); -} - -static void mloop_evhandle_kbd_del(void) -{ - QDict *qdict; - int slot = 0; - char slotbuf[4] = {0,}; - - TRACE("try to remove a keyboard device.\n"); - - if (!hostkbd) { - ERR("Failed to remove a keyboard device " - "because the device has not been created yet.\n"); - return; - } - - slot = PCI_SLOT(hostkbd->devfn); - snprintf(slotbuf, sizeof(slotbuf), "%x", slot); - TRACE("virtio-keyboard slot %s.\n", slotbuf); - - qdict = qdict_new(); - qdict_put(qdict, "pci_addr", qstring_from_str(slotbuf)); - - do_pci_device_hot_remove(cur_mon, qdict); - INFO("hot_remove keyboard.\n"); - - hostkbd = NULL; - - QDECREF(qdict); -} - -static void mloop_evhandle_sdcard_attach(char *name) -{ - char opts[PATH_MAX]; - - INFO("try to attach sdcard.\n"); - - if (name == NULL) { - ERR("Packet data is NULL.\n"); - return; - } - - if (virtio_sdcard) { - ERR("sdcard is already attached.\n"); - return; - } - - QDict *qdict = qdict_new(); - - qdict_put(qdict, "pci_addr", qstring_from_str("auto")); - qdict_put(qdict, "type", qstring_from_str("storage")); - snprintf(opts, sizeof(opts), "file=%s,if=virtio", name); - qdict_put(qdict, "opts", qstring_from_str(opts)); - - virtio_sdcard = do_pci_device_hot_add(cur_mon, qdict); - if (virtio_sdcard) { - INFO("hot add virtio storage device with [%s]\n", opts); - INFO("virtio-sdcard device: root_bus_path %s, bus %d, slot %d, function %d\n", - pci_root_bus_path(virtio_sdcard), pci_bus_num(virtio_sdcard->bus), - PCI_SLOT(virtio_sdcard->devfn), PCI_FUNC(virtio_sdcard->devfn)); - } else { - ERR("failed to create a sdcard device.\n"); - } - - QDECREF(qdict); -} - -static void mloop_evhandle_sdcard_detach(void) -{ - INFO("try to detach sdcard.\n"); - - if (!virtio_sdcard) { - ERR("sdcard is not attached yet.\n"); - return; - } - - QDict *qdict = qdict_new(); - int slot = 0; - char slotbuf[4] = {0,}; - - slot = PCI_SLOT(virtio_sdcard->devfn); - snprintf(slotbuf, sizeof(slotbuf), "%x", slot); - INFO("virtio-sdcard slot [%d].\n", slot); - qdict_put(qdict, "pci_addr", qstring_from_str(slotbuf)); - - do_pci_device_hot_remove(cur_mon, qdict); - - virtio_sdcard = NULL; - - INFO("hot remove virtio storage device.\n"); - - QDECREF(qdict); -} - -int mloop_evcmd_get_hostkbd_status(void) -{ - return hostkbd ? 1 : 0; -} -#endif - static void mloop_evhandle_ramdump(struct mloop_evpack* pack) { #define MAX_PATH 256 @@ -505,25 +365,9 @@ static void mloop_evcb_recv(struct mloop_evsock *ev) case MLOOP_EVTYPE_TOUCH: mloop_evhandle_touch(&pack); break; -#ifdef TARGET_I386 - case MLOOP_EVTYPE_KBD_ADD: - mloop_evhandle_kbd_add(pack.data); - break; - case MLOOP_EVTYPE_KBD_DEL: - mloop_evhandle_kbd_del(); - break; -#endif case MLOOP_EVTYPE_RAMDUMP: mloop_evhandle_ramdump(&pack); break; -#ifdef TARGET_I386 - case MLOOP_EVTYPE_SDCARD_ATTACH: - mloop_evhandle_sdcard_attach(pack.data); - break; - case MLOOP_EVTYPE_SDCARD_DETACH: - mloop_evhandle_sdcard_detach(); - break; -#endif default: break; } @@ -570,16 +414,6 @@ void mloop_evcmd_lower_intr(void *irq) mloop_evsock_send(&mloop, &pack); } -void mloop_evcmd_hostkbd(int on) -{ - struct mloop_evpack pack - = {MLOOP_EVTYPE_KBD_ADD, 13, "keyboard"}; - if (on == 0) { - pack.type = MLOOP_EVTYPE_KBD_DEL; - } - mloop_evsock_send(&mloop, &pack); -} - void mloop_evcmd_usbdisk(char *img) { struct mloop_evpack pack; @@ -601,27 +435,6 @@ void mloop_evcmd_usbdisk(char *img) mloop_evsock_send(&mloop, &pack); } -void mloop_evcmd_sdcard(char *img) -{ - struct mloop_evpack pack; - - if (img) { - if (strlen(img) > PACKET_LEN-5) { - ERR("The length of disk image path is greater than " - "lenth of maximum packet.\n"); - return; - } - - pack.type = MLOOP_EVTYPE_SDCARD_ATTACH; - pack.size = 5 + sprintf(pack.data, "%s", img); - } else { - pack.type = MLOOP_EVTYPE_SDCARD_DETACH; - pack.size = 5; - } - - mloop_evsock_send(&mloop, &pack); -} - void mloop_evcmd_set_usbdisk(void *dev) { usbdisk = (USBDevice *)dev; diff --git a/tizen/src/skin/maruskin_operation.c b/tizen/src/skin/maruskin_operation.c index d4fb8f97ad..31d2879ba2 100644 --- a/tizen/src/skin/maruskin_operation.c +++ b/tizen/src/skin/maruskin_operation.c @@ -50,6 +50,7 @@ #include "maruskin_server.h" #include "display/maru_display.h" #include "hw/maru_pm.h" +#include "util/maru_device_hotplug.h" #include "ecs/ecs.h" #ifdef CONFIG_HAX @@ -258,7 +259,7 @@ void do_keyboard_key_event(int event_type, #endif #if defined(TARGET_I386) - if (!mloop_evcmd_get_hostkbd_status()) { + if (!is_host_keyboard_attached()) { TRACE("ignore keyboard input because usb keyboard is dettached.\n"); return; } @@ -546,7 +547,11 @@ void do_host_kbd_enable(bool on) #if defined(TARGET_ARM) mloop_evcmd_usbkbd(on); #elif defined(TARGET_I386) - mloop_evcmd_hostkbd(on); + if (on) { + do_hotplug(ATTACH_HOST_KEYBOARD, NULL, 0); + } else { + do_hotplug(DETACH_HOST_KEYBOARD, NULL, 0); + } #endif } diff --git a/tizen/src/util/Makefile.objs b/tizen/src/util/Makefile.objs index d77c8131cd..1102f2ea23 100644 --- a/tizen/src/util/Makefile.objs +++ b/tizen/src/util/Makefile.objs @@ -14,4 +14,7 @@ obj-$(CONFIG_LINUX) += check_gl_glx.o obj-$(CONFIG_WIN32) += check_gl_wgl.o obj-$(CONFIG_DARWIN) += check_gl_cgl.o +# hotplug +obj-y += maru_device_hotplug.o + $(obj)/osutil.o: QEMU_CFLAGS += $(CURL_CFLAGS) diff --git a/tizen/src/util/maru_device_hotplug.c b/tizen/src/util/maru_device_hotplug.c new file mode 100644 index 0000000000..578161b698 --- /dev/null +++ b/tizen/src/util/maru_device_hotplug.c @@ -0,0 +1,214 @@ +/* + * Maru device hotplug + * + * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * SeokYeon Hwang + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + * + * Contributors: + * - S-Core Co., Ltd + * + */ + +#include "qemu/main-loop.h" +#include "qemu/config-file.h" +#include "hw/qdev.h" +#include "monitor/qdev.h" +#include "qmp-commands.h" +#include "sysemu/blockdev.h" +#include "qemu/event_notifier.h" + +#include "maru_common.h" +#include "emulator.h" +#include "maru_device_hotplug.h" + +#define HOST_KEYBOARD_DRIVER "virtio-keyboard-pci" +#define HOST_KEYBOARD_DEFAULT_ID "HOSTKBD0" + +#define SDCARD_DRIVE_DEFAULT_ID "SDCARD_DRIVE0" +#define SDCARD_DRIVER "virtio-blk-pci" +#define SDCARD_DEFAULT_ID "SDCARD0" + +struct maru_device_hotplug { + EventNotifier notifier; + + char *opaque; + int command; + + // FIXME: Should we query device every time ?? + bool host_keyboard_attached; + bool sdcard_attached; +}; + +static struct maru_device_hotplug *state; + +static bool do_host_keyboard_attach(void) +{ + QDict *qdict = qdict_new(); + qdict_put(qdict, "driver", qstring_from_str(HOST_KEYBOARD_DRIVER)); + qdict_put(qdict, "id", qstring_from_str(HOST_KEYBOARD_DEFAULT_ID)); + + if (do_device_add(default_mon, qdict, NULL)) { + QDECREF(qdict); + // TODO error reporting + return false; + } + + QDECREF(qdict); + + state->host_keyboard_attached = true; + + return true; +} + +static bool do_host_keyboard_detach(void) +{ + QDict *qdict = qdict_new(); + qdict_put(qdict, "id", qstring_from_str(HOST_KEYBOARD_DEFAULT_ID)); + + if (qmp_marshal_input_device_del(default_mon, qdict, NULL)) { + QDECREF(qdict); + // TODO error reporting + return false; + } + + QDECREF(qdict); + + state->host_keyboard_attached = false; + + return true; +} + +static bool do_sdcard_attach(const char * const file) +{ + QDict *qdict = qdict_new(); + QDict *qdict_file = qdict_new(); + QDict *qdict_options = qdict_new(); + + qdict_put(qdict_file, "driver", qstring_from_str("file")); + qdict_put(qdict_file, "filename", qstring_from_str(file)); + qdict_put(qdict_options, "file", qdict_file); + qdict_put(qdict_options, "driver", qstring_from_str("qcow2")); + qdict_put(qdict_options, "id", qstring_from_str(SDCARD_DRIVE_DEFAULT_ID)); + qdict_put(qdict, "options", qdict_options); + + if (qmp_marshal_input_blockdev_add(default_mon, qdict, NULL)) { + QDECREF(qdict); + } + + QDECREF(qdict); + + qdict = qdict_new(); + qdict_put(qdict, "driver", qstring_from_str(SDCARD_DRIVER)); + qdict_put(qdict, "drive", qstring_from_str(SDCARD_DRIVE_DEFAULT_ID)); + qdict_put(qdict, "id", qstring_from_str(SDCARD_DEFAULT_ID)); + + if (do_device_add(default_mon, qdict, NULL)) { + QDECREF(qdict); + // TODO error reporting + return false; + } + + QDECREF(qdict); + + state->sdcard_attached = true; + + return true; +} + +static bool do_sdcard_detach(void) { + QDict *qdict = qdict_new(); + qdict_put(qdict, "id", qstring_from_str(SDCARD_DEFAULT_ID)); + + if (qmp_marshal_input_device_del(cur_mon, qdict, NULL)) { + QDECREF(qdict); + // TODO error reporting + return false; + } + + QDECREF(qdict); + + state->sdcard_attached = false; + + return true; +} + +void do_hotplug(int command, void *opaque, size_t size) +{ + if (command == ATTACH_SDCARD) { + state->opaque = g_malloc(size); + memcpy(state->opaque, opaque, size); + } + state->command = command; + + event_notifier_set(&state->notifier); +} + +static void device_hotplug_handler(EventNotifier *e) +{ + event_notifier_test_and_clear(e); + + switch(state->command) { + case ATTACH_HOST_KEYBOARD: + do_host_keyboard_attach(); + break; + case DETACH_HOST_KEYBOARD: + do_host_keyboard_detach(); + break; + case ATTACH_SDCARD: + do_sdcard_attach(state->opaque); + g_free(state->opaque); + break; + case DETACH_SDCARD: + do_sdcard_detach(); + break; + default: + break; + } +} + +static void maru_device_hotplug_deinit(Notifier *notifier, void *data) +{ + event_notifier_cleanup(&state->notifier); + + g_free(state); +} + +static Notifier maru_device_hotplug_exit = { .notify = maru_device_hotplug_deinit }; + +void maru_device_hotplug_init(void) +{ + state = g_malloc0(sizeof(struct maru_device_hotplug)); + + event_notifier_init(&state->notifier, 0); + event_notifier_set_handler(&state->notifier, device_hotplug_handler); + + emulator_add_exit_notifier(&maru_device_hotplug_exit); +} + +bool is_host_keyboard_attached(void) +{ + return state->host_keyboard_attached; +} + +bool is_sdcard_attached(void) +{ + return state->sdcard_attached; +} + diff --git a/tizen/src/util/maru_device_hotplug.h b/tizen/src/util/maru_device_hotplug.h new file mode 100644 index 0000000000..462baf3e80 --- /dev/null +++ b/tizen/src/util/maru_device_hotplug.h @@ -0,0 +1,46 @@ +/* + * Maru device hotplug + * + * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * SeokYeon Hwang + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + * + * Contributors: + * - S-Core Co., Ltd + * + */ + +#ifndef _MARU_DEVICE_HOTPLUG_H_ +#define _MARU_DEVICE_HOTPLUG_H_ + +enum command { + ATTACH_HOST_KEYBOARD, + DETACH_HOST_KEYBOARD, + ATTACH_SDCARD, + DETACH_SDCARD, +}; + +void maru_device_hotplug_init(void); + +void do_hotplug(int command, void *opaque, size_t size); + +bool is_host_keyboard_attached(void); +bool is_sdcard_attached(void); + +#endif // _MARU_DEVICE_HOTPLUG_H_