diff options
author | Sebastian Ott <sebott@linux.vnet.ibm.com> | 2009-03-26 10:24:15 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2009-03-26 10:24:16 -0400 |
commit | e909074bb91773680c0b2e49ea8af9f85c6f59bd (patch) | |
tree | 6d37028d4fdd85fe9ec429257fd7136cefa98118 /drivers/s390 | |
parent | 50f1548399b7bd00ceb38c84a84463a89c82afe8 (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/s390')
-rw-r--r-- | drivers/s390/cio/ccwgroup.c | 42 |
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 | } |
315 | EXPORT_SYMBOL(ccwgroup_create_from_string); | 315 | EXPORT_SYMBOL(ccwgroup_create_from_string); |
316 | 316 | ||
317 | static int __init | 317 | static int ccwgroup_notifier(struct notifier_block *nb, unsigned long action, |
318 | init_ccwgroup (void) | 318 | void *data); |
319 | |||
320 | static struct notifier_block ccwgroup_nb = { | ||
321 | .notifier_call = ccwgroup_notifier | ||
322 | }; | ||
323 | |||
324 | static 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 | ||
323 | static void __exit | 339 | static void __exit cleanup_ccwgroup(void) |
324 | cleanup_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 | ||
329 | module_init(init_ccwgroup); | 345 | module_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 | |||
513 | static 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 |