diff options
author | Marcus Folkesson <marcus.folkesson@gmail.com> | 2018-03-17 10:50:48 -0700 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2018-03-17 11:05:18 -0700 |
commit | ff0d2cba646dc0e195317c20a0630a5c7a2e328e (patch) | |
tree | 60e1e671639f55731ad26195b6839a039d3446bd /drivers/input | |
parent | b8a7cc4b5e5a0681fdeffe92b613e3e4eb769801 (diff) | |
download | linux-ff0d2cba646dc0e195317c20a0630a5c7a2e328e.tar.bz2 |
Input: synaptics_usb - do not rely on input_dev->users
If the device is unused and suspended, a call to open will cause the
device to autoresume through the call to usb_autopm_get_interface().
input_dev->users is already incremented by the input subsystem,
therefore this expression will always be evaluated to true:
if ((input_dev->users || (synusb->flags & SYNUSB_IO_ALWAYS)) &&
usb_submit_urb(synusb->urb, GFP_NOIO) < 0) {
retval = -EIO;
}
The same URB will then be fail when resubmitted in synusb_open().
Introduce synusb->is_open to keep track of the state instead.
Signed-off-by: Marcus Folkesson <marcus.folkesson@gmail.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Diffstat (limited to 'drivers/input')
-rw-r--r-- | drivers/input/mouse/synaptics_usb.c | 9 |
1 files changed, 5 insertions, 4 deletions
diff --git a/drivers/input/mouse/synaptics_usb.c b/drivers/input/mouse/synaptics_usb.c index 2c66913cf5a2..83d2412a64cf 100644 --- a/drivers/input/mouse/synaptics_usb.c +++ b/drivers/input/mouse/synaptics_usb.c @@ -84,6 +84,7 @@ struct synusb { /* serialize access to open/suspend */ struct mutex pm_mutex; + bool is_open; /* input device related data structures */ struct input_dev *input; @@ -266,6 +267,7 @@ static int synusb_open(struct input_dev *dev) } synusb->intf->needs_remote_wakeup = 1; + synusb->is_open = true; out: mutex_unlock(&synusb->pm_mutex); @@ -283,6 +285,7 @@ static void synusb_close(struct input_dev *dev) mutex_lock(&synusb->pm_mutex); usb_kill_urb(synusb->urb); synusb->intf->needs_remote_wakeup = 0; + synusb->is_open = false; mutex_unlock(&synusb->pm_mutex); if (!autopm_error) @@ -485,12 +488,11 @@ static int synusb_suspend(struct usb_interface *intf, pm_message_t message) static int synusb_resume(struct usb_interface *intf) { struct synusb *synusb = usb_get_intfdata(intf); - struct input_dev *input_dev = synusb->input; int retval = 0; mutex_lock(&synusb->pm_mutex); - if ((input_dev->users || (synusb->flags & SYNUSB_IO_ALWAYS)) && + if ((synusb->is_open || (synusb->flags & SYNUSB_IO_ALWAYS)) && usb_submit_urb(synusb->urb, GFP_NOIO) < 0) { retval = -EIO; } @@ -513,10 +515,9 @@ static int synusb_pre_reset(struct usb_interface *intf) static int synusb_post_reset(struct usb_interface *intf) { struct synusb *synusb = usb_get_intfdata(intf); - struct input_dev *input_dev = synusb->input; int retval = 0; - if ((input_dev->users || (synusb->flags & SYNUSB_IO_ALWAYS)) && + if ((synusb->is_open || (synusb->flags & SYNUSB_IO_ALWAYS)) && usb_submit_urb(synusb->urb, GFP_NOIO) < 0) { retval = -EIO; } |