// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * IUCV base infrastructure.
 *
 * Copyright IBM Corp. 2001, 2009
 *
 * Author(s):
 *    Original source:
 *	Alan Altmark (Alan_Altmark@us.ibm.com)	Sept. 2000
 *	Xenia Tkatschow (xenia@us.ibm.com)
 *    2Gb awareness and general cleanup:
 *	Fritz Elfert (elfert@de.ibm.com, felfert@millenux.com)
 *    Rewritten for af_iucv:
 *	Martin Schwidefsky <schwidefsky@de.ibm.com>
 *    PM functions:
 *	Ursula Braun (ursula.braun@de.ibm.com)
 *
 * Documentation used:
 *    The original source
 *    CP Programming Service, IBM document # SC24-5760
 */

#define KMSG_COMPONENT "iucv"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt

#include <linux/kernel_stat.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/spinlock.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/list.h>
#include <linux/errno.h>
#include <linux/err.h>
#include <linux/device.h>
#include <linux/cpu.h>
#include <linux/reboot.h>
#include <net/iucv/iucv.h>
#include <linux/atomic.h>
#include <asm/ebcdic.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/smp.h>

/*
 * FLAGS:
 * All flags are defined in the field IPFLAGS1 of each function
 * and can be found in CP Programming Services.
 * IPSRCCLS - Indicates you have specified a source class.
 * IPTRGCLS - Indicates you have specified a target class.
 * IPFGPID  - Indicates you have specified a pathid.
 * IPFGMID  - Indicates you have specified a message ID.
 * IPNORPY  - Indicates a one-way message. No reply expected.
 * IPALL    - Indicates that all paths are affected.
 */
#define IUCV_IPSRCCLS	0x01
#define IUCV_IPTRGCLS	0x01
#define IUCV_IPFGPID	0x02
#define IUCV_IPFGMID	0x04
#define IUCV_IPNORPY	0x10
#define IUCV_IPALL	0x80

static int iucv_bus_match(struct device *dev, struct device_driver *drv)
{
	return 0;
}

enum iucv_pm_states {
	IUCV_PM_INITIAL = 0,
	IUCV_PM_FREEZING = 1,
	IUCV_PM_THAWING = 2,
	IUCV_PM_RESTORING = 3,
};
static enum iucv_pm_states iucv_pm_state;

static int iucv_pm_prepare(struct device *);
static void iucv_pm_complete(struct device *);
static int iucv_pm_freeze(struct device *);
static int iucv_pm_thaw(struct device *);
static int iucv_pm_restore(struct device *);

static const struct dev_pm_ops iucv_pm_ops = {
	.prepare = iucv_pm_prepare,
	.complete = iucv_pm_complete,
	.freeze = iucv_pm_freeze,
	.thaw = iucv_pm_thaw,
	.restore = iucv_pm_restore,
};

struct bus_type iucv_bus = {
	.name = "iucv",
	.match = iucv_bus_match,
	.pm = &iucv_pm_ops,
};
EXPORT_SYMBOL(iucv_bus);

struct device *iucv_root;
EXPORT_SYMBOL(iucv_root);

static int iucv_available;

/* General IUCV interrupt structure */
struct iucv_irq_data {
	u16 ippathid;
	u8  ipflags1;
	u8  iptype;
	u32 res2[9];
};

struct iucv_irq_list {
	struct list_head list;
	struct iucv_irq_data data;
};

static struct iucv_irq_data *iucv_irq_data[NR_CPUS];
static cpumask_t iucv_buffer_cpumask = { CPU_BITS_NONE };
static cpumask_t iucv_irq_cpumask = { CPU_BITS_NONE };

/*
 * Queue of interrupt buffers lock for delivery via the tasklet
 * (fast but can't call smp_call_function).
 */
static LIST_HEAD(iucv_task_queue);

/*
 * The tasklet for fast delivery of iucv interrupts.
 */
static void iucv_tasklet_fn(unsigned long);
static DECLARE_TASKLET_OLD(iucv_tasklet, iucv_tasklet_fn);

/*
 * Queue of interrupt buffers for delivery via a work queue
 * (slower but can call smp_call_function).
 */
static LIST_HEAD(iucv_work_queue);

/*
 * The work element to deliver path pending interrupts.
 */
static void iucv_work_fn(struct work_struct *work);
static DECLARE_WORK(iucv_work, iucv_work_fn);

/*
 * Spinlock protecting task and work queue.
 */
static DEFINE_SPINLOCK(iucv_queue_lock);

enum iucv_command_codes {
	IUCV_QUERY = 0,
	IUCV_RETRIEVE_BUFFER = 2,
	IUCV_SEND = 4,
	IUCV_RECEIVE = 5,
	IUCV_REPLY = 6,
	IUCV_REJECT = 8,
	IUCV_PURGE = 9,
	IUCV_ACCEPT = 10,
	IUCV_CONNECT = 11,
	IUCV_DECLARE_BUFFER = 12,
	IUCV_QUIESCE = 13,
	IUCV_RESUME = 14,
	IUCV_SEVER = 15,
	IUCV_SETMASK = 16,
	IUCV_SETCONTROLMASK = 17,
};

/*
 * Error messages that are used with the iucv_sever function. They get
 * converted to EBCDIC.
 */
static char iucv_error_no_listener[16] = "NO LISTENER";
static char iucv_error_no_memory[16] = "NO MEMORY";
static char iucv_error_pathid[16] = "INVALID PATHID";

/*
 * iucv_handler_list: List of registered handlers.
 */
static LIST_HEAD(iucv_handler_list);

/*
 * iucv_path_table: array of pointers to iucv_path structures.
 */
static struct iucv_path **iucv_path_table;
static unsigned long iucv_max_pathid;

/*
 * iucv_lock: spinlock protecting iucv_handler_list and iucv_pathid_table
 */
static DEFINE_SPINLOCK(iucv_table_lock);

/*
 * iucv_active_cpu: contains the number of the cpu executing the tasklet
 * or the work handler. Needed for iucv_path_sever called from tasklet.
 */
static int iucv_active_cpu = -1;

/*
 * Mutex and wait queue for iucv_register/iucv_unregister.
 */
static DEFINE_MUTEX(iucv_register_mutex);

/*
 * Counter for number of non-smp capable handlers.
 */
static int iucv_nonsmp_handler;

/*
 * IUCV control data structure. Used by iucv_path_accept, iucv_path_connect,
 * iucv_path_quiesce and iucv_path_sever.
 */
struct iucv_cmd_control {
	u16 ippathid;
	u8  ipflags1;
	u8  iprcode;
	u16 ipmsglim;
	u16 res1;
	u8  ipvmid[8];
	u8  ipuser[16];
	u8  iptarget[8];
} __attribute__ ((packed,aligned(8)));

/*
 * Data in parameter list iucv structure. Used by iucv_message_send,
 * iucv_message_send2way and iucv_message_reply.
 */
struct iucv_cmd_dpl {
	u16 ippathid;
	u8  ipflags1;
	u8  iprcode;
	u32 ipmsgid;
	u32 iptrgcls;
	u8  iprmmsg[8];
	u32 ipsrccls;
	u32 ipmsgtag;
	u32 ipbfadr2;
	u32 ipbfln2f;
	u32 res;
} __attribute__ ((packed,aligned(8)));

/*
 * Data in buffer iucv structure. Used by iucv_message_receive,
 * iucv_message_reject, iucv_message_send, iucv_message_send2way
 * and iucv_declare_cpu.
 */
struct iucv_cmd_db {
	u16 ippathid;
	u8  ipflags1;
	u8  iprcode;
	u32 ipmsgid;
	u32 iptrgcls;
	u32 ipbfadr1;
	u32 ipbfln1f;
	u32 ipsrccls;
	u32 ipmsgtag;
	u32 ipbfadr2;
	u32 ipbfln2f;
	u32 res;
} __attribute__ ((packed,aligned(8)));

/*
 * Purge message iucv structure. Used by iucv_message_purge.
 */
struct iucv_cmd_purge {
	u16 ippathid;
	u8  ipflags1;
	u8  iprcode;
	u32 ipmsgid;
	u8  ipaudit[3];
	u8  res1[5];
	u32 res2;
	u32 ipsrccls;
	u32 ipmsgtag;
	u32 res3[3];
} __attribute__ ((packed,aligned(8)));

/*
 * Set mask iucv structure. Used by iucv_enable_cpu.
 */
struct iucv_cmd_set_mask {
	u8  ipmask;
	u8  res1[2];
	u8  iprcode;
	u32 res2[9];
} __attribute__ ((packed,aligned(8)));

union iucv_param {
	struct iucv_cmd_control ctrl;
	struct iucv_cmd_dpl dpl;
	struct iucv_cmd_db db;
	struct iucv_cmd_purge purge;
	struct iucv_cmd_set_mask set_mask;
};

/*
 * Anchor for per-cpu IUCV command parameter block.
 */
static union iucv_param *iucv_param[NR_CPUS];
static union iucv_param *iucv_param_irq[NR_CPUS];

/**
 * iucv_call_b2f0
 * @code: identifier of IUCV call to CP.
 * @parm: pointer to a struct iucv_parm block
 *
 * Calls CP to execute IUCV commands.
 *
 * Returns the result of the CP IUCV call.
 */
static inline int __iucv_call_b2f0(int command, union iucv_param *parm)
{
	register unsigned long reg0 asm ("0");
	register unsigned long reg1 asm ("1");
	int ccode;

	reg0 = command;
	reg1 = (unsigned long)parm;
	asm volatile(
		"	.long 0xb2f01000\n"
		"	ipm	%0\n"
		"	srl	%0,28\n"
		: "=d" (ccode), "=m" (*parm), "+d" (reg0), "+a" (reg1)
		:  "m" (*parm) : "cc");
	return ccode;
}

static inline int iucv_call_b2f0(int command, union iucv_param *parm)
{
	int ccode;

	ccode = __iucv_call_b2f0(command, parm);
	return ccode == 1 ? parm->ctrl.iprcode : ccode;
}

/**
 * iucv_query_maxconn
 *
 * Determines the maximum number of connections that may be established.
 *
 * Returns the maximum number of connections or -EPERM is IUCV is not
 * available.
 */
static int __iucv_query_maxconn(void *param, unsigned long *max_pathid)
{
	register unsigned long reg0 asm ("0");
	register unsigned long reg1 asm ("1");
	int ccode;

	reg0 = IUCV_QUERY;
	reg1 = (unsigned long) param;
	asm volatile (
		"	.long	0xb2f01000\n"
		"	ipm	%0\n"
		"	srl	%0,28\n"
		: "=d" (ccode), "+d" (reg0), "+d" (reg1) : : "cc");
	*max_pathid = reg1;
	return ccode;
}

static int iucv_query_maxconn(void)
{
	unsigned long max_pathid;
	void *param;
	int ccode;

	param = kzalloc(sizeof(union iucv_param), GFP_KERNEL | GFP_DMA);
	if (!param)
		return -ENOMEM;
	ccode = __iucv_query_maxconn(param, &max_pathid);
	if (ccode == 0)
		iucv_max_pathid = max_pathid;
	kfree(param);
	return ccode ? -EPERM : 0;
}

/**
 * iucv_allow_cpu
 * @data: unused
 *
 * Allow iucv interrupts on this cpu.
 */
static void iucv_allow_cpu(void *data)
{
	int cpu = smp_processor_id();
	union iucv_param *parm;

	/*
	 * Enable all iucv interrupts.
	 * ipmask contains bits for the different interrupts
	 *	0x80 - Flag to allow nonpriority message pending interrupts
	 *	0x40 - Flag to allow priority message pending interrupts
	 *	0x20 - Flag to allow nonpriority message completion interrupts
	 *	0x10 - Flag to allow priority message completion interrupts
	 *	0x08 - Flag to allow IUCV control interrupts
	 */
	parm = iucv_param_irq[cpu];
	memset(parm, 0, sizeof(union iucv_param));
	parm->set_mask.ipmask = 0xf8;
	iucv_call_b2f0(IUCV_SETMASK, parm);

	/*
	 * Enable all iucv control interrupts.
	 * ipmask contains bits for the different interrupts
	 *	0x80 - Flag to allow pending connections interrupts
	 *	0x40 - Flag to allow connection complete interrupts
	 *	0x20 - Flag to allow connection severed interrupts
	 *	0x10 - Flag to allow connection quiesced interrupts
	 *	0x08 - Flag to allow connection resumed interrupts
	 */
	memset(parm, 0, sizeof(union iucv_param));
	parm->set_mask.ipmask = 0xf8;
	iucv_call_b2f0(IUCV_SETCONTROLMASK, parm);
	/* Set indication that iucv interrupts are allowed for this cpu. */
	cpumask_set_cpu(cpu, &iucv_irq_cpumask);
}

/**
 * iucv_block_cpu
 * @data: unused
 *
 * Block iucv interrupts on this cpu.
 */
static void iucv_block_cpu(void *data)
{
	int cpu = smp_processor_id();
	union iucv_param *parm;

	/* Disable all iucv interrupts. */
	parm = iucv_param_irq[cpu];
	memset(parm, 0, sizeof(union iucv_param));
	iucv_call_b2f0(IUCV_SETMASK, parm);

	/* Clear indication that iucv interrupts are allowed for this cpu. */
	cpumask_clear_cpu(cpu, &iucv_irq_cpumask);
}

/**
 * iucv_block_cpu_almost
 * @data: unused
 *
 * Allow connection-severed interrupts only on this cpu.
 */
static void iucv_block_cpu_almost(void *data)
{
	int cpu = smp_processor_id();
	union iucv_param *parm;

	/* Allow iucv control interrupts only */
	parm = iucv_param_irq[cpu];
	memset(parm, 0, sizeof(union iucv_param));
	parm->set_mask.ipmask = 0x08;
	iucv_call_b2f0(IUCV_SETMASK, parm);
	/* Allow iucv-severed interrupt only */
	memset(parm, 0, sizeof(union iucv_param));
	parm->set_mask.ipmask = 0x20;
	iucv_call_b2f0(IUCV_SETCONTROLMASK, parm);

	/* Clear indication that iucv interrupts are allowed for this cpu. */
	cpumask_clear_cpu(cpu, &iucv_irq_cpumask);
}

/**
 * iucv_declare_cpu
 * @data: unused
 *
 * Declare a interrupt buffer on this cpu.
 */
static void iucv_declare_cpu(void *data)
{
	int cpu = smp_processor_id();
	union iucv_param *parm;
	int rc;

	if (cpumask_test_cpu(cpu, &iucv_buffer_cpumask))
		return;

	/* Declare interrupt buffer. */
	parm = iucv_param_irq[cpu];
	memset(parm, 0, sizeof(union iucv_param));
	parm->db.ipbfadr1 = virt_to_phys(iucv_irq_data[cpu]);
	rc = iucv_call_b2f0(IUCV_DECLARE_BUFFER, parm);
	if (rc) {
		char *err = "Unknown";
		switch (rc) {
		case 0x03:
			err = "Directory error";
			break;
		case 0x0a:
			err = "Invalid length";
			break;
		case 0x13:
			err = "Buffer already exists";
			break;
		case 0x3e:
			err = "Buffer overlap";
			break;
		case 0x5c:
			err = "Paging or storage error";
			break;
		}
		pr_warn("Defining an interrupt buffer on CPU %i failed with 0x%02x (%s)\n",
			cpu, rc, err);
		return;
	}

	/* Set indication that an iucv buffer exists for this cpu. */
	cpumask_set_cpu(cpu, &iucv_buffer_cpumask);

	if (iucv_nonsmp_handler == 0 || cpumask_empty(&iucv_irq_cpumask))
		/* Enable iucv interrupts on this cpu. */
		iucv_allow_cpu(NULL);
	else
		/* Disable iucv interrupts on this cpu. */
		iucv_block_cpu(NULL);
}

/**
 * iucv_retrieve_cpu
 * @data: unused
 *
 * Retrieve interrupt buffer on this cpu.
 */
static void iucv_retrieve_cpu(void *data)
{
	int cpu = smp_processor_id();
	union iucv_param *parm;

	if (!cpumask_test_cpu(cpu, &iucv_buffer_cpumask))
		return;

	/* Block iucv interrupts. */
	iucv_block_cpu(NULL);

	/* Retrieve interrupt buffer. */
	parm = iucv_param_irq[cpu];
	iucv_call_b2f0(IUCV_RETRIEVE_BUFFER, parm);

	/* Clear indication that an iucv buffer exists for this cpu. */
	cpumask_clear_cpu(cpu, &iucv_buffer_cpumask);
}

/**
 * iucv_setmask_smp
 *
 * Allow iucv interrupts on all cpus.
 */
static void iucv_setmask_mp(void)
{
	int cpu;

	get_online_cpus();
	for_each_online_cpu(cpu)
		/* Enable all cpus with a declared buffer. */
		if (cpumask_test_cpu(cpu, &iucv_buffer_cpumask) &&
		    !cpumask_test_cpu(cpu, &iucv_irq_cpumask))
			smp_call_function_single(cpu, iucv_allow_cpu,
						 NULL, 1);
	put_online_cpus();
}

/**
 * iucv_setmask_up
 *
 * Allow iucv interrupts on a single cpu.
 */
static void iucv_setmask_up(void)
{
	cpumask_t cpumask;
	int cpu;

	/* Disable all cpu but the first in cpu_irq_cpumask. */
	cpumask_copy(&cpumask, &iucv_irq_cpumask);
	cpumask_clear_cpu(cpumask_first(&iucv_irq_cpumask), &cpumask);
	for_each_cpu(cpu, &cpumask)
		smp_call_function_single(cpu, iucv_block_cpu, NULL, 1);
}

/**
 * iucv_enable
 *
 * This function makes iucv ready for use. It allocates the pathid
 * table, declares an iucv interrupt buffer and enables the iucv
 * interrupts. Called when the first user has registered an iucv
 * handler.
 */
static int iucv_enable(void)
{
	size_t alloc_size;
	int cpu, rc;

	get_online_cpus();
	rc = -ENOMEM;
	alloc_size = iucv_max_pathid * sizeof(*iucv_path_table);
	iucv_path_table = kzalloc(alloc_size, GFP_KERNEL);
	if (!iucv_path_table)
		goto out;
	/* Declare per cpu buffers. */
	rc = -EIO;
	for_each_online_cpu(cpu)
		smp_call_function_single(cpu, iucv_declare_cpu, NULL, 1);
	if (cpumask_empty(&iucv_buffer_cpumask))
		/* No cpu could declare an iucv buffer. */
		goto out;
	put_online_cpus();
	return 0;
out:
	kfree(iucv_path_table);
	iucv_path_table = NULL;
	put_online_cpus();
	return rc;
}

/**
 * iucv_disable
 *
 * This function shuts down iucv. It disables iucv interrupts, retrieves
 * the iucv interrupt buffer and frees the pathid table. Called after the
 * last user unregister its iucv handler.
 */
static void iucv_disable(void)
{
	get_online_cpus();
	on_each_cpu(iucv_retrieve_cpu, NULL, 1);
	kfree(iucv_path_table);
	iucv_path_table = NULL;
	put_online_cpus();
}

static int iucv_cpu_dead(unsigned int cpu)
{
	kfree(iucv_param_irq[cpu]);
	iucv_param_irq[cpu] = NULL;
	kfree(iucv_param[cpu]);
	iucv_param[cpu] = NULL;
	kfree(iucv_irq_data[cpu]);
	iucv_irq_data[cpu] = NULL;
	return 0;
}

static int iucv_cpu_prepare(unsigned int cpu)
{
	/* Note: GFP_DMA used to get memory below 2G */
	iucv_irq_data[cpu] = kmalloc_node(sizeof(struct iucv_irq_data),
			     GFP_KERNEL|GFP_DMA, cpu_to_node(cpu));
	if (!iucv_irq_data[cpu])
		goto out_free;

	/* Allocate parameter blocks. */
	iucv_param[cpu] = kmalloc_node(sizeof(union iucv_param),
			  GFP_KERNEL|GFP_DMA, cpu_to_node(cpu));
	if (!iucv_param[cpu])
		goto out_free;

	iucv_param_irq[cpu] = kmalloc_node(sizeof(union iucv_param),
			  GFP_KERNEL|GFP_DMA, cpu_to_node(cpu));
	if (!iucv_param_irq[cpu])
		goto out_free;

	return 0;

out_free:
	iucv_cpu_dead(cpu);
	return -ENOMEM;
}

static int iucv_cpu_online(unsigned int cpu)
{
	if (!iucv_path_table)
		return 0;
	iucv_declare_cpu(NULL);
	return 0;
}

static int iucv_cpu_down_prep(unsigned int cpu)
{
	cpumask_t cpumask;

	if (!iucv_path_table)
		return 0;

	cpumask_copy(&cpumask, &iucv_buffer_cpumask);
	cpumask_clear_cpu(cpu, &cpumask);
	if (cpumask_empty(&cpumask))
		/* Can't offline last IUCV enabled cpu. */
		return -EINVAL;

	iucv_retrieve_cpu(NULL);
	if (!cpumask_empty(&iucv_irq_cpumask))
		return 0;
	smp_call_function_single(cpumask_first(&iucv_buffer_cpumask),
				 iucv_allow_cpu, NULL, 1);
	return 0;
}

/**
 * iucv_sever_pathid
 * @pathid: path identification number.
 * @userdata: 16-bytes of user data.
 *
 * Sever an iucv path to free up the pathid. Used internally.
 */
static int iucv_sever_pathid(u16 pathid, u8 *userdata)
{
	union iucv_param *parm;

	parm = iucv_param_irq[smp_processor_id()];
	memset(parm, 0, sizeof(union iucv_param));
	if (userdata)
		memcpy(parm->ctrl.ipuser, userdata, sizeof(parm->ctrl.ipuser));
	parm->ctrl.ippathid = pathid;
	return iucv_call_b2f0(IUCV_SEVER, parm);
}

/**
 * __iucv_cleanup_queue
 * @dummy: unused dummy argument
 *
 * Nop function called via smp_call_function to force work items from
 * pending external iucv interrupts to the work queue.
 */
static void __iucv_cleanup_queue(void *dummy)
{
}

/**
 * iucv_cleanup_queue
 *
 * Function called after a path has been severed to find all remaining
 * work items for the now stale pathid. The caller needs to hold the
 * iucv_table_lock.
 */
static void iucv_cleanup_queue(void)
{
	struct iucv_irq_list *p, *n;

	/*
	 * When a path is severed, the pathid can be reused immediately
	 * on a iucv connect or a connection pending interrupt. Remove
	 * all entries from the task queue that refer to a stale pathid
	 * (iucv_path_table[ix] == NULL). Only then do the iucv connect
	 * or deliver the connection pending interrupt. To get all the
	 * pending interrupts force them to the work queue by calling
	 * an empty function on all cpus.
	 */
	smp_call_function(__iucv_cleanup_queue, NULL, 1);
	spin_lock_irq(&iucv_queue_lock);
	list_for_each_entry_safe(p, n, &iucv_task_queue, list) {
		/* Remove stale work items from the task queue. */
		if (iucv_path_table[p->data.ippathid] == NULL) {
			list_del(&p->list);
			kfree(p);
		}
	}
	spin_unlock_irq(&iucv_queue_lock);
}

/**
 * iucv_register:
 * @handler: address of iucv handler structure
 * @smp: != 0 indicates that the handler can deal with out of order messages
 *
 * Registers a driver with IUCV.
 *
 * Returns 0 on success, -ENOMEM if the memory allocation for the pathid
 * table failed, or -EIO if IUCV_DECLARE_BUFFER failed on all cpus.
 */
int iucv_register(struct iucv_handler *handler, int smp)
{
	int rc;

	if (!iucv_available)
		return -ENOSYS;
	mutex_lock(&iucv_register_mutex);
	if (!smp)
		iucv_nonsmp_handler++;
	if (list_empty(&iucv_handler_list)) {
		rc = iucv_enable();
		if (rc)
			goto out_mutex;
	} else if (!smp && iucv_nonsmp_handler == 1)
		iucv_setmask_up();
	INIT_LIST_HEAD(&handler->paths);

	spin_lock_bh(&iucv_table_lock);
	list_add_tail(&handler->list, &iucv_handler_list);
	spin_unlock_bh(&iucv_table_lock);
	rc = 0;
out_mutex:
	mutex_unlock(&iucv_register_mutex);
	return rc;
}
EXPORT_SYMBOL(iucv_register);

/**
 * iucv_unregister
 * @handler:  address of iucv handler structure
 * @smp: != 0 indicates that the handler can deal with out of order messages
 *
 * Unregister driver from IUCV.
 */
void iucv_unregister(struct iucv_handler *handler, int smp)
{
	struct iucv_path *p, *n;

	mutex_lock(&iucv_register_mutex);
	spin_lock_bh(&iucv_table_lock);
	/* Remove handler from the iucv_handler_list. */
	list_del_init(&handler->list);
	/* Sever all pathids still referring to the handler. */
	list_for_each_entry_safe(p, n, &handler->paths, list) {
		iucv_sever_pathid(p->pathid, NULL);
		iucv_path_table[p->pathid] = NULL;
		list_del(&p->list);
		iucv_path_free(p);
	}
	spin_unlock_bh(&iucv_table_lock);
	if (!smp)
		iucv_nonsmp_handler--;
	if (list_empty(&iucv_handler_list))
		iucv_disable();
	else if (!smp && iucv_nonsmp_handler == 0)
		iucv_setmask_mp();
	mutex_unlock(&iucv_register_mutex);
}
EXPORT_SYMBOL(iucv_unregister);

