aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base
diff options
context:
space:
mode:
authorRoman Kagan <rkagan@mail.ru>2005-04-13 13:40:17 -0400
committerGreg KH <gregkh@suse.de>2005-05-05 02:44:38 -0400
commitb2d84f078a8be40f5ae3b4d2ac001e2a7f45fe4f (patch)
tree173f941991f1b68da820e9926a3b7ebdd3a2c8b9 /drivers/base
parent177a4324944478f2799ce4ede2797cb0f602f274 (diff)
[PATCH] drivers/base/bus.c: fix iteration in driver_detach()
With 2.6.11 and 2.6.12-rc2 (and perhaps a few versions before) usb drivers for multi-interface devices, which do usb_driver_release_interface() in their disconnect(), make rmmod hang. It turns out to be due to a bug in drivers/base/bus.c:driver_detach(), that iterates over the list of attached devices with list_for_each_safe() under an assumption that device_release_driver() only releases the current device, while it may also call device_release_driver() for other devices on the same list. The following patch fixes it. Please consider applying. Signed-off-by: Roman Kagan <rkagan@mail.ru> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/base')
-rw-r--r--drivers/base/bus.c5
1 files changed, 2 insertions, 3 deletions
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index f4fa27315fb4..2b3902c867da 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -405,9 +405,8 @@ void device_release_driver(struct device * dev)
405 405
406static void driver_detach(struct device_driver * drv) 406static void driver_detach(struct device_driver * drv)
407{ 407{
408 struct list_head * entry, * next; 408 while (!list_empty(&drv->devices)) {
409 list_for_each_safe(entry, next, &drv->devices) { 409 struct device * dev = container_of(drv->devices.next, struct device, driver_list);
410 struct device * dev = container_of(entry, struct device, driver_list);
411 device_release_driver(dev); 410 device_release_driver(dev);
412 } 411 }
413} 412}