aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorArjan Mels <arjan.mels@gmx.net>2011-04-05 14:26:11 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2011-04-06 18:51:13 -0400
commitd2dd0b07c3e725d386d20294ec906f7ddef207fa (patch)
tree6b3d26aff120d41bac0a06b06ed03d7e88daa228 /drivers
parent2f8c4c5494c2589e6cb9a62f399e61a1c4c2378d (diff)
staging: usbip: bugfixes related to kthread conversion
When doing a usb port reset do a queued reset instead to prevent a deadlock: the reset will cause the driver to unbind, causing the usb_driver_lock_for_reset to stall. Signed-off-by: Arjan Mels <arjan.mels@gmx.net> Cc: Takahiro Hirofuchi <hirofuchi@users.sourceforge.net> Cc: Max Vozeler <max@vozeler.com> Cc: Arnd Bergmann <arnd@arndb.de> Cc: stable <stable@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/staging/usbip/stub_rx.c40
1 files changed, 15 insertions, 25 deletions
diff --git a/drivers/staging/usbip/stub_rx.c b/drivers/staging/usbip/stub_rx.c
index 6445f12cb4fd..51fbd0986475 100644
--- a/drivers/staging/usbip/stub_rx.c
+++ b/drivers/staging/usbip/stub_rx.c
@@ -171,33 +171,23 @@ static int tweak_set_configuration_cmd(struct urb *urb)
171 171
172static int tweak_reset_device_cmd(struct urb *urb) 172static int tweak_reset_device_cmd(struct urb *urb)
173{ 173{
174 struct usb_ctrlrequest *req; 174 struct stub_priv *priv = (struct stub_priv *) urb->context;
175 __u16 value; 175 struct stub_device *sdev = priv->sdev;
176 __u16 index;
177 int ret;
178
179 req = (struct usb_ctrlrequest *) urb->setup_packet;
180 value = le16_to_cpu(req->wValue);
181 index = le16_to_cpu(req->wIndex);
182
183 usbip_uinfo("reset_device (port %d) to %s\n", index,
184 dev_name(&urb->dev->dev));
185 176
186 /* all interfaces should be owned by usbip driver, so just reset it. */ 177 usbip_uinfo("reset_device %s\n", dev_name(&urb->dev->dev));
187 ret = usb_lock_device_for_reset(urb->dev, NULL);
188 if (ret < 0) {
189 dev_err(&urb->dev->dev, "lock for reset\n");
190 return ret;
191 }
192
193 /* try to reset the device */
194 ret = usb_reset_device(urb->dev);
195 if (ret < 0)
196 dev_err(&urb->dev->dev, "device reset\n");
197 178
198 usb_unlock_device(urb->dev); 179 /*
199 180 * usb_lock_device_for_reset caused a deadlock: it causes the driver
200 return ret; 181 * to unbind. In the shutdown the rx thread is signalled to shut down
182 * but this thread is pending in the usb_lock_device_for_reset.
183 *
184 * Instead queue the reset.
185 *
186 * Unfortunatly an existing usbip connection will be dropped due to
187 * driver unbinding.
188 */
189 usb_queue_reset_device(sdev->interface);
190 return 0;
201} 191}
202 192
203/* 193/*