static int iucv_reboot_event(struct notifier_block *this,
			     unsigned long event, void *ptr)
{
	int i;

	if (cpumask_empty(&iucv_irq_cpumask))
		return NOTIFY_DONE;

	get_online_cpus();
	on_each_cpu_mask(&iucv_irq_cpumask, iucv_block_cpu, NULL, 1);
	preempt_disable();
	for (i = 0; i < iucv_max_pathid; i++) {
		if (iucv_path_table[i])
			iucv_sever_pathid(i, NULL);
	}
	preempt_enable();
	put_online_cpus();
	iucv_disable();
	return NOTIFY_DONE;
}

static struct notifier_block iucv_reboot_notifier = {
	.notifier_call = iucv_reboot_event,
};

/**
 * iucv_path_accept
 * @path: address of iucv path structure
 * @handler: address of iucv handler structure
 * @userdata: 16 bytes of data reflected to the communication partner
 * @private: private data passed to interrupt handlers for this path
 *
 * This function is issued after the user received a connection pending
 * external interrupt and now wishes to complete the IUCV communication path.
 *
 * Returns the result of the CP IUCV call.
 */
int iucv_path_accept(struct iucv_path *path, struct iucv_handler *handler,
		     u8 *userdata, void *private)
{
	union iucv_param *parm;
	int rc;

	local_bh_disable();
	if (cpumask_empty(&iucv_buffer_cpumask)) {
		rc = -EIO;
		goto out;
	}
	/* Prepare parameter block. */
	parm = iucv_param[smp_processor_id()];
	memset(parm, 0, sizeof(union iucv_param));
	parm->ctrl.ippathid = path->pathid;
	parm->ctrl.ipmsglim = path->msglim;
	if (userdata)
		memcpy(parm->ctrl.ipuser, userdata, sizeof(parm->ctrl.ipuser));
	parm->ctrl.ipflags1 = path->flags;

	rc = iucv_call_b2f0(IUCV_ACCEPT, parm);
	if (!rc) {
		path->private = private;
		path->msglim = parm->ctrl.ipmsglim;
		path->flags = parm->ctrl.ipflags1;
	}
out:
	local_bh_enable();
	return rc;
}
EXPORT_SYMBOL(iucv_path_accept);

/**
 * iucv_path_connect
 * @path: address of iucv path structure
 * @handler: address of iucv handler structure
 * @userid: 8-byte user identification
 * @system: 8-byte target system identification
 * @userdata: 16 bytes of data reflected to the communication partner
 * @private: private data passed to interrupt handlers for this path
 *
 * This function establishes an IUCV path. Although the connect may complete
 * successfully, you are not able to use the path until you receive an IUCV
 * Connection Complete external interrupt.
 *
 * Returns the result of the CP IUCV call.
 */
int iucv_path_connect(struct iucv_path *path, struct iucv_handler *handler,
		      u8 *userid, u8 *system, u8 *userdata,
		      void *private)
{
	union iucv_param *parm;
	int rc;

	spin_lock_bh(&iucv_table_lock);
	iucv_cleanup_queue();
	if (cpumask_empty(&iucv_buffer_cpumask)) {
		rc = -EIO;
		goto out;
	}
	parm = iucv_param[smp_processor_id()];
	memset(parm, 0, sizeof(union iucv_param));
	parm->ctrl.ipmsglim = path->msglim;
	parm->ctrl.ipflags1 = path->flags;
	if (userid) {
		memcpy(parm->ctrl.ipvmid, userid, sizeof(parm->ctrl.ipvmid));
		ASCEBC(parm->ctrl.ipvmid, sizeof(parm->ctrl.ipvmid));
		EBC_TOUPPER(parm->ctrl.ipvmid, sizeof(parm->ctrl.ipvmid));
	}
	if (system) {
		memcpy(parm->ctrl.iptarget, system,
		       sizeof(parm->ctrl.iptarget));
		ASCEBC(parm->ctrl.iptarget, sizeof(parm->ctrl.iptarget));
		EBC_TOUPPER(parm->ctrl.iptarget, sizeof(parm->ctrl.iptarget));
	}
	if (userdata)
		memcpy(parm->ctrl.ipuser, userdata, sizeof(parm->ctrl.ipuser));

	rc = iucv_call_b2f0(IUCV_CONNECT, parm);
	if (!rc) {
		if (parm->ctrl.ippathid < iucv_max_pathid) {
			path->pathid = parm->ctrl.ippathid;
			path->msglim = parm->ctrl.ipmsglim;
			path->flags = parm->ctrl.ipflags1;
			path->handler = handler;
			path->private = private;
			list_add_tail(&path->list, &handler->paths);
			iucv_path_table[path->pathid] = path;
		} else {
			iucv_sever_pathid(parm->ctrl.ippathid,
					  iucv_error_pathid);
			rc = -EIO;
		}
	}
out:
	spin_unlock_bh(&iucv_table_lock);
	return rc;
}
EXPORT_SYMBOL(iucv_path_connect);

/**
 * iucv_path_quiesce:
 * @path: address of iucv path structure
 * @userdata: 16 bytes of data reflected to the communication partner
 *
 * This function temporarily suspends incoming messages on an IUCV path.
 * You can later reactivate the path by invoking the iucv_resume function.
 *
 * Returns the result from the CP IUCV call.
 */
int iucv_path_quiesce(struct iucv_path *path, u8 *userdata)
{
	union iucv_param *parm;
	int rc;

	local_bh_disable();
	if (cpumask_empty(&iucv_buffer_cpumask)) {
		rc = -EIO;
		goto out;
	}
	parm = iucv_param[smp_processor_id()];
	memset(parm, 0, sizeof(union iucv_param));
	if (userdata)
		memcpy(parm->ctrl.ipuser, userdata, sizeof(parm->ctrl.ipuser));
	parm->ctrl.ippathid = path->pathid;
	rc = iucv_call_b2f0(IUCV_QUIESCE, parm);
out:
	local_bh_enable();
	return rc;
}
EXPORT_SYMBOL(iucv_path_quiesce);

/**
 * iucv_path_resume:
 * @path: address of iucv path structure
 * @userdata: 16 bytes of data reflected to the communication partner
 *
 * This function resumes incoming messages on an IUCV path that has
 * been stopped with iucv_path_quiesce.
 *
 * Returns the result from the CP IUCV call.
 */
int iucv_path_resume(struct iucv_path *path, u8 *userdata)
{
	union iucv_param *parm;
	int rc;

	local_bh_disable();
	if (cpumask_empty(&iucv_buffer_cpumask)) {
		rc = -EIO;
		goto out;
	}
	parm = iucv_param[smp_processor_id()];
	memset(parm, 0, sizeof(union iucv_param));
	if (userdata)
		memcpy(parm->ctrl.ipuser, userdata, sizeof(parm->ctrl.ipuser));
	parm->ctrl.ippathid = path->pathid;
	rc = iucv_call_b2f0(IUCV_RESUME, parm);
out:
	local_bh_enable();
	return rc;
}

/**
 * iucv_path_sever
 * @path: address of iucv path structure
 * @userdata: 16 bytes of data reflected to the communication partner
 *
 * This function terminates an IUCV path.
 *
 * Returns the result from the CP IUCV call.
 */
int iucv_path_sever(struct iucv_path *path, u8 *userdata)
{
	int rc;

	preempt_disable();
	if (cpumask_empty(&iucv_buffer_cpumask)) {
		rc = -EIO;
		goto out;
	}
	if (iucv_active_cpu != smp_processor_id())
		spin_lock_bh(&iucv_table_lock);
	rc = iucv_sever_pathid(path->pathid, userdata);
	iucv_path_table[path->pathid] = NULL;
	list_del_init(&path->list);
	if (iucv_active_cpu != smp_processor_id())
		spin_unlock_bh(&iucv_table_lock);
out:
	preempt_enable();
	return rc;
}
EXPORT_SYMBOL(iucv_path_sever);

/**
 * iucv_message_purge
 * @path: address of iucv path structure
 * @msg: address of iucv msg structure
 * @srccls: source class of message
 *
 * Cancels a message you have sent.
 *
 * Returns the result from the CP IUCV call.
 */
