Skip to content

Commit 60faafd

Browse files
Shuah Khan (Samsung OSG)ZhengShunQian
authored andcommitted
usbip: usbip_host: run rebind from exit when module is removed
commit 7510df3 upstream. After removing usbip_host module, devices it releases are left without a driver. For example, when a keyboard or a mass storage device are bound to usbip_host when it is removed, these devices are no longer bound to any driver. Fix it to run device_attach() from the module exit routine to restore the devices to their original drivers. This includes cleanup changes and moving device_attach() code to a common routine to be called from rebind_store() and usbip_host_exit(). Signed-off-by: Shuah Khan (Samsung OSG) <[email protected]> Cc: stable <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 6dcf12c commit 60faafd

File tree

2 files changed

+52
-14
lines changed

2 files changed

+52
-14
lines changed

drivers/usb/usbip/stub_dev.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -463,12 +463,8 @@ static void stub_disconnect(struct usb_device *udev)
463463
busid_priv->sdev = NULL;
464464
stub_device_free(sdev);
465465

466-
if (busid_priv->status == STUB_BUSID_ALLOC) {
466+
if (busid_priv->status == STUB_BUSID_ALLOC)
467467
busid_priv->status = STUB_BUSID_ADDED;
468-
} else {
469-
busid_priv->status = STUB_BUSID_OTHER;
470-
del_match_busid((char *)udev_busid);
471-
}
472468
}
473469

474470
#ifdef CONFIG_PM

drivers/usb/usbip/stub_main.c

Lines changed: 51 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#define DRIVER_DESC "USB/IP Host Driver"
2929

3030
struct kmem_cache *stub_priv_cache;
31+
3132
/*
3233
* busid_tables defines matching busids that usbip can grab. A user can change
3334
* dynamically what device is locally used and what device is exported to a
@@ -184,6 +185,51 @@ static ssize_t store_match_busid(struct device_driver *dev, const char *buf,
184185
static DRIVER_ATTR(match_busid, S_IRUSR | S_IWUSR, show_match_busid,
185186
store_match_busid);
186187

188+
static int do_rebind(char *busid, struct bus_id_priv *busid_priv)
189+
{
190+
int ret;
191+
192+
/* device_attach() callers should hold parent lock for USB */
193+
if (busid_priv->udev->dev.parent)
194+
device_lock(busid_priv->udev->dev.parent);
195+
ret = device_attach(&busid_priv->udev->dev);
196+
if (busid_priv->udev->dev.parent)
197+
device_unlock(busid_priv->udev->dev.parent);
198+
if (ret < 0) {
199+
dev_err(&busid_priv->udev->dev, "rebind failed\n");
200+
return ret;
201+
}
202+
return 0;
203+
}
204+
205+
static void stub_device_rebind(void)
206+
{
207+
#if IS_MODULE(CONFIG_USBIP_HOST)
208+
struct bus_id_priv *busid_priv;
209+
int i;
210+
211+
/* update status to STUB_BUSID_OTHER so probe ignores the device */
212+
spin_lock(&busid_table_lock);
213+
for (i = 0; i < MAX_BUSID; i++) {
214+
if (busid_table[i].name[0] &&
215+
busid_table[i].shutdown_busid) {
216+
busid_priv = &(busid_table[i]);
217+
busid_priv->status = STUB_BUSID_OTHER;
218+
}
219+
}
220+
spin_unlock(&busid_table_lock);
221+
222+
/* now run rebind */
223+
for (i = 0; i < MAX_BUSID; i++) {
224+
if (busid_table[i].name[0] &&
225+
busid_table[i].shutdown_busid) {
226+
busid_priv = &(busid_table[i]);
227+
do_rebind(busid_table[i].name, busid_priv);
228+
}
229+
}
230+
#endif
231+
}
232+
187233
static ssize_t rebind_store(struct device_driver *dev, const char *buf,
188234
size_t count)
189235
{
@@ -204,16 +250,9 @@ static ssize_t rebind_store(struct device_driver *dev, const char *buf,
204250
/* mark the device for deletion so probe ignores it during rescan */
205251
bid->status = STUB_BUSID_OTHER;
206252

207-
/* device_attach() callers should hold parent lock for USB */
208-
if (bid->udev->dev.parent)
209-
device_lock(bid->udev->dev.parent);
210-
ret = device_attach(&bid->udev->dev);
211-
if (bid->udev->dev.parent)
212-
device_unlock(bid->udev->dev.parent);
213-
if (ret < 0) {
214-
dev_err(&bid->udev->dev, "rebind failed\n");
253+
ret = do_rebind((char *) buf, bid);
254+
if (ret < 0)
215255
return ret;
216-
}
217256

218257
/* delete device from busid_table */
219258
del_match_busid((char *) buf);
@@ -339,6 +378,9 @@ static void __exit usbip_host_exit(void)
339378
*/
340379
usb_deregister_device_driver(&stub_driver);
341380

381+
/* initiate scan to attach devices */
382+
stub_device_rebind();
383+
342384
kmem_cache_destroy(stub_priv_cache);
343385
}
344386

0 commit comments

Comments
 (0)