Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

[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
Loading
Loading
Loading
Loading
+6 −0
Original line number Original line Diff line number Diff line
@@ -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.
+42 −5
Original line number Original line Diff line number Diff line
@@ -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)
	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)
{
{
	/* 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;