int iucv_message_purge(struct iucv_path *path, struct iucv_message *msg,
		       u32 srccls)
{
	union iucv_param *parm;
	int rc;

	local_bh_disable();
	if (cpumask_empty(&iucv_buffer_cpumask)) {
		rc = -EIO;
		goto out;
	}
	parm = iucv_param[smp_processor_id()];
	memset(parm, 0, sizeof(union iucv_param));
	parm->purge.ippathid = path->pathid;
	parm->purge.ipmsgid = msg->id;
	parm->purge.ipsrccls = srccls;
	parm->purge.ipflags1 = IUCV_IPSRCCLS | IUCV_IPFGMID | IUCV_IPFGPID;
	rc = iucv_call_b2f0(IUCV_PURGE, parm);
	if (!rc) {
		msg->audit = (*(u32 *) &parm->purge.ipaudit) >> 8;
		msg->tag = parm->purge.ipmsgtag;
	}
out:
	local_bh_enable();
	return rc;
}
EXPORT_SYMBOL(iucv_message_purge);

/**
 * iucv_message_receive_iprmdata
 * @path: address of iucv path structure
 * @msg: address of iucv msg structure
 * @flags: how the message is received (IUCV_IPBUFLST)
 * @buffer: address of data buffer or address of struct iucv_array
 * @size: length of data buffer
 * @residual:
 *
 * Internal function used by iucv_message_receive and __iucv_message_receive
 * to receive RMDATA data stored in struct iucv_message.
 */
static int iucv_message_receive_iprmdata(struct iucv_path *path,
					 struct iucv_message *msg,
					 u8 flags, void *buffer,
					 size_t size, size_t *residual)
{
	struct iucv_array *array;
	u8 *rmmsg;
	size_t copy;

	/*
	 * Message is 8 bytes long and has been stored to the
	 * message descriptor itself.
	 */
	if (residual)
		*residual = abs(size - 8);
	rmmsg = msg->rmmsg;
	if (flags & IUCV_IPBUFLST) {
		/* Copy to struct iucv_array. */
		size = (size < 8) ? size : 8;
		for (array = buffer; size > 0; array++) {
			copy = min_t(size_t, size, array->length);
			memcpy((u8 *)(addr_t) array->address,
				rmmsg, copy);
			rmmsg += copy;
			size -= copy;
		}
	} else {
		/* Copy to direct buffer. */
		memcpy(buffer, rmmsg, min_t(size_t, size, 8));
	}
	return 0;
}

/**
 * __iucv_message_receive
 * @path: address of iucv path structure
 * @msg: address of iucv msg structure
 * @flags: how the message is received (IUCV_IPBUFLST)
 * @buffer: address of data buffer or address of struct iucv_array
 * @size: length of data buffer
 * @residual:
 *
 * This function receives messages that are being sent to you over
 * established paths. This function will deal with RMDATA messages
 * embedded in struct iucv_message as well.
 *
 * Locking:	no locking
 *
 * Returns the result from the CP IUCV call.
 */
int __iucv_message_receive(struct iucv_path *path, struct iucv_message *msg,
			   u8 flags, void *buffer, size_t size, size_t *residual)
{
	union iucv_param *parm;
	int rc;

	if (msg->flags & IUCV_IPRMDATA)
		return iucv_message_receive_iprmdata(path, msg, flags,
						     buffer, size, residual);
	 if (cpumask_empty(&iucv_buffer_cpumask)) {
		rc = -EIO;
		goto out;
	}
	parm = iucv_param[smp_processor_id()];
	memset(parm, 0, sizeof(union iucv_param));
	parm->db.ipbfadr1 = (u32)(addr_t) buffer;
	parm->db.ipbfln1f = (u32) size;
	parm->db.ipmsgid = msg->id;
	parm->db.ippathid = path->pathid;
	parm->db.iptrgcls = msg->class;
	parm->db.ipflags1 = (flags | IUCV_IPFGPID |
			     IUCV_IPFGMID | IUCV_IPTRGCLS);
	rc = iucv_call_b2f0(IUCV_RECEIVE, parm);
	if (!rc || rc == 5) {
		msg->flags = parm->db.ipflags1;
		if (residual)
			*residual = parm->db.ipbfln1f;
	}
out:
	return rc;
}
EXPORT_SYMBOL(__iucv_message_receive);

/**
 * iucv_message_receive
 * @path: address of iucv path structure
 * @msg: address of iucv msg structure
 * @flags: how the message is received (IUCV_IPBUFLST)
 * @buffer: address of data buffer or address of struct iucv_array
 * @size: length of data buffer
 * @residual:
 *
 * This function receives messages that are being sent to you over
 * established paths. This function will deal with RMDATA messages
 * embedded in struct iucv_message as well.
 *
 * Locking:	local_bh_enable/local_bh_disable
 *
 * Returns the result from the CP IUCV call.
 */
int iucv_message_receive(struct iucv_path *path, struct iucv_message *msg,
			 u8 flags, void *buffer, size_t size, size_t *residual)
{
	int rc;

	if (msg->flags & IUCV_IPRMDATA)
		return iucv_message_receive_iprmdata(path, msg, flags,
						     buffer, size, residual);
	local_bh_disable();
	rc = __iucv_message_receive(path, msg, flags, buffer, size, residual);
	local_bh_enable();
	return rc;
}
EXPORT_SYMBOL(iucv_message_receive);

/**
 * iucv_message_reject
 * @path: address of iucv path structure
 * @msg: address of iucv msg structure
 *
 * The reject function refuses a specified message. Between the time you
 * are notified of a message and the time that you complete the message,
 * the message may be rejected.
 *
 * Returns the result from the CP IUCV call.
 */
int iucv_message_reject(struct iucv_path *path, struct iucv_message *msg)
{
	union iucv_param *parm;
	int rc;

	local_bh_disable();
	if (cpumask_empty(&iucv_buffer_cpumask)) {
		rc = -EIO;
		goto out;
	}
	parm = iucv_param[smp_processor_id()];
	memset(parm, 0, sizeof(union iucv_param));
	parm->db.ippathid = path->pathid;
	parm->db.ipmsgid = msg->id;
	parm->db.iptrgcls = msg->class;
	parm->db.ipflags1 = (IUCV_IPTRGCLS | IUCV_IPFGMID | IUCV_IPFGPID);
	rc = iucv_call_b2f0(IUCV_REJECT, parm);
out:
	local_bh_enable();
	return rc;
}
EXPORT_SYMBOL(iucv_message_reject);

/**
 * iucv_message_reply
 * @path: address of iucv path structure
 * @msg: address of iucv msg structure
 * @flags: how the reply is sent (IUCV_IPRMDATA, IUCV_IPPRTY, IUCV_IPBUFLST)
 * @reply: address of reply data buffer or address of struct iucv_array
 * @size: length of reply data buffer
 *
 * This function responds to the two-way messages that you receive. You
 * must identify completely the message to which you wish to reply. ie,
 * pathid, msgid, and trgcls. Prmmsg signifies the data is moved into
 * the parameter list.
 *
 * Returns the result from the CP IUCV call.
 */
int iucv_message_reply(struct iucv_path *path, struct iucv_message *msg,
		       u8 flags, void *reply, size_t size)
{
	union iucv_param *parm;
	int rc;

	local_bh_disable();
	if (cpumask_empty(&iucv_buffer_cpumask)) {
		rc = -EIO;
		goto out;
	}
	parm = iucv_param[smp_processor_id()];
	memset(parm, 0, sizeof(union iucv_param));
	if (flags & IUCV_IPRMDATA) {
		parm->dpl.ippathid = path->pathid;
		parm->dpl.ipflags1 = flags;
		parm->dpl.ipmsgid = msg->id;
		parm->dpl.iptrgcls = msg->class;
		memcpy(parm->dpl.iprmmsg, reply, min_t(size_t, size, 8));
	} else {
		parm->db.ipbfadr1 = (u32)(addr_t) reply;
		parm->db.ipbfln1f = (u32) size;
		parm->db.ippathid = path->pathid;
		parm->db.ipflags1 = flags;
		parm->db.ipmsgid = msg->id;
		parm->db.iptrgcls = msg->class;
	}
	rc = iucv_call_b2f0(IUCV_REPLY, parm);
out:
	local_bh_enable();
	return rc;
}
EXPORT_SYMBOL(iucv_message_reply);

/**
 * __iucv_message_send
 * @path: address of iucv path structure
 * @msg: address of iucv msg structure
 * @flags: how the message is sent (IUCV_IPRMDATA, IUCV_IPPRTY, IUCV_IPBUFLST)
 * @srccls: source class of message
 * @buffer: address of send buffer or address of struct iucv_array
 * @size: length of send buffer
 *
 * This function transmits data to another application. Data to be
 * transmitted is in a buffer and this is a one-way message and the
 * receiver will not reply to the message.
 *
 * Locking:	no locking
 *
 * Returns the result from the CP IUCV call.
 */
