aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/s390/CommonIO6
-rw-r--r--drivers/s390/cio/css.c47
2 files changed, 48 insertions, 5 deletions
diff --git a/Documentation/s390/CommonIO b/Documentation/s390/CommonIO
index 339207d11d95..d378cba66456 100644
--- a/Documentation/s390/CommonIO
+++ b/Documentation/s390/CommonIO
@@ -87,6 +87,12 @@ Command line parameters
87 compatibility, by the device number in hexadecimal (0xabcd or abcd). Device 87 compatibility, by the device number in hexadecimal (0xabcd or abcd). Device
88 numbers given as 0xabcd will be interpreted as 0.0.abcd. 88 numbers given as 0xabcd will be interpreted as 0.0.abcd.
89 89
90* /proc/cio_settle
91
92 A write request to this file is blocked until all queued cio actions are
93 handled. This will allow userspace to wait for pending work affecting
94 device availability after changing cio_ignore or the hardware configuration.
95
90* For some of the information present in the /proc filesystem in 2.4 (namely, 96* For some of the information present in the /proc filesystem in 2.4 (namely,
91 /proc/subchannels and /proc/chpids), see driver-model.txt. 97 /proc/subchannels and /proc/chpids), see driver-model.txt.
92 Information formerly in /proc/irq_count is now in /proc/interrupts. 98 Information formerly in /proc/irq_count is now in /proc/interrupts.
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
index 99fcf9d0ea14..366affcd9bbf 100644
--- a/drivers/s390/cio/css.c
+++ b/drivers/s390/cio/css.c
@@ -18,6 +18,7 @@
18#include <linux/list.h> 18#include <linux/list.h>
19#include <linux/reboot.h> 19#include <linux/reboot.h>
20#include <linux/suspend.h> 20#include <linux/suspend.h>
21#include <linux/proc_fs.h>
21#include <asm/isc.h> 22#include <asm/isc.h>
22#include <asm/crw.h> 23#include <asm/crw.h>
23 24
@@ -1019,6 +1020,18 @@ static int css_settle(struct device_driver *drv, void *unused)
1019 return 0; 1020 return 0;
1020} 1021}
1021 1022
1023static inline void css_complete_work(void)
1024{
1025 int ret;
1026
1027 /* Wait for the evaluation of subchannels to finish. */
1028 wait_event(css_eval_wq, atomic_read(&css_eval_scheduled) == 0);
1029 flush_workqueue(cio_work_q);
1030 /* Wait for the subchannel type specific initialization to finish */
1031 ret = bus_for_each_drv(&css_bus_type, NULL, NULL, css_settle);
1032}
1033
1034
1022/* 1035/*
1023 * Wait for the initialization of devices to finish, to make sure we are 1036 * Wait for the initialization of devices to finish, to make sure we are
1024 * done with our setup if the search for the root device starts. 1037 * done with our setup if the search for the root device starts.
@@ -1027,14 +1040,38 @@ static int __init channel_subsystem_init_sync(void)
1027{ 1040{
1028 /* Start initial subchannel evaluation. */ 1041 /* Start initial subchannel evaluation. */
1029 css_schedule_eval_all(); 1042 css_schedule_eval_all();
1030 /* Wait for the evaluation of subchannels to finish. */ 1043 css_complete_work();
1031 wait_event(css_eval_wq, atomic_read(&css_eval_scheduled) == 0); 1044 return 0;
1032 flush_workqueue(cio_work_q);
1033 /* Wait for the subchannel type specific initialization to finish */
1034 return bus_for_each_drv(&css_bus_type, NULL, NULL, css_settle);
1035} 1045}
1036subsys_initcall_sync(channel_subsystem_init_sync); 1046subsys_initcall_sync(channel_subsystem_init_sync);
1037 1047
1048#ifdef CONFIG_PROC_FS
1049static ssize_t cio_settle_write(struct file *file, const char __user *buf,
1050 size_t count, loff_t *ppos)
1051{
1052 /* Handle pending CRW's. */
1053 crw_wait_for_channel_report();
1054 css_complete_work();
1055 return count;
1056}
1057
1058static const struct file_operations cio_settle_proc_fops = {
1059 .write = cio_settle_write,
1060};
1061
1062static int __init cio_settle_init(void)
1063{
1064 struct proc_dir_entry *entry;
1065
1066 entry = proc_create("cio_settle", S_IWUSR, NULL,
1067 &cio_settle_proc_fops);
1068 if (!entry)
1069 return -ENOMEM;
1070 return 0;
1071}
1072device_initcall(cio_settle_init);
1073#endif /*CONFIG_PROC_FS*/
1074
1038int sch_is_pseudo_sch(struct subchannel *sch) 1075int sch_is_pseudo_sch(struct subchannel *sch)
1039{ 1076{
1040 return sch == to_css(sch->dev.parent)->pseudo_subchannel; 1077 return sch == to_css(sch->dev.parent)->pseudo_subchannel;