// SPDX-License-Identifier: GPL-2.0
/*
 *    Copyright IBM Corp. 1999, 2010
 *    Author(s): Cornelia Huck (cornelia.huck@de.ibm.com)
 *		 Arnd Bergmann (arndb@de.ibm.com)
 *		 Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
 */

#include <linux/bug.h>
#include <linux/workqueue.h>
#include <linux/spinlock.h>
#include <linux/export.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/jiffies.h>
#include <linux/wait.h>
#include <linux/mutex.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <asm/chpid.h>
#include <asm/sclp.h>
#include <asm/crw.h>

#include "cio.h"
#include "css.h"
#include "ioasm.h"
#include "cio_debug.h"
#include "chp.h"

#define to_channelpath(device) container_of(device, struct channel_path, dev)
#define CHP_INFO_UPDATE_INTERVAL	1*HZ

enum cfg_task_t {
	cfg_none,
	cfg_configure,
	cfg_deconfigure
};

/* Map for pending configure tasks. */
static enum cfg_task_t chp_cfg_task[__MAX_CSSID + 1][__MAX_CHPID + 1];
static DEFINE_SPINLOCK(cfg_lock);

/* Map for channel-path status. */
static struct sclp_chp_info chp_info;
static DEFINE_MUTEX(info_lock);

/* Time after which channel-path status may be outdated. */
static unsigned long chp_info_expires;

static struct work_struct cfg_work;

/* Wait queue for configure completion events. */
static wait_queue_head_t cfg_wait_queue;

/* Set vary state for given chpid. */
static void set_chp_logically_online(struct chp_id chpid, int onoff)
{
	chpid_to_chp(chpid)->state = onoff;
}

/* On success return 0 if channel-path is varied offline, 1 if it is varied
 * online. Return -ENODEV if channel-path is not registered. */
int chp_get_status(struct chp_id chpid)
{
	return (chpid_to_chp(chpid) ? chpid_to_chp(chpid)->state : -ENODEV);
}

/**
 * chp_get_sch_opm - return opm for subchannel
 * @sch: subchannel
 *
 * Calculate and return the operational path mask (opm) based on the chpids
 * used by the subchannel and the status of the associated channel-paths.
 */
u8 chp_get_sch_opm(struct subchannel *sch)
{
	struct chp_id chpid;
	int opm;
	int i;

	opm = 0;
	chp_id_init(&chpid);
	for (i = 0; i < 8; i++) {
		opm <<= 1;
		chpid.id = sch->schib.pmcw.chpid[i];
		if (chp_get_status(chpid) != 0)
			opm |= 1;
	}
	return opm;
}
EXPORT_SYMBOL_GPL(chp_get_sch_opm);

/**
 * chp_is_registered - check if a channel-path is registered
 * @chpid: channel-path ID
 *
 * Return non-zero if a channel-path with the given chpid is registered,
 * zero otherwise.
 */
int chp_is_registered(struct chp_id chpid)
{
	return chpid_to_chp(chpid) != NULL;
}

/*
 * Function: s390_vary_chpid
 * Varies the specified chpid online or offline
 */
static int s390_vary_chpid(struct chp_id chpid, int on)
{
	char dbf_text[15];
	int status;

	sprintf(dbf_text, on?"varyon%x.%02x":"varyoff%x.%02x", chpid.cssid,
		chpid.id);
	CIO_TRACE_EVENT(2, dbf_text);

	status = chp_get_status(chpid);
	if (!on && !status)
		return 0;

	set_chp_logically_online(chpid, on);
	chsc_chp_vary(chpid, on);
	return 0;
}

/*
 * Channel measurement related functions
 */
static ssize_t chp_measurement_chars_read(struct file *filp,
					  struct kobject *kobj,
					  struct bin_attribute *bin_attr,
					  char *buf, loff_t off, size_t count)
{
	struct channel_path *chp;
	struct device *device;

	device = container_of(kobj, struct device, kobj);
	chp = to_channelpath(device);
	if (chp->cmg == -1)
		return 0;

	return memory_read_from_buffer(buf, count, &off, &chp->cmg_chars,
				       sizeof(chp->cmg_chars));
}

