Commit 879acca5 authored by Sebastian Ott's avatar Sebastian Ott Committed by Martin Schwidefsky

[S390] cio: introduce cio_settle

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: default avatarSebastian Ott <sebott@linux.vnet.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent be5d3823
...@@ -87,6 +87,12 @@ Command line parameters ...@@ -87,6 +87,12 @@ Command line parameters
compatibility, by the device number in hexadecimal (0xabcd or abcd). Device compatibility, by the device number in hexadecimal (0xabcd or abcd). Device
numbers given as 0xabcd will be interpreted as 0.0.abcd. 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, * For some of the information present in the /proc filesystem in 2.4 (namely,
/proc/subchannels and /proc/chpids), see driver-model.txt. /proc/subchannels and /proc/chpids), see driver-model.txt.
Information formerly in /proc/irq_count is now in /proc/interrupts. Information formerly in /proc/irq_count is now in /proc/interrupts.
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include <linux/list.h> #include <linux/list.h>
#include <linux/reboot.h> #include <linux/reboot.h>
#include <linux/suspend.h> #include <linux/suspend.h>
#include <linux/proc_fs.h>
#include <asm/isc.h> #include <asm/isc.h>
#include <asm/crw.h> #include <asm/crw.h>
...@@ -1019,6 +1020,18 @@ static int css_settle(struct device_driver *drv, void *unused) ...@@ -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 * 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. * 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,14 +1040,38 @@ static int __init channel_subsystem_init_sync(void)
{ {
/* Start initial subchannel evaluation. */ /* Start initial subchannel evaluation. */
css_schedule_eval_all(); css_schedule_eval_all();
/* Wait for the evaluation of subchannels to finish. */ css_complete_work();
wait_event(css_eval_wq, atomic_read(&css_eval_scheduled) == 0); return 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);
} }
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) int sch_is_pseudo_sch(struct subchannel *sch)
{ {
return sch == to_css(sch->dev.parent)->pseudo_subchannel; return sch == to_css(sch->dev.parent)->pseudo_subchannel;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment