]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/3.10.39/usb-unbind-all-interfaces-before-rebinding-any.patch
Linux 4.4.177
[thirdparty/kernel/stable-queue.git] / releases / 3.10.39 / usb-unbind-all-interfaces-before-rebinding-any.patch
CommitLineData
e56a7dfa
GKH
1From 6aec044cc2f5670cf3b143c151c8be846499bd15 Mon Sep 17 00:00:00 2001
2From: Alan Stern <stern@rowland.harvard.edu>
3Date: Wed, 12 Mar 2014 11:30:38 -0400
4Subject: USB: unbind all interfaces before rebinding any
5
6From: Alan Stern <stern@rowland.harvard.edu>
7
8commit 6aec044cc2f5670cf3b143c151c8be846499bd15 upstream.
9
10When a driver doesn't have pre_reset, post_reset, or reset_resume
11methods, the USB core unbinds that driver when its device undergoes a
12reset or a reset-resume, and then rebinds it afterward.
13
14The existing straightforward implementation can lead to problems,
15because each interface gets unbound and rebound before the next
16interface is handled. If a driver claims additional interfaces, the
17claim may fail because the old binding instance may still own the
18additional interface when the new instance tries to claim it.
19
20This patch fixes the problem by first unbinding all the interfaces
21that are marked (i.e., their needs_binding flag is set) and then
22rebinding all of them.
23
24The patch also makes the helper functions in driver.c a little more
25uniform and adjusts some out-of-date comments.
26
27Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
28Reported-and-tested-by: "Poulain, Loic" <loic.poulain@intel.com>
29Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
30
31---
32 drivers/usb/core/driver.c | 94 +++++++++++++++++++++++++++-------------------
33 drivers/usb/core/hub.c | 5 +-
34 drivers/usb/core/usb.h | 2
35 3 files changed, 60 insertions(+), 41 deletions(-)
36
37--- a/drivers/usb/core/driver.c
38+++ b/drivers/usb/core/driver.c
39@@ -953,8 +953,7 @@ EXPORT_SYMBOL_GPL(usb_deregister);
40 * it doesn't support pre_reset/post_reset/reset_resume or
41 * because it doesn't support suspend/resume.
42 *
43- * The caller must hold @intf's device's lock, but not its pm_mutex
44- * and not @intf->dev.sem.
45+ * The caller must hold @intf's device's lock, but not @intf's lock.
46 */
47 void usb_forced_unbind_intf(struct usb_interface *intf)
48 {
49@@ -967,16 +966,37 @@ void usb_forced_unbind_intf(struct usb_i
50 intf->needs_binding = 1;
51 }
52
53+/*
54+ * Unbind drivers for @udev's marked interfaces. These interfaces have
55+ * the needs_binding flag set, for example by usb_resume_interface().
56+ *
57+ * The caller must hold @udev's device lock.
58+ */
59+static void unbind_marked_interfaces(struct usb_device *udev)
60+{
61+ struct usb_host_config *config;
62+ int i;
63+ struct usb_interface *intf;
64+
65+ config = udev->actconfig;
66+ if (config) {
67+ for (i = 0; i < config->desc.bNumInterfaces; ++i) {
68+ intf = config->interface[i];
69+ if (intf->dev.driver && intf->needs_binding)
70+ usb_forced_unbind_intf(intf);
71+ }
72+ }
73+}
74+
75 /* Delayed forced unbinding of a USB interface driver and scan
76 * for rebinding.
77 *
78- * The caller must hold @intf's device's lock, but not its pm_mutex
79- * and not @intf->dev.sem.
80+ * The caller must hold @intf's device's lock, but not @intf's lock.
81 *
82 * Note: Rebinds will be skipped if a system sleep transition is in
83 * progress and the PM "complete" callback hasn't occurred yet.
84 */
85-void usb_rebind_intf(struct usb_interface *intf)
86+static void usb_rebind_intf(struct usb_interface *intf)
87 {
88 int rc;
89
90@@ -993,68 +1013,66 @@ void usb_rebind_intf(struct usb_interfac
91 }
92 }
93
94-#ifdef CONFIG_PM
95-
96-/* Unbind drivers for @udev's interfaces that don't support suspend/resume
97- * There is no check for reset_resume here because it can be determined
98- * only during resume whether reset_resume is needed.
99+/*
100+ * Rebind drivers to @udev's marked interfaces. These interfaces have
101+ * the needs_binding flag set.
102 *
103 * The caller must hold @udev's device lock.
104 */
105-static void unbind_no_pm_drivers_interfaces(struct usb_device *udev)
106+static void rebind_marked_interfaces(struct usb_device *udev)
107 {
108 struct usb_host_config *config;
109 int i;
110 struct usb_interface *intf;
111- struct usb_driver *drv;
112
113 config = udev->actconfig;
114 if (config) {
115 for (i = 0; i < config->desc.bNumInterfaces; ++i) {
116 intf = config->interface[i];
117-
118- if (intf->dev.driver) {
119- drv = to_usb_driver(intf->dev.driver);
120- if (!drv->suspend || !drv->resume)
121- usb_forced_unbind_intf(intf);
122- }
123+ if (intf->needs_binding)
124+ usb_rebind_intf(intf);
125 }
126 }
127 }
128
129-/* Unbind drivers for @udev's interfaces that failed to support reset-resume.
130- * These interfaces have the needs_binding flag set by usb_resume_interface().
131+/*
132+ * Unbind all of @udev's marked interfaces and then rebind all of them.
133+ * This ordering is necessary because some drivers claim several interfaces
134+ * when they are first probed.
135 *
136 * The caller must hold @udev's device lock.
137 */
138-static void unbind_no_reset_resume_drivers_interfaces(struct usb_device *udev)
139+void usb_unbind_and_rebind_marked_interfaces(struct usb_device *udev)
140 {
141- struct usb_host_config *config;
142- int i;
143- struct usb_interface *intf;
144-
145- config = udev->actconfig;
146- if (config) {
147- for (i = 0; i < config->desc.bNumInterfaces; ++i) {
148- intf = config->interface[i];
149- if (intf->dev.driver && intf->needs_binding)
150- usb_forced_unbind_intf(intf);
151- }
152- }
153+ unbind_marked_interfaces(udev);
154+ rebind_marked_interfaces(udev);
155 }
156
157-static void do_rebind_interfaces(struct usb_device *udev)
158+#ifdef CONFIG_PM
159+
160+/* Unbind drivers for @udev's interfaces that don't support suspend/resume
161+ * There is no check for reset_resume here because it can be determined
162+ * only during resume whether reset_resume is needed.
163+ *
164+ * The caller must hold @udev's device lock.
165+ */
166+static void unbind_no_pm_drivers_interfaces(struct usb_device *udev)
167 {
168 struct usb_host_config *config;
169 int i;
170 struct usb_interface *intf;
171+ struct usb_driver *drv;
172
173 config = udev->actconfig;
174 if (config) {
175 for (i = 0; i < config->desc.bNumInterfaces; ++i) {
176 intf = config->interface[i];
177- if (intf->needs_binding)
178- usb_rebind_intf(intf);
179+
180+ if (intf->dev.driver) {
181+ drv = to_usb_driver(intf->dev.driver);
182+ if (!drv->suspend || !drv->resume)
183+ usb_forced_unbind_intf(intf);
184+ }
185 }
186 }
187 }
188@@ -1379,7 +1397,7 @@ int usb_resume_complete(struct device *d
189 * whose needs_binding flag is set
190 */
191 if (udev->state != USB_STATE_NOTATTACHED)
192- do_rebind_interfaces(udev);
193+ rebind_marked_interfaces(udev);
194 return 0;
195 }
196
197@@ -1401,7 +1419,7 @@ int usb_resume(struct device *dev, pm_me
198 pm_runtime_disable(dev);
199 pm_runtime_set_active(dev);
200 pm_runtime_enable(dev);
201- unbind_no_reset_resume_drivers_interfaces(udev);
202+ unbind_marked_interfaces(udev);
203 }
204
205 /* Avoid PM error messages for devices disconnected while suspended
206--- a/drivers/usb/core/hub.c
207+++ b/drivers/usb/core/hub.c
208@@ -5252,10 +5252,11 @@ int usb_reset_device(struct usb_device *
209 else if (cintf->condition ==
210 USB_INTERFACE_BOUND)
211 rebind = 1;
212+ if (rebind)
213+ cintf->needs_binding = 1;
214 }
215- if (ret == 0 && rebind)
216- usb_rebind_intf(cintf);
217 }
218+ usb_unbind_and_rebind_marked_interfaces(udev);
219 }
220
221 usb_autosuspend_device(udev);
222--- a/drivers/usb/core/usb.h
223+++ b/drivers/usb/core/usb.h
224@@ -55,7 +55,7 @@ extern int usb_match_one_id_intf(struct
225 extern int usb_match_device(struct usb_device *dev,
226 const struct usb_device_id *id);
227 extern void usb_forced_unbind_intf(struct usb_interface *intf);
228-extern void usb_rebind_intf(struct usb_interface *intf);
229+extern void usb_unbind_and_rebind_marked_interfaces(struct usb_device *udev);
230
231 extern int usb_hub_claim_port(struct usb_device *hdev, unsigned port,
232 struct dev_state *owner);