int __iucv_message_send(struct iucv_path *path, struct iucv_message *msg,
		      u8 flags, u32 srccls, void *buffer, size_t size)
{
	union iucv_param *parm;
	int rc;

	if (cpumask_empty(&iucv_buffer_cpumask)) {
		rc = -EIO;
		goto out;
	}
	parm = iucv_param[smp_processor_id()];
	memset(parm, 0, sizeof(union iucv_param));
	if (flags & IUCV_IPRMDATA) {
		/* Message of 8 bytes can be placed into the parameter list. */
		parm->dpl.ippathid = path->pathid;
		parm->dpl.ipflags1 = flags | IUCV_IPNORPY;
		parm->dpl.iptrgcls = msg->class;
		parm->dpl.ipsrccls = srccls;
		parm->dpl.ipmsgtag = msg->tag;
		memcpy(parm->dpl.iprmmsg, buffer, 8);
	} else {
		parm->db.ipbfadr1 = (u32)(addr_t) buffer;
		parm->db.ipbfln1f = (u32) size;
		parm->db.ippathid = path->pathid;
		parm->db.ipflags1 = flags | IUCV_IPNORPY;
		parm->db.iptrgcls = msg->class;
		parm->db.ipsrccls = srccls;
		parm->db.ipmsgtag = msg->tag;
	}
	rc = iucv_call_b2f0(IUCV_SEND, parm);
	if (!rc)
		msg->id = parm->db.ipmsgid;
out:
	return rc;
}
EXPORT_SYMBOL(__iucv_message_send);

/**
 * iucv_message_send
 * @path: address of iucv path structure
 * @msg: address of iucv msg structure
 * @flags: how the message is sent (IUCV_IPRMDATA, IUCV_IPPRTY, IUCV_IPBUFLST)
 * @srccls: source class of message
 * @buffer: address of send buffer or address of struct iucv_array
 * @size: length of send buffer
 *
 * This function transmits data to another application. Data to be
 * transmitted is in a buffer and this is a one-way message and the
 * receiver will not reply to the message.
 *
 * Locking:	local_bh_enable/local_bh_disable
 *
 * Returns the result from the CP IUCV call.
 */
int iucv_message_send(struct iucv_path *path, struct iucv_message *msg,
		      u8 flags, u32 srccls, void *buffer, size_t size)
{
	int rc;

	local_bh_disable();
	rc = __iucv_message_send(path, msg, flags, srccls, buffer, size);
	local_bh_enable();
	return rc;
}
EXPORT_SYMBOL(iucv_message_send);

/**
 * iucv_message_send2way
 * @path: address of iucv path structure
 * @msg: address of iucv msg structure
 * @flags: how the message is sent and the reply is received
 *	   (IUCV_IPRMDATA, IUCV_IPBUFLST, IUCV_IPPRTY, IUCV_ANSLST)
 * @srccls: source class of message
 * @buffer: address of send buffer or address of struct iucv_array
 * @size: length of send buffer
 * @ansbuf: address of answer buffer or address of struct iucv_array
 * @asize: size of reply buffer
 *
 * This function transmits data to another application. Data to be
 * transmitted is in a buffer. The receiver of the send is expected to
 * reply to the message and a buffer is provided into which IUCV moves
 * the reply to this message.
 *
 * Returns the result from the CP IUCV call.
 */
int iucv_message_send2way(struct iucv_path *path, struct iucv_message *msg,
			  u8 flags, u32 srccls, void *buffer, size_t size,
			  void *answer, size_t asize, size_t *residual)
{
	union iucv_param *parm;
	int rc;

	local_bh_disable();
	if (cpumask_empty(&iucv_buffer_cpumask)) {
		rc = -EIO;
		goto out;
	}
	parm = iucv_param[smp_processor_id()];
	memset(parm, 0, sizeof(union iucv_param));
	if (flags & IUCV_IPRMDATA) {
		parm->dpl.ippathid = path->pathid;
		parm->dpl.ipflags1 = path->flags;	/* priority message */
		parm->dpl.iptrgcls = msg->class;
		parm->dpl.ipsrccls = srccls;
		parm->dpl.ipmsgtag = msg->tag;
		parm->dpl.ipbfadr2 = (u32)(addr_t) answer;
		parm->dpl.ipbfln2f = (u32) asize;
		memcpy(parm->dpl.iprmmsg, buffer, 8);
	} else {
		parm->db.ippathid = path->pathid;
		parm->db.ipflags1 = path->flags;	/* priority message */
		parm->db.iptrgcls = msg->class;
		parm->db.ipsrccls = srccls;
		parm->db.ipmsgtag = msg->tag;
		parm->db.ipbfadr1 = (u32)(addr_t) buffer;
		parm->db.ipbfln1f = (u32) size;
		parm->db.ipbfadr2 = (u32)(addr_t) answer;
		parm->db.ipbfln2f = (u32) asize;
	}
	rc = iucv_call_b2f0(IUCV_SEND, parm);
	if (!rc)
		msg->id = parm->db.ipmsgid;
out:
	local_bh_enable();
	return rc;
}
EXPORT_SYMBOL(iucv_message_send2way);

/**
 * iucv_path_pending
 * @data: Pointer to external interrupt buffer
 *
 * Process connection pending work item. Called from tasklet while holding
 * iucv_table_lock.
 */
struct iucv_path_pending {
	u16 ippathid;
	u8  ipflags1;
	u8  iptype;
	u16 ipmsglim;
	u16 res1;
	u8  ipvmid[8];
	u8  ipuser[16];
	u32 res3;
	u8  ippollfg;
	u8  res4[3];
} __packed;

static void iucv_path_pending(struct iucv_irq_data *data)
{
	struct iucv_path_pending *ipp = (void *) data;
	struct iucv_handler *handler;
	struct iucv_path *path;
	char *error;

	BUG_ON(iucv_path_table[ipp->ippathid]);
	/* New pathid, handler found. Create a new path struct. */
	error = iucv_error_no_memory;
	path = iucv_path_alloc(ipp->ipmsglim, ipp->ipflags1, GFP_ATOMIC);
	if (!path)
		goto out_sever;
	path->pathid = ipp->ippathid;
	iucv_path_table[path->pathid] = path;
	EBCASC(ipp->ipvmid, 8);

	/* Call registered handler until one is found that wants the path. */
	list_for_each_entry(handler, &iucv_handler_list, list) {
		if (!handler->path_pending)
			continue;
		/*
		 * Add path to handler to allow a call to iucv_path_sever
		 * inside the path_pending function. If the handler returns
		 * an error remove the path from the handler again.
		 */
		list_add(&path->list, &handler->paths);
		path->handler = handler;
		if (!handler->path_pending(path, ipp->ipvmid, ipp->ipuser))
			return;
		list_del(&path->list);
		path->handler = NULL;
	}
	/* No handler wanted the path. */
	iucv_path_table[path->pathid] = NULL;
	iucv_path_free(path);
	error = iucv_error_no_listener;
out_sever:
	iucv_sever_pathid(ipp->ippathid, error);
}

/**
 * iucv_path_complete
 * @data: Pointer to external interrupt buffer
 *
 * Process connection complete work item. Called from tasklet while holding
 * iucv_table_lock.
 */
struct iucv_path_complete {
	u16 ippathid;
	u8  ipflags1;
	u8  iptype;
	u16 ipmsglim;
	u16 res1;
	u8  res2[8];
	u8  ipuser[16];
	u32 res3;
	u8  ippollfg;
	u8  res4[3];
} __packed;

static void iucv_path_complete(struct iucv_irq_data *data)
{
	struct iucv_path_complete *ipc = (void *) data;
	struct iucv_path *path = iucv_path_table[ipc->ippathid];

	if (path)
		path->flags = ipc->ipflags1;
	if (path && path->handler && path->handler->path_complete)
		path->handler->path_complete(path, ipc->ipuser);
}

/**
 * iucv_path_severed
 * @data: Pointer to external interrupt buffer
 *
 * Process connection severed work item. Called from tasklet while holding
 * iucv_table_lock.
 */
struct iucv_path_severed {
	u16 ippathid;
	u8  res1;
	u8  iptype;
	u32 res2;
	u8  res3[8];
	u8  ipuser[16];
	u32 res4;
	u8  ippollfg;
	u8  res5[3];
} __packed;

