/*
 * 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
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#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(iucv_tasklet, iucv_tasklet_fn,0);

/*
 * 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: an array of 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(struct iucv_path);
	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
 */
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");
