From 887ab5992925736ab23985c35f8149739e9de354 Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Thu, 29 Jun 2006 14:56:52 +0200 Subject: [S390] ccwgroup device unregister. Work around the problem that a device cannot be unregistered from driver_for_each_device() because of klist node refcounting: Get device after device owned by the driver to be unregistered with driver_find_device() and then unregister it. This works because driver_get_device() gets us out of the region of the elevated klist node refcount. driver_find_device() will always get the next device in the list after the found one has been unregistered. Signed-off-by: Cornelia Huck Signed-off-by: Martin Schwidefsky --- drivers/s390/cio/ccwgroup.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'drivers/s390/cio/ccwgroup.c') diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c index bdfee7fbaa2..c7319a07ba3 100644 --- a/drivers/s390/cio/ccwgroup.c +++ b/drivers/s390/cio/ccwgroup.c @@ -404,21 +404,24 @@ ccwgroup_driver_register (struct ccwgroup_driver *cdriver) } static int -__ccwgroup_driver_unregister_device(struct device *dev, void *data) +__ccwgroup_match_all(struct device *dev, void *data) { - __ccwgroup_remove_symlinks(to_ccwgroupdev(dev)); - device_unregister(dev); - put_device(dev); - return 0; + return 1; } void ccwgroup_driver_unregister (struct ccwgroup_driver *cdriver) { + struct device *dev; + /* We don't want ccwgroup devices to live longer than their driver. */ get_driver(&cdriver->driver); - driver_for_each_device(&cdriver->driver, NULL, NULL, - __ccwgroup_driver_unregister_device); + while ((dev = driver_find_device(&cdriver->driver, NULL, NULL, + __ccwgroup_match_all))) { + __ccwgroup_remove_symlinks(to_ccwgroupdev(dev)); + device_unregister(dev); + put_device(dev); + } put_driver(&cdriver->driver); driver_unregister(&cdriver->driver); } -- cgit v1.2.3