From: Greg Kroah-Hartman Date: Fri, 5 May 2006 00:01:23 +0000 (-0700) Subject: added usb patch to queue X-Git-Tag: v2.6.16.15~4 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=98f6c3f1b5852be9d62627996a719434b9bef57e;p=thirdparty%2Fkernel%2Fstable-queue.git added usb patch to queue --- diff --git a/queue-2.6.16/series b/queue-2.6.16/series index 0684c1b31a2..3122a84d229 100644 --- a/queue-2.6.16/series +++ b/queue-2.6.16/series @@ -1,2 +1,3 @@ md-avoid-oops-when-attempting-to-fix-read-errors-on-raid10.patch via-rhine-zero-pad-short-packets-on-rhine-i-ethernet-cards.patch +usb-ub-oops-in-block_uevent.patch diff --git a/queue-2.6.16/usb-ub-oops-in-block_uevent.patch b/queue-2.6.16/usb-ub-oops-in-block_uevent.patch new file mode 100644 index 00000000000..59fe63b4d7d --- /dev/null +++ b/queue-2.6.16/usb-ub-oops-in-block_uevent.patch @@ -0,0 +1,72 @@ +From zaitcev@redhat.com Wed May 3 00:16:11 2006 +Date: Wed, 3 May 2006 00:16:00 -0700 +From: Pete Zaitcev +To: greg@kroah.com +Cc: zaitcev@redhat.com, linux-usb-devel@lists.sourceforge.net +Subject: USB: ub oops in block_uevent +Message-Id: <20060503001600.c9012512.zaitcev@redhat.com> + +In kernel 2.6.16, if a mounted storage device is removed, an oops happens +because ub supplies an interface device (and kobject) to the block layer, +but neglects to pin it. And apparently, the block layer expects its users +to pin device structures. + +The code in ub was broken this way for years. But the bug was exposed only +by 2.6.16 when it started to call block_uevent on close, which traverses +device structures (kobjects actually). + +Signed-off-by: Pete Zaitcev +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/block/ub.c | 18 ++++++++++-------- + 1 file changed, 10 insertions(+), 8 deletions(-) + +--- linux-2.6.16.13.orig/drivers/block/ub.c ++++ linux-2.6.16.13/drivers/block/ub.c +@@ -704,6 +704,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); + } + +@@ -2428,7 +2431,12 @@ static int ub_probe(struct usb_interface + // 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); +@@ -2509,7 +2517,7 @@ static int ub_probe(struct usb_interface + err_diag: + 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: +@@ -2688,12 +2696,6 @@ static void ub_disconnect(struct usb_int + */ + + device_remove_file(&sc->intf->dev, &dev_attr_diag); +- usb_set_intfdata(intf, NULL); +- // usb_put_intf(sc->intf); +- sc->intf = NULL; +- usb_put_dev(sc->dev); +- sc->dev = NULL; +- + ub_put(sc); + } +