static const struct bin_attribute chp_measurement_chars_attr = {
	.attr = {
		.name = "measurement_chars",
		.mode = S_IRUSR,
	},
	.size = sizeof(struct cmg_chars),
	.read = chp_measurement_chars_read,
};

static void chp_measurement_copy_block(struct cmg_entry *buf,
				       struct channel_subsystem *css,
				       struct chp_id chpid)
{
	void *area;
	struct cmg_entry *entry, reference_buf;
	int idx;

	if (chpid.id < 128) {
		area = css->cub_addr1;
		idx = chpid.id;
	} else {
		area = css->cub_addr2;
		idx = chpid.id - 128;
	}
	entry = area + (idx * sizeof(struct cmg_entry));
	do {
		memcpy(buf, entry, sizeof(*entry));
		memcpy(&reference_buf, entry, sizeof(*entry));
	} while (reference_buf.values[0] != buf->values[0]);
}

static ssize_t chp_measurement_read(struct file *filp, struct kobject *kobj,
				    struct bin_attribute *bin_attr,
				    char *buf, loff_t off, size_t count)
{
	struct channel_path *chp;
	struct channel_subsystem *css;
	struct device *device;
	unsigned int size;

	device = container_of(kobj, struct device, kobj);
	chp = to_channelpath(device);
	css = to_css(chp->dev.parent);

	size = sizeof(struct cmg_entry);

	/* Only allow single reads. */
	if (off || count < size)
		return 0;
	chp_measurement_copy_block((struct cmg_entry *)buf, css, chp->chpid);
	count = size;
	return count;
}

static const struct bin_attribute chp_measurement_attr = {
	.attr = {
		.name = "measurement",
		.mode = S_IRUSR,
	},
	.size = sizeof(struct cmg_entry),
	.read = chp_measurement_read,
};

void chp_remove_cmg_attr(struct channel_path *chp)
{
	device_remove_bin_file(&chp->dev, &chp_measurement_chars_attr);
	device_remove_bin_file(&chp->dev, &chp_measurement_attr);
}

int chp_add_cmg_attr(struct channel_path *chp)
{
	int ret;

	ret = device_create_bin_file(&chp->dev, &chp_measurement_chars_attr);
	if (ret)
		return ret;
	ret = device_create_bin_file(&chp->dev, &chp_measurement_attr);
	if (ret)
		device_remove_bin_file(&chp->dev, &chp_measurement_chars_attr);
	return ret;
}

/*
 * Files for the channel path entries.
 */
static ssize_t chp_status_show(struct device *dev,
			       struct device_attribute *attr, char *buf)
{
	struct channel_path *chp = to_channelpath(dev);
	int status;

	mutex_lock(&chp->lock);
	status = chp->state;
	mutex_unlock(&chp->lock);

	return status ? sprintf(buf, "online\n") : sprintf(buf, "offline\n");
}

static ssize_t chp_status_write(struct device *dev,
				struct device_attribute *attr,
				const char *buf, size_t count)
{
	struct channel_path *cp = to_channelpath(dev);
	char cmd[10];
	int num_args;
	int error;

	num_args = sscanf(buf, "%5s", cmd);
	if (!num_args)
		return count;

	/* Wait until previous actions have settled. */
	css_wait_for_slow_path();

	if (!strncasecmp(cmd, "on", 2) || !strcmp(cmd, "1")) {
		mutex_lock(&cp->lock);
		error = s390_vary_chpid(cp->chpid, 1);
		mutex_unlock(&cp->lock);
	} else if (!strncasecmp(cmd, "off", 3) || !strcmp(cmd, "0")) {
		mutex_lock(&cp->lock);
		error = s390_vary_chpid(cp->chpid, 0);
		mutex_unlock(&cp->lock);
	} else
		error = -EINVAL;

	return error < 0 ? error : count;
}

static DEVICE_ATTR(status, 0644, chp_status_show, chp_status_write);

static ssize_t chp_configure_show(struct device *dev,
				  struct device_attribute *attr, char *buf)
{
	struct channel_path *cp;
	int status;

	cp = to_channelpath(dev);
	status = chp_info_get_status(cp->chpid);
	if (status < 0)
		return status;

