From 0e59ab1e2bf6ed117989cebafc08788ce3f243a0 Mon Sep 17 00:00:00 2001 From: lanshh Date: Tue, 11 Oct 2016 16:13:52 +0800 Subject: [PATCH] hid: rkvr: change sync implement Change-Id: I2c18d79339f067e8b567be0568ff3de8a8934a27 Signed-off-by: lanshh --- drivers/hid/hid-rkvr.c | 66 ++++++++++++++++++++++++++++-------------- drivers/hid/hid-rkvr.h | 6 ++++ 2 files changed, 50 insertions(+), 22 deletions(-) diff --git a/drivers/hid/hid-rkvr.c b/drivers/hid/hid-rkvr.c index 63d7fc00a53c..ec75de69582f 100644 --- a/drivers/hid/hid-rkvr.c +++ b/drivers/hid/hid-rkvr.c @@ -71,7 +71,6 @@ static unsigned int count_array[15] = {0,}; static unsigned long old_jiffy_array[15] = {0,}; static int rkvr_index; static int opens; -static char sync_string[64]; struct sensor_hid_data { void *priv; @@ -567,6 +566,31 @@ static int rkvr_report_event(struct hid_device *hid, u8 *data, int len) return ret; } +/****************************************** + *-------------------- + *| ID | BUF ..... | + *-------------------- + * + ******************************************/ +static int rkvr_send_report(struct device *dev, unsigned char *data, size_t len) +{ + struct hid_device *hid = container_of(dev, struct hid_device, dev); + unsigned char reportnum = HID_REPORT_ID_RKVR; + unsigned char rtype = HID_OUTPUT_REPORT; + int ret = -EINVAL; + + ret = hid_hw_raw_request(hid, reportnum, (unsigned char *)data, len, rtype, HID_REQ_SET_REPORT); + if (ret != len) { + hid_err(hid, "rkvr_send_report fail\n"); + ret = -EIO; + goto fail; + } + hid_info(hid, "rkvr_send_report ok\n"); + ret = 0; +fail: + return ret; +} + /* * for enable sensor data ************************************ @@ -577,64 +601,62 @@ static int rkvr_report_event(struct hid_device *hid, u8 *data, int len) *********************************** */ -static int hid_report_sync(struct device *dev, const char *data, size_t len) +static int hid_report_sync(struct device *dev, const char *data, size_t count) { struct hid_device *hid = container_of(dev, struct hid_device, dev); u64 *tmp; - unsigned char buf[64]; + unsigned char buf[64] = {HID_REPORT_ID_RKVR, RKVR_ID_SYNC}; unsigned char buf2[3] = {0}; char *colon; int i, ret = 0; char *p; - unsigned char report_number = HID_REPORT_ID_CRYP; - unsigned char report_type = HID_SYNCW_REPORT; + size_t len; - p = kmalloc(sizeof(*p) * len, GFP_KERNEL); + p = kmalloc(sizeof(*p) * count, GFP_KERNEL); if (!p) { hid_err(hid, "no mem\n"); return -ENOMEM; } - memcpy(p, data, len); - colon = strchr(p, ':'); + memcpy(p, data, count); + colon = strnchr(p, count, ':'); if (!colon) { hid_err(hid, "must have conlon\n"); ret = -EINVAL; goto fail; } - if (colon - p + 1 >= len) { + if (colon - p + 1 >= count) { hid_err(hid, "must have sync string after conlon\n"); ret = -EINVAL; goto fail; } colon[0] = 0; colon++; - tmp = (u64 *)(buf + 1); + tmp = (u64 *)(buf + 2); if (kstrtoull(p, 10, tmp)) { hid_err(hid, "convert rand string fail,only decimal string allowed\n"); ret = -EINVAL; goto fail; } - len = min((len - (colon - p)) / 2, sizeof(buf) - 9); + hid_info(hid, "uint64 %llu\n", *(u64 *)(buf + 2)); + len = min((count - (colon - p)) / 2, sizeof(buf) - (sizeof(*tmp) + 2)); for (i = 0; i < len; i++) { buf2[0] = colon[i * 2]; buf2[1] = colon[i * 2 + 1]; - if (kstrtou8(buf2, 16, &buf[9 + i])) { + if (kstrtou8(buf2, 16, &buf[sizeof(*tmp) + 2 + i])) { hid_err(hid, "err sync string,only hex string allowed\n"); ret = -EINVAL; goto fail; } } - - len = i + 9; - ret = hid_hw_raw_request(hid, report_number, (unsigned char *)buf, len, - report_type, HID_REQ_SET_REPORT); - if (ret != len) { + len = i + sizeof(*tmp) + 2; + ret = rkvr_send_report(dev, (unsigned char *)buf, len); + if (ret) { hid_err(hid, "hid_report_encrypt fail\n"); ret = -EIO; goto fail; } hid_info(hid, "hid_report_encrypt ok\n"); - ret = 0; + ret = count; fail: kfree(p); @@ -725,8 +747,10 @@ static ssize_t rkvr_dev_attr_sync_store(struct device *dev, struct device_attrib const char *buf, size_t count) { struct hidraw *devraw = dev_get_drvdata(dev); + int ret; - return hid_report_sync(&devraw->hid->dev, buf, count); + ret = hid_report_sync(&devraw->hid->dev, buf, count - 1); + return ret > 0 ? count : ret; } static DEVICE_ATTR(sync, S_IWUSR, NULL, rkvr_dev_attr_sync_store); @@ -888,8 +912,6 @@ static int rkvr_connect(struct hid_device *hid) hid_err(hid, "rkvr_connect:hid_hw_open fail\n"); goto out; } - if (strlen(sync_string)) - hid_report_sync(&hid->dev, sync_string, strlen(sync_string)); init_waitqueue_head(&dev->wait); spin_lock_init(&dev->list_lock); @@ -1183,8 +1205,8 @@ static void rkvr_remove(struct hid_device *hdev) struct usb_interface *intf = to_usb_interface(hdev->dev.parent); if (intf->cur_altsetting->desc.bInterfaceNumber == RKVR_INTERFACE_USB_SENSOR_ID) { - rkvr_keys_remove(hdev); rkvr_hw_stop(hdev); + rkvr_keys_remove(hdev); } else { hid_hw_stop(hdev); } diff --git a/drivers/hid/hid-rkvr.h b/drivers/hid/hid-rkvr.h index 309bc37cb550..32d38ff7e4b6 100644 --- a/drivers/hid/hid-rkvr.h +++ b/drivers/hid/hid-rkvr.h @@ -10,9 +10,15 @@ #define __HID_RKVR_H #define HIDRKVRHANDSHAKE(len) _IOC(_IOC_WRITE, 'H', 0x1A, len) + +#define HID_REPORT_ID_RKVR 3 +#define RKVR_ID_IDLE 1 +#define RKVR_ID_SYNC 2 + #define HID_REPORT_ID_R 4 #define HID_REPORT_ID_W 5 #define HID_REPORT_ID_CRYP 6 + #define HID_REGR_REPORT (4 - 1) #define HID_REGW_REPORT (5 - 1) -- 2.34.1