summaryrefslogtreecommitdiffstats
path: root/drivers/s390/cio
diff options
context:
space:
mode:
authorSebastian Ott <sebott@linux.vnet.ibm.com>2009-03-26 15:24:15 +0100
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2009-03-26 15:24:16 +0100
commite909074bb91773680c0b2e49ea8af9f85c6f59bd (patch)
tree6d37028d4fdd85fe9ec429257fd7136cefa98118 /drivers/s390/cio
parent[S390] cio: fix sanity checks in ccwgroup driver. (diff)
downloadlinux-e909074bb91773680c0b2e49ea8af9f85c6f59bd.tar.xz
linux-e909074bb91773680c0b2e49ea8af9f85c6f59bd.zip
[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/cio')
-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:
}
EXPORT_SYMBOL(ccwgroup_create_from_string);
-static int __init
-init_ccwgroup (void)
+static int ccwgroup_notifier(struct notifier_block *nb, unsigned long action,
+ void *data);
+
+static struct notifier_block ccwgroup_nb = {
+ .notifier_call = ccwgroup_notifier
+};
+
+static int __init init_ccwgroup(void)
{
- return bus_register (&ccwgroup_bus_type);
+ int ret;
+
+ ret = bus_register(&ccwgroup_bus_type);
+ if (ret)
+ return ret;
+
+ ret = bus_register_notifier(&ccwgroup_bus_type, &ccwgroup_nb);
+ if (ret)
+ bus_unregister(&ccwgroup_bus_type);
+
+ return ret;
}
-static void __exit
-cleanup_ccwgroup (void)
+static void __exit cleanup_ccwgroup(void)
{
- bus_unregister (&ccwgroup_bus_type);
+ bus_unregister_notifier(&ccwgroup_bus_type, &ccwgroup_nb);
+ bus_unregister(&ccwgroup_bus_type);
}
module_init(init_ccwgroup);
@@ -455,6 +471,7 @@ ccwgroup_remove (struct device *dev)
struct ccwgroup_driver *gdrv;
device_remove_file(dev, &dev_attr_online);
+ device_remove_file(dev, &dev_attr_ungroup);
if (!dev->driver)
return 0;
@@ -492,6 +509,19 @@ static struct bus_type ccwgroup_bus_type = {
.shutdown = ccwgroup_shutdown,
};
+
+static int ccwgroup_notifier(struct notifier_block *nb, unsigned long action,
+ void *data)
+{
+ struct device *dev = data;
+
+ if (action == BUS_NOTIFY_UNBIND_DRIVER)
+ device_schedule_callback(dev, ccwgroup_ungroup_callback);
+
+ return NOTIFY_OK;
+}
+
+
/**
* ccwgroup_driver_register() - register a ccw group driver
* @cdriver: driver to be registered