nfc: apply nfc device
authormunkyu.im <munkyu.im@samsung.com>
Thu, 11 Jul 2013 15:37:51 +0000 (00:37 +0900)
committermunkyu.im <munkyu.im@samsung.com>
Thu, 11 Jul 2013 15:37:51 +0000 (00:37 +0900)
Signed-off-by: munkyu.im <munkyu.im@samsung.com>
hw/virtio-pci.c
tizen/src/Makefile.tizen
tizen/src/ecs.c
tizen/src/ecs.h
tizen/src/hw/maru_device_ids.h
tizen/src/hw/maru_virtio_nfc.c [new file with mode: 0755]
tizen/src/hw/maru_virtio_nfc.h [new file with mode: 0755]

index 233009a..9c83978 100755 (executable)
@@ -1038,6 +1038,29 @@ static void virtio_sensor_exit_pci(PCIDevice *pci_dev)
     virtio_exit_pci(pci_dev);
 }
 
+static int virtio_nfc_init_pci(PCIDevice *pci_dev)
+{
+    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
+    VirtIODevice *vdev;
+
+    vdev = virtio_nfc_init(&pci_dev->qdev);
+    if (!vdev) {
+        return -1;
+    }
+    virtio_init_pci(proxy, vdev);
+    return 0;
+}
+
+static void virtio_nfc_exit_pci(PCIDevice *pci_dev)
+{
+    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
+
+    virtio_pci_stop_ioeventfd(proxy);
+    virtio_evdi_exit(proxy->vdev);
+    virtio_exit_pci(pci_dev);
+}
+
+
 #endif
 
 static Property virtio_blk_properties[] = {
@@ -1369,6 +1392,19 @@ static void virtio_sensor_class_init(ObjectClass *klass, void *data) {
        dc->desc = "Emulator Sensor Virtual Device";
 }
 
+static void virtio_nfc_class_init(ObjectClass *klass, void *data) {
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = virtio_nfc_init_pci;
+    k->exit = virtio_nfc_exit_pci;
+    k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
+    k->device_id = PCI_DEVICE_ID_VIRTIO_NFC;
+    k->revision = VIRTIO_PCI_ABI_VERSION;
+    k->class_id = PCI_CLASS_OTHERS;
+    dc->reset = virtio_pci_reset;
+}
+
 
 static TypeInfo virtio_sensor_info = {
     .name          = "virtio-sensor-pci",
@@ -1377,6 +1413,13 @@ static TypeInfo virtio_sensor_info = {
     .class_init    = virtio_sensor_class_init,
 };
 
+static TypeInfo virtio_nfc_info = {
+    .name          = "virtio-nfc-pci",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(VirtIOPCIProxy),
+    .class_init    = virtio_nfc_class_init,
+};
+
 #endif /* CONFIG_MARU */
 
 static void virtio_pci_register_types(void)
@@ -1396,6 +1439,7 @@ static void virtio_pci_register_types(void)
     type_register_static(&virtio_hwkey_info);
     type_register_static(&virtio_evdi_info);
     type_register_static(&virtio_sensor_info);
+    type_register_static(&virtio_nfc_info);
 #endif
 }
 
index 79b8dce..de36836 100755 (executable)
@@ -118,6 +118,7 @@ obj-y += maru_virtio_esm.o
 obj-y += maru_virtio_hwkey.o
 obj-y += maru_virtio_evdi.o
 obj-y += maru_virtio_sensor.o
+obj-y += maru_virtio_nfc.o
 
 obj-$(CONFIG_PCI) += maru_camera_common_pci.o
 obj-$(CONFIG_LINUX) += maru_camera_linux_pci.o
index 0315308..ca3b42e 100644 (file)
@@ -21,6 +21,7 @@
 #include "ecs.h"
 #include "hw/maru_virtio_evdi.h"
 #include "hw/maru_virtio_sensor.h"
+#include "hw/maru_virtio_nfc.h"
 #include <stdbool.h>
 #include <pthread.h>
 #include "base64.h"
@@ -873,7 +874,15 @@ static bool device_command_proc(ECS_Client *clii, QObject *obj) {
                } else {
                        set_sensor_data(length, data);
                }
-       }
+       }else if (!strncmp(cmd, MSG_TYPE_NFC, 3)) {
+        if (group == MSG_GROUP_STATUS) {
+                   send_to_nfc(request_get, data, length);     
+               } else {
+                   send_to_nfc(request_set, data, length);     
+
+               }
+    }
+
 
        return true;
 }
