aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hid')
-rw-r--r--drivers/hid/i2c-hid/i2c-hid.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c
index c6630d442e78..ce01d5916184 100644
--- a/drivers/hid/i2c-hid/i2c-hid.c
+++ b/drivers/hid/i2c-hid/i2c-hid.c
@@ -502,23 +502,31 @@ static int i2c_hid_get_raw_report(struct hid_device *hid,
502{ 502{
503 struct i2c_client *client = hid->driver_data; 503 struct i2c_client *client = hid->driver_data;
504 struct i2c_hid *ihid = i2c_get_clientdata(client); 504 struct i2c_hid *ihid = i2c_get_clientdata(client);
505 size_t ret_count, ask_count;
505 int ret; 506 int ret;
506 507
507 if (report_type == HID_OUTPUT_REPORT) 508 if (report_type == HID_OUTPUT_REPORT)
508 return -EINVAL; 509 return -EINVAL;
509 510
510 if (count > ihid->bufsize) 511 /* +2 bytes to include the size of the reply in the query buffer */
511 count = ihid->bufsize; 512 ask_count = min(count + 2, (size_t)ihid->bufsize);
512 513
513 ret = i2c_hid_get_report(client, 514 ret = i2c_hid_get_report(client,
514 report_type == HID_FEATURE_REPORT ? 0x03 : 0x01, 515 report_type == HID_FEATURE_REPORT ? 0x03 : 0x01,
515 report_number, ihid->inbuf, count); 516 report_number, ihid->inbuf, ask_count);
516 517
517 if (ret < 0) 518 if (ret < 0)
518 return ret; 519 return ret;
519 520
520 count = ihid->inbuf[0] | (ihid->inbuf[1] << 8); 521 ret_count = ihid->inbuf[0] | (ihid->inbuf[1] << 8);
521 522
523 if (!ret_count)
524 return 0;
525
526 ret_count = min(ret_count, ask_count);
527
528 /* The query buffer contains the size, dropping it in the reply */
529 count = min(count, ret_count - 2);
522 memcpy(buf, ihid->inbuf + 2, count); 530 memcpy(buf, ihid->inbuf + 2, count);
523 531
524 return count; 532 return count;