	return snprintf(buf, PAGE_SIZE, "%d\n", status);
}

static int cfg_wait_idle(void);

static ssize_t chp_configure_write(struct device *dev,
				   struct device_attribute *attr,
				   const char *buf, size_t count)
{
	struct channel_path *cp;
	int val;
	char delim;

	if (sscanf(buf, "%d %c", &val, &delim) != 1)
		return -EINVAL;
	if (val != 0 && val != 1)
		return -EINVAL;
	cp = to_channelpath(dev);
	chp_cfg_schedule(cp->chpid, val);
	cfg_wait_idle();

	return count;
}

static DEVICE_ATTR(configure, 0644, chp_configure_show, chp_configure_write);

static ssize_t chp_type_show(struct device *dev, struct device_attribute *attr,
			     char *buf)
{
	struct channel_path *chp = to_channelpath(dev);
	u8 type;

	mutex_lock(&chp->lock);
	type = chp->desc.desc;
	mutex_unlock(&chp->lock);
	return sprintf(buf, "%x\n", type);
}

static DEVICE_ATTR(type, 0444, chp_type_show, NULL);

static ssize_t chp_cmg_show(struct device *dev, struct device_attribute *attr,
			    char *buf)
{
	struct channel_path *chp = to_channelpath(dev);

	if (!chp)
		return 0;
	if (chp->cmg == -1) /* channel measurements not available */
		return sprintf(buf, "unknown\n");
	return sprintf(buf, "%x\n", chp->cmg);
}

static DEVICE_ATTR(cmg, 0444, chp_cmg_show, NULL);

static ssize_t chp_shared_show(struct device *dev,
			       struct device_attribute *attr, char *buf)
{
	struct channel_path *chp = to_channelpath(dev);

	if (!chp)
		return 0;
	if (chp->shared == -1) /* channel measurements not available */
		return sprintf(buf, "unknown\n");
	return sprintf(buf, "%x\n", chp->shared);
}

static DEVICE_ATTR(shared, 0444, chp_shared_show, NULL);

static ssize_t chp_chid_show(struct device *dev, struct device_attribute *attr,
			     char *buf)
{
	struct channel_path *chp = to_channelpath(dev);
	ssize_t rc;

	mutex_lock(&chp->lock);
	if (chp->desc_fmt1.flags & 0x10)
		rc = sprintf(buf, "%04x\n", chp->desc_fmt1.chid);
	else
		rc = 0;
	mutex_unlock(&chp->lock);

	return rc;
}
static DEVICE_ATTR(chid, 0444, chp_chid_show, NULL);

static ssize_t chp_chid_external_show(struct device *dev,
				      struct device_attribute *attr, char *buf)
{
	struct channel_path *chp = to_channelpath(dev);
	ssize_t rc;

	mutex_lock(&chp->lock);
	if (chp->desc_fmt1.flags & 0x10)
		rc = sprintf(buf, "%x\n", chp->desc_fmt1.flags & 0x8 ? 1 : 0);
	else
		rc = 0;
	mutex_unlock(&chp->lock);

	return rc;
}
static DEVICE_ATTR(chid_external, 0444, chp_chid_external_show, NULL);

static ssize_t util_string_read(struct file *filp, struct kobject *kobj,
				struct bin_attribute *attr, char *buf,
				loff_t off, size_t count)
{
	struct channel_path *chp = to_channelpath(kobj_to_dev(kobj));
	ssize_t rc;

	mutex_lock(&chp->lock);
	rc = memory_read_from_buffer(buf, count, &off, chp->desc_fmt3.util_str,
				     sizeof(chp->desc_fmt3.util_str));
	mutex_unlock(&chp->lock);

	return rc;
}
static BIN_ATTR_RO(util_string,
		   sizeof(((struct channel_path_desc_fmt3 *)0)->util_str));

static struct bin_attribute *chp_bin_attrs[] = {
	&bin_attr_util_string,
	NULL,
};