static void iucv_path_severed(struct iucv_irq_data *data)
{
	struct iucv_path_severed *ips = (void *) data;
	struct iucv_path *path = iucv_path_table[ips->ippathid];

	if (!path || !path->handler)	/* Already severed */
		return;
	if (path->handler->path_severed)
		path->handler->path_severed(path, ips->ipuser);
	else {
		iucv_sever_pathid(path->pathid, NULL);
		iucv_path_table[path->pathid] = NULL;
		list_del(&path->list);
		iucv_path_free(path);
	}
}

/**
 * iucv_path_quiesced
 * @data: Pointer to external interrupt buffer
 *
 * Process connection quiesced work item. Called from tasklet while holding
 * iucv_table_lock.
 */
struct iucv_path_quiesced {
	u16 ippathid;
	u8  res1;
	u8  iptype;
	u32 res2;
	u8  res3[8];
	u8  ipuser[16];
	u32 res4;
	u8  ippollfg;
	u8  res5[3];
} __packed;

static void iucv_path_quiesced(struct iucv_irq_data *data)
{
	struct iucv_path_quiesced *ipq = (void *) data;
	struct iucv_path *path = iucv_path_table[ipq->ippathid];

	if (path && path->handler && path->handler->path_quiesced)
		path->handler->path_quiesced(path, ipq->ipuser);
}

/**
 * iucv_path_resumed
 * @data: Pointer to external interrupt buffer
 *
 * Process connection resumed work item. Called from tasklet while holding
 * iucv_table_lock.
 */
struct iucv_path_resumed {
	u16 ippathid;
	u8  res1;
	u8  iptype;
	u32 res2;
	u8  res3[8];
	u8  ipuser[16];
	u32 res4;
	u8  ippollfg;
	u8  res5[3];
} __packed;

static void iucv_path_resumed(struct iucv_irq_data *data)
{
	struct iucv_path_resumed *ipr = (void *) data;
	struct iucv_path *path = iucv_path_table[ipr->ippathid];

	if (path && path->handler && path->handler->path_resumed)
		path->handler->path_resumed(path, ipr->ipuser);
}

/**
 * iucv_message_complete
 * @data: Pointer to external interrupt buffer
 *
 * Process message complete work item. Called from tasklet while holding
 * iucv_table_lock.
 */
struct iucv_message_complete {
	u16 ippathid;
	u8  ipflags1;
	u8  iptype;
	u32 ipmsgid;
	u32 ipaudit;
	u8  iprmmsg[8];
	u32 ipsrccls;
	u32 ipmsgtag;
	u32 res;
	u32 ipbfln2f;
	u8  ippollfg;
	u8  res2[3];
} __packed;

static void iucv_message_complete(struct iucv_irq_data *data)
{
	struct iucv_message_complete *imc = (void *) data;
	struct iucv_path *path = iucv_path_table[imc->ippathid];
	struct iucv_message msg;

	if (path && path->handler && path->handler->message_complete) {
		msg.flags = imc->ipflags1;
		msg.id = imc->ipmsgid;
		msg.audit = imc->ipaudit;
		memcpy(msg.rmmsg, imc->iprmmsg, 8);
		msg.class = imc->ipsrccls;
		msg.tag = imc->ipmsgtag;
		msg.length = imc->ipbfln2f;
		path->handler->message_complete(path, &msg);
	}
}

/**
 * iucv_message_pending
 * @data: Pointer to external interrupt buffer
 *
 * Process message pending work item. Called from tasklet while holding
 * iucv_table_lock.
 */
struct iucv_message_pending {
	u16 ippathid;
	u8  ipflags1;
	u8  iptype;
	u32 ipmsgid;
	u32 iptrgcls;
	union {
		u32 iprmmsg1_u32;
		u8  iprmmsg1[4];
	} ln1msg1;
	union {
		u32 ipbfln1f;
		u8  iprmmsg2[4];
	} ln1msg2;
	u32 res1[3];
	u32 ipbfln2f;
	u8  ippollfg;
	u8  res2[3];
} __packed;

static void iucv_message_pending(struct iucv_irq_data *data)
{
	struct iucv_message_pending *imp = (void *) data;
	struct iucv_path *path = iucv_path_table[imp->ippathid];
	struct iucv_message msg;

	if (path && path->handler && path->handler->message_pending) {
		msg.flags = imp->ipflags1;
		msg.id = imp->ipmsgid;
		msg.class = imp->iptrgcls;
		if (imp->ipflags1 & IUCV_IPRMDATA) {
			memcpy(msg.rmmsg, imp->ln1msg1.iprmmsg1, 8);
			msg.length = 8;
		} else
			msg.length = imp->ln1msg2.ipbfln1f;
		msg.reply_size = imp->ipbfln2f;
		path->handler->message_pending(path, &msg);
	}
}

/**
 * iucv_tasklet_fn:
 *
 * This tasklet loops over the queue of irq buffers created by
 * iucv_external_interrupt, calls the appropriate action handler
 * and then frees the buffer.
 */
static void iucv_tasklet_fn(unsigned long ignored)
{
	typedef void iucv_irq_fn(struct iucv_irq_data *);
	static iucv_irq_fn *irq_fn[] = {
		[0x02] = iucv_path_complete,
		[0x03] = iucv_path_severed,
		[0x04] = iucv_path_quiesced,
		[0x05] = iucv_path_resumed,
		[0x06] = iucv_message_complete,
		[0x07] = iucv_message_complete,
		[0x08] = iucv_message_pending,
		[0x09] = iucv_message_pending,
	};
	LIST_HEAD(task_queue);
	struct iucv_irq_list *p, *n;

	/* Serialize tasklet, iucv_path_sever and iucv_path_connect. */
	if (!spin_trylock(&iucv_table_lock)) {
		tasklet_schedule(&iucv_tasklet);
		return;
	}
	iucv_active_cpu = smp_processor_id();

	spin_lock_irq(&iucv_queue_lock);
	list_splice_init(&iucv_task_queue, &task_queue);
	spin_unlock_irq(&iucv_queue_lock);

	list_for_each_entry_safe(p, n, &task_queue, list) {
		list_del_init(&p->list);
		irq_fn[p->data.iptype](&p->data);
		kfree(p);
	}

	iucv_active_cpu = -1;
	spin_unlock(&iucv_table_lock);
}

/**
 * iucv_work_fn:
 *
 * This work function loops over the queue of path pending irq blocks
 * created by iucv_external_interrupt, calls the appropriate action
 * handler and then frees the buffer.
 */
static void iucv_work_fn(struct work_struct *work)
{
	LIST_HEAD(work_queue);
	struct iucv_irq_list *p, *n;

	/* Serialize tasklet, iucv_path_sever and iucv_path_connect. */
	spin_lock_bh(&iucv_table_lock);
	iucv_active_cpu = smp_processor_id();

	spin_lock_irq(&iucv_queue_lock);
	list_splice_init(&iucv_work_queue, &work_queue);
	spin_unlock_irq(&iucv_queue_lock);

	iucv_cleanup_queue();
	list_for_each_entry_safe(p, n, &work_queue, list) {
		list_del_init(&p->list);
		iucv_path_pending(&p->data);
		kfree(p);
	}

	iucv_active_cpu = -1;
	spin_unlock_bh(&iucv_table_lock);
}

/**
 * iucv_external_interrupt
 * @code: irq code
 *
 * Handles external interrupts coming in from CP.
 * Places the interrupt buffer on a queue and schedules iucv_tasklet_fn().
 */
static void iucv_external_interrupt(struct ext_code ext_code,
				    unsigned int param32, unsigned long param64)
{
	struct iucv_irq_data *p;
	struct iucv_irq_list *work;

	inc_irq_stat(IRQEXT_IUC);
	p = iucv_irq_data[smp_processor_id()];
	if (p->ippathid >= iucv_max_pathid) {
		WARN_ON(p->ippathid >= iucv_max_pathid);
		iucv_sever_pathid(p->ippathid, iucv_error_no_listener);
		return;
	}
	BUG_ON(p->iptype  < 0x01 || p->iptype > 0x09);
	work = kmalloc(sizeof(struct iucv_irq_list), GFP_ATOMIC);
	if (!work) {
		pr_warn("iucv_external_interrupt: out of memory\n");
		return;
	}
	memcpy(&work->data, p, sizeof(work->data));
	spin_lock(&iucv_queue_lock);
	if (p->iptype == 0x01) {
		/* Path pending interrupt. */
		list_add_tail(&work->list, &iucv_work_queue);
		schedule_work(&iucv_work);
	} else {
		/* The other interrupts. */
		list_add_tail(&work->list, &iucv_task_queue);
		tasklet_schedule(&iucv_tasklet);
	}
	spin_unlock(&iucv_queue_lock);
}

