From ff0d2cba646dc0e195317c20a0630a5c7a2e328e Mon Sep 17 00:00:00 2001 From: Marcus Folkesson Date: Sat, 17 Mar 2018 10:50:48 -0700 Subject: [PATCH] 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 Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/synaptics_usb.c | 9 +++++---- 1 file 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; } -- 2.11.0