static struct attribute *chp_attrs[] = {
	&dev_attr_status.attr,
	&dev_attr_configure.attr,
	&dev_attr_type.attr,
	&dev_attr_cmg.attr,
	&dev_attr_shared.attr,
	&dev_attr_chid.attr,
	&dev_attr_chid_external.attr,
	NULL,
};
static struct attribute_group chp_attr_group = {
	.attrs = chp_attrs,
	.bin_attrs = chp_bin_attrs,
};
static const struct attribute_group *chp_attr_groups[] = {
	&chp_attr_group,
	NULL,
};

static void chp_release(struct device *dev)
{
	struct channel_path *cp;

	cp = to_channelpath(dev);
	kfree(cp);
}

/**
 * chp_update_desc - update channel-path description
 * @chp: channel-path
 *
 * Update the channel-path description of the specified channel-path
 * including channel measurement related information.
 * Return zero on success, non-zero otherwise.
 */
int chp_update_desc(struct channel_path *chp)
{
	int rc;

	rc = chsc_determine_fmt0_channel_path_desc(chp->chpid, &chp->desc);
	if (rc)
		return rc;

	/*
	 * Fetching the following data is optional. Not all machines or
	 * hypervisors implement the required chsc commands.
	 */
	chsc_determine_fmt1_channel_path_desc(chp->chpid, &chp->desc_fmt1);
	chsc_determine_fmt3_channel_path_desc(chp->chpid, &chp->desc_fmt3);
	chsc_get_channel_measurement_chars(chp);

	return 0;
}

/**
 * chp_new - register a new channel-path
 * @chpid: channel-path ID
 *
 * Create and register data structure representing new channel-path. Return
 * zero on success, non-zero otherwise.
 */
int chp_new(struct chp_id chpid)
{
	struct channel_subsystem *css = css_by_id(chpid.cssid);
	struct channel_path *chp;
	int ret = 0;

	mutex_lock(&css->mutex);
	if (chp_is_registered(chpid))
		goto out;

	chp = kzalloc(sizeof(struct channel_path), GFP_KERNEL);
	if (!chp) {
		ret = -ENOMEM;
		goto out;
	}
	/* fill in status, etc. */
	chp->chpid = chpid;
	chp->state = 1;
	chp->dev.parent = &css->device;
	chp->dev.groups = chp_attr_groups;
	chp->dev.release = chp_release;
	mutex_init(&chp->lock);

	/* Obtain channel path description and fill it in. */
	ret = chp_update_desc(chp);
	if (ret)
		goto out_free;
	if ((chp->desc.flags & 0x80) == 0) {
		ret = -ENODEV;
		goto out_free;
	}
	dev_set_name(&chp->dev, "chp%x.%02x", chpid.cssid, chpid.id);

	/* make it known to the system */
	ret = device_register(&chp->dev);
	if (ret) {
		CIO_MSG_EVENT(0, "Could not register chp%x.%02x: %d\n",
			      chpid.cssid, chpid.id, ret);
		put_device(&chp->dev);
		goto out;
	}

	if (css->cm_enabled) {
		ret = chp_add_cmg_attr(chp);
		if (ret) {
			device_unregister(&chp->dev);
			goto out;
		}
	}
	css->chps[chpid.id] = chp;
	goto out;
out_free:
	kfree(chp);
out:
	mutex_unlock(&css->mutex);
	return ret;
}

/**
 * chp_get_chp_desc - return newly allocated channel-path description
 * @chpid: channel-path ID
 *
 * On success return a newly allocated copy of the channel-path description
 * data associated with the given channel-path ID. Return %NULL on error.
 */
struct channel_path_desc_fmt0 *chp_get_chp_desc(struct chp_id chpid)
{
	struct channel_path *chp;
	struct channel_path_desc_fmt0 *desc;

	chp = chpid_to_chp(chpid);
	if (!chp)
		return NULL;
	desc = kmalloc(sizeof(*desc), GFP_KERNEL);
	if (!desc)
		return NULL;

	mutex_lock(&chp->lock);
	memcpy(desc, &chp->desc, sizeof(*desc));
	mutex_unlock(&chp->lock);
	return desc;
}

/**
 * chp_process_crw - process channel-path status change
 * @crw0: channel report-word to handler
 * @crw1: second channel-report word (always NULL)
 * @overflow: crw overflow indication
 *
 * Handle channel-report-words indicating that the status of a channel-path
 * has changed.
 */
