Skip to content

Commit a66eebd

Browse files
author
Jiri Kosina
committed
Merge branch 'for-5.9/core-v2' into for-linus
- fix for some modern devices that return multi-byte battery report, from Grant Likely - fix for devices with Resolution Multiplier, from Peter Hutterer - device probing speed increase, from Dmitry Torokhov
2 parents 68f775d + 4f57cac commit a66eebd

File tree

3 files changed

+55
-38
lines changed

3 files changed

+55
-38
lines changed

drivers/hid/hid-input.c

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -350,13 +350,13 @@ static int hidinput_query_battery_capacity(struct hid_device *dev)
350350
u8 *buf;
351351
int ret;
352352

353-
buf = kmalloc(2, GFP_KERNEL);
353+
buf = kmalloc(4, GFP_KERNEL);
354354
if (!buf)
355355
return -ENOMEM;
356356

357-
ret = hid_hw_raw_request(dev, dev->battery_report_id, buf, 2,
357+
ret = hid_hw_raw_request(dev, dev->battery_report_id, buf, 4,
358358
dev->battery_report_type, HID_REQ_GET_REPORT);
359-
if (ret != 2) {
359+
if (ret < 2) {
360360
kfree(buf);
361361
return -ENODATA;
362362
}
@@ -1560,21 +1560,12 @@ static bool __hidinput_change_resolution_multipliers(struct hid_device *hid,
15601560
{
15611561
struct hid_usage *usage;
15621562
bool update_needed = false;
1563+
bool get_report_completed = false;
15631564
int i, j;
15641565

15651566
if (report->maxfield == 0)
15661567
return false;
15671568

1568-
/*
1569-
* If we have more than one feature within this report we
1570-
* need to fill in the bits from the others before we can
1571-
* overwrite the ones for the Resolution Multiplier.
1572-
*/
1573-
if (report->maxfield > 1) {
1574-
hid_hw_request(hid, report, HID_REQ_GET_REPORT);
1575-
hid_hw_wait(hid);
1576-
}
1577-
15781569
for (i = 0; i < report->maxfield; i++) {
15791570
__s32 value = use_logical_max ?
15801571
report->field[i]->logical_maximum :
@@ -1593,6 +1584,25 @@ static bool __hidinput_change_resolution_multipliers(struct hid_device *hid,
15931584
if (usage->hid != HID_GD_RESOLUTION_MULTIPLIER)
15941585
continue;
15951586

1587+
/*
1588+
* If we have more than one feature within this
1589+
* report we need to fill in the bits from the
1590+
* others before we can overwrite the ones for the
1591+
* Resolution Multiplier.
1592+
*
1593+
* But if we're not allowed to read from the device,
1594+
* we just bail. Such a device should not exist
1595+
* anyway.
1596+
*/
1597+
if (!get_report_completed && report->maxfield > 1) {
1598+
if (hid->quirks & HID_QUIRK_NO_INIT_REPORTS)
1599+
return update_needed;
1600+
1601+
hid_hw_request(hid, report, HID_REQ_GET_REPORT);
1602+
hid_hw_wait(hid);
1603+
get_report_completed = true;
1604+
}
1605+
15961606
report->field[i]->value[j] = value;
15971607
update_needed = true;
15981608
}

drivers/hid/usbhid/hid-core.c

Lines changed: 30 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include <linux/wait.h>
2727
#include <linux/workqueue.h>
2828
#include <linux/string.h>
29+
#include <linux/timekeeping.h>
2930

3031
#include <linux/usb.h>
3132

@@ -95,6 +96,18 @@ static int hid_start_in(struct hid_device *hid)
9596
set_bit(HID_NO_BANDWIDTH, &usbhid->iofl);
9697
} else {
9798
clear_bit(HID_NO_BANDWIDTH, &usbhid->iofl);
99+
100+
if (test_bit(HID_RESUME_RUNNING, &usbhid->iofl)) {
101+
/*
102+
* In case events are generated while nobody was
103+
* listening, some are released when the device
104+
* is re-opened. Wait 50 msec for the queue to
105+
* empty before allowing events to go through
106+
* hid.
107+
*/
108+
usbhid->input_start_time =
109+
ktime_add_ms(ktime_get_coarse(), 50);
110+
}
98111
}
99112
}
100113
spin_unlock_irqrestore(&usbhid->lock, flags);
@@ -280,20 +293,23 @@ static void hid_irq_in(struct urb *urb)
280293
if (!test_bit(HID_OPENED, &usbhid->iofl))
281294
break;
282295
usbhid_mark_busy(usbhid);
283-
if (!test_bit(HID_RESUME_RUNNING, &usbhid->iofl)) {
284-
hid_input_report(urb->context, HID_INPUT_REPORT,
285-
urb->transfer_buffer,
286-
urb->actual_length, 1);
287-
/*
288-
* autosuspend refused while keys are pressed
289-
* because most keyboards don't wake up when
290-
* a key is released
291-
*/
292-
if (hid_check_keys_pressed(hid))
293-
set_bit(HID_KEYS_PRESSED, &usbhid->iofl);
294-
else
295-
clear_bit(HID_KEYS_PRESSED, &usbhid->iofl);
296+
if (test_bit(HID_RESUME_RUNNING, &usbhid->iofl)) {
297+
if (ktime_before(ktime_get_coarse(),
298+
usbhid->input_start_time))
299+
break;
300+
clear_bit(HID_RESUME_RUNNING, &usbhid->iofl);
296301
}
302+
hid_input_report(urb->context, HID_INPUT_REPORT,
303+
urb->transfer_buffer, urb->actual_length, 1);
304+
/*
305+
* autosuspend refused while keys are pressed
306+
* because most keyboards don't wake up when
307+
* a key is released
308+
*/
309+
if (hid_check_keys_pressed(hid))
310+
set_bit(HID_KEYS_PRESSED, &usbhid->iofl);
311+
else
312+
clear_bit(HID_KEYS_PRESSED, &usbhid->iofl);
297313
break;
298314
case -EPIPE: /* stall */
299315
usbhid_mark_busy(usbhid);
@@ -720,17 +736,6 @@ static int usbhid_open(struct hid_device *hid)
720736

721737
usb_autopm_put_interface(usbhid->intf);
722738

723-
/*
724-
* In case events are generated while nobody was listening,
725-
* some are released when the device is re-opened.
726-
* Wait 50 msec for the queue to empty before allowing events
727-
* to go through hid.
728-
*/
729-
if (res == 0)
730-
msleep(50);
731-
732-
clear_bit(HID_RESUME_RUNNING, &usbhid->iofl);
733-
734739
Done:
735740
mutex_unlock(&usbhid->mutex);
736741
return res;
@@ -1667,7 +1672,7 @@ struct usb_interface *usbhid_find_interface(int minor)
16671672

16681673
static int __init hid_init(void)
16691674
{
1670-
int retval = -ENOMEM;
1675+
int retval;
16711676

16721677
retval = hid_quirks_init(quirks_param, BUS_USB, MAX_USBHID_BOOT_QUIRKS);
16731678
if (retval)

drivers/hid/usbhid/usbhid.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
#include <linux/types.h>
1515
#include <linux/slab.h>
16+
#include <linux/ktime.h>
1617
#include <linux/list.h>
1718
#include <linux/mutex.h>
1819
#include <linux/timer.h>
@@ -83,6 +84,7 @@ struct usbhid_device {
8384
struct mutex mutex; /* start/stop/open/close */
8485
spinlock_t lock; /* fifo spinlock */
8586
unsigned long iofl; /* I/O flags (CTRL_RUNNING, OUT_RUNNING) */
87+
ktime_t input_start_time; /* When to start handling input */
8688
struct timer_list io_retry; /* Retry timer */
8789
unsigned long stop_retry; /* Time to give up, in jiffies */
8890
unsigned int retry_delay; /* Delay length in ms */

0 commit comments

Comments
 (0)