static int iucv_pm_prepare(struct device *dev)
{
	int rc = 0;

#ifdef CONFIG_PM_DEBUG
	printk(KERN_INFO "iucv_pm_prepare\n");
#endif
	if (dev->driver && dev->driver->pm && dev->driver->pm->prepare)
		rc = dev->driver->pm->prepare(dev);
	return rc;
}

static void iucv_pm_complete(struct device *dev)
{
#ifdef CONFIG_PM_DEBUG
	printk(KERN_INFO "iucv_pm_complete\n");
#endif
	if (dev->driver && dev->driver->pm && dev->driver->pm->complete)
		dev->driver->pm->complete(dev);
}

/**
 * iucv_path_table_empty() - determine if iucv path table is empty
 *
 * Returns 0 if there are still iucv pathes defined
 *	   1 if there are no iucv pathes defined
 */
static int iucv_path_table_empty(void)
{
	int i;

	for (i = 0; i < iucv_max_pathid; i++) {
		if (iucv_path_table[i])
			return 0;
	}
	return 1;
}

/**
 * iucv_pm_freeze() - Freeze PM callback
 * @dev:	iucv-based device
 *
 * disable iucv interrupts
 * invoke callback function of the iucv-based driver
 * shut down iucv, if no iucv-pathes are established anymore
 */
static int iucv_pm_freeze(struct device *dev)
{
	int cpu;
	struct iucv_irq_list *p, *n;
	int rc = 0;

#ifdef CONFIG_PM_DEBUG
	printk(KERN_WARNING "iucv_pm_freeze\n");
#endif
	if (iucv_pm_state != IUCV_PM_FREEZING) {
		for_each_cpu(cpu, &iucv_irq_cpumask)
			smp_call_function_single(cpu, iucv_block_cpu_almost,
						 NULL, 1);
		cancel_work_sync(&iucv_work);
		list_for_each_entry_safe(p, n, &iucv_work_queue, list) {
			list_del_init(&p->list);
			iucv_sever_pathid(p->data.ippathid,
					  iucv_error_no_listener);
			kfree(p);
		}
	}
	iucv_pm_state = IUCV_PM_FREEZING;
	if (dev->driver && dev->driver->pm && dev->driver->pm->freeze)
		rc = dev->driver->pm->freeze(dev);
	if (iucv_path_table_empty())
		iucv_disable();
	return rc;
}

/**
 * iucv_pm_thaw() - Thaw PM callback
 * @dev:	iucv-based device
 *
 * make iucv ready for use again: allocate path table, declare interrupt buffers
 *				  and enable iucv interrupts
 * invoke callback function of the iucv-based driver
 */
static int iucv_pm_thaw(struct device *dev)
{
	int rc = 0;

#ifdef CONFIG_PM_DEBUG
	printk(KERN_WARNING "iucv_pm_thaw\n");
#endif
	iucv_pm_state = IUCV_PM_THAWING;
	if (!iucv_path_table) {
		rc = iucv_enable();
		if (rc)
			goto out;
	}
	if (cpumask_empty(&iucv_irq_cpumask)) {
		if (iucv_nonsmp_handler)
			/* enable interrupts on one cpu */
			iucv_allow_cpu(NULL);
		else
			/* enable interrupts on all cpus */
			iucv_setmask_mp();
	}
	if (dev->driver && dev->driver->pm && dev->driver->pm->thaw)
		rc = dev->driver->pm->thaw(dev);
out:
	return rc;
}

/**
 * iucv_pm_restore() - Restore PM callback
 * @dev:	iucv-based device
 *
 * make iucv ready for use again: allocate path table, declare interrupt buffers
 *				  and enable iucv interrupts
 * invoke callback function of the iucv-based driver
 */
static int iucv_pm_restore(struct device *dev)
{
	int rc = 0;

#ifdef CONFIG_PM_DEBUG
	printk(KERN_WARNING "iucv_pm_restore %p\n", iucv_path_table);
#endif
	if ((iucv_pm_state != IUCV_PM_RESTORING) && iucv_path_table)
		pr_warn("Suspending Linux did not completely close all IUCV connections\n");
	iucv_pm_state = IUCV_PM_RESTORING;
	if (cpumask_empty(&iucv_irq_cpumask)) {
		rc = iucv_query_maxconn();
		rc = iucv_enable();
		if (rc)
			goto out;
	}
	if (dev->driver && dev->driver->pm && dev->driver->pm->restore)
		rc = dev->driver->pm->restore(dev);
out:
	return rc;
}

struct iucv_interface iucv_if = {
	.message_receive = iucv_message_receive,
	.__message_receive = __iucv_message_receive,
	.message_reply = iucv_message_reply,
	.message_reject = iucv_message_reject,
	.message_send = iucv_message_send,
	.__message_send = __iucv_message_send,
	.message_send2way = iucv_message_send2way,
	.message_purge = iucv_message_purge,
	.path_accept = iucv_path_accept,
	.path_connect = iucv_path_connect,
	.path_quiesce = iucv_path_quiesce,
	.path_resume = iucv_path_resume,
	.path_sever = iucv_path_sever,
	.iucv_register = iucv_register,
	.iucv_unregister = iucv_unregister,
	.bus = NULL,
	.root = NULL,
};
EXPORT_SYMBOL(iucv_if);

static enum cpuhp_state iucv_online;
/**
 * iucv_init
 *
 * Allocates and initializes various data structures.
 */
static int __init iucv_init(void)
{
	int rc;

	if (!MACHINE_IS_VM) {
		rc = -EPROTONOSUPPORT;
		goto out;
	}
	ctl_set_bit(0, 1);
	rc = iucv_query_maxconn();
	if (rc)
		goto out_ctl;
	rc = register_external_irq(EXT_IRQ_IUCV, iucv_external_interrupt);
	if (rc)
		goto out_ctl;
	iucv_root = root_device_register("iucv");
	if (IS_ERR(iucv_root)) {
		rc = PTR_ERR(iucv_root);
		goto out_int;
	}

	rc = cpuhp_setup_state(CPUHP_NET_IUCV_PREPARE, "net/iucv:prepare",
			       iucv_cpu_prepare, iucv_cpu_dead);
	if (rc)
		goto out_dev;
	rc = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "net/iucv:online",
			       iucv_cpu_online, iucv_cpu_down_prep);
	if (rc < 0)
		goto out_prep;
	iucv_online = rc;

	rc = register_reboot_notifier(&iucv_reboot_notifier);
	if (rc)
		goto out_remove_hp;
	ASCEBC(iucv_error_no_listener, 16);
	ASCEBC(iucv_error_no_memory, 16);
	ASCEBC(iucv_error_pathid, 16);
	iucv_available = 1;
	rc = bus_register(&iucv_bus);
	if (rc)
		goto out_reboot;
	iucv_if.root = iucv_root;
	iucv_if.bus = &iucv_bus;
	return 0;

out_reboot:
	unregister_reboot_notifier(&iucv_reboot_notifier);
out_remove_hp:
	cpuhp_remove_state(iucv_online);
out_prep:
	cpuhp_remove_state(CPUHP_NET_IUCV_PREPARE);
out_dev:
	root_device_unregister(iucv_root);
out_int:
	unregister_external_irq(EXT_IRQ_IUCV, iucv_external_interrupt);
out_ctl:
	ctl_clear_bit(0, 1);
out:
	return rc;
}

/**
 * iucv_exit
 *
 * Frees everything allocated from iucv_init.
 */
static void __exit iucv_exit(void)
{
	struct iucv_irq_list *p, *n;

	spin_lock_irq(&iucv_queue_lock);
	list_for_each_entry_safe(p, n, &iucv_task_queue, list)
		kfree(p);
	list_for_each_entry_safe(p, n, &iucv_work_queue, list)
		kfree(p);
	spin_unlock_irq(&iucv_queue_lock);
	unregister_reboot_notifier(&iucv_reboot_notifier);

	cpuhp_remove_state_nocalls(iucv_online);
	cpuhp_remove_state(CPUHP_NET_IUCV_PREPARE);
	root_device_unregister(iucv_root);
	bus_unregister(&iucv_bus);
	unregister_external_irq(EXT_IRQ_IUCV, iucv_external_interrupt);
}

subsys_initcall(iucv_init);
module_exit(iucv_exit);

MODULE_AUTHOR("(C) 2001 IBM Corp. by Fritz Elfert (felfert@millenux.com)");
MODULE_DESCRIPTION("Linux for S/390 IUCV lowlevel driver");
MODULE_LICENSE("GPL");