static void chp_process_crw(struct crw *crw0, struct crw *crw1,
			    int overflow)
{
	struct chp_id chpid;

	if (overflow) {
		css_schedule_eval_all();
		return;
	}
	CIO_CRW_EVENT(2, "CRW reports slct=%d, oflw=%d, "
		      "chn=%d, rsc=%X, anc=%d, erc=%X, rsid=%X\n",
		      crw0->slct, crw0->oflw, crw0->chn, crw0->rsc, crw0->anc,
		      crw0->erc, crw0->rsid);
	/*
	 * Check for solicited machine checks. These are
	 * created by reset channel path and need not be
	 * handled here.
	 */
	if (crw0->slct) {
		CIO_CRW_EVENT(2, "solicited machine check for "
			      "channel path %02X\n", crw0->rsid);
		return;
	}
	chp_id_init(&chpid);
	chpid.id = crw0->rsid;
	switch (crw0->erc) {
	case CRW_ERC_IPARM: /* Path has come. */
	case CRW_ERC_INIT:
		chp_new(chpid);
		chsc_chp_online(chpid);
		break;
	case CRW_ERC_PERRI: /* Path has gone. */
	case CRW_ERC_PERRN:
		chsc_chp_offline(chpid);
		break;
	default:
		CIO_CRW_EVENT(2, "Don't know how to handle erc=%x\n",
			      crw0->erc);
	}
}

int chp_ssd_get_mask(struct chsc_ssd_info *ssd, struct chp_link *link)
{
	int i;
	int mask;

	for (i = 0; i < 8; i++) {
		mask = 0x80 >> i;
		if (!(ssd->path_mask & mask))
			continue;
		if (!chp_id_is_equal(&ssd->chpid[i], &link->chpid))
			continue;
		if ((ssd->fla_valid_mask & mask) &&
		    ((ssd->fla[i] & link->fla_mask) != link->fla))
			continue;
		return mask;
	}
	return 0;
}
EXPORT_SYMBOL_GPL(chp_ssd_get_mask);

static inline int info_bit_num(struct chp_id id)
{
	return id.id + id.cssid * (__MAX_CHPID + 1);
}

/* Force chp_info refresh on next call to info_validate(). */
static void info_expire(void)
{
	mutex_lock(&info_lock);
	chp_info_expires = jiffies - 1;
	mutex_unlock(&info_lock);
}

/* Ensure that chp_info is up-to-date. */
static int info_update(void)
{
	int rc;

	mutex_lock(&info_lock);
	rc = 0;
	if (time_after(jiffies, chp_info_expires)) {
		/* Data is too old, update. */
		rc = sclp_chp_read_info(&chp_info);
		chp_info_expires = jiffies + CHP_INFO_UPDATE_INTERVAL ;
	}
	mutex_unlock(&info_lock);

	return rc;
}

/**
 * chp_info_get_status - retrieve configure status of a channel-path
 * @chpid: channel-path ID
 *
 * On success, return 0 for standby, 1 for configured, 2 for reserved,
 * 3 for not recognized. Return negative error code on error.
 */
int chp_info_get_status(struct chp_id chpid)
{
	int rc;
	int bit;

	rc = info_update();
	if (rc)
		return rc;

	bit = info_bit_num(chpid);
	mutex_lock(&info_lock);
	if (!chp_test_bit(chp_info.recognized, bit))
		rc = CHP_STATUS_NOT_RECOGNIZED;
	else if (chp_test_bit(chp_info.configured, bit))
		rc = CHP_STATUS_CONFIGURED;
	else if (chp_test_bit(chp_info.standby, bit))
		rc = CHP_STATUS_STANDBY;
	else
		rc = CHP_STATUS_RESERVED;
	mutex_unlock(&info_lock);

	return rc;
}

/* Return configure task for chpid. */
static enum cfg_task_t cfg_get_task(struct chp_id chpid)
{
	return chp_cfg_task[chpid.cssid][chpid.id];
}

/* Set configure task for chpid. */
static void cfg_set_task(struct chp_id chpid, enum cfg_task_t cfg)
{
	chp_cfg_task[chpid.cssid][chpid.id] = cfg;
}

