aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/ub.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/block/ub.c')
-rw-r--r--drivers/block/ub.c18
1 files changed, 10 insertions, 8 deletions
diff --git a/drivers/block/ub.c b/drivers/block/ub.c
index f73446f580df..c688c25992e4 100644
--- a/drivers/block/ub.c
+++ b/drivers/block/ub.c
@@ -536,6 +536,9 @@ static void ub_cleanup(struct ub_dev *sc)
kfree(lun);
}
+ usb_set_intfdata(sc->intf, NULL);
+ usb_put_intf(sc->intf);
+ usb_put_dev(sc->dev);
kfree(sc);
}
@@ -2221,7 +2224,12 @@ static int ub_probe(struct usb_interface *intf,
// sc->ifnum = intf->cur_altsetting->desc.bInterfaceNumber;
usb_set_intfdata(intf, sc);
usb_get_dev(sc->dev);
- // usb_get_intf(sc->intf); /* Do we need this? */
+ /*
+ * Since we give the interface struct to the block level through
+ * disk->driverfs_dev, we have to pin it. Otherwise, block_uevent
+ * oopses on close after a disconnect (kernels 2.6.16 and up).
+ */
+ usb_get_intf(sc->intf);
snprintf(sc->name, 12, DRV_NAME "(%d.%d)",
sc->dev->bus->busnum, sc->dev->devnum);
@@ -2286,7 +2294,7 @@ static int ub_probe(struct usb_interface *intf,
err_dev_desc:
usb_set_intfdata(intf, NULL);
- // usb_put_intf(sc->intf);
+ usb_put_intf(sc->intf);
usb_put_dev(sc->dev);
kfree(sc);
err_core:
@@ -2461,12 +2469,6 @@ static void ub_disconnect(struct usb_interface *intf)
* and no URBs left in transit.
*/
- usb_set_intfdata(intf, NULL);
- // usb_put_intf(sc->intf);
- sc->intf = NULL;
- usb_put_dev(sc->dev);
- sc->dev = NULL;
-
ub_put(sc);
}