aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorSebastian Ott <sebott@linux.vnet.ibm.com>2009-03-26 10:24:15 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2009-03-26 10:24:16 -0400
commite909074bb91773680c0b2e49ea8af9f85c6f59bd (patch)
tree6d37028d4fdd85fe9ec429257fd7136cefa98118 /drivers
parent50f1548399b7bd00ceb38c84a84463a89c82afe8 (diff)
[S390] cio: ccw group fix unbind behaviour.
For a ccw group device unbinding it from its driver should do the same as a call to ungroup, since this virtual device can not exist without a driver. Signed-off-by: Sebastian Ott <sebott@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/s390/cio/ccwgroup.c42
1 files changed, 36 insertions, 6 deletions
diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c
index 2becedbe8883..86b136cb09e0 100644
--- a/drivers/s390/cio/ccwgroup.c
+++ b/drivers/s390/cio/ccwgroup.c
@@ -314,16 +314,32 @@ error:
314} 314}
315EXPORT_SYMBOL(ccwgroup_create_from_string); 315EXPORT_SYMBOL(ccwgroup_create_from_string);
316 316
317static int __init 317static int ccwgroup_notifier(struct notifier_block *nb, unsigned long action,
318init_ccwgroup (void) 318 void *data);
319
320static struct notifier_block ccwgroup_nb = {
321 .notifier_call = ccwgroup_notifier
322};
323
324static int __init init_ccwgroup(void)
319{ 325{
320 return bus_register (&ccwgroup_bus_type); 326 int ret;
327
328 ret = bus_register(&ccwgroup_bus_type);
329 if (ret)
330 return ret;
331
332 ret = bus_register_notifier(&ccwgroup_bus_type, &ccwgroup_nb);
333 if (ret)
334 bus_unregister(&ccwgroup_bus_type);
335
336 return ret;
321} 337}
322 338
323static void __exit 339static void __exit cleanup_ccwgroup(void)
324cleanup_ccwgroup (void)
325{ 340{
326 bus_unregister (&ccwgroup_bus_type); 341 bus_unregister_notifier(&ccwgroup_bus_type, &ccwgroup_nb);
342 bus_unregister(&ccwgroup_bus_type);
327} 343}
328 344
329module_init(init_ccwgroup); 345module_init(init_ccwgroup);
@@ -455,6 +471,7 @@ ccwgroup_remove (struct device *dev)
455 struct ccwgroup_driver *gdrv; 471 struct ccwgroup_driver *gdrv;
456 472
457 device_remove_file(dev, &dev_attr_online); 473 device_remove_file(dev, &dev_attr_online);
474 device_remove_file(dev, &dev_attr_ungroup);
458 475
459 if (!dev->driver) 476 if (!dev->driver)
460 return 0; 477 return 0;
@@ -492,6 +509,19 @@ static struct bus_type ccwgroup_bus_type = {
492 .shutdown = ccwgroup_shutdown, 509 .shutdown = ccwgroup_shutdown,
493}; 510};
494 511
512
513static int ccwgroup_notifier(struct notifier_block *nb, unsigned long action,
514 void *data)
515{
516 struct device *dev = data;
517
518 if (action == BUS_NOTIFY_UNBIND_DRIVER)
519 device_schedule_callback(dev, ccwgroup_ungroup_callback);
520
521 return NOTIFY_OK;
522}
523
524
495/** 525/**
496 * ccwgroup_driver_register() - register a ccw group driver 526 * ccwgroup_driver_register() - register a ccw group driver
497 * @cdriver: driver to be registered 527 * @cdriver: driver to be registered