/* Fetch the first configure task. Set chpid accordingly. */
static enum cfg_task_t chp_cfg_fetch_task(struct chp_id *chpid)
{
	enum cfg_task_t t = cfg_none;

	chp_id_for_each(chpid) {
		t = cfg_get_task(*chpid);
		if (t != cfg_none)
			break;
	}

	return t;
}

/* Perform one configure/deconfigure request. Reschedule work function until
 * last request. */
static void cfg_func(struct work_struct *work)
{
	struct chp_id chpid;
	enum cfg_task_t t;
	int rc;

	spin_lock(&cfg_lock);
	t = chp_cfg_fetch_task(&chpid);
	spin_unlock(&cfg_lock);

	switch (t) {
	case cfg_configure:
		rc = sclp_chp_configure(chpid);
		if (rc)
			CIO_MSG_EVENT(2, "chp: sclp_chp_configure(%x.%02x)="
				      "%d\n", chpid.cssid, chpid.id, rc);
		else {
			info_expire();
			chsc_chp_online(chpid);
		}
		break;
	case cfg_deconfigure:
		rc = sclp_chp_deconfigure(chpid);
		if (rc)
			CIO_MSG_EVENT(2, "chp: sclp_chp_deconfigure(%x.%02x)="
				      "%d\n", chpid.cssid, chpid.id, rc);
		else {
			info_expire();
			chsc_chp_offline(chpid);
		}
		break;
	case cfg_none:
		/* Get updated information after last change. */
		info_update();
		wake_up_interruptible(&cfg_wait_queue);
		return;
	}
	spin_lock(&cfg_lock);
	if (t == cfg_get_task(chpid))
		cfg_set_task(chpid, cfg_none);
	spin_unlock(&cfg_lock);
	schedule_work(&cfg_work);
}

/**
 * chp_cfg_schedule - schedule chpid configuration request
 * @chpid: channel-path ID
 * @configure: Non-zero for configure, zero for deconfigure
 *
 * Schedule a channel-path configuration/deconfiguration request.
 */
void chp_cfg_schedule(struct chp_id chpid, int configure)
{
	CIO_MSG_EVENT(2, "chp_cfg_sched%x.%02x=%d\n", chpid.cssid, chpid.id,
		      configure);
	spin_lock(&cfg_lock);
	cfg_set_task(chpid, configure ? cfg_configure : cfg_deconfigure);
	spin_unlock(&cfg_lock);
	schedule_work(&cfg_work);
}

/**
 * chp_cfg_cancel_deconfigure - cancel chpid deconfiguration request
 * @chpid: channel-path ID
 *
 * Cancel an active channel-path deconfiguration request if it has not yet
 * been performed.
 */
void chp_cfg_cancel_deconfigure(struct chp_id chpid)
{
	CIO_MSG_EVENT(2, "chp_cfg_cancel:%x.%02x\n", chpid.cssid, chpid.id);
	spin_lock(&cfg_lock);
	if (cfg_get_task(chpid) == cfg_deconfigure)
		cfg_set_task(chpid, cfg_none);
	spin_unlock(&cfg_lock);
}

static bool cfg_idle(void)
{
	struct chp_id chpid;
	enum cfg_task_t t;

	spin_lock(&cfg_lock);
	t = chp_cfg_fetch_task(&chpid);
	spin_unlock(&cfg_lock);

	return t == cfg_none;
}

static int cfg_wait_idle(void)
{
	if (wait_event_interruptible(cfg_wait_queue, cfg_idle()))
		return -ERESTARTSYS;
	return 0;
}

static int __init chp_init(void)
{
	struct chp_id chpid;
	int state, ret;

	ret = crw_register_handler(CRW_RSC_CPATH, chp_process_crw);
	if (ret)
		return ret;
	INIT_WORK(&cfg_work, cfg_func);
	init_waitqueue_head(&cfg_wait_queue);
	if (info_update())
		return 0;
	/* Register available channel-paths. */
	chp_id_for_each(&chpid) {
		state = chp_info_get_status(chpid);
		if (state == CHP_STATUS_CONFIGURED ||
		    state == CHP_STATUS_STANDBY)
			chp_new(chpid);
	}

	return 0;
}

subsys_initcall(chp_init);
