From: Jinhyung Choi Date: Thu, 6 Mar 2014 05:22:54 +0000 (+0900) Subject: Jack/power/sensor: Data is moved into qemu X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=65f42eba9d431ed8fef09930ace5af03a5c36d3b;p=sdk%2Femulator%2Femulator-kernel.git Jack/power/sensor: Data is moved into qemu - data is moved into qemu - evdi logs are separated into debug and error Change-Id: Ie4ee5af44f454dcd63e34089444dd0c402b38adc Signed-off-by: Jinhyung Choi --- diff --git a/drivers/maru/maru_jack.c b/drivers/maru/maru_jack.c index f60265a56cf0..6ae299177ae1 100644 --- a/drivers/maru/maru_jack.c +++ b/drivers/maru/maru_jack.c @@ -1,11 +1,11 @@ /* - * Virtual device node for event injector of emulator + * Virtual device node * - * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2011 Samsung Electronics Co., Ltd. All rights reserved. * * Contact: - * SooYoung Ha * JinHyung Choi + * SooYoung Ha * Sungmin Ha * YeongKyoon Lee #include +#include +#include +#include +#include #include #include #include +#include +#include +#include +#include +#include +#include + +#define __MAX_BUF_SIZE 1024 + +struct msg_info { + char buf[__MAX_BUF_SIZE]; + + uint16_t type; + uint16_t req; +}; -int charger_online = 0; -int earjack_online = 0; -int earkey_online = 0; -int hdmi_online = 0; -int usb_online = 0; +struct virtio_jack { + struct virtio_device* vdev; + struct virtqueue* vq; + + struct msg_info msginfo; + + struct scatterlist sg_vq[2]; + + int flags; + struct mutex lock; +}; + +enum jack_types { + jack_type_charger = 0, + jack_type_earjack, + jack_type_earkey, + jack_type_hdmi, + jack_type_usb, + jack_type_max +}; + +enum request_cmd { + request_get = 0, + request_set, + request_answer +}; struct jack_data { int no; char buffer[50]; }; +struct virtio_jack *v_jack; + +static char jack_data [PAGE_SIZE]; + +static DECLARE_WAIT_QUEUE_HEAD(wq); + +static struct virtio_device_id id_table[] = { { VIRTIO_ID_JACK, + VIRTIO_DEV_ANY_ID }, { 0 }, }; + #define DEVICE_NAME "jack" #define JACK_DEBUG @@ -55,85 +104,175 @@ struct jack_data { #define DLOG(level, fmt, ...) #endif +static void jack_vq_done(struct virtqueue *vq) { + unsigned int len; + struct msg_info* msg; + + msg = (struct msg_info*) virtqueue_get_buf(v_jack->vq, &len); + if (msg == NULL) { + DLOG(KERN_ERR, "failed to virtqueue_get_buf"); + return; + } + + if (msg->req != request_answer || msg->buf == NULL) { + return; + } + + DLOG(KERN_DEBUG, "msg buf: %s, req: %d, type: %d", msg->buf, msg->req, msg->type); + + mutex_lock(&v_jack->lock); + strcpy(jack_data, msg->buf); + v_jack->flags ++; + DLOG(KERN_DEBUG, "flags : %d", v_jack->flags); + mutex_unlock(&v_jack->lock); + + wake_up_interruptible(&wq); +} + +static void set_jack_data(int type, const char* buf) +{ + int err = 0; + + if (buf == NULL) { + DLOG(KERN_ERR, "set_jack buf is NULL."); + return; + } + + if (v_jack == NULL) { + DLOG(KERN_ERR, "Invalid jack handle"); + return; + } + + mutex_lock(&v_jack->lock); + memset(jack_data, 0, PAGE_SIZE); + memset(&v_jack->msginfo, 0, sizeof(v_jack->msginfo)); + + strcpy(jack_data, buf); + + v_jack->msginfo.req = request_set; + v_jack->msginfo.type = type; + strcpy(v_jack->msginfo.buf, buf); + mutex_unlock(&v_jack->lock); + + DLOG(KERN_DEBUG, "set_jack_data type: %d, req: %d, buf: %s", + v_jack->msginfo.type, v_jack->msginfo.req, v_jack->msginfo.buf); + + err = virtqueue_add_buf(v_jack->vq, v_jack->sg_vq, 1, 0, &v_jack->msginfo, GFP_ATOMIC); + if (err < 0) { + DLOG(KERN_ERR, "failed to add buffer to virtqueue (err = %d)", err); + return; + } + + virtqueue_kick(v_jack->vq); +} + +static void get_jack_data(int type) +{ + int err = 0; + + if (v_jack == NULL) { + DLOG(KERN_ERR, "Invalid jack handle"); + return; + } + + mutex_lock(&v_jack->lock); + memset(jack_data, 0, PAGE_SIZE); + memset(&v_jack->msginfo, 0, sizeof(v_jack->msginfo)); + + v_jack->msginfo.req = request_get; + v_jack->msginfo.type = type; + + mutex_unlock(&v_jack->lock); + + DLOG(KERN_DEBUG, "get_jack_data type: %d, req: %d", + v_jack->msginfo.type, v_jack->msginfo.req); + + err = virtqueue_add_buf(v_jack->vq, v_jack->sg_vq, 1, 1, &v_jack->msginfo, GFP_ATOMIC); + if (err < 0) { + DLOG(KERN_ERR, "failed to add buffer to virtqueue (err = %d)", err); + return; + } + + virtqueue_kick(v_jack->vq); + + wait_event_interruptible(wq, v_jack->flags != 0); + + mutex_lock(&v_jack->lock); + v_jack->flags --; + DLOG(KERN_DEBUG, "flags : %d", v_jack->flags); + mutex_unlock(&v_jack->lock); +} + static ssize_t show_charger_online(struct device *dev, struct device_attribute *attr, char *buf) { - DLOG(KERN_INFO, "get charger_online: %d\n", charger_online); - return snprintf(buf, PAGE_SIZE, "%d", charger_online); + get_jack_data(jack_type_charger); + return snprintf(buf, PAGE_SIZE, "%s", jack_data); } static ssize_t store_charger_online(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - sscanf(buf, "%d", &charger_online); - DLOG(KERN_INFO, "set charger_online: %d\n", charger_online); - + set_jack_data(jack_type_charger, buf); return strnlen(buf, PAGE_SIZE); } static ssize_t show_earjack_online(struct device *dev, struct device_attribute *attr, char *buf) { - DLOG(KERN_INFO, "get earjack_online: %d\n", earjack_online); - return snprintf(buf, PAGE_SIZE, "%d", earjack_online); + get_jack_data(jack_type_earjack); + return snprintf(buf, PAGE_SIZE, "%s", jack_data); } static ssize_t store_earjack_online(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - sscanf(buf, "%d", &earjack_online); - DLOG(KERN_INFO, "set earjack_online: %d\n", earjack_online); - + set_jack_data(jack_type_earjack, buf); return strnlen(buf, PAGE_SIZE); } static ssize_t show_earkey_online(struct device *dev, struct device_attribute *attr, char *buf) { - DLOG(KERN_INFO, "get earkey_online: %d\n", earkey_online); - return snprintf(buf, PAGE_SIZE, "%d", earkey_online); + get_jack_data(jack_type_earkey); + return snprintf(buf, PAGE_SIZE, "%s", jack_data); } static ssize_t store_earkey_online(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - sscanf(buf, "%d", &earkey_online); - DLOG(KERN_INFO, "set earkey_online: %d\n", earkey_online); - + set_jack_data(jack_type_earkey, buf); return strnlen(buf, PAGE_SIZE); } static ssize_t show_hdmi_online(struct device *dev, struct device_attribute *attr, char *buf) { - DLOG(KERN_INFO, "get hdmi_online: %d\n", hdmi_online); - return snprintf(buf, PAGE_SIZE, "%d", hdmi_online); + get_jack_data(jack_type_hdmi); + return snprintf(buf, PAGE_SIZE, "%s", jack_data); } static ssize_t store_hdmi_online(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - sscanf(buf, "%d", &hdmi_online); - DLOG(KERN_INFO, "set hdmi_online: %d\n", hdmi_online); - + set_jack_data(jack_type_hdmi, buf); return strnlen(buf, PAGE_SIZE); } static ssize_t show_usb_online(struct device *dev, struct device_attribute *attr, char *buf) { - DLOG(KERN_INFO, "get usb_online: %d\n", usb_online); - return snprintf(buf, PAGE_SIZE, "%d", usb_online); + get_jack_data(jack_type_usb); + return snprintf(buf, PAGE_SIZE, "%s", jack_data); } static ssize_t store_usb_online(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - sscanf(buf, "%d", &usb_online); - DLOG(KERN_INFO, "set usb_online: %d\n", usb_online); - + set_jack_data(jack_type_usb, buf); return strnlen(buf, PAGE_SIZE); } + static DEVICE_ATTR(charger_online, S_IRUGO | S_IWUSR, show_charger_online, store_charger_online); static DEVICE_ATTR(earjack_online, S_IRUGO | S_IWUSR, show_earjack_online, store_earjack_online); static DEVICE_ATTR(earkey_online, S_IRUGO | S_IWUSR, show_earkey_online, store_earkey_online); @@ -204,12 +343,17 @@ static struct platform_device the_pdev = { } }; -static int __init maru_jack_sysfs_init(void) -{ - int err = 0; +static int jack_probe(struct virtio_device* dev){ + int err = 0, index = 0; struct jack_data *data; - DLOG(KERN_INFO, "sysfs_init\n"); + DLOG(KERN_INFO, "jack_probe\n"); + + v_jack = kmalloc(sizeof(struct virtio_jack), GFP_KERNEL); + + v_jack->vdev = dev; + dev->priv = v_jack; + v_jack->flags = 0; err = platform_device_register(&the_pdev); if (err) { @@ -234,11 +378,29 @@ static int __init maru_jack_sysfs_init(void) return err; } + v_jack->vq = virtio_find_single_vq(dev, jack_vq_done, "jack"); + if (IS_ERR(v_jack->vq)) { + DLOG(KERN_ERR, "virtio queue is not found.\n"); + kfree(data); + platform_device_unregister(&the_pdev); + return err; + } + + virtqueue_enable_cb(v_jack->vq); + + memset(&v_jack->msginfo, 0x00, sizeof(v_jack->msginfo)); + + sg_init_table(v_jack->sg_vq, 2); + for (; index < 2; index++) { + sg_set_buf(&v_jack->sg_vq[index], &v_jack->msginfo, sizeof(v_jack->msginfo)); + } + + mutex_init(&v_jack->lock); + return 0; } -static void __exit maru_jack_sysfs_exit(void) -{ +static void jack_remove(struct virtio_device* dev){ void *data = dev_get_drvdata(&the_pdev.dev); DLOG(KERN_INFO, "sysfs_exit\n"); @@ -248,9 +410,40 @@ static void __exit maru_jack_sysfs_exit(void) } maru_jack_sysfs_remove_file(&the_pdev.dev); platform_device_unregister(&the_pdev); + + if (v_jack) { + kfree(v_jack); + v_jack = NULL; + } +} + +MODULE_DEVICE_TABLE(virtio, id_table); + +static struct virtio_driver virtio_jack_driver = { + .driver = { + .name = KBUILD_MODNAME, + .owner = THIS_MODULE , + }, + .id_table = id_table, + .probe = jack_probe, + .remove = jack_remove, +}; + +static int __init maru_jack_init(void) +{ + DLOG(KERN_INFO, "maru_%s: init\n", DEVICE_NAME); + return register_virtio_driver(&virtio_jack_driver); +} + +static void __exit maru_jack_exit(void) +{ + DLOG(KERN_INFO, "maru_%s: exit\n", DEVICE_NAME); + unregister_virtio_driver(&virtio_jack_driver); } -module_init(maru_jack_sysfs_init); -module_exit(maru_jack_sysfs_exit); +module_init(maru_jack_init); +module_exit(maru_jack_exit); -MODULE_LICENSE("GPL"); +MODULE_LICENSE("GPL2"); +MODULE_AUTHOR("Jinhyung Choi "); +MODULE_DESCRIPTION("Emulator Virtio Power Driver"); diff --git a/drivers/maru/maru_power_supply.c b/drivers/maru/maru_power_supply.c index 0c3a5f193532..10429db1f58d 100644 --- a/drivers/maru/maru_power_supply.c +++ b/drivers/maru/maru_power_supply.c @@ -1,11 +1,11 @@ /* - * Virtual device node for event injector of emulator + * Virtual device node * - * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2011 Samsung Electronics Co., Ltd. All rights reserved. * * Contact: - * SooYoung Ha * JinHyung Choi + * SooYoung Ha * Sungmin Ha * YeongKyoon Lee #include +#include +#include +#include +#include #include #include +#include +#include +#include +#include +#include +#include +#include -static struct class *mtd_class; -static struct device* mtd_device; #define DEVICE_NAME "power_supply" #define FILE_PERMISSION (S_IRUGO | S_IWUSR) -#define HALF_CAPACITY 50 //#define DEBUG_MARU_POWER_SUPPLY @@ -49,49 +57,184 @@ static struct device* mtd_device; #define DLOG(level, fmt, ...) #endif -static int capacity = HALF_CAPACITY; -static int charge_full = 0; -static int charge_now = 0; +#define __MAX_BUF_SIZE 1024 + +static struct virtio_device_id id_table[] = { { VIRTIO_ID_POWER, + VIRTIO_DEV_ANY_ID }, { 0 }, }; + +struct msg_info { + char buf[__MAX_BUF_SIZE]; + + uint16_t type; + uint16_t req; +}; + +struct virtio_power { + struct virtio_device* vdev; + struct virtqueue* vq; + + struct msg_info msginfo; + + struct scatterlist sg_vq[2]; + + int flags; + struct mutex lock; +}; + +enum power_types { + power_type_capacity = 0, + power_type_charge_full, + power_type_charge_now, + power_type_max +}; + +enum request_cmd { + request_get = 0, + request_set, + request_answer +}; + +struct virtio_power *v_power; + +static struct class* power_class; +static struct device* power_device; + +static char power_data [PAGE_SIZE]; + +static DECLARE_WAIT_QUEUE_HEAD(wq); + +static void power_vq_done(struct virtqueue *vq) { + unsigned int len; + struct msg_info* msg; + + msg = (struct msg_info*) virtqueue_get_buf(v_power->vq, &len); + if (msg == NULL) { + DLOG(KERN_ERR, "failed to virtqueue_get_buf"); + return; + } + + if (msg->req != request_answer || msg->buf == NULL) { + return; + } + + DLOG(KERN_DEBUG, "msg buf: %s, req: %d, type: %d", msg->buf, msg->req, msg->type); + + mutex_lock(&v_power->lock); + strcpy(power_data, msg->buf); + v_power->flags ++; + DLOG(KERN_DEBUG, "flags : %d", v_power->flags); + mutex_unlock(&v_power->lock); + + wake_up_interruptible(&wq); +} + +static void set_power_data(int type, const char* buf) +{ + int err = 0; + + if (buf == NULL) { + DLOG(KERN_ERR, "set_power buf is NULL."); + return; + } + + if (v_power == NULL) { + DLOG(KERN_ERR, "Invalid power handle"); + return; + } + + mutex_lock(&v_power->lock); + memset(power_data, 0, PAGE_SIZE); + memset(&v_power->msginfo, 0, sizeof(v_power->msginfo)); + + strcpy(power_data, buf); + + v_power->msginfo.req = request_set; + v_power->msginfo.type = type; + strcpy(v_power->msginfo.buf, buf); + mutex_unlock(&v_power->lock); + + DLOG(KERN_DEBUG, "set_power_data type: %d, req: %d, buf: %s", + v_power->msginfo.type, v_power->msginfo.req, v_power->msginfo.buf); + + err = virtqueue_add_buf(v_power->vq, v_power->sg_vq, 1, 0, &v_power->msginfo, GFP_ATOMIC); + if (err < 0) { + DLOG(KERN_ERR, "failed to add buffer to virtqueue (err = %d)", err); + return; + } + + virtqueue_kick(v_power->vq); +} + +static void get_power_data(int type) +{ + int err = 0; + + if (v_power == NULL) { + DLOG(KERN_ERR, "Invalid power handle"); + return; + } + + mutex_lock(&v_power->lock); + memset(power_data, 0, PAGE_SIZE); + memset(&v_power->msginfo, 0, sizeof(v_power->msginfo)); + + v_power->msginfo.req = request_get; + v_power->msginfo.type = type; + + mutex_unlock(&v_power->lock); + + DLOG(KERN_DEBUG, "get_power_data type: %d, req: %d", + v_power->msginfo.type, v_power->msginfo.req); + + err = virtqueue_add_buf(v_power->vq, v_power->sg_vq, 1, 1, &v_power->msginfo, GFP_ATOMIC); + if (err < 0) { + DLOG(KERN_ERR, "failed to add buffer to virtqueue (err = %d)", err); + return; + } + + virtqueue_kick(v_power->vq); + + wait_event_interruptible(wq, v_power->flags != 0); + + mutex_lock(&v_power->lock); + v_power->flags --; + DLOG(KERN_DEBUG, "flags : %d", v_power->flags); + mutex_unlock(&v_power->lock); +} static ssize_t show_capacity(struct device *dev, struct device_attribute *attr, char *buf) { - DLOG(KERN_INFO, "get capacity: %d\n", capacity); - return snprintf(buf, PAGE_SIZE, "%d", capacity); + get_power_data(power_type_capacity); + return snprintf(buf, PAGE_SIZE, "%s", power_data); } static ssize_t store_capacity(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - sscanf(buf, "%d", &capacity); - DLOG(KERN_INFO, "set capacity: %d\n", capacity); - + set_power_data(power_type_capacity, buf); return strnlen(buf, PAGE_SIZE); } static ssize_t show_charge_full(struct device *dev, struct device_attribute *attr, char *buf) { - DLOG(KERN_INFO, "get capacity_full: %d\n", capacity); - return snprintf(buf, PAGE_SIZE, "%d", charge_full); + get_power_data(power_type_charge_full); + return snprintf(buf, PAGE_SIZE, "%s", power_data); } static ssize_t store_charge_full(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - sscanf(buf, "%d", &charge_full); - DLOG(KERN_INFO, "set capacity_full: %d\n", capacity); - + set_power_data(power_type_charge_full, buf); return strnlen(buf, PAGE_SIZE); } static ssize_t show_charge_now(struct device *dev, struct device_attribute *attr, char *buf) { - DLOG(KERN_INFO, "get capacity_now: %d\n", capacity); - return snprintf(buf, PAGE_SIZE, "%d", charge_now); + get_power_data(power_type_charge_now); + return snprintf(buf, PAGE_SIZE, "%s", power_data); } static ssize_t store_charge_now(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - sscanf(buf, "%d", &charge_now); - DLOG(KERN_INFO, "set capacity_now: %d\n", capacity); - + set_power_data(power_type_charge_now, buf); return strnlen(buf, PAGE_SIZE); } @@ -101,44 +244,149 @@ static struct device_attribute ps_device_attributes[] = { __ATTR(charge_now, FILE_PERMISSION, show_charge_now, store_charge_now), }; -struct device new_device_dev; - -static int __init maru_power_supply_sysfs_init(void) +static void class_cleanup (void) { - int err = 0, i = 0; + int i = 2; + + for (; i > 0; i--) { + + if (power_device == NULL) + continue; + + device_remove_file(power_device, &ps_device_attributes[i]); - printk(KERN_INFO "maru_%s: sysfs_init\n", DEVICE_NAME); + device_unregister(power_device); - mtd_class = class_create(THIS_MODULE, DEVICE_NAME); - mtd_device = device_create(mtd_class, NULL, (dev_t)NULL, NULL, "battery"); + device_destroy(power_class, (dev_t)NULL); + } + + class_destroy(power_class); + power_class = NULL; +} + +static int init_device(void) +{ + int err = 0, i = 0; + power_device = device_create(power_class, NULL, (dev_t)NULL, NULL, "battery"); for (i = 0; i < 3; i++) { - err = device_create_file(mtd_device, &ps_device_attributes[i]); + err = device_create_file(power_device, &ps_device_attributes[i]); if (err) { printk(KERN_ERR "maru_%s: failed to create power_supply files\n", DEVICE_NAME); - break; + goto device_err; } } - if (i != 3) { - while (--i >= 0) { - device_remove_file(mtd_device, &ps_device_attributes[i]); - } + return err; +device_err: + class_cleanup(); + return -1; +} + +static void cleanup(struct virtio_device* dev) { + dev->config->del_vqs(dev); - device_unregister(mtd_device); + if (v_power) { + kfree(v_power); + v_power = NULL; } + class_cleanup(); +} + +static int power_probe(struct virtio_device* dev) +{ + int err = 0; + int ret = 0; + int index = 0; + + DLOG(KERN_INFO, "Power probe starts"); + + v_power = kmalloc(sizeof(struct virtio_power), GFP_KERNEL); + + v_power->vdev = dev; + dev->priv = v_power; + v_power->flags = 0; + + power_class = class_create(THIS_MODULE, DEVICE_NAME); + if (power_class == NULL) { + DLOG(KERN_ERR, "Power class creation is failed."); + return -1; + } + + ret = init_device(); + if (ret) { + cleanup(dev); + return ret; + } + + v_power->vq = virtio_find_single_vq(dev, power_vq_done, "power"); + if (IS_ERR(v_power->vq)) { + cleanup(dev); + DLOG(KERN_ERR, "failed to init virt queue"); + return ret; + } + + virtqueue_enable_cb(v_power->vq); + + memset(&v_power->msginfo, 0x00, sizeof(v_power->msginfo)); + + sg_init_table(v_power->sg_vq, 2); + for (; index < 2; index++) { + sg_set_buf(&v_power->sg_vq[index], &v_power->msginfo, sizeof(v_power->msginfo)); + } + + mutex_init(&v_power->lock); + + DLOG(KERN_INFO, "Power probe completes"); + return err; } -static void __exit maru_power_supply_sysfs_exit(void) +static void power_remove(struct virtio_device* dev) +{ + struct virtio_power* v_power = dev->priv; + if (!v_power) + { + DLOG(KERN_ERR, "virtio_power is NULL"); + return; + } + + dev->config->reset(dev); + + cleanup(dev); + + DLOG(KERN_INFO, "Power driver is removed."); +} + +MODULE_DEVICE_TABLE(virtio, id_table); + +static struct virtio_driver virtio_power_driver = { + .driver = { + .name = KBUILD_MODNAME, + .owner = THIS_MODULE , + }, + .id_table = id_table, + .probe = power_probe, + .remove = power_remove, +}; + +static int __init maru_power_supply_init(void) +{ + DLOG(KERN_INFO, "maru_%s: init\n", DEVICE_NAME); + return register_virtio_driver(&virtio_power_driver); +} + +static void __exit maru_power_supply_exit(void) { - printk(KERN_INFO "maru_%s: sysfs_exit\n", DEVICE_NAME); - class_destroy(mtd_class); + DLOG(KERN_INFO, "maru_%s: exit\n", DEVICE_NAME); + unregister_virtio_driver(&virtio_power_driver); } -module_init(maru_power_supply_sysfs_init); -module_exit(maru_power_supply_sysfs_exit); +module_init(maru_power_supply_init); +module_exit(maru_power_supply_exit); -MODULE_LICENSE("GPL"); +MODULE_LICENSE("GPL2"); +MODULE_AUTHOR("Jinhyung Choi "); +MODULE_DESCRIPTION("Emulator Virtio Power Driver"); diff --git a/drivers/maru/maru_virtio_evdi.c b/drivers/maru/maru_virtio_evdi.c index 7ba946d48ef4..a77e8a19a784 100644 --- a/drivers/maru/maru_virtio_evdi.c +++ b/drivers/maru/maru_virtio_evdi.c @@ -48,7 +48,10 @@ #define DRIVER_NAME "EVDI" -#define LOG(fmt, ...) \ +#define LOGDEBUG(fmt, ...) \ + printk(KERN_DEBUG "%s: " fmt, DRIVER_NAME, ##__VA_ARGS__) + +#define LOGERR(fmt, ...) \ printk(KERN_ERR "%s: " fmt, DRIVER_NAME, ##__VA_ARGS__) #define NUM_OF_EVDI 2 @@ -145,7 +148,7 @@ int _make_buf_and_kick(void) ret = virtqueue_add_buf(vevdi->rvq, vevdi->sg_read, 0, 1, &vevdi->read_msginfo, GFP_ATOMIC ); if (ret < 0) { - LOG("failed to add buffer to virtqueue.(%d)\n", ret); + LOGERR("failed to add buffer to virtqueue.(%d)\n", ret); return ret; } @@ -191,11 +194,11 @@ static int evdi_open(struct inode* inode, struct file* filp) struct cdev *cdev = inode->i_cdev; evdi_info = NULL; - LOG("evdi_open\n"); + LOGDEBUG("evdi_open\n"); for (i = 0; i < NUM_OF_EVDI; i++) { - LOG("evdi info index = %d, cdev dev = %d, inode dev = %d\n", + LOGDEBUG("evdi info index = %d, cdev dev = %d, inode dev = %d\n", i, pevdi_info[i]->cdev.dev, cdev->dev); if (pevdi_info[i]->cdev.dev == cdev->dev) @@ -215,7 +218,7 @@ static int evdi_open(struct inode* inode, struct file* filp) return ret; - LOG("evdi_opened\n"); + LOGDEBUG("evdi_opened\n"); return 0; } @@ -225,7 +228,7 @@ static int evdi_close(struct inode* i, struct file* filp) { evdi_info = filp->private_data; evdi_info->guest_connected = false; - LOG("evdi_closed\n"); + LOGDEBUG("evdi_closed\n"); return 0; } @@ -246,7 +249,7 @@ static ssize_t evdi_read(struct file *filp, char __user *ubuf, size_t len, { if (filp->f_flags & O_NONBLOCK) { - LOG("list is empty, return EAGAIN\n"); + LOGERR("list is empty, return EAGAIN\n"); return -EAGAIN; } return -EFAULT; @@ -255,7 +258,7 @@ static ssize_t evdi_read(struct file *filp, char __user *ubuf, size_t len, next = list_first_entry(&vevdi->read_list, struct msg_buf, list); if (next == NULL) { - LOG("invliad list entry\n"); + LOGERR("invliad list entry\n"); return -EFAULT; } @@ -269,14 +272,11 @@ static ssize_t evdi_read(struct file *filp, char __user *ubuf, size_t len, if (add_inbuf(vevdi->rvq, &vevdi->read_msginfo) < 0) { - LOG("failed add_buf\n"); + LOGERR("failed add_buf\n"); } spin_unlock_irqrestore(&pevdi_info[EVID_READ]->inbuf_lock, flags); - - //LOG("evdi_read count = %d!\n", ++g_read_count); - if (ret < 0) return -EFAULT; @@ -293,17 +293,17 @@ static ssize_t evdi_write(struct file *f, const char __user *ubuf, size_t len, int err = 0; ssize_t ret = 0; - //LOG("start of evdi_write len= %d, msglen = %d\n", len, sizeof(vevdi->send_msginfo)); + LOGDEBUG("start of evdi_write len= %d, msglen = %d\n", len, sizeof(vevdi->send_msginfo)); if (vevdi == NULL) { - LOG("invalid evdi handle\n"); + LOGERR("invalid evdi handle\n"); return 0; } memset(&vevdi->send_msginfo, 0, sizeof(vevdi->send_msginfo)); ret = copy_from_user(&vevdi->send_msginfo, ubuf, sizeof(vevdi->send_msginfo)); - //LOG("copy_from_user ret = %d, msg = %s", ret, vevdi->send_msginfo.buf); + LOGDEBUG("copy_from_user ret = %d, msg = %s", ret, vevdi->send_msginfo.buf); if (ret) { ret = -EFAULT; @@ -319,13 +319,13 @@ static ssize_t evdi_write(struct file *f, const char __user *ubuf, size_t len, &_msg, GFP_ATOMIC);*/ if (err < 0) { - LOG("failed to add buffer to virtqueue (err = %d)\n", err); + LOGERR("failed to add buffer to virtqueue (err = %d)\n", err); return 0; } virtqueue_kick(vevdi->svq); - //LOG("send to host\n"); + LOGDEBUG("send to host\n"); return len; } @@ -347,7 +347,7 @@ static unsigned int evdi_poll(struct file *filp, poll_table *wait) if (has_readdata(evdi)) { - LOG("POLLIN | POLLRDNORM\n"); + LOGDEBUG("POLLIN | POLLRDNORM\n"); ret |= POLLIN | POLLRDNORM; } @@ -378,25 +378,24 @@ static void evdi_recv_done(struct virtqueue *rvq) { _msg = (struct msg_info*) virtqueue_get_buf(vevdi->rvq, &len); if (_msg == NULL ) { - LOG("failed to virtqueue_get_buf\n"); + LOGERR("failed to virtqueue_get_buf\n"); return; } do { - //LOG("msg use = %d\n", _msg->use); - //LOG("msg data = %s\n", _msg->buf); + LOGDEBUG("msg use = %d\n", _msg->use); + LOGDEBUG("msg data = %s\n", _msg->buf); /* insert into queue */ msgbuf = (struct msg_buf*) __xmalloc(SIZEOF_MSG_BUF); memset(msgbuf, 0x00, sizeof(*msgbuf)); memcpy(&(msgbuf->msg), _msg, sizeof(*_msg)); - //LOG("copied msg data = %s, %s\n", msgbuf->msg.buf, _msg->buf); + LOGDEBUG("copied msg data = %s, %s\n", msgbuf->msg.buf, _msg->buf); spin_lock_irqsave(&pevdi_info[EVID_READ]->inbuf_lock, flags); list_add_tail(&msgbuf->list, &vevdi->read_list); - //LOG("== wake_up_interruptible = %d!\n", ++g_wake_up_interruptible_count); spin_unlock_irqrestore(&pevdi_info[EVID_READ]->inbuf_lock, flags); @@ -449,7 +448,7 @@ int _init_device(void) int i, ret; if (alloc_chrdev_region(&evdi_dev_number, 0, NUM_OF_EVDI, DEVICE_NAME) < 0) { - LOG("fail to alloc_chrdev_region\n"); + LOGERR("fail to alloc_chrdev_region\n"); return -1; } @@ -464,7 +463,7 @@ int _init_device(void) pevdi_info[i] = kmalloc(sizeof(struct virtevdi_info), GFP_KERNEL); if (!pevdi_info[i]) { - LOG("Bad malloc\n"); + LOGERR("Bad malloc\n"); return -ENOMEM; } @@ -483,7 +482,7 @@ int _init_device(void) spin_lock_init(&pevdi_info[i]->outvq_lock); if (ret == -1) { - LOG("Bad cdev\n"); + LOGERR("Bad cdev\n"); return ret; } @@ -508,7 +507,7 @@ static int evdi_probe(struct virtio_device* dev) { ret = _init_device(); if (ret) { - LOG("failed to _init_device\n"); + LOGERR("failed to _init_device\n"); return ret; } ret = init_vqs(vevdi); @@ -517,7 +516,7 @@ static int evdi_probe(struct virtio_device* dev) { kfree(vevdi); dev->priv = NULL; - LOG("failed to init_vqs\n"); + LOGERR("failed to init_vqs\n"); return ret; } @@ -536,9 +535,7 @@ static int evdi_probe(struct virtio_device* dev) { sg_init_one(vevdi->sg_read, &vevdi->read_msginfo, sizeof(vevdi->read_msginfo)); sg_init_one(vevdi->sg_send, &vevdi->send_msginfo, sizeof(vevdi->send_msginfo)); - - - LOG("EVDI Probe completed"); + LOGDEBUG("EVDI Probe completed"); return 0; } @@ -547,7 +544,7 @@ static void __devexit evdi_remove(struct virtio_device* dev) struct virtio_evdi* _evdi = dev->priv; if (!_evdi) { - LOG("evdi is NULL\n"); + LOGERR("evdi is NULL\n"); return; } @@ -556,7 +553,7 @@ static void __devexit evdi_remove(struct virtio_device* dev) kfree(_evdi); - LOG("driver is removed.\n"); + LOGDEBUG("driver is removed.\n"); } MODULE_DEVICE_TABLE(virtio, id_table); @@ -573,7 +570,7 @@ static struct virtio_driver virtio_evdi_driver = { static int __init evdi_init(void) { - LOG("EVDI driver initialized.\n"); + LOGDEBUG("EVDI driver initialized.\n"); return register_virtio_driver(&virtio_evdi_driver); } @@ -596,7 +593,7 @@ static void __exit evdi_exit(void) unregister_virtio_driver(&virtio_evdi_driver); - LOG("EVDI driver is destroyed.\n"); + LOGDEBUG("EVDI driver is destroyed.\n"); } module_init(evdi_init); diff --git a/drivers/maru/maru_virtio_sensor.c b/drivers/maru/maru_virtio_sensor.c index 1c6cdc20272a..db670082e120 100644 --- a/drivers/maru/maru_virtio_sensor.c +++ b/drivers/maru/maru_virtio_sensor.c @@ -37,6 +37,8 @@ #include #include #include +#include +#include #include @@ -60,7 +62,12 @@ enum sensor_types { sensor_type_accel = 0, sensor_type_geo, sensor_type_gyro, + sensor_type_gyro_x, + sensor_type_gyro_y, + sensor_type_gyro_z, sensor_type_light, + sensor_type_light_adc, + sensor_type_light_level, sensor_type_proxi, sensor_type_mag, sensor_type_tilt, @@ -82,14 +89,14 @@ struct msg_info { struct virtio_sensor { struct virtio_device* vdev; - struct virtqueue* rvq; - struct virtqueue* svq; + struct virtqueue* vq; - struct msg_info read_msginfo; - struct msg_info send_msginfo; + struct msg_info msginfo; - struct scatterlist sg_read[2]; - struct scatterlist sg_send[2]; + struct scatterlist sg_vq[2]; + + int flags; + struct mutex lock; }; static struct virtio_device_id id_table[] = { { VIRTIO_ID_SENSOR, @@ -99,6 +106,8 @@ struct virtio_sensor *vs; static struct class* sensor_class; +static DECLARE_WAIT_QUEUE_HEAD(wq); + #define __ATTR_RONLY(_name,_show) { \ .attr = { .name = __stringify(_name), .mode = 0444 }, \ .show = _show, \ @@ -110,14 +119,112 @@ static struct class* sensor_class; .store = _name##_store, \ } +static char sensor_data [PAGE_SIZE]; + +static void sensor_vq_done(struct virtqueue *rvq) { + unsigned int len; + struct msg_info* msg; + + msg = (struct msg_info*) virtqueue_get_buf(vs->vq, &len); + if (msg == NULL) { + LOG(KERN_ERR, "failed to virtqueue_get_buf"); + return; + } + + if (msg->req != request_answer || msg->buf == NULL) { + LOG(KERN_ERR, "message from host is cracked."); + return; + } + + LOG(KERN_DEBUG, "msg buf: %s, req: %d, type: %d", msg->buf, msg->req, msg->type); + + mutex_lock(&vs->lock); + strcpy(sensor_data, msg->buf); + vs->flags = 1; + mutex_unlock(&vs->lock); + + wake_up_interruptible(&wq); +} + +static void set_sensor_data(int type, const char* buf) +{ + int err = 0; + + if (buf == NULL) { + LOG(KERN_ERR, "set_sensor buf is NULL."); + return; + } + + if (vs == NULL) { + LOG(KERN_ERR, "Invalid sensor handle"); + return; + } + + mutex_lock(&vs->lock); + memset(sensor_data, 0, PAGE_SIZE); + memset(&vs->msginfo, 0, sizeof(vs->msginfo)); + + strcpy(sensor_data, buf); + + vs->msginfo.req = request_set; + vs->msginfo.type = type; + strcpy(vs->msginfo.buf, buf); + mutex_unlock(&vs->lock); + + LOG(KERN_DEBUG, "set_sensor_data type: %d, req: %d, buf: %s", + vs->msginfo.type, vs->msginfo.req, vs->msginfo.buf); + + err = virtqueue_add_buf(vs->vq, vs->sg_vq, 1, 0, &vs->msginfo, GFP_ATOMIC); + if (err < 0) { + LOG(KERN_ERR, "failed to add buffer to virtqueue (err = %d)", err); + return; + } + + virtqueue_kick(vs->vq); +} + +static void get_sensor_data(int type) +{ + int err = 0; + + if (vs == NULL) { + LOG(KERN_ERR, "Invalid sensor handle"); + return; + } + + mutex_lock(&vs->lock); + memset(sensor_data, 0, PAGE_SIZE); + memset(&vs->msginfo, 0, sizeof(vs->msginfo)); + + vs->msginfo.req = request_get; + vs->msginfo.type = type; + + mutex_unlock(&vs->lock); + + LOG(KERN_DEBUG, "get_sensor_data type: %d, req: %d", + vs->msginfo.type, vs->msginfo.req); + + err = virtqueue_add_buf(vs->vq, vs->sg_vq, 1, 1, &vs->msginfo, GFP_ATOMIC); + if (err < 0) { + LOG(KERN_ERR, "failed to add buffer to virtqueue (err = %d)", err); + return; + } + + virtqueue_kick(vs->vq); + + wait_event_interruptible(wq, vs->flags != 0); + + mutex_lock(&vs->lock); + vs->flags = 0; + mutex_unlock(&vs->lock); +} + /* * Accelerometer */ #define ACCEL_NAME_STR "accel_sim" #define ACCEL_FILE_NUM 2 -static char accel_xyz [__MAX_BUF_SENSOR] = {'0',',','9','8','0','6','6','5',',','0'}; - static ssize_t accel_name_show(struct device *dev, struct device_attribute *attr, char *buf) { return snprintf(buf, PAGE_SIZE, ACCEL_NAME_STR); @@ -125,12 +232,13 @@ static ssize_t accel_name_show(struct device *dev, struct device_attribute *attr static ssize_t xyz_show(struct device *dev, struct device_attribute *attr, char *buf) { - return snprintf(buf, PAGE_SIZE, "%s", accel_xyz); + get_sensor_data(sensor_type_accel); + return snprintf(buf, PAGE_SIZE, "%s", sensor_data); } static ssize_t xyz_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - strcpy(accel_xyz, buf); + set_sensor_data(sensor_type_accel, buf); return strnlen(buf, PAGE_SIZE); } @@ -146,9 +254,6 @@ static struct device_attribute da_accel [] = #define GEO_NAME_STR "geo_sim" #define GEO_FILE_NUM 3 -static char geo_raw [__MAX_BUF_SENSOR] = {'0',' ','-','9','0',' ','0',' ','3'}; -static char geo_tesla [__MAX_BUF_SENSOR] = {'1',' ','0',' ','-','1','0'}; - static ssize_t geo_name_show(struct device *dev, struct device_attribute *attr, char *buf) { return snprintf(buf, PAGE_SIZE, GEO_NAME_STR); @@ -156,23 +261,25 @@ static ssize_t geo_name_show(struct device *dev, struct device_attribute *attr, static ssize_t raw_show(struct device *dev, struct device_attribute *attr, char *buf) { - return snprintf(buf, PAGE_SIZE, "%s", geo_raw); + get_sensor_data(sensor_type_tilt); + return snprintf(buf, PAGE_SIZE, "%s", sensor_data); } static ssize_t raw_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - strcpy(geo_raw, buf); + set_sensor_data(sensor_type_tilt, buf); return strnlen(buf, PAGE_SIZE); } static ssize_t tesla_show(struct device *dev, struct device_attribute *attr, char *buf) { - return snprintf(buf, PAGE_SIZE, "%s", geo_tesla); + get_sensor_data(sensor_type_mag); + return snprintf(buf, PAGE_SIZE, "%s", sensor_data); } static ssize_t tesla_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - strcpy(geo_tesla, buf); + set_sensor_data(sensor_type_mag, buf); return strnlen(buf, PAGE_SIZE); } @@ -191,10 +298,6 @@ static struct device_attribute da_geo [] = #define GYRO_NAME_STR "gyro_sim" #define GYRO_FILE_NUM 4 -static int gyro_x_raw = 0; -static int gyro_y_raw = 0; -static int gyro_z_raw = 0; - static ssize_t gyro_name_show(struct device *dev, struct device_attribute *attr, char *buf) { return snprintf(buf, PAGE_SIZE, GYRO_NAME_STR); @@ -202,34 +305,37 @@ static ssize_t gyro_name_show(struct device *dev, struct device_attribute *attr, static ssize_t gyro_x_raw_show(struct device *dev, struct device_attribute *attr, char *buf) { - return snprintf(buf, PAGE_SIZE, "%d", gyro_x_raw); + get_sensor_data(sensor_type_gyro_x); + return snprintf(buf, PAGE_SIZE, "%s", sensor_data); } static ssize_t gyro_x_raw_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - sscanf(buf, "%d", &gyro_x_raw); + set_sensor_data(sensor_type_gyro_x, buf); return strnlen(buf, PAGE_SIZE); } static ssize_t gyro_y_raw_show(struct device *dev, struct device_attribute *attr, char *buf) { - return snprintf(buf, PAGE_SIZE, "%d", gyro_y_raw); + get_sensor_data(sensor_type_gyro_y); + return snprintf(buf, PAGE_SIZE, "%s", sensor_data); } static ssize_t gyro_y_raw_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - sscanf(buf, "%d", &gyro_y_raw); + set_sensor_data(sensor_type_gyro_y, buf); return strnlen(buf, PAGE_SIZE); } static ssize_t gyro_z_raw_show(struct device *dev, struct device_attribute *attr, char *buf) { - return snprintf(buf, PAGE_SIZE, "%d", gyro_z_raw); + get_sensor_data(sensor_type_gyro_z); + return snprintf(buf, PAGE_SIZE, "%s", sensor_data); } static ssize_t gyro_z_raw_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - sscanf(buf, "%d", &gyro_z_raw); + set_sensor_data(sensor_type_gyro_z, buf); return strnlen(buf, PAGE_SIZE); } @@ -248,9 +354,6 @@ static struct device_attribute da_gyro [] = #define LIGHT_NAME_STR "light_sim" #define LIGHT_FILE_NUM 3 -static int light_adc = 65535; -static int light_level = 10; - static ssize_t light_name_show(struct device *dev, struct device_attribute *attr, char *buf) { return snprintf(buf, PAGE_SIZE, LIGHT_NAME_STR); @@ -258,23 +361,25 @@ static ssize_t light_name_show(struct device *dev, struct device_attribute *attr static ssize_t adc_show(struct device *dev, struct device_attribute *attr, char *buf) { - return snprintf(buf, PAGE_SIZE, "%d", light_adc); + get_sensor_data(sensor_type_light_adc); + return snprintf(buf, PAGE_SIZE, "%s", sensor_data); } static ssize_t adc_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - sscanf(buf, "%d", &light_adc); + set_sensor_data(sensor_type_light_adc, buf); return strnlen(buf, PAGE_SIZE); } static ssize_t level_show(struct device *dev, struct device_attribute *attr, char *buf) { - return snprintf(buf, PAGE_SIZE, "%d", light_level); + get_sensor_data(sensor_type_light_level); + return snprintf(buf, PAGE_SIZE, "%s", sensor_data); } static ssize_t level_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - sscanf(buf, "%d", &light_level); + set_sensor_data(sensor_type_light_level, buf); return strnlen(buf, PAGE_SIZE); } @@ -294,7 +399,6 @@ static struct device_attribute da_light [] = #define PROXI_FILE_NUM 3 static int proxi_enable = 1; -static int proxi_vo = 8; static ssize_t proxi_name_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -314,12 +418,13 @@ static ssize_t enable_store(struct device *dev, struct device_attribute *attr, c static ssize_t vo_show(struct device *dev, struct device_attribute *attr, char *buf) { - return snprintf(buf, PAGE_SIZE, "%d", proxi_vo); + get_sensor_data(sensor_type_proxi); + return snprintf(buf, PAGE_SIZE, "%s", sensor_data); } static ssize_t vo_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - sscanf(buf, "%d", &proxi_vo); + set_sensor_data(sensor_type_proxi, buf); return strnlen(buf, PAGE_SIZE); } @@ -392,155 +497,6 @@ device_err: return -1; } -static int _make_buf_and_kick(void) -{ - int ret; - memset(&vs->read_msginfo, 0x00, sizeof(vs->read_msginfo)); - ret = virtqueue_add_buf(vs->rvq, vs->sg_read, 0, 1, &vs->read_msginfo, GFP_ATOMIC ); - if (ret < 0) { - LOG(KERN_ERR, "failed to add buffer to virtqueue.(%d)\n", ret); - return ret; - } - - virtqueue_kick(vs->rvq); - - return 0; -} - -static void get_sensor_value(int type) -{ - int err = 0; - - if (vs == NULL) { - LOG(KERN_ERR, "Invalid sensor handle"); - return; - } - - memset(&vs->send_msginfo, 0, sizeof(vs->send_msginfo)); - - vs->send_msginfo.req = request_answer; - - switch (type) { - case sensor_type_accel: - vs->send_msginfo.type = sensor_type_accel; - strcpy(vs->send_msginfo.buf, accel_xyz); - break; - case sensor_type_mag: - vs->send_msginfo.type = sensor_type_mag; - strcpy(vs->send_msginfo.buf, geo_tesla); - break; - case sensor_type_gyro: - vs->send_msginfo.type = sensor_type_gyro; - sprintf(vs->send_msginfo.buf, "%d, %d, %d", gyro_x_raw, gyro_y_raw, gyro_z_raw); - break; - case sensor_type_light: - vs->send_msginfo.type = sensor_type_light; - sprintf(vs->send_msginfo.buf, "%d", light_adc); - break; - case sensor_type_proxi: - vs->send_msginfo.type = sensor_type_proxi; - sprintf(vs->send_msginfo.buf, "%d", proxi_vo); - break; - default: - return; - } - - LOG(KERN_INFO, "vs->send_msginfo type: %d, req: %d, buf: %s", - vs->send_msginfo.type, vs->send_msginfo.req, vs->send_msginfo.buf); - - err = virtqueue_add_buf(vs->svq, vs->sg_send, 1, 0, &vs->send_msginfo, GFP_ATOMIC); - if (err < 0) { - LOG(KERN_ERR, "failed to add buffer to virtqueue (err = %d)", err); - return; - } - - virtqueue_kick(vs->svq); -} - -static void set_sensor_value(char* buf, int type) -{ - - LOG(KERN_INFO, "set_sensor_value- type: %d, buf: %s", type, buf); - - switch (type) { - case sensor_type_accel: - strcpy(accel_xyz, buf); - break; - case sensor_type_gyro: - sscanf(buf, "%d %d %d", &gyro_x_raw, &gyro_y_raw, &gyro_z_raw); - break; - case sensor_type_light: - sscanf(buf, "%d", &light_adc); - light_level = (light_adc / 6554) % 10 + 1; - break; - case sensor_type_proxi: - sscanf(buf, "%d", &proxi_vo); - break; - case sensor_type_mag: - strcpy(geo_tesla, buf); - break; - case sensor_type_tilt: - strcpy(geo_raw, buf); - break; - default: - return; - } - -} - -static void message_handler(char* buf, int req, int type) -{ - if (req == request_get) { - get_sensor_value(type); - } else if (req == request_set) { - set_sensor_value(buf, type); - } else { - LOG(KERN_INFO, "wrong message request"); - } -} - -static void sensor_recv_done(struct virtqueue *rvq) { - unsigned int len; - struct msg_info* msg; - - msg = (struct msg_info*) virtqueue_get_buf(vs->rvq, &len); - if (msg == NULL ) { - LOG(KERN_ERR, "failed to virtqueue_get_buf"); - return; - } - - LOG(KERN_INFO, "msg buf: %s, req: %d, type: %d", msg->buf, msg->req, msg->type); - - message_handler(msg->buf, msg->req, msg->type); - - _make_buf_and_kick(); -} - -static void sensor_send_done(struct virtqueue *svq) { - unsigned int len = 0; - - virtqueue_get_buf(svq, &len); -} - -static int init_vqs(struct virtio_sensor *vsensor) { - struct virtqueue *vqs[2]; - vq_callback_t *vq_callbacks[] = { sensor_recv_done, sensor_send_done }; - const char *vq_names[] = { "sensor_input", "sensor_output" }; - int err; - - err = vs->vdev->config->find_vqs(vs->vdev, 2, vqs, vq_callbacks, vq_names); - if (err < 0) - return err; - - vs->rvq = vqs[0]; - vs->svq = vqs[1]; - - virtqueue_enable_cb(vs->rvq); - virtqueue_enable_cb(vs->svq); - - return 0; -} - static void cleanup(struct virtio_device* dev) { dev->config->del_vqs(dev); @@ -556,6 +512,7 @@ static int sensor_probe(struct virtio_device* dev) { int err = 0; int ret = 0; + int index = 0; LOG(KERN_INFO, "Sensor probe starts"); @@ -576,37 +533,30 @@ static int sensor_probe(struct virtio_device* dev) return ret; } - ret = init_vqs(vs); - if (ret) { + vs->vq = virtio_find_single_vq(dev, sensor_vq_done, "sensor"); + if (IS_ERR(vs->vq)) { cleanup(dev); - LOG(KERN_ERR, "failed to init vqs"); + LOG(KERN_ERR, "failed to init virt queue"); return ret; } - memset(&vs->read_msginfo, 0x00, sizeof(vs->read_msginfo)); - sg_set_buf(vs->sg_read, &vs->read_msginfo, sizeof(struct msg_info)); + virtqueue_enable_cb(vs->vq); - memset(&vs->send_msginfo, 0x00, sizeof(vs->send_msginfo)); - sg_set_buf(vs->sg_send, &vs->send_msginfo, sizeof(struct msg_info)); + memset(&vs->msginfo, 0x00, sizeof(vs->msginfo)); - sg_init_one(vs->sg_read, &vs->read_msginfo, sizeof(vs->read_msginfo)); - sg_init_one(vs->sg_send, &vs->send_msginfo, sizeof(vs->send_msginfo)); - - ret = _make_buf_and_kick(); - if (ret) { - cleanup(dev); - LOG(KERN_ERR, "failed to send buf"); - return ret; + sg_init_table(vs->sg_vq, 2); + for (; index < 2; index++) { + sg_set_buf(&vs->sg_vq[index], &vs->msginfo, sizeof(vs->msginfo)); } + mutex_init(&vs->lock); + LOG(KERN_INFO, "Sensor probe completes"); return err; } - - -static void __devexit sensor_remove(struct virtio_device* dev) +static void sensor_remove(struct virtio_device* dev) { struct virtio_sensor* vs = dev->priv; if (!vs) diff --git a/include/linux/virtio_ids.h b/include/linux/virtio_ids.h index 39fb25407a0e..fffab63242d6 100755 --- a/include/linux/virtio_ids.h +++ b/include/linux/virtio_ids.h @@ -48,6 +48,8 @@ #define VIRTIO_ID_GL 36 /* virtio glmem */ #define VIRTIO_ID_SENSOR 37 /* virtio sensor */ #define VIRTIO_ID_NFC 38 /* virtio nfc */ +#define VIRTIO_ID_JACK 39 /* virtio jack */ +#define VIRTIO_ID_POWER 40 /* virtio power supply */ #endif #endif /* _LINUX_VIRTIO_IDS_H */ diff --git a/package/changelog b/package/changelog index 0de4e3c4d8d9..ebc37d37f17c 100644 --- a/package/changelog +++ b/package/changelog @@ -1,3 +1,6 @@ +* 1.4.32 +- Data is moved into qemu for jacks, battery, and sensors +== Jinhyung Choi 2014-03-06 * 1.4.31 - Implemented multicore rendering and fences == GiWoong Kim 2014-01-17 diff --git a/package/pkginfo.manifest b/package/pkginfo.manifest index b3157b1fdadd..f0e329dd8493 100644 --- a/package/pkginfo.manifest +++ b/package/pkginfo.manifest @@ -1,4 +1,4 @@ -Version: 1.4.31 +Version: 1.4.32 Maintainer: Yeong-Kyoon, Lee Source: emulator-kernel