HID: i2c-hid: fix i2c_hid_output_raw_report
authorBenjamin Tissoires <benjamin.tissoires@gmail.com>
Thu, 31 Jan 2013 16:50:02 +0000 (17:50 +0100)
committerJiri Kosina <jkosina@suse.cz>
Thu, 31 Jan 2013 16:57:53 +0000 (17:57 +0100)
i2c_hid_output_raw_report is used by hidraw to forward set_report requests.
The current implementation of i2c_hid_set_report needs to take the
report_id as an argument. The report_id is stored in the first byte
of the buffer in argument of i2c_hid_output_raw_report.

Not removing the report_id from the given buffer adds this byte 2 times
in the command, leading to a non working command.

Reported-by: Andrew Duggan <aduggan@synaptics.com>
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
drivers/hid/i2c-hid/i2c-hid.c

index 9ef222442ca0e989438ec3695ab473fc427339f3..5774ebf4298c7ba1d4f8ddbbbe42cbb9d857f7be 100644 (file)
@@ -540,13 +540,24 @@ static int i2c_hid_output_raw_report(struct hid_device *hid, __u8 *buf,
 {
        struct i2c_client *client = hid->driver_data;
        int report_id = buf[0];
+       int ret;
 
        if (report_type == HID_INPUT_REPORT)
                return -EINVAL;
 
-       return i2c_hid_set_report(client,
+       if (report_id) {
+               buf++;
+               count--;
+       }
+
+       ret = i2c_hid_set_report(client,
                                report_type == HID_FEATURE_REPORT ? 0x03 : 0x02,
                                report_id, buf, count);
+
+       if (report_id && ret >= 0)
+               ret++; /* add report_id to the number of transfered bytes */
+
+       return ret;
 }
 
 static int i2c_hid_parse(struct hid_device *hid)