diff options
author | Marcus Folkesson <marcus.folkesson@gmail.com> | 2018-03-17 13:50:48 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2018-03-17 14:05:18 -0400 |
commit | ff0d2cba646dc0e195317c20a0630a5c7a2e328e (patch) | |
tree | 60e1e671639f55731ad26195b6839a039d3446bd | |
parent | b8a7cc4b5e5a0681fdeffe92b613e3e4eb769801 (diff) |
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>
-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 { | |||
84 | 84 | ||
85 | /* serialize access to open/suspend */ | 85 | /* serialize access to open/suspend */ |
86 | struct mutex pm_mutex; | 86 | struct mutex pm_mutex; |
87 | bool is_open; | ||
87 | 88 | ||
88 | /* input device related data structures */ | 89 | /* input device related data structures */ |
89 | struct input_dev *input; | 90 | struct input_dev *input; |
@@ -266,6 +267,7 @@ static int synusb_open(struct input_dev *dev) | |||
266 | } | 267 | } |
267 | 268 | ||
268 | synusb->intf->needs_remote_wakeup = 1; | 269 | synusb->intf->needs_remote_wakeup = 1; |
270 | synusb->is_open = true; | ||
269 | 271 | ||
270 | out: | 272 | out: |
271 | mutex_unlock(&synusb->pm_mutex); | 273 | mutex_unlock(&synusb->pm_mutex); |
@@ -283,6 +285,7 @@ static void synusb_close(struct input_dev *dev) | |||
283 | mutex_lock(&synusb->pm_mutex); | 285 | mutex_lock(&synusb->pm_mutex); |
284 | usb_kill_urb(synusb->urb); | 286 | usb_kill_urb(synusb->urb); |
285 | synusb->intf->needs_remote_wakeup = 0; | 287 | synusb->intf->needs_remote_wakeup = 0; |
288 | synusb->is_open = false; | ||
286 | mutex_unlock(&synusb->pm_mutex); | 289 | mutex_unlock(&synusb->pm_mutex); |
287 | 290 | ||
288 | if (!autopm_error) | 291 | if (!autopm_error) |
@@ -485,12 +488,11 @@ static int synusb_suspend(struct usb_interface *intf, pm_message_t message) | |||
485 | static int synusb_resume(struct usb_interface *intf) | 488 | static int synusb_resume(struct usb_interface *intf) |
486 | { | 489 | { |
487 | struct synusb *synusb = usb_get_intfdata(intf); | 490 | struct synusb *synusb = usb_get_intfdata(intf); |
488 | struct input_dev *input_dev = synusb->input; | ||
489 | int retval = 0; | 491 | int retval = 0; |
490 | 492 | ||
491 | mutex_lock(&synusb->pm_mutex); | 493 | mutex_lock(&synusb->pm_mutex); |
492 | 494 | ||
493 | if ((input_dev->users || (synusb->flags & SYNUSB_IO_ALWAYS)) && | 495 | if ((synusb->is_open || (synusb->flags & SYNUSB_IO_ALWAYS)) && |
494 | usb_submit_urb(synusb->urb, GFP_NOIO) < 0) { | 496 | usb_submit_urb(synusb->urb, GFP_NOIO) < 0) { |
495 | retval = -EIO; | 497 | retval = -EIO; |
496 | } | 498 | } |
@@ -513,10 +515,9 @@ static int synusb_pre_reset(struct usb_interface *intf) | |||
513 | static int synusb_post_reset(struct usb_interface *intf) | 515 | static int synusb_post_reset(struct usb_interface *intf) |
514 | { | 516 | { |
515 | struct synusb *synusb = usb_get_intfdata(intf); | 517 | struct synusb *synusb = usb_get_intfdata(intf); |
516 | struct input_dev *input_dev = synusb->input; | ||
517 | int retval = 0; | 518 | int retval = 0; |
518 | 519 | ||
519 | if ((input_dev->users || (synusb->flags & SYNUSB_IO_ALWAYS)) && | 520 | if ((synusb->is_open || (synusb->flags & SYNUSB_IO_ALWAYS)) && |
520 | usb_submit_urb(synusb->urb, GFP_NOIO) < 0) { | 521 | usb_submit_urb(synusb->urb, GFP_NOIO) < 0) { |
521 | retval = -EIO; | 522 | retval = -EIO; |
522 | } | 523 | } |