From: munkyu.im Date: Thu, 11 Jul 2013 15:37:51 +0000 (+0900) Subject: nfc: apply nfc device X-Git-Tag: Tizen_Studio_1.3_Release_p2.3.1~875^2~7^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a20bfe1bb93eec48bd282fbfc3a151c9213672da;p=sdk%2Femulator%2Fqemu.git nfc: apply nfc device Signed-off-by: munkyu.im --- diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c index 233009a3eb..9c83978a4b 100755 --- a/hw/virtio-pci.c +++ b/hw/virtio-pci.c @@ -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 } diff --git a/tizen/src/Makefile.tizen b/tizen/src/Makefile.tizen index 79b8dce41c..de368368e0 100755 --- a/tizen/src/Makefile.tizen +++ b/tizen/src/Makefile.tizen @@ -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 diff --git a/tizen/src/ecs.c b/tizen/src/ecs.c index 0315308e5b..ca3b42ea91 100644 --- a/tizen/src/ecs.c +++ b/tizen/src/ecs.c @@ -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 #include #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; } diff --git a/tizen/src/ecs.h b/tizen/src/ecs.h index 68dd4522dd..7c3bc4861d 100644 --- a/tizen/src/ecs.h +++ b/tizen/src/ecs.h @@ -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 diff --git a/tizen/src/hw/maru_device_ids.h b/tizen/src/hw/maru_device_ids.h index 5baffa3e4c..3775a25444 100755 --- a/tizen/src/hw/maru_device_ids.h +++ b/tizen/src/hw/maru_device_ids.h @@ -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 index 0000000000..b89517507b --- /dev/null +++ b/tizen/src/hw/maru_virtio_nfc.c @@ -0,0 +1,307 @@ +/* + * Virtio NFC Device + * + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: + * DaiYoung Kim + * YeongKyoon Lee + * + * 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 + +#include "maru_device_ids.h" +#include "maru_virtio_nfc.h" +#include "debug_ch.h" +#include "../ecs.h" + +MULTI_DEBUG_CHANNEL(qemu, virtio-nfc); + +#define VIRTIO_NFC_DEVICE_NAME "virtio-nfc" + + +enum { + IOTYPE_INPUT = 0, + IOTYPE_OUTPUT = 1 +}; + + +#ifndef min +#define min(a,b) ((a)<(b)?(a):(b)) +#endif + +#define MAX_BUF_SIZE 4096 +typedef struct VirtIO_NFC{ + VirtIODevice vdev; + VirtQueue *rvq; + VirtQueue *svq; + DeviceState *qdev; + + QEMUBH *bh; +} VirtIO_NFC; + + +VirtIO_NFC* vio_nfc; + + +typedef unsigned int CSCliSN; + +typedef struct msg_info { + char buf[MAX_BUF_SIZE]; + + uint32_t route; + uint32_t use; + uint16_t count; + uint16_t index; + + CSCliSN cclisn; +}msg_info; + +// + +typedef struct MsgInfo +{ + msg_info info; + QTAILQ_ENTRY(MsgInfo) next; +}MsgInfo; + +static QTAILQ_HEAD(MsgInfoRecvHead , MsgInfo) nfc_recv_msg_queue = + QTAILQ_HEAD_INITIALIZER(nfc_recv_msg_queue); + + +static QTAILQ_HEAD(MsgInfoSendHead , MsgInfo) nfc_send_msg_queue = + QTAILQ_HEAD_INITIALIZER(nfc_send_msg_queue); + + +// + +typedef struct EvdiBuf { + VirtQueueElement elem; + + QTAILQ_ENTRY(EvdiBuf) next; +} EvdiBuf; + +static QTAILQ_HEAD(EvdiMsgHead , EvdiBuf) nfc_in_queue = + QTAILQ_HEAD_INITIALIZER(nfc_in_queue); + +static int count = 0; + +static pthread_mutex_t recv_buf_mutex = PTHREAD_MUTEX_INITIALIZER; + +bool send_to_nfc(enum request_cmd req, char* data, const uint32_t len) +{ + MsgInfo* _msg = (MsgInfo*) malloc(sizeof(MsgInfo)); + if (!_msg) + return false; + + memset(&_msg->info, 0, sizeof(msg_info)); + + memcpy(_msg->info.buf, data, len); + _msg->info.use = len; + _msg->info.index = count++; + _msg->info.route = req; + pthread_mutex_lock(&recv_buf_mutex); + + QTAILQ_INSERT_TAIL(&nfc_recv_msg_queue, _msg, next); + + pthread_mutex_unlock(&recv_buf_mutex); + + qemu_bh_schedule(vio_nfc->bh); + + return true; +} + + +static int g_cnt = 0; + +static void flush_nfc_recv_queue(void) +{ + int index; + + if (unlikely(!virtio_queue_ready(vio_nfc->rvq))) { + INFO("virtio queue is not ready\n"); + return; + } + + if (unlikely(virtio_queue_empty(vio_nfc->rvq))) { + TRACE("virtqueue is empty\n"); + return; + } + + + pthread_mutex_lock(&recv_buf_mutex); + + while (!QTAILQ_EMPTY(&nfc_recv_msg_queue)) + { + MsgInfo* msginfo = QTAILQ_FIRST(&nfc_recv_msg_queue); + if (!msginfo) + break; + + VirtQueueElement elem; + index = virtqueue_pop(vio_nfc->rvq, &elem); + if (index == 0) + { + //ERR("unexpected empty queue"); + break; + } + + INFO(">> virtqueue_pop. index: %d, out_num : %d, in_num : %d\n", index, elem.out_num, elem.in_num); + + memcpy(elem.in_sg[0].iov_base, &msginfo->info, sizeof(struct msg_info)); + + INFO(">> send to guest count = %d, use = %d, msg = %s, iov_len = %d \n", + ++g_cnt, msginfo->info.use, msginfo->info.buf, elem.in_sg[0].iov_len); + + virtqueue_push(vio_nfc->rvq, &elem, sizeof(msg_info)); + virtio_notify(&vio_nfc->vdev, vio_nfc->rvq); + + QTAILQ_REMOVE(&nfc_recv_msg_queue, msginfo, next); + if (msginfo) + free(msginfo); + } + + pthread_mutex_unlock(&recv_buf_mutex); + +} + + +static void virtio_nfc_recv(VirtIODevice *vdev, VirtQueue *vq) +{ + flush_nfc_recv_queue(); +} + +static void send_to_ecs(struct msg_info* msg) +{ + int buf_len; + char data_len [2]; + char group [1] = { 15 }; + char action [1]; + int message_len = 0; + + char* ecs_message = NULL; + + buf_len = strlen(msg->buf); + message_len = buf_len + 14; + + ecs_message = (char*) malloc(message_len + 1); + if (!ecs_message) + return; + + memset(ecs_message, 0, message_len + 1); + + data_len[0] = buf_len; + action[0] = 0; + + memcpy(ecs_message, "nfc", 10); + memcpy(ecs_message + 10, &data_len, 2); + memcpy(ecs_message + 12, &group, 1); + memcpy(ecs_message + 13, &action, 1); + memcpy(ecs_message + 14, msg->buf, buf_len); + + INFO("ntf_to_injector- bufnum: %s, group: %s, action: %s, data: %s\n", data_len, group, action, msg->buf); + + ntf_to_injector(ecs_message, message_len); + + if (ecs_message) + free(ecs_message); +} + +static void virtio_nfc_send(VirtIODevice *vdev, VirtQueue *vq) +{ + VirtIO_NFC *vnfc = (VirtIO_NFC *)vdev; + int index = 0; + struct msg_info _msg; + + if (virtio_queue_empty(vnfc->svq)) { + INFO("<< virtqueue is empty.\n"); + return; + } + + VirtQueueElement elem; + + while ((index = virtqueue_pop(vq, &elem))) { + + INFO("<< virtqueue pop. index: %d, out_num : %d, in_num : %d\n", index, elem.out_num, elem.in_num); + + if (index == 0) { + INFO("<< virtqueue break\n"); + break; + } + + INFO("<< use=%d, iov_len = %d\n", _msg.use, elem.out_sg[0].iov_len); + + memset(&_msg, 0x00, sizeof(_msg)); + memcpy(&_msg, elem.out_sg[0].iov_base, elem.out_sg[0].iov_len); + + INFO("<< recv from guest len = %d, msg = %s \n", _msg.use, _msg.buf); + + send_to_ecs(&_msg); + + } + + virtqueue_push(vq, &elem, sizeof(VirtIO_NFC)); + virtio_notify(&vio_nfc->vdev, vq); +} + +static uint32_t virtio_nfc_get_features(VirtIODevice *vdev, + uint32_t request_feature) +{ + TRACE("virtio_nfc_get_features.\n"); + return 0; +} + +static void maru_nfc_bh(void *opaque) +{ + flush_nfc_recv_queue(); +} + +VirtIODevice *virtio_nfc_init(DeviceState *dev) +{ + INFO("initialize nfc device\n"); + + vio_nfc = (VirtIO_NFC *)virtio_common_init(VIRTIO_NFC_DEVICE_NAME, + VIRTIO_ID_NFC, 0, sizeof(VirtIO_NFC)); + if (vio_nfc == NULL) { + ERR("failed to initialize nfc device\n"); + return NULL; + } + + vio_nfc->vdev.get_features = virtio_nfc_get_features; + vio_nfc->rvq = virtio_add_queue(&vio_nfc->vdev, 256, virtio_nfc_recv); + vio_nfc->svq = virtio_add_queue(&vio_nfc->vdev, 256, virtio_nfc_send); + vio_nfc->qdev = dev; + + vio_nfc->bh = qemu_bh_new(maru_nfc_bh, vio_nfc); + + return &vio_nfc->vdev; +} + +void virtio_nfc_exit(VirtIODevice *vdev) +{ + INFO("destroy nfc device\n"); + + if (vio_nfc->bh) { + qemu_bh_delete(vio_nfc->bh); + } + + virtio_cleanup(vdev); +} + diff --git a/tizen/src/hw/maru_virtio_nfc.h b/tizen/src/hw/maru_virtio_nfc.h new file mode 100755 index 0000000000..918ea83b2e --- /dev/null +++ b/tizen/src/hw/maru_virtio_nfc.h @@ -0,0 +1,53 @@ +/* + * Virtio NFC Device + * + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: + * DaiYoung Kim + * YeongKyoon Lee + * + * 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_VIRTIO_NFC_H_ +#define MARU_VIRTIO_NFC_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "hw/virtio.h" + + +/* device protocol */ + +#define __MAX_BUF_SIZE 1024 + +VirtIODevice *virtio_nfc_init(DeviceState *dev); + +void virtio_nfc_exit(VirtIODevice *vdev); +bool send_to_nfc(enum request_cmd req, char* data, const uint32_t len); + +#ifdef __cplusplus +} +#endif + + +#endif /* MARU_VIRTIO_NFC_H_ */