index 68dd452..7c3bc48 100644 (file)
@@ -45,6 +45,7 @@
 #define ECS_MSG_STARTINFO_ANS  "startinfo_ans"
 
 #define MSG_TYPE_SENSOR                        "sensor"
+#define MSG_TYPE_NFC                   "nfc"
 
 #define MSG_GROUP_STATUS               15
 
index 5baffa3..3775a25 100755 (executable)
@@ -55,6 +55,7 @@
 #define PCI_DEVICE_ID_VIRTIO_HWKEY       0x1028
 #define PCI_DEVICE_ID_VIRTIO_EVDI        0x102C
 #define PCI_DEVICE_ID_VIRTIO_SENSOR      0x1030
+#define PCI_DEVICE_ID_VIRTIO_NFC         0x1034
 
 /* Virtio */
 /*
@@ -89,5 +90,6 @@
 #define VIRTIO_ID_HWKEY         14
 #define VIRTIO_ID_EVDI          15
 #define VIRTIO_ID_SENSOR        16
+#define VIRTIO_ID_NFC           17
 
 #endif /* MARU_DEVICE_IDS_H_ */
diff --git a/tizen/src/hw/maru_virtio_nfc.c b/tizen/src/hw/maru_virtio_nfc.c
new file mode 100755 (executable)
index 0000000..b895175
--- /dev/null
@@ -0,0 +1,307 @@
+/*\r
+ * Virtio NFC Device\r
+ *\r
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Contact:\r
+ *  DaiYoung Kim <munkyu.im@samsung.com>\r
+ *  YeongKyoon Lee <yeongkyoon.lee@samsung.com>\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ *\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, write to the Free Software\r
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.\r
+ *\r
+ * Contributors:\r
+ * - S-Core Co., Ltd\r
+ *\r
+ */\r
+\r
+#include <pthread.h>\r
+\r
+#include "maru_device_ids.h"\r
+#include "maru_virtio_nfc.h"\r
+#include "debug_ch.h"\r
+#include "../ecs.h"\r
+\r
+MULTI_DEBUG_CHANNEL(qemu, virtio-nfc);\r
+\r
+#define VIRTIO_NFC_DEVICE_NAME "virtio-nfc"\r
+\r
+\r
+enum {\r
+       IOTYPE_INPUT = 0,\r
+       IOTYPE_OUTPUT = 1\r
+};\r
+\r
+\r
+#ifndef min\r
+#define min(a,b) ((a)<(b)?(a):(b))\r
+#endif\r
+\r
+#define MAX_BUF_SIZE    4096\r
+typedef struct VirtIO_NFC{\r
+    VirtIODevice    vdev;\r
+    VirtQueue       *rvq;\r
+    VirtQueue          *svq;\r
+    DeviceState     *qdev;\r
+\r
+    QEMUBH *bh;\r
+} VirtIO_NFC;\r
+\r
+\r
+VirtIO_NFC* vio_nfc;\r
+\r
+\r
+typedef unsigned int CSCliSN;\r
+\r
+typedef struct msg_info {\r
+       char buf[MAX_BUF_SIZE];\r
+\r
+       uint32_t route;\r
+       uint32_t use;\r
+       uint16_t count;\r
+       uint16_t index;\r
+\r
+       CSCliSN cclisn;\r
+}msg_info;\r
+\r
+//\r
+\r
+typedef struct MsgInfo\r
+{\r
+       msg_info info;\r
+       QTAILQ_ENTRY(MsgInfo) next;\r
+}MsgInfo;\r
+\r
+static QTAILQ_HEAD(MsgInfoRecvHead , MsgInfo) nfc_recv_msg_queue =\r
+    QTAILQ_HEAD_INITIALIZER(nfc_recv_msg_queue);\r
+\r
+\r
+static QTAILQ_HEAD(MsgInfoSendHead , MsgInfo) nfc_send_msg_queue =\r
+    QTAILQ_HEAD_INITIALIZER(nfc_send_msg_queue);\r
+\r
+\r
+//\r
+\r
+typedef struct EvdiBuf {\r
+    VirtQueueElement elem;\r
+\r
+    QTAILQ_ENTRY(EvdiBuf) next;\r
+} EvdiBuf;\r
+\r
+static QTAILQ_HEAD(EvdiMsgHead , EvdiBuf) nfc_in_queue =\r
+    QTAILQ_HEAD_INITIALIZER(nfc_in_queue);\r
+\r
+static int count = 0;\r
+\r
+static pthread_mutex_t recv_buf_mutex = PTHREAD_MUTEX_INITIALIZER;\r
+\r
+bool send_to_nfc(enum request_cmd req, char* data, const uint32_t len)\r
+{\r
+    MsgInfo* _msg = (MsgInfo*) malloc(sizeof(MsgInfo));\r
+    if (!_msg)\r
+        return false;\r
+\r
+    memset(&_msg->info, 0, sizeof(msg_info));\r
+\r
+    memcpy(_msg->info.buf, data, len);\r
+    _msg->info.use = len;\r
+    _msg->info.index = count++;\r
+    _msg->info.route = req;\r
+    pthread_mutex_lock(&recv_buf_mutex);\r
+\r
+    QTAILQ_INSERT_TAIL(&nfc_recv_msg_queue, _msg, next);\r
+\r
+    pthread_mutex_unlock(&recv_buf_mutex);\r
+\r
+       qemu_bh_schedule(vio_nfc->bh);\r
+\r
+       return true;\r
+}\r
+\r
+\r
+static int g_cnt = 0;\r
+\r
+static void flush_nfc_recv_queue(void)\r
+{\r
+       int index;\r
+\r
+    if (unlikely(!virtio_queue_ready(vio_nfc->rvq))) {\r
+        INFO("virtio queue is not ready\n");\r
+        return;\r
+    }\r
+\r
+       if (unlikely(virtio_queue_empty(vio_nfc->rvq))) {\r
+               TRACE("virtqueue is empty\n");\r
+               return;\r
+       }\r
+\r
+\r
+       pthread_mutex_lock(&recv_buf_mutex);\r
+\r
+       while (!QTAILQ_EMPTY(&nfc_recv_msg_queue))\r
+       {\r
+                MsgInfo* msginfo = QTAILQ_FIRST(&nfc_recv_msg_queue);\r
+                if (!msginfo)\r
+                        break;\r
+\r
+                VirtQueueElement elem;\r
+                index = virtqueue_pop(vio_nfc->rvq, &elem);\r
+                if (index == 0)\r
+                {\r
+                        //ERR("unexpected empty queue");\r
+                        break;\r
+                }\r
+\r
+                INFO(">> virtqueue_pop. index: %d, out_num : %d, in_num : %d\n", index, elem.out_num, elem.in_num);\r
+\r
+                memcpy(elem.in_sg[0].iov_base, &msginfo->info, sizeof(struct msg_info));\r
+\r
+                INFO(">> send to guest count = %d, use = %d, msg = %s, iov_len = %d \n",\r
+                                ++g_cnt, msginfo->info.use, msginfo->info.buf, elem.in_sg[0].iov_len);\r
+\r
+                virtqueue_push(vio_nfc->rvq, &elem, sizeof(msg_info));\r
+                virtio_notify(&vio_nfc->vdev, vio_nfc->rvq);\r
+\r
+                QTAILQ_REMOVE(&nfc_recv_msg_queue, msginfo, next);\r
+                if (msginfo)\r
+                        free(msginfo);\r
+       }\r
+\r
+       pthread_mutex_unlock(&recv_buf_mutex);\r
+\r
+}\r
+\r
+\r
+static void virtio_nfc_recv(VirtIODevice *vdev, VirtQueue *vq)\r
+{\r
+       flush_nfc_recv_queue();\r
+}\r
+\r
+static void send_to_ecs(struct msg_info* msg)\r
+{\r
+       int buf_len;\r
+       char data_len [2];\r
+       char group [1] = { 15 }; \r
+       char action [1];\r
+       int message_len = 0;\r
+\r
+       char* ecs_message = NULL;\r
+       \r
+       buf_len = strlen(msg->buf);\r
+       message_len =  buf_len + 14;\r
+\r
+       ecs_message = (char*) malloc(message_len + 1);\r
+       if (!ecs_message)\r
+               return;\r
+\r
+       memset(ecs_message, 0, message_len + 1);\r
+\r
+       data_len[0] = buf_len;\r
+       action[0] = 0;\r
+\r
+       memcpy(ecs_message, "nfc", 10);\r
+       memcpy(ecs_message + 10, &data_len, 2);\r
+       memcpy(ecs_message + 12, &group, 1);\r
+       memcpy(ecs_message + 13, &action, 1);\r
+       memcpy(ecs_message + 14, msg->buf, buf_len);\r
+\r
+       INFO("ntf_to_injector- bufnum: %s, group: %s, action: %s, data: %s\n", data_len, group, action, msg->buf);\r
+\r
+       ntf_to_injector(ecs_message, message_len);\r
+\r
+       if (ecs_message)\r
+               free(ecs_message);\r
+}\r
+\r
+static void virtio_nfc_send(VirtIODevice *vdev, VirtQueue *vq)\r
+{\r
+       VirtIO_NFC *vnfc = (VirtIO_NFC *)vdev;\r
+    int index = 0;\r
+    struct msg_info _msg;\r
+\r
+    if (virtio_queue_empty(vnfc->svq)) {\r
+        INFO("<< virtqueue is empty.\n");\r
+        return;\r
+    }\r
+\r
+    VirtQueueElement elem;\r
+\r
+    while ((index = virtqueue_pop(vq, &elem))) {\r
+\r
+               INFO("<< virtqueue pop. index: %d, out_num : %d, in_num : %d\n", index,  elem.out_num, elem.in_num);\r
+\r
+               if (index == 0) {\r
+                       INFO("<< virtqueue break\n");\r
+                       break;\r
+               }\r
+\r
+               INFO("<< use=%d, iov_len = %d\n", _msg.use, elem.out_sg[0].iov_len);\r
+\r
+               memset(&_msg, 0x00, sizeof(_msg));\r
+               memcpy(&_msg, elem.out_sg[0].iov_base, elem.out_sg[0].iov_len);\r
+\r
+               INFO("<< recv from guest len = %d, msg = %s \n", _msg.use, _msg.buf);\r
+\r
+        send_to_ecs(&_msg);\r
+\r
+    }\r
+\r
+       virtqueue_push(vq, &elem, sizeof(VirtIO_NFC));\r
+       virtio_notify(&vio_nfc->vdev, vq);\r
+}\r
+\r
+static uint32_t virtio_nfc_get_features(VirtIODevice *vdev,\r
+                                            uint32_t request_feature)\r
+{\r
+    TRACE("virtio_nfc_get_features.\n");\r
+    return 0;\r
+}\r
+\r
+static void maru_nfc_bh(void *opaque)\r
+{\r
+       flush_nfc_recv_queue();\r
+}\r
+\r
+VirtIODevice *virtio_nfc_init(DeviceState *dev)\r
+{\r
+    INFO("initialize nfc device\n");\r
+\r
+    vio_nfc = (VirtIO_NFC *)virtio_common_init(VIRTIO_NFC_DEVICE_NAME,\r
+            VIRTIO_ID_NFC, 0, sizeof(VirtIO_NFC));\r
+    if (vio_nfc == NULL) {\r
+        ERR("failed to initialize nfc device\n");\r
+        return NULL;\r
+    }\r
+\r
+    vio_nfc->vdev.get_features = virtio_nfc_get_features;\r
+    vio_nfc->rvq = virtio_add_queue(&vio_nfc->vdev, 256, virtio_nfc_recv);\r
+    vio_nfc->svq = virtio_add_queue(&vio_nfc->vdev, 256, virtio_nfc_send);\r
+    vio_nfc->qdev = dev;\r
+\r
+    vio_nfc->bh = qemu_bh_new(maru_nfc_bh, vio_nfc);\r
+\r
+    return &vio_nfc->vdev;\r
+}\r
+\r
+void virtio_nfc_exit(VirtIODevice *vdev)\r
+{\r
+    INFO("destroy nfc device\n");\r
+\r
+    if (vio_nfc->bh) {\r
+            qemu_bh_delete(vio_nfc->bh);\r
+        }\r
+\r
+    virtio_cleanup(vdev);\r
+}\r
+\r
diff --git a/tizen/src/hw/maru_virtio_nfc.h b/tizen/src/hw/maru_virtio_nfc.h
new file mode 100755 (executable)
index 0000000..918ea83
--- /dev/null
@@ -0,0 +1,53 @@
+/*\r
+ * Virtio NFC Device\r
+ *\r
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Contact:\r
+ *  DaiYoung Kim <munkyu.im@samsung.com>\r
+ *  YeongKyoon Lee <yeongkyoon.lee@samsung.com>\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ *\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, write to the Free Software\r
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.\r
+ *\r
+ * Contributors:\r
+ * - S-Core Co., Ltd\r
+ *\r
+ */\r
+\r
+#ifndef MARU_VIRTIO_NFC_H_\r
+#define MARU_VIRTIO_NFC_H_\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+#include "hw/virtio.h"\r
+\r
+\r
+/* device protocol */\r
+\r
+#define __MAX_BUF_SIZE 1024\r
+\r
+VirtIODevice *virtio_nfc_init(DeviceState *dev);\r
+\r
+void virtio_nfc_exit(VirtIODevice *vdev);\r
+bool send_to_nfc(enum request_cmd req, char* data, const uint32_t len);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+\r
+#endif /* MARU_VIRTIO_NFC_H_ */\r