diff options
Diffstat (limited to 'drivers/hid/usbhid')
-rw-r--r-- | drivers/hid/usbhid/hid-core.c | 53 | ||||
-rw-r--r-- | drivers/hid/usbhid/hiddev.c | 5 | ||||
-rw-r--r-- | drivers/hid/usbhid/usbhid.h | 2 |
3 files changed, 28 insertions, 32 deletions
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index 492dd641a25d..17a29ee0ac6c 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c @@ -26,7 +26,6 @@ #include <linux/wait.h> #include <linux/workqueue.h> #include <linux/string.h> -#include <linux/timekeeping.h> #include <linux/usb.h> @@ -96,18 +95,6 @@ static int hid_start_in(struct hid_device *hid) set_bit(HID_NO_BANDWIDTH, &usbhid->iofl); } else { clear_bit(HID_NO_BANDWIDTH, &usbhid->iofl); - - if (test_bit(HID_RESUME_RUNNING, &usbhid->iofl)) { - /* - * In case events are generated while nobody was - * listening, some are released when the device - * is re-opened. Wait 50 msec for the queue to - * empty before allowing events to go through - * hid. - */ - usbhid->input_start_time = - ktime_add_ms(ktime_get_coarse(), 50); - } } } spin_unlock_irqrestore(&usbhid->lock, flags); @@ -293,23 +280,20 @@ static void hid_irq_in(struct urb *urb) if (!test_bit(HID_OPENED, &usbhid->iofl)) break; usbhid_mark_busy(usbhid); - if (test_bit(HID_RESUME_RUNNING, &usbhid->iofl)) { - if (ktime_before(ktime_get_coarse(), - usbhid->input_start_time)) - break; - clear_bit(HID_RESUME_RUNNING, &usbhid->iofl); + if (!test_bit(HID_RESUME_RUNNING, &usbhid->iofl)) { + hid_input_report(urb->context, HID_INPUT_REPORT, + urb->transfer_buffer, + urb->actual_length, 1); + /* + * autosuspend refused while keys are pressed + * because most keyboards don't wake up when + * a key is released + */ + if (hid_check_keys_pressed(hid)) + set_bit(HID_KEYS_PRESSED, &usbhid->iofl); + else + clear_bit(HID_KEYS_PRESSED, &usbhid->iofl); } - hid_input_report(urb->context, HID_INPUT_REPORT, - urb->transfer_buffer, urb->actual_length, 1); - /* - * autosuspend refused while keys are pressed - * because most keyboards don't wake up when - * a key is released - */ - if (hid_check_keys_pressed(hid)) - set_bit(HID_KEYS_PRESSED, &usbhid->iofl); - else - clear_bit(HID_KEYS_PRESSED, &usbhid->iofl); break; case -EPIPE: /* stall */ usbhid_mark_busy(usbhid); @@ -736,6 +720,17 @@ static int usbhid_open(struct hid_device *hid) usb_autopm_put_interface(usbhid->intf); + /* + * In case events are generated while nobody was listening, + * some are released when the device is re-opened. + * Wait 50 msec for the queue to empty before allowing events + * to go through hid. + */ + if (res == 0) + msleep(50); + + clear_bit(HID_RESUME_RUNNING, &usbhid->iofl); + Done: mutex_unlock(&usbhid->mutex); return res; diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c index 4140dea693e9..45e0b1c75cb1 100644 --- a/drivers/hid/usbhid/hiddev.c +++ b/drivers/hid/usbhid/hiddev.c @@ -519,12 +519,16 @@ static noinline int hiddev_ioctl_usage(struct hiddev *hiddev, unsigned int cmd, switch (cmd) { case HIDIOCGUSAGE: + if (uref->usage_index >= field->report_count) + goto inval; uref->value = field->value[uref->usage_index]; if (copy_to_user(user_arg, uref, sizeof(*uref))) goto fault; goto goodreturn; case HIDIOCSUSAGE: + if (uref->usage_index >= field->report_count) + goto inval; field->value[uref->usage_index] = uref->value; goto goodreturn; @@ -781,7 +785,6 @@ static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) break; case HIDIOCGUCODE: - /* fall through */ case HIDIOCGUSAGE: case HIDIOCSUSAGE: case HIDIOCGUSAGES: diff --git a/drivers/hid/usbhid/usbhid.h b/drivers/hid/usbhid/usbhid.h index c6ad684d099a..75fe85d3d27a 100644 --- a/drivers/hid/usbhid/usbhid.h +++ b/drivers/hid/usbhid/usbhid.h @@ -13,7 +13,6 @@ #include <linux/types.h> #include <linux/slab.h> -#include <linux/ktime.h> #include <linux/list.h> #include <linux/mutex.h> #include <linux/timer.h> @@ -84,7 +83,6 @@ struct usbhid_device { struct mutex mutex; /* start/stop/open/close */ spinlock_t lock; /* fifo spinlock */ unsigned long iofl; /* I/O flags (CTRL_RUNNING, OUT_RUNNING) */ - ktime_t input_start_time; /* When to start handling input */ struct timer_list io_retry; /* Retry timer */ unsigned long stop_retry; /* Time to give up, in jiffies */ unsigned int retry_delay; /* Delay length in ms */ |