]> bbs.cooldavid.org Git - net-next-2.6.git/commitdiff
[S390] cio: introduce cio_settle
authorSebastian Ott <sebott@linux.vnet.ibm.com>
Fri, 26 Feb 2010 21:37:25 +0000 (22:37 +0100)
committerMartin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com>
Fri, 26 Feb 2010 21:37:29 +0000 (22:37 +0100)
This patch introduces a proc file cio_settle. A write request to
this file is blocked until all queued cio actions are handled.

This will allow userspace to wait for pending work affecting
device availability after changing cio_ignore or the hardware
configuration.

Signed-off-by: Sebastian Ott <sebott@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Documentation/s390/CommonIO
drivers/s390/cio/css.c

index 339207d11d951a99e54257df96100ab0713e11a9..d378cba6645698d98678c75489ce1bd02b38bd82 100644 (file)
@@ -87,6 +87,12 @@ Command line parameters
   compatibility, by the device number in hexadecimal (0xabcd or abcd). Device
   numbers given as 0xabcd will be interpreted as 0.0.abcd.
 
   compatibility, by the device number in hexadecimal (0xabcd or abcd). Device
   numbers given as 0xabcd will be interpreted as 0.0.abcd.
 
+* /proc/cio_settle
+
+  A write request to this file is blocked until all queued cio actions are
+  handled. This will allow userspace to wait for pending work affecting
+  device availability after changing cio_ignore or the hardware configuration.
+
 * For some of the information present in the /proc filesystem in 2.4 (namely,
   /proc/subchannels and /proc/chpids), see driver-model.txt.
   Information formerly in /proc/irq_count is now in /proc/interrupts.
 * For some of the information present in the /proc filesystem in 2.4 (namely,
   /proc/subchannels and /proc/chpids), see driver-model.txt.
   Information formerly in /proc/irq_count is now in /proc/interrupts.
index 99fcf9d0ea1437b63138350e55d6f07ee82900d8..366affcd9bbf8bb9d6ef143bcec4147a22b2c922 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/list.h>
 #include <linux/reboot.h>
 #include <linux/suspend.h>
 #include <linux/list.h>
 #include <linux/reboot.h>
 #include <linux/suspend.h>
+#include <linux/proc_fs.h>
 #include <asm/isc.h>
 #include <asm/crw.h>
 
 #include <asm/isc.h>
 #include <asm/crw.h>
 
@@ -1019,6 +1020,18 @@ static int css_settle(struct device_driver *drv, void *unused)
        return 0;
 }
 
        return 0;
 }
 
+static inline void css_complete_work(void)
+{
+       int ret;
+
+       /* Wait for the evaluation of subchannels to finish. */
+       wait_event(css_eval_wq, atomic_read(&css_eval_scheduled) == 0);
+       flush_workqueue(cio_work_q);
+       /* Wait for the subchannel type specific initialization to finish */
+       ret = bus_for_each_drv(&css_bus_type, NULL, NULL, css_settle);
+}
+
+
 /*
  * Wait for the initialization of devices to finish, to make sure we are
  * done with our setup if the search for the root device starts.
 /*
  * Wait for the initialization of devices to finish, to make sure we are
  * done with our setup if the search for the root device starts.
@@ -1027,14 +1040,38 @@ static int __init channel_subsystem_init_sync(void)
 {
        /* Start initial subchannel evaluation. */
        css_schedule_eval_all();
 {
        /* Start initial subchannel evaluation. */
        css_schedule_eval_all();
-       /* Wait for the evaluation of subchannels to finish. */
-       wait_event(css_eval_wq, atomic_read(&css_eval_scheduled) == 0);
-       flush_workqueue(cio_work_q);
-       /* Wait for the subchannel type specific initialization to finish */
-       return bus_for_each_drv(&css_bus_type, NULL, NULL, css_settle);
+       css_complete_work();
+       return 0;
 }
 subsys_initcall_sync(channel_subsystem_init_sync);
 
 }
 subsys_initcall_sync(channel_subsystem_init_sync);
 
+#ifdef CONFIG_PROC_FS
+static ssize_t cio_settle_write(struct file *file, const char __user *buf,
+                               size_t count, loff_t *ppos)
+{
+       /* Handle pending CRW's. */
+       crw_wait_for_channel_report();
+       css_complete_work();
+       return count;
+}
+
+static const struct file_operations cio_settle_proc_fops = {
+       .write = cio_settle_write,
+};
+
+static int __init cio_settle_init(void)
+{
+       struct proc_dir_entry *entry;
+
+       entry = proc_create("cio_settle", S_IWUSR, NULL,
+                           &cio_settle_proc_fops);
+       if (!entry)
+               return -ENOMEM;
+       return 0;
+}
+device_initcall(cio_settle_init);
+#endif /*CONFIG_PROC_FS*/
+
 int sch_is_pseudo_sch(struct subchannel *sch)
 {
        return sch == to_css(sch->dev.parent)->pseudo_subchannel;
 int sch_is_pseudo_sch(struct subchannel *sch)
 {
        return sch == to_css(sch->dev.parent)->pseudo_subchannel;