/*
 * IUCV network driver
 *
 * Copyright (C) 2001 IBM Deutschland Entwicklung GmbH, IBM Corporation
 * 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)
 *
 * 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 DEBUG */

#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 <asm/atomic.h>
#include "iucv.h"
#include <asm/io.h>
#include <asm/s390_ext.h>
#include <asm/ebcdic.h>
#include <asm/smp.h>
#include <asm/s390_rdev.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
 * IPFGMCL  - Indicates you have specified a target class
 * IPFGPID  - Indicates you have specified a pathid
 * IPFGMID  - Indicates you have specified a message ID
 * IPANSLST - Indicates that you are using an address list for
 *            reply data
 * IPBUFLST - Indicates that you are using an address list for
 *            message data
 */

#define IPSRCCLS 	0x01
#define IPFGMCL         0x01
#define IPFGPID         0x02
#define IPFGMID         0x04
#define IPANSLST        0x08
#define IPBUFLST        0x40

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

struct bus_type iucv_bus = {
	.name = "iucv",
	.match = iucv_bus_match,
};

struct device *iucv_root;

/* General IUCV interrupt structure */
typedef struct {
	__u16 ippathid;
	__u8  res1;
	__u8  iptype;
	__u32 res2;
	__u8  ipvmid[8];
	__u8  res3[24];
} iucv_GeneralInterrupt;

static iucv_GeneralInterrupt *iucv_external_int_buffer = NULL;

/* Spin Lock declaration */

static DEFINE_SPINLOCK(iucv_lock);

static int messagesDisabled = 0;

/***************INTERRUPT HANDLING ***************/

typedef struct {
	struct list_head queue;
	iucv_GeneralInterrupt data;
} iucv_irqdata;

static struct list_head  iucv_irq_queue;
static DEFINE_SPINLOCK(iucv_irq_queue_lock);

/*
 *Internal function prototypes
 */
static void iucv_tasklet_handler(unsigned long);
static void iucv_irq_handler(__u16);

static DECLARE_TASKLET(iucv_tasklet,iucv_tasklet_handler,0);

/************ FUNCTION ID'S ****************************/

#define ACCEPT          10
#define CONNECT         11
#define DECLARE_BUFFER  12
#define PURGE           9
#define QUERY           0
#define QUIESCE         13
#define RECEIVE         5
#define REJECT          8
#define REPLY           6
#define RESUME          14
#define RETRIEVE_BUFFER 2
#define SEND            4
#define SETMASK         16
#define SEVER           15

/**
 * Structure: handler
 * members: list - list management.
 *          structure: id
 *             userid - 8 char array of machine identification
 *             user_data - 16 char array for user identification
 *             mask - 24 char array used to compare the 2 previous
 *          interrupt_table - vector of interrupt functions.
 *          pgm_data -  ulong, application data that is passed
 *                      to the interrupt handlers
*/
typedef struct handler_t {
	struct list_head list;
	struct {
		__u8 userid[8];
		__u8 user_data[16];
		__u8 mask[24];
	}                    id;
	iucv_interrupt_ops_t *interrupt_table;
	void                 *pgm_data;
} handler;

/**
 * iucv_handler_table: List of registered handlers.
 */
static struct list_head iucv_handler_table;

/**
 * iucv_pathid_table: an array of *handler pointing into
 *                    iucv_handler_table for fast indexing by pathid;
 */
static handler **iucv_pathid_table;

static unsigned long max_connections;

/**
 * iucv_cpuid: contains the logical cpu number of the cpu which
 * has declared the iucv buffer by issuing DECLARE_BUFFER.
 * If no cpu has done the initialization iucv_cpuid contains -1.
 */
static int iucv_cpuid = -1;
/**
 * register_flag: is 0 when external interrupt has not been registered
 */
static int register_flag;

/****************FIVE 40-BYTE PARAMETER STRUCTURES******************/
/* Data struct 1: iparml_control
 * Used for iucv_accept
 *          iucv_connect
 *          iucv_quiesce
 *          iucv_resume
 *          iucv_sever
 *          iucv_retrieve_buffer
 * Data struct 2: iparml_dpl     (data in parameter list)
 * Used for iucv_send_prmmsg
 *          iucv_send2way_prmmsg
 *          iucv_send2way_prmmsg_array
 *          iucv_reply_prmmsg
 * Data struct 3: iparml_db       (data in a buffer)
 * Used for iucv_receive
 *          iucv_receive_array
 *          iucv_reject
 *          iucv_reply
 *          iucv_reply_array
 *          iucv_send
 *          iucv_send_array
 *          iucv_send2way
 *          iucv_send2way_array
 *          iucv_declare_buffer
 * Data struct 4: iparml_purge
 * Used for iucv_purge
 *          iucv_query
 * Data struct 5: iparml_set_mask
 * Used for iucv_set_mask
 */

typedef struct {
	__u16 ippathid;
	__u8  ipflags1;
	__u8  iprcode;
	__u16 ipmsglim;
	__u16 res1;
	__u8  ipvmid[8];
	__u8  ipuser[16];
	__u8  iptarget[8];
} iparml_control;

typedef struct {
	__u16 ippathid;
	__u8  ipflags1;
	__u8  iprcode;
	__u32 ipmsgid;
	__u32 iptrgcls;
	__u8  iprmmsg[8];
	__u32 ipsrccls;
	__u32 ipmsgtag;
	__u32 ipbfadr2;
	__u32 ipbfln2f;
	__u32 res;
} iparml_dpl;

typedef struct {
	__u16 ippathid;
	__u8  ipflags1;
	__u8  iprcode;
	__u32 ipmsgid;
	__u32 iptrgcls;
	__u32 ipbfadr1;
	__u32 ipbfln1f;
	__u32 ipsrccls;
	__u32 ipmsgtag;
	__u32 ipbfadr2;
	__u32 ipbfln2f;
	__u32 res;
} iparml_db;

typedef struct {
	__u16 ippathid;
	__u8  ipflags1;
	__u8  iprcode;
	__u32 ipmsgid;
	__u8  ipaudit[3];
	__u8  res1[5];
	__u32 res2;
	__u32 ipsrccls;
	__u32 ipmsgtag;
	__u32 res3[3];
} iparml_purge;

typedef struct {
	__u8  ipmask;
	__u8  res1[2];
	__u8  iprcode;
	__u32 res2[9];
} iparml_set_mask;

typedef struct {
	union {
		iparml_control  p_ctrl;
		iparml_dpl      p_dpl;
		iparml_db       p_db;
		iparml_purge    p_purge;
		iparml_set_mask p_set_mask;
	} param;
	atomic_t in_use;
	__u32    res;
}  __attribute__ ((aligned(8))) iucv_param;
#define PARAM_POOL_SIZE (PAGE_SIZE / sizeof(iucv_param))

static iucv_param * iucv_param_pool;

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

/*
 * Debugging stuff
 *******************************************************************************/


#ifdef DEBUG
static int debuglevel = 0;

module_param(debuglevel, int, 0);
MODULE_PARM_DESC(debuglevel,
 "Specifies the debug level (0=off ... 3=all)");

static void
iucv_dumpit(char *title, void *buf, int len)
{
	int i;
	__u8 *p = (__u8 *)buf;

	if (debuglevel < 3)
		return;

	printk(KERN_DEBUG "%s\n", title);
	printk("  ");
	for (i = 0; i < len; i++) {
		if (!(i % 16) && i != 0)
			printk ("\n  ");
		else if (!(i % 4) && i != 0)
			printk(" ");
		printk("%02X", *p++);
	}
	if (len % 16)
		printk ("\n");
	return;
}
#define iucv_debug(lvl, fmt, args...) \
do { \
	if (debuglevel >= lvl) \
		printk(KERN_DEBUG "%s: " fmt "\n", __FUNCTION__ , ## args); \
} while (0)

#else

#define iucv_debug(lvl, fmt, args...)	do { } while (0)
#define iucv_dumpit(title, buf, len)	do { } while (0)

#endif

/*
 * Internal functions
 *******************************************************************************/

/**
 * print start banner
 */
static void
iucv_banner(void)
{
	printk(KERN_INFO "IUCV lowlevel driver initialized\n");
}

/**
 * iucv_init - Initialization
 *
 * Allocates and initializes various data structures.
 */
static int
iucv_init(void)
{
	int ret;

	if (iucv_external_int_buffer)
		return 0;

	if (!MACHINE_IS_VM) {
		printk(KERN_ERR "IUCV: IUCV connection needs VM as base\n");
		return -EPROTONOSUPPORT;
	}

	ret = bus_register(&iucv_bus);
	if (ret) {
		printk(KERN_ERR "IUCV: failed to register bus.\n");
		return ret;
	}

	iucv_root = s390_root_dev_register("iucv");
	if (IS_ERR(iucv_root)) {
		printk(KERN_ERR "IUCV: failed to register iucv root.\n");
		bus_unregister(&iucv_bus);
		return PTR_ERR(iucv_root);
	}

	/* Note: GFP_DMA used used to get memory below 2G */
	iucv_external_int_buffer = kzalloc(sizeof(iucv_GeneralInterrupt),
					   GFP_KERNEL|GFP_DMA);
	if (!iucv_external_int_buffer) {
		printk(KERN_WARNING
		       "%s: Could not allocate external interrupt buffer\n",
		       __FUNCTION__);
		s390_root_dev_unregister(iucv_root);
		bus_unregister(&iucv_bus);
		return -ENOMEM;
	}

	/* Initialize parameter pool */
	iucv_param_pool = kzalloc(sizeof(iucv_param) * PARAM_POOL_SIZE,
				  GFP_KERNEL|GFP_DMA);
	if (!iucv_param_pool) {
		printk(KERN_WARNING "%s: Could not allocate param pool\n",
		       __FUNCTION__);
		kfree(iucv_external_int_buffer);
		iucv_external_int_buffer = NULL;
		s390_root_dev_unregister(iucv_root);
		bus_unregister(&iucv_bus);
		return -ENOMEM;
	}

	/* Initialize irq queue */
	INIT_LIST_HEAD(&iucv_irq_queue);

	/* Initialize handler table */
	INIT_LIST_HEAD(&iucv_handler_table);

	iucv_banner();
	return 0;
}

/**
 * iucv_exit - De-Initialization
 *
 * Frees everything allocated from iucv_init.
 */
static int iucv_retrieve_buffer (void);

static void
iucv_exit(void)
{
	iucv_retrieve_buffer();
	kfree(iucv_external_int_buffer);
	iucv_external_int_buffer = NULL;
	kfree(iucv_param_pool);
	iucv_param_pool = NULL;
	s390_root_dev_unregister(iucv_root);
	bus_unregister(&iucv_bus);
	printk(KERN_INFO "IUCV lowlevel driver unloaded\n");
}

/**
 * grab_param: - Get a parameter buffer from the pre-allocated pool.
 *
 * This function searches for an unused element in the pre-allocated pool
 * of parameter buffers. If one is found, it marks it "in use" and returns
 * a pointer to it. The calling function is responsible for releasing it
 * when it has finished its usage.
 *
 * Returns: A pointer to iucv_param.
 */
static __inline__ iucv_param *
grab_param(void)
{
	iucv_param *ptr;
        static int hint = 0;

	ptr = iucv_param_pool + hint;
	do {
		ptr++;
		if (ptr >= iucv_param_pool + PARAM_POOL_SIZE)
			ptr = iucv_param_pool;
	} while (atomic_cmpxchg(&ptr->in_use, 0, 1) != 0);
	hint = ptr - iucv_param_pool;

	memset(&ptr->param, 0, sizeof(ptr->param));
	return ptr;
}

/**
 * release_param - Release a parameter buffer.
 * @p: A pointer to a struct iucv_param, previously obtained by calling
 *     grab_param().
 *
 * This function marks the specified parameter buffer "unused".
 */
static __inline__ void
release_param(void *p)
{
	atomic_set(&((iucv_param *)p)->in_use, 0);
}

/**
 * iucv_add_handler: - Add a new handler
 * @new_handler: handle that is being entered into chain.
 *
 * Places new handle on iucv_handler_table, if identical handler is not
 * found.
 *
 * Returns: 0 on success, !0 on failure (handler already in chain).
 */
static int
iucv_add_handler (handler *new)
{
	ulong flags;

	iucv_debug(1, "entering");
	iucv_dumpit("handler:", new, sizeof(handler));

	spin_lock_irqsave (&iucv_lock, flags);
	if (!list_empty(&iucv_handler_table)) {
		struct list_head *lh;

		/**
		 * Search list for handler with identical id. If one
		 * is found, the new handler is _not_ added.
		 */
		list_for_each(lh, &iucv_handler_table) {
			handler *h = list_entry(lh, handler, list);
			if (!memcmp(&new->id, &h->id, sizeof(h->id))) {
				iucv_debug(1, "ret 1");
				spin_unlock_irqrestore (&iucv_lock, flags);
				return 1;
			}
		}
	}
	/**
	 * If we get here, no handler was found.
	 */
	INIT_LIST_HEAD(&new->list);
	list_add(&new->list, &iucv_handler_table);
	spin_unlock_irqrestore (&iucv_lock, flags);

	iucv_debug(1, "exiting");
	return 0;
}

/**
 * b2f0:
 * @code: identifier of IUCV call to CP.
 * @parm: pointer to 40 byte iparml area passed to CP
 *
 * Calls CP to execute IUCV commands.
 *
 * Returns: return code from CP's IUCV call
 */
static inline ulong b2f0(__u32 code, void *parm)
{
	register unsigned long reg0 asm ("0");
	register unsigned long reg1 asm ("1");
	iucv_dumpit("iparml before b2f0 call:", parm, sizeof(iucv_param));

	reg0 = code;
	reg1 = virt_to_phys(parm);
	asm volatile(".long 0xb2f01000" : : "d" (reg0), "a" (reg1));

	iucv_dumpit("iparml after b2f0 call:", parm, sizeof(iucv_param));

	return (unsigned long)*((__u8 *)(parm + 3));
}

/*
 * Name: iucv_add_pathid
 * Purpose: Adds a path id to the system.
 * Input: pathid -  pathid that is going to be entered into system
 *        handle -  address of handler that the pathid will be associated
 *		   with.
 *        pgm_data - token passed in by application.
 * Output: 0: successful addition of pathid
 *	   - EINVAL - pathid entry is being used by another application
 *	   - ENOMEM - storage allocation for a new pathid table failed
*/
static int
__iucv_add_pathid(__u16 pathid, handler *handler)
{

	iucv_debug(1, "entering");

	iucv_debug(1, "handler is pointing to %p", handler);

	if (pathid > (max_connections - 1))
		return -EINVAL;

	if (iucv_pathid_table[pathid]) {
		iucv_debug(1, "pathid entry is %p", iucv_pathid_table[pathid]);
		printk(KERN_WARNING
		       "%s: Pathid being used, error.\n", __FUNCTION__);
		return -EINVAL;
	}
	iucv_pathid_table[pathid] = handler;

	iucv_debug(1, "exiting");
	return 0;
}				/* end of add_pathid function */

static int
iucv_add_pathid(__u16 pathid, handler *handler)
{
	ulong flags;
	int rc;

	spin_lock_irqsave (&iucv_lock, flags);
	rc = __iucv_add_pathid(pathid, handler);
	spin_unlock_irqrestore (&iucv_lock, flags);
	return rc;
}

static void
iucv_remove_pathid(__u16 pathid)
{
	ulong flags;

	if (pathid > (max_connections - 1))
		return;

	spin_lock_irqsave (&iucv_lock, flags);
	iucv_pathid_table[pathid] = NULL;
	spin_unlock_irqrestore (&iucv_lock, flags);
}

/**
 * iucv_declare_buffer_cpuid
 * Register at VM for subsequent IUCV operations. This is executed
 * on the reserved CPU iucv_cpuid. Called from iucv_declare_buffer().
 */
static void
iucv_declare_buffer_cpuid (void *result)
{
	iparml_db *parm;

	parm = (iparml_db *)grab_param();
	parm->ipbfadr1 = virt_to_phys(iucv_external_int_buffer);
	if ((*((ulong *)result) = b2f0(DECLARE_BUFFER, parm)) == 1)
		*((ulong *)result) = parm->iprcode;
	release_param(parm);
}

/**
 * iucv_retrieve_buffer_cpuid:
 * Unregister IUCV usage at VM. This is always executed on the same
 * cpu that registered the buffer to VM.
 * Called from iucv_retrieve_buffer().
 */
static void
iucv_retrieve_buffer_cpuid (void *cpu)
{
	iparml_control *parm;

	parm = (iparml_control *)grab_param();
	b2f0(RETRIEVE_BUFFER, parm);
	release_param(parm);
}

/**
 * Name: iucv_declare_buffer
 * Purpose: Specifies the guests real address of an external
 *          interrupt.
 * Input: void
 * Output: iprcode - return code from b2f0 call
 */
static int
iucv_declare_buffer (void)
{
	unsigned long flags;
	ulong b2f0_result;

	iucv_debug(1, "entering");
	b2f0_result = -ENODEV;
	spin_lock_irqsave (&iucv_lock, flags);
	if (iucv_cpuid == -1) {
		/* Reserve any cpu for use by iucv. */
		iucv_cpuid = smp_get_cpu(CPU_MASK_ALL);
		spin_unlock_irqrestore (&iucv_lock, flags);
		smp_call_function_on(iucv_declare_buffer_cpuid,
			&b2f0_result, 0, 1, iucv_cpuid);
		if (b2f0_result) {
			smp_put_cpu(iucv_cpuid);
			iucv_cpuid = -1;
		}
		iucv_debug(1, "Address of EIB = %p", iucv_external_int_buffer);
	} else {
		spin_unlock_irqrestore (&iucv_lock, flags);
		b2f0_result = 0;
	}
	iucv_debug(1, "exiting");
	return b2f0_result;
}

/**
 * iucv_retrieve_buffer:
 *
 * Terminates all use of IUCV.
 * Returns: return code from CP
 */
static int
iucv_retrieve_buffer (void)
{
	iucv_debug(1, "entering");
	if (iucv_cpuid != -1) {
		smp_call_function_on(iucv_retrieve_buffer_cpuid,
				     NULL, 0, 1, iucv_cpuid);
		/* Release the cpu reserved by iucv_declare_buffer. */
		smp_put_cpu(iucv_cpuid);
		iucv_cpuid = -1;
	}
	iucv_debug(1, "exiting");
	return 0;
}

/**
 * iucv_remove_handler:
 * @users_handler: handler to be removed
 *
 * Remove handler when application unregisters.
 */
static void
iucv_remove_handler(handler *handler)
{
	unsigned long flags;

	if ((!iucv_pathid_table) || (!handler))
		return;

	iucv_debug(1, "entering");

	spin_lock_irqsave (&iucv_lock, flags);
	list_del(&handler->list);
	if (list_empty(&iucv_handler_table)) {
		if (register_flag) {
			unregister_external_interrupt(0x4000, iucv_irq_handler);
			register_flag = 0;
		}
	}
	spin_unlock_irqrestore (&iucv_lock, flags);

	iucv_debug(1, "exiting");
	return;
}

/**
 * iucv_register_program:
 * @pgmname:  user identification
 * @userid:   machine identification
 * @pgmmask:  Indicates which bits in the pgmname and userid combined will be
 *            used to determine who is given control.
 * @ops:      Address of interrupt handler table.
 * @pgm_data: Application data to be passed to interrupt handlers.
 *
 * Registers an application with IUCV.
 * Returns:
 *           The address of handler, or NULL on failure.
 * NOTE on pgmmask:
 *   If pgmname, userid and pgmmask are provided, pgmmask is entered into the
 *   handler as is.
 *   If pgmmask is NULL, the internal mask is set to all 0xff's
 *   When userid is NULL, the first 8 bytes of the internal mask are forced
 *   to 0x00.
 *   If pgmmask and userid are NULL, the first 8 bytes of the internal mask
 *   are forced to 0x00 and the last 16 bytes to 0xff.
 */

iucv_handle_t
iucv_register_program (__u8 pgmname[16],
		       __u8 userid[8],
		       __u8 pgmmask[24],
		       iucv_interrupt_ops_t * ops, void *pgm_data)
{
	ulong rc = 0;		/* return code from function calls */
	handler *new_handler;

	iucv_debug(1, "entering");

	if (ops == NULL) {
		/* interrupt table is not defined */
		printk(KERN_WARNING "%s: Interrupt table is not defined, "
		       "exiting\n", __FUNCTION__);
		return NULL;
	}
	if (!pgmname) {
		printk(KERN_WARNING "%s: pgmname not provided\n", __FUNCTION__);
		return NULL;
	}

	/* Allocate handler entry */
	new_handler = (handler *)kmalloc(sizeof(handler), GFP_ATOMIC);
	if (new_handler == NULL) {
		printk(KERN_WARNING "%s: storage allocation for new handler "
		       "failed.\n", __FUNCTION__);
		return NULL;
	}

	if (!iucv_pathid_table) {
		if (iucv_init()) {
			kfree(new_handler);
			return NULL;
		}

		max_connections = iucv_query_maxconn();
		iucv_pathid_table = kcalloc(max_connections, sizeof(handler *),
					GFP_ATOMIC);
		if (iucv_pathid_table == NULL) {
			printk(KERN_WARNING "%s: iucv_pathid_table storage "
			       "allocation failed\n", __FUNCTION__);
			kfree(new_handler);
			return NULL;
		}
	}
	memset(new_handler, 0, sizeof (handler));
	memcpy(new_handler->id.user_data, pgmname,
		sizeof (new_handler->id.user_data));
	if (userid) {
		memcpy (new_handler->id.userid, userid,
			sizeof (new_handler->id.userid));
		ASCEBC (new_handler->id.userid,
			sizeof (new_handler->id.userid));
		EBC_TOUPPER (new_handler->id.userid,
			     sizeof (new_handler->id.userid));

		if (pgmmask) {
			memcpy (new_handler->id.mask, pgmmask,
				sizeof (new_handler->id.mask));
		} else {
			memset (new_handler->id.mask, 0xFF,
				sizeof (new_handler->id.mask));
		}
	} else {
		if (pgmmask) {
			memcpy (new_handler->id.mask, pgmmask,
				sizeof (new_handler->id.mask));
		} else {
			memset (new_handler->id.mask, 0xFF,
				sizeof (new_handler->id.mask));
		}
		memset (new_handler->id.userid, 0x00,
			sizeof (new_handler->id.userid));
	}
	/* fill in the rest of handler */
	new_handler->pgm_data = pgm_data;
	new_handler->interrupt_table = ops;

	/*
	 * Check if someone else is registered with same pgmname, userid
	 * and mask. If someone is already registered with same pgmname,
	 * userid and mask, registration will fail and NULL will be returned
	 * to the application.
	 * If identical handler not found, then handler is added to list.
	 */
	rc = iucv_add_handler(new_handler);
	if (rc) {
		printk(KERN_WARNING "%s: Someone already registered with same "
		       "pgmname, userid, pgmmask\n", __FUNCTION__);
		kfree (new_handler);
		return NULL;
	}

	rc = iucv_declare_buffer();
	if (rc) {
		char *err = "Unknown";
		iucv_remove_handler(new_handler);
		kfree(new_handler);
		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;
		}
		printk(KERN_WARNING "%s: iucv_declare_buffer "
		       "returned error 0x%02lx (%s)\n", __FUNCTION__, rc, err);
		return NULL;
	}
	if (!register_flag) {
		/* request the 0x4000 external interrupt */
		rc = register_external_interrupt (0x4000, iucv_irq_handler);
		if (rc) {
			iucv_remove_handler(new_handler);
			kfree (new_handler);
			printk(KERN_WARNING "%s: "
			       "register_external_interrupt returned %ld\n",
			       __FUNCTION__, rc);
			return NULL;

		}
		register_flag = 1;
	}
	iucv_debug(1, "exiting");
	return new_handler;
}				/* end of register function */

/**
 * iucv_unregister_program:
 * @handle: address of handler
 *
 * Unregister application with IUCV.
 * Returns:
 *   0 on success, -EINVAL, if specified handle is invalid.
 */

int
iucv_unregister_program (iucv_handle_t handle)
{
	handler *h = NULL;
	struct list_head *lh;
	int i;
	ulong flags;

	iucv_debug(1, "entering");
	iucv_debug(1, "address of handler is %p", h);

	/* Checking if handle is valid  */
	spin_lock_irqsave (&iucv_lock, flags);
	list_for_each(lh, &iucv_handler_table) {
		if ((handler *)handle == list_entry(lh, handler, list)) {
			h = (handler *)handle;
			break;
		}
	}
	if (!h) {
		spin_unlock_irqrestore (&iucv_lock, flags);
		if (handle)
			printk(KERN_WARNING
			       "%s: Handler not found in iucv_handler_table.\n",
			       __FUNCTION__);
		else
			printk(KERN_WARNING
			       "%s: NULL handle passed by application.\n",
			       __FUNCTION__);
		return -EINVAL;
	}

	/**
	 * First, walk thru iucv_pathid_table and sever any pathid which is
	 * still pointing to the handler to be removed.
	 */
	for (i = 0; i < max_connections; i++)
		if (iucv_pathid_table[i] == h) {
			spin_unlock_irqrestore (&iucv_lock, flags);
			iucv_sever(i, h->id.user_data);
			spin_lock_irqsave(&iucv_lock, flags);
		}
	spin_unlock_irqrestore (&iucv_lock, flags);

	iucv_remove_handler(h);
	kfree(h);

	iucv_debug(1, "exiting");
	return 0;
}

/**
 * iucv_accept:
 * @pathid:             Path identification number
 * @msglim_reqstd:      The number of outstanding messages requested.
 * @user_data:          Data specified by the iucv_connect function.
 * @flags1:             Contains options for this path.
 *     - IPPRTY (0x20)   Specifies if you want to send priority message.
 *     - IPRMDATA (0x80) Specifies whether your program can handle a message
 *                       in the parameter list.
 *     - IPQUSCE (0x40)  Specifies whether you want to quiesce the path being
 *		         established.
 * @handle:             Address of handler.
 * @pgm_data:           Application data passed to interrupt handlers.
 * @flags1_out:         Pointer to an int. If not NULL, on return the options for
 *                      the path are stored at the given location:
 *     - IPPRTY (0x20)  Indicates you may send a priority message.
 * @msglim:             Pointer to an __u16. If not NULL, on return the maximum
 *                      number of outstanding messages is stored at the given
 *                      location.
 *
 * This function is issued after the user receives a Connection Pending external
 * interrupt and now wishes to complete the IUCV communication path.
 * Returns:
 *   return code from CP
 */
int
iucv_accept(__u16 pathid, __u16 msglim_reqstd,
	     __u8 user_data[16], int flags1,
	     iucv_handle_t handle, void *pgm_data,
	     int *flags1_out, __u16 * msglim)
{
	ulong b2f0_result = 0;
	ulong flags;
	struct list_head *lh;
	handler *h = NULL;
	iparml_control *parm;

	iucv_debug(1, "entering");
	iucv_debug(1, "pathid = %d", pathid);

	/* Checking if handle is valid  */
	spin_lock_irqsave (&iucv_lock, flags);
	list_for_each(lh, &iucv_handler_table) {
		if ((handler *)handle == list_entry(lh, handler, list)) {
			h = (handler *)handle;
			break;
		}
	}
	spin_unlock_irqrestore (&iucv_lock, flags);

	if (!h) {
		if (handle)
			printk(KERN_WARNING
			       "%s: Handler not found in iucv_handler_table.\n",
			       __FUNCTION__);
		else
			printk(KERN_WARNING
			       "%s: NULL handle passed by application.\n",
			       __FUNCTION__);
		return -EINVAL;
	}

	parm = (iparml_control *)grab_param();

	parm->ippathid = pathid;
	parm->ipmsglim = msglim_reqstd;
	if (user_data)
		memcpy(parm->ipuser, user_data, sizeof(parm->ipuser));

	parm->ipflags1 = (__u8)flags1;
	b2f0_result = b2f0(ACCEPT, parm);

	if (!b2f0_result) {
		if (msglim)
			*msglim = parm->ipmsglim;
		if (pgm_data)
			h->pgm_data = pgm_data;
		if (flags1_out)
			*flags1_out = (parm->ipflags1 & IPPRTY) ? IPPRTY : 0;
	}
	release_param(parm);

	iucv_debug(1, "exiting");
	return b2f0_result;
}

/**
 * iucv_connect:
 * @pathid:        Path identification number
 * @msglim_reqstd: Number of outstanding messages requested
 * @user_data:     16-byte user data
 * @userid:        8-byte of user identification
 * @system_name:   8-byte identifying the system name
 * @flags1:        Specifies options for this path:
 *     - IPPRTY (0x20)   Specifies if you want to send priority message.
 *     - IPRMDATA (0x80) Specifies whether your program can handle a message
 *                       in  the parameter list.
 *     - IPQUSCE (0x40)  Specifies whether you want to quiesce the path being
 *                       established.
 *     - IPLOCAL (0x01)  Allows an application to force the partner to be on the
 *                       local system. If local is specified then target class
 *                       cannot be specified.
 * @flags1_out:    Pointer to an int. If not NULL, on return the options for
 *                 the path are stored at the given location:
 *     - IPPRTY (0x20)   Indicates you may send a priority message.
 * @msglim:        Pointer to an __u16. If not NULL, on return the maximum
 *                 number of outstanding messages is stored at the given
 *                 location.
 * @handle:        Address of handler.
 * @pgm_data:      Application data to be passed to interrupt handlers.
 *
 * 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: return code from CP, or one of the following
 *     - ENOMEM
 *     - return code from iucv_declare_buffer
 *     - EINVAL - invalid handle passed by application
 *     - EINVAL - pathid address is NULL
 *     - ENOMEM - pathid table storage allocation failed
 *     - return code from internal function add_pathid
 */
int
iucv_connect (__u16 *pathid, __u16 msglim_reqstd,
	      __u8 user_data[16], __u8 userid[8],
	      __u8 system_name[8], int flags1,
	      int *flags1_out, __u16 * msglim,
	      iucv_handle_t handle, void *pgm_data)
{
	iparml_control *parm;
	iparml_control local_parm;
	struct list_head *lh;
	ulong b2f0_result = 0;
	ulong flags;
	int add_pathid_result = 0;
	handler *h = NULL;
	__u8 no_memory[16] = "NO MEMORY";

	iucv_debug(1, "entering");

	/* Checking if handle is valid  */
	spin_lock_irqsave (&iucv_lock, flags);
	list_for_each(lh, &iucv_handler_table) {
		if ((handler *)handle == list_entry(lh, handler, list)) {
			h = (handler *)handle;
			break;
		}
	}
	spin_unlock_irqrestore (&iucv_lock, flags);

	if (!h) {
		if (handle)
			printk(KERN_WARNING
			       "%s: Handler not found in iucv_handler_table.\n",
			       __FUNCTION__);
		else
			printk(KERN_WARNING
			       "%s: NULL handle passed by application.\n",
			       __FUNCTION__);
		return -EINVAL;
	}

	if (pathid == NULL) {
		printk(KERN_WARNING "%s: NULL pathid pointer\n",
		       __FUNCTION__);
		return -EINVAL;
	}

	parm = (iparml_control *)grab_param();

	parm->ipmsglim = msglim_reqstd;

	if (user_data)
		memcpy(parm->ipuser, user_data, sizeof(parm->ipuser));

	if (userid) {
		memcpy(parm->ipvmid, userid, sizeof(parm->ipvmid));
		ASCEBC(parm->ipvmid, sizeof(parm->ipvmid));
		EBC_TOUPPER(parm->ipvmid, sizeof(parm->ipvmid));
	}

	if (system_name) {
		memcpy(parm->iptarget, system_name, sizeof(parm->iptarget));
		ASCEBC(parm->iptarget, sizeof(parm->iptarget));
		EBC_TOUPPER(parm->iptarget, sizeof(parm->iptarget));
	}

	/* In order to establish an IUCV connection, the procedure is:
         *
         * b2f0(CONNECT)
         * take the ippathid from the b2f0 call
         * register the handler to the ippathid
         *
         * Unfortunately, the ConnectionEstablished message gets sent after the
         * b2f0(CONNECT) call but before the register is handled.
         *
         * In order for this race condition to be eliminated, the IUCV Control
         * Interrupts must be disabled for the above procedure.
         *
         * David Kennedy <dkennedy@linuxcare.com>
         */

	/* Enable everything but IUCV Control messages */
	iucv_setmask(~(AllInterrupts));
	messagesDisabled = 1;

	spin_lock_irqsave (&iucv_lock, flags);
	parm->ipflags1 = (__u8)flags1;
	b2f0_result = b2f0(CONNECT, parm);
	memcpy(&local_parm, parm, sizeof(local_parm));
	release_param(parm);
	parm = &local_parm;
	if (!b2f0_result)
		add_pathid_result = __iucv_add_pathid(parm->ippathid, h);
	spin_unlock_irqrestore (&iucv_lock, flags);

	if (b2f0_result) {
		iucv_setmask(~0);
		messagesDisabled = 0;
		return b2f0_result;
	}

	*pathid = parm->ippathid;

	/* Enable everything again */
	iucv_setmask(IUCVControlInterruptsFlag);

	if (msglim)
		*msglim = parm->ipmsglim;
	if (flags1_out)
		*flags1_out = (parm->ipflags1 & IPPRTY) ? IPPRTY : 0;

	if (add_pathid_result) {
		iucv_sever(*pathid, no_memory);
		printk(KERN_WARNING "%s: add_pathid failed with rc ="
			" %d\n", __FUNCTION__, add_pathid_result);
		return(add_pathid_result);
	}

	iucv_debug(1, "exiting");
	return b2f0_result;
}

/**
 * iucv_purge:
 * @pathid: Path identification number
 * @msgid:  Message ID of message to purge.
 * @srccls: Message class of the message to purge.
 * @audit:  Pointer to an __u32. If not NULL, on return, information about
 *          asynchronous errors that may have affected the normal completion
 *          of this message ist stored at the given location.
 *
 * Cancels a message you have sent.
 * Returns: return code from CP
 */
int
iucv_purge (__u16 pathid, __u32 msgid, __u32 srccls, __u32 *audit)
{
	iparml_purge *parm;
	ulong b2f0_result = 0;

	iucv_debug(1, "entering");
	iucv_debug(1, "pathid = %d", pathid);

	parm = (iparml_purge *)grab_param();

	parm->ipmsgid = msgid;
	parm->ippathid = pathid;
	parm->ipsrccls = srccls;
	parm->ipflags1 |= (IPSRCCLS | IPFGMID | IPFGPID);
	b2f0_result = b2f0(PURGE, parm);

	if (!b2f0_result && audit) {
		memcpy(audit, parm->ipaudit, sizeof(parm->ipaudit));
		/* parm->ipaudit has only 3 bytes */
		*audit >>= 8;
	}

	release_param(parm);

	iucv_debug(1, "b2f0_result = %ld", b2f0_result);
	iucv_debug(1, "exiting");
	return b2f0_result;
}

/**
 * iucv_query_generic:
 * @want_maxconn: Flag, describing which value is to be returned.
 *
 * Helper function for iucv_query_maxconn() and iucv_query_bufsize().
 *
 * Returns: The buffersize, if want_maxconn is 0; the maximum number of
 *           connections, if want_maxconn is 1 or an error-code < 0 on failure.
 */
static int
iucv_query_generic(int want_maxconn)
{
	register unsigned long reg0 asm ("0");
	register unsigned long reg1 asm ("1");
	iparml_purge *parm = (iparml_purge *)grab_param();
	int bufsize, maxconn;
	int ccode;

	/**
	 * Call b2f0 and store R0 (max buffer size),
	 * R1 (max connections) and CC.
	 */
	reg0 = QUERY;
	reg1 = virt_to_phys(parm);
	asm volatile(
		"	.long	0xb2f01000\n"
		"	ipm	%0\n"
		"	srl	%0,28\n"
		: "=d" (ccode), "+d" (reg0), "+d" (reg1) : : "cc");
	bufsize = reg0;
	maxconn = reg1;
	release_param(parm);

	if (ccode)
		return -EPERM;
	if (want_maxconn)
		return maxconn;
	return bufsize;
}

/**
 * iucv_query_maxconn:
 *
 * Determines the maximum number of connections thay may be established.
 *
 * Returns: Maximum number of connections that can be.
 */
ulong
iucv_query_maxconn(void)
{
	return iucv_query_generic(1);
}

/**
 * iucv_query_bufsize:
 *
 * Determines the size of the external interrupt buffer.
 *
 * Returns: Size of external interrupt buffer.
 */
ulong
iucv_query_bufsize (void)
{
	return iucv_query_generic(0);
}

/**
 * iucv_quiesce:
 * @pathid:    Path identification number
 * @user_data: 16-byte user data
 *
 * Temporarily suspends incoming messages on an IUCV path.
 * You can later reactivate the path by invoking the iucv_resume function.
 * Returns: return code from CP
 */
int
iucv_quiesce (__u16 pathid, __u8 user_data[16])
{
	iparml_control *parm;
	ulong b2f0_result = 0;

	iucv_debug(1, "entering");
	iucv_debug(1, "pathid = %d", pathid);

	parm = (iparml_control *)grab_param();

	memcpy(parm->ipuser, user_data, sizeof(parm->ipuser));
	parm->ippathid = pathid;

	b2f0_result = b2f0(QUIESCE, parm);
	release_param(parm);

	iucv_debug(1, "b2f0_result = %ld", b2f0_result);
	iucv_debug(1, "exiting");

	return b2f0_result;
}

/**
 * iucv_receive:
 * @pathid: Path identification number.
 * @buffer: Address of buffer to receive. Must be below 2G.
 * @buflen: Length of buffer to receive.
 * @msgid:  Specifies the message ID.
 * @trgcls: Specifies target class.
 * @flags1_out: Receives options for path on return.
 *    - IPNORPY (0x10)  Specifies whether a reply is required
 *    - IPPRTY (0x20)   Specifies if you want to send priority message
 *    - IPRMDATA (0x80) Specifies the data is contained in the parameter list
 * @residual_buffer: Receives the address of buffer updated by the number
 *                   of bytes you have received on return.
 * @residual_length: On return, receives one of the following values:
 *    - 0                          If the receive buffer is the same length as
 *                                 the message.
 *    - Remaining bytes in buffer  If the receive buffer is longer than the
 *                                 message.
 *    - Remaining bytes in message If the receive buffer is shorter than the
 *                                 message.
 *
 * This function receives messages that are being sent to you over established
 * paths.
 * Returns: return code from CP IUCV call; If the receive buffer is shorter
 *   than the message, always 5
 *   -EINVAL - buffer address is pointing to NULL
 */
int
iucv_receive (__u16 pathid, __u32 msgid, __u32 trgcls,
	      void *buffer, ulong buflen,
	      int *flags1_out, ulong * residual_buffer, ulong * residual_length)
{
	iparml_db *parm;
	ulong b2f0_result;
	int moved = 0;	/* number of bytes moved from parmlist to buffer */

	iucv_debug(2, "entering");

	if (!buffer)
		return -EINVAL;

	parm = (iparml_db *)grab_param();

	parm->ipbfadr1 = (__u32) (addr_t) buffer;
	parm->ipbfln1f = (__u32) ((ulong) buflen);
	parm->ipmsgid = msgid;
	parm->ippathid = pathid;
	parm->iptrgcls = trgcls;
	parm->ipflags1 = (IPFGPID | IPFGMID | IPFGMCL);

	b2f0_result = b2f0(RECEIVE, parm);

	if (!b2f0_result || b2f0_result == 5) {
		if (flags1_out) {
			iucv_debug(2, "*flags1_out = %d", *flags1_out);
			*flags1_out = (parm->ipflags1 & (~0x07));
			iucv_debug(2, "*flags1_out = %d", *flags1_out);
		}

		if (!(parm->ipflags1 & IPRMDATA)) {	/*msg not in parmlist */
			if (residual_length)
				*residual_length = parm->ipbfln1f;

			if (residual_buffer)
				*residual_buffer = parm->ipbfadr1;
		} else {
			moved = min_t (unsigned long, buflen, 8);

			memcpy ((char *) buffer,
				(char *) &parm->ipbfadr1, moved);

			if (buflen < 8)
				b2f0_result = 5;

			if (residual_length)
				*residual_length = abs (buflen - 8);

			if (residual_buffer)
				*residual_buffer = (ulong) (buffer + moved);
		}
	}
	release_param(parm);

	iucv_debug(2, "exiting");
	return b2f0_result;
}

/*
 * Name: iucv_receive_array
 * Purpose: This function receives messages that are being sent to you
 *          over established paths.
 * Input: pathid - path identification number
 *        buffer - address of array of buffers
 *        buflen - total length of buffers
 *        msgid - specifies the message ID.
 *        trgcls - specifies target class
 * Output:
 *        flags1_out: Options for path.
 *          IPNORPY - 0x10 specifies whether a reply is required
 *          IPPRTY - 0x20 specifies if you want to send priority message
 *         IPRMDATA - 0x80 specifies the data is contained in the parameter list
 *       residual_buffer - address points to the current list entry IUCV
 *                         is working on.
 *       residual_length -
 *              Contains one of the following values, if the receive buffer is:
 *               The same length as the message, this field is zero.
 *               Longer than the message, this field contains the number of
 *                bytes remaining in the buffer.
 *               Shorter than the message, this field contains the residual
 *                count (that is, the number of bytes remaining in the
 *                message that does not fit into the buffer. In this case
 *		  b2f0_result = 5.
 * Return: b2f0_result - return code from CP
 *         (-EINVAL) - buffer address is NULL
 */
int
iucv_receive_array (__u16 pathid,
		    __u32 msgid, __u32 trgcls,
		    iucv_array_t * buffer, ulong buflen,
		    int *flags1_out,
		    ulong * residual_buffer, ulong * residual_length)
{
	iparml_db *parm;
	ulong b2f0_result;
	int i = 0, moved = 0, need_to_move = 8, dyn_len;

	iucv_debug(2, "entering");

	if (!buffer)
		return -EINVAL;

	parm = (iparml_db *)grab_param();

	parm->ipbfadr1 = (__u32) ((ulong) buffer);
	parm->ipbfln1f = (__u32) buflen;
	parm->ipmsgid = msgid;
	parm->ippathid = pathid;
	parm->iptrgcls = trgcls;
	parm->ipflags1 = (IPBUFLST | IPFGPID | IPFGMID | IPFGMCL);

	b2f0_result = b2f0(RECEIVE, parm);

	if (!b2f0_result || b2f0_result == 5) {

		if (flags1_out) {
			iucv_debug(2, "*flags1_out = %d", *flags1_out);
			*flags1_out = (parm->ipflags1 & (~0x07));
			iucv_debug(2, "*flags1_out = %d", *flags1_out);
		}

		if (!(parm->ipflags1 & IPRMDATA)) {	/*msg not in parmlist */

			if (residual_length)
				*residual_length = parm->ipbfln1f;

			if (residual_buffer)
				*residual_buffer = parm->ipbfadr1;

		} else {
			/* copy msg from parmlist to users array. */

			while ((moved < 8) && (moved < buflen)) {
				dyn_len =
				    min_t (unsigned int,
					 (buffer + i)->length, need_to_move);

				memcpy ((char *)((ulong)((buffer + i)->address)),
					((char *) &parm->ipbfadr1) + moved,
					dyn_len);

				moved += dyn_len;
				need_to_move -= dyn_len;

				(buffer + i)->address =
				    	(__u32)
				((ulong)(__u8 *) ((ulong)(buffer + i)->address)
						+ dyn_len);

				(buffer + i)->length -= dyn_len;
				i++;
			}

			if (need_to_move)	/* buflen < 8 bytes */
				b2f0_result = 5;

			if (residual_length)
				*residual_length = abs (buflen - 8);

			if (residual_buffer) {
				if (!moved)
					*residual_buffer = (ulong) buffer;
				else
					*residual_buffer =
					    (ulong) (buffer + (i - 1));
			}

		}
	}
	release_param(parm);

	iucv_debug(2, "exiting");
	return b2f0_result;
}

/**
 * iucv_reject:
 * @pathid: Path identification number.
 * @msgid:  Message ID of the message to reject.
 * @trgcls: Target class of the message to reject.
 * Returns: return code from CP
 *
 * 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.
 */
int
iucv_reject (__u16 pathid, __u32 msgid, __u32 trgcls)
{
	iparml_db *parm;
	ulong b2f0_result = 0;

	iucv_debug(1, "entering");
	iucv_debug(1, "pathid = %d", pathid);

	parm = (iparml_db *)grab_param();

	parm->ippathid = pathid;
	parm->ipmsgid = msgid;
	parm->iptrgcls = trgcls;
	parm->ipflags1 = (IPFGMCL | IPFGMID | IPFGPID);

	b2f0_result = b2f0(REJECT, parm);
	release_param(parm);

	iucv_debug(1, "b2f0_result = %ld", b2f0_result);
	iucv_debug(1, "exiting");

	return b2f0_result;
}

/*
 * Name: iucv_reply
 * Purpose: 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.
 * Input: pathid - path identification number
 *        msgid - specifies the message ID.
 *        trgcls - specifies target class
 *        flags1 - option for path
 *                 IPPRTY- 0x20 - specifies if you want to send priority message
 *        buffer - address of reply buffer
 *        buflen - length of reply buffer
 * Output: ipbfadr2 - Address of buffer updated by the number
 *                    of bytes you have moved.
 *         ipbfln2f - Contains one of the following values:
 *              If the answer buffer is the same length as the reply, this field
 *               contains zero.
 *              If the answer buffer is longer than the reply, this field contains
 *               the number of bytes remaining in the buffer.
 *              If the answer buffer is shorter than the reply, this field contains
 *               a residual count (that is, the number of bytes remianing in the
 *               reply that does not fit into the buffer. In this
 *                case b2f0_result = 5.
 * Return: b2f0_result - return code from CP
 *         (-EINVAL) - buffer address is NULL
 */
int
iucv_reply (__u16 pathid,
	    __u32 msgid, __u32 trgcls,
	    int flags1,
	    void *buffer, ulong buflen, ulong * ipbfadr2, ulong * ipbfln2f)
{
	iparml_db *parm;
	ulong b2f0_result;

	iucv_debug(2, "entering");

	if (!buffer)
		return -EINVAL;

	parm = (iparml_db *)grab_param();

	parm->ipbfadr2 = (__u32) ((ulong) buffer);
	parm->ipbfln2f = (__u32) buflen;	/* length of message */
	parm->ippathid = pathid;
	parm->ipmsgid = msgid;
	parm->iptrgcls = trgcls;
	parm->ipflags1 = (__u8) flags1;	/* priority message */

	b2f0_result = b2f0(REPLY, parm);

	if ((!b2f0_result) || (b2f0_result == 5)) {
		if (ipbfadr2)
			*ipbfadr2 = parm->ipbfadr2;
		if (ipbfln2f)
			*ipbfln2f = parm->ipbfln2f;
	}
	release_param(parm);

	iucv_debug(2, "exiting");

	return b2f0_result;
}

/*
 * Name: iucv_reply_array
 * Purpose: 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.
 *          The array identifies a list of addresses and lengths of
 *          discontiguous buffers that contains the reply data.
 * Input: pathid - path identification number
 *        msgid - specifies the message ID.
 *        trgcls - specifies target class
 *        flags1 - option for path
 *                 IPPRTY- specifies if you want to send priority message
 *        buffer - address of array of reply buffers
 *        buflen - total length of reply buffers
 * Output: ipbfadr2 - Address of buffer which IUCV is currently working on.
 *         ipbfln2f - Contains one of the following values:
 *              If the answer buffer is the same length as the reply, this field
 *               contains zero.
 *              If the answer buffer is longer than the reply, this field contains
 *               the number of bytes remaining in the buffer.
 *              If the answer buffer is shorter than the reply, this field contains
 *               a residual count (that is, the number of bytes remianing in the
 *               reply that does not fit into the buffer. In this
 *               case b2f0_result = 5.
 * Return: b2f0_result - return code from CP
 *             (-EINVAL) - buffer address is NULL
*/
int
iucv_reply_array (__u16 pathid,
		  __u32 msgid, __u32 trgcls,
		  int flags1,
		  iucv_array_t * buffer,
		  ulong buflen, ulong * ipbfadr2, ulong * ipbfln2f)
{
	iparml_db *parm;
	ulong b2f0_result;

	iucv_debug(2, "entering");

	if (!buffer)
		return -EINVAL;

	parm = (iparml_db *)grab_param();

	parm->ipbfadr2 = (__u32) ((ulong) buffer);
	parm->ipbfln2f = buflen;	/* length of message */
	parm->ippathid = pathid;
	parm->ipmsgid = msgid;
	parm->iptrgcls = trgcls;
	parm->ipflags1 = (IPANSLST | flags1);

	b2f0_result = b2f0(REPLY, parm);

	if ((!b2f0_result) || (b2f0_result == 5)) {

		if (ipbfadr2)
			*ipbfadr2 = parm->ipbfadr2;
		if (ipbfln2f)
			*ipbfln2f = parm->ipbfln2f;
	}
	release_param(parm);

	iucv_debug(2, "exiting");

	return b2f0_result;
}

/*
 * Name: iucv_reply_prmmsg
 * Purpose: 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.
 * Input: pathid - path identification number
 *        msgid - specifies the message ID.
 *        trgcls - specifies target class
 *        flags1 - option for path
 *                 IPPRTY- specifies if you want to send priority message
 *        prmmsg - 8-bytes of data to be placed into the parameter
 *                 list.
 * Output: NA
 * Return: b2f0_result - return code from CP
*/
int
iucv_reply_prmmsg (__u16 pathid,
		   __u32 msgid, __u32 trgcls, int flags1, __u8 prmmsg[8])
{
	iparml_dpl *parm;
	ulong b2f0_result;

	iucv_debug(2, "entering");

	parm = (iparml_dpl *)grab_param();

	parm->ippathid = pathid;
	parm->ipmsgid = msgid;
	parm->iptrgcls = trgcls;
	memcpy(parm->iprmmsg, prmmsg, sizeof (parm->iprmmsg));
	parm->ipflags1 = (IPRMDATA | flags1);

	b2f0_result = b2f0(REPLY, parm);
	release_param(parm);

	iucv_debug(2, "exiting");

	return b2f0_result;
}

/**
 * iucv_resume:
 * @pathid:    Path identification number
 * @user_data: 16-byte of user data
 *
 * This function restores communication over a quiesced path.
 * Returns: return code from CP
 */
int
iucv_resume (__u16 pathid, __u8 user_data[16])
{
	iparml_control *parm;
	ulong b2f0_result = 0;

	iucv_debug(1, "entering");
	iucv_debug(1, "pathid = %d", pathid);

	parm = (iparml_control *)grab_param();

	memcpy (parm->ipuser, user_data, sizeof (*user_data));
	parm->ippathid = pathid;

	b2f0_result = b2f0(RESUME, parm);
	release_param(parm);

	iucv_debug(1, "exiting");

	return b2f0_result;
}

/*
 * Name: iucv_send
 * Purpose: sends messages
 * Input: pathid - ushort, pathid
 *        msgid  - ulong *, id of message returned to caller
 *        trgcls - ulong, target message class
 *        srccls - ulong, source message class
 *        msgtag - ulong, message tag
 *	  flags1  - Contains options for this path.
 *		IPPRTY - Ox20 - specifies if you want to send a priority message.
 *        buffer - pointer to buffer
 *        buflen - ulong, length of buffer
 * Output: b2f0_result - return code from b2f0 call
 *         msgid - returns message id
 */
int
iucv_send (__u16 pathid, __u32 * msgid,
	   __u32 trgcls, __u32 srccls,
	   __u32 msgtag, int flags1, void *buffer, ulong buflen)
{
	iparml_db *parm;
	ulong b2f0_result;

	iucv_debug(2, "entering");

	if (!buffer)
		return -EINVAL;

	parm = (iparml_db *)grab_param();

	parm->ipbfadr1 = (__u32) ((ulong) buffer);
	parm->ippathid = pathid;
	parm->iptrgcls = trgcls;
	parm->ipbfln1f = (__u32) buflen;	/* length of message */
	parm->ipsrccls = srccls;
	parm->ipmsgtag = msgtag;
	parm->ipflags1 = (IPNORPY | flags1);	/* one way priority message */

	b2f0_result = b2f0(SEND, parm);

	if ((!b2f0_result) && (msgid))
		*msgid = parm->ipmsgid;
	release_param(parm);

	iucv_debug(2, "exiting");

	return b2f0_result;
}

/*
 * Name: iucv_send_array
 * Purpose: This function transmits data to another application.
 *          The contents of buffer is the address of the array of
 *          addresses and lengths of discontiguous buffers that hold
 *          the message text. This is a one-way message and the
 *          receiver will not reply to the message.
 * Input: pathid - path identification number
 *        trgcls - specifies target class
 *        srccls - specifies the source message class
 *        msgtag - specifies a tag to be associated witht the message
 *        flags1 - option for path
 *                 IPPRTY- specifies if you want to send priority message
 *        buffer - address of array of send buffers
 *        buflen - total length of send buffers
 * Output: msgid - specifies the message ID.
 * Return: b2f0_result - return code from CP
 *         (-EINVAL) - buffer address is NULL
 */
int
iucv_send_array (__u16 pathid,
		 __u32 * msgid,
		 __u32 trgcls,
		 __u32 srccls,
		 __u32 msgtag, int flags1, iucv_array_t * buffer, ulong buflen)
{
	iparml_db *parm;
	ulong b2f0_result;

	iucv_debug(2, "entering");

	if (!buffer)
		return -EINVAL;

	parm = (iparml_db *)grab_param();

	parm->ippathid = pathid;
	parm->iptrgcls = trgcls;
	parm->ipbfadr1 = (__u32) ((ulong) buffer);
	parm->ipbfln1f = (__u32) buflen;	/* length of message */
	parm->ipsrccls = srccls;
	parm->ipmsgtag = msgtag;
	parm->ipflags1 = (IPNORPY | IPBUFLST | flags1);
	b2f0_result = b2f0(SEND, parm);

	if ((!b2f0_result) && (msgid))
		*msgid = parm->ipmsgid;
	release_param(parm);

	iucv_debug(2, "exiting");
	return b2f0_result;
}

/*
 * Name: iucv_send_prmmsg
 * Purpose: This function transmits data to another application.
 *          Prmmsg specifies that the 8-bytes of data are to be moved
 *          into the parameter list. This is a one-way message and the
 *          receiver will not reply to the message.
 * Input: pathid - path identification number
 *        trgcls - specifies target class
 *        srccls - specifies the source message class
 *        msgtag - specifies a tag to be associated with the message
 *        flags1 - option for path
 *                 IPPRTY- specifies if you want to send priority message
 *        prmmsg - 8-bytes of data to be placed into parameter list
 * Output: msgid - specifies the message ID.
 * Return: b2f0_result - return code from CP
*/
int
iucv_send_prmmsg (__u16 pathid,
		  __u32 * msgid,
		  __u32 trgcls,
		  __u32 srccls, __u32 msgtag, int flags1, __u8 prmmsg[8])
{
	iparml_dpl *parm;
	ulong b2f0_result;

	iucv_debug(2, "entering");

	parm = (iparml_dpl *)grab_param();

	parm->ippathid = pathid;
	parm->iptrgcls = trgcls;
	parm->ipsrccls = srccls;
	parm->ipmsgtag = msgtag;
	parm->ipflags1 = (IPRMDATA | IPNORPY | flags1);
	memcpy(parm->iprmmsg, prmmsg, sizeof(parm->iprmmsg));

	b2f0_result = b2f0(SEND, parm);

	if ((!b2f0_result) && (msgid))
		*msgid = parm->ipmsgid;
	release_param(parm);

	iucv_debug(2, "exiting");

	return b2f0_result;
}

/*
 * Name: iucv_send2way
 * Purpose: 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.
 * Input: pathid - path identification number
 *        trgcls - specifies target class
 *        srccls - specifies the source message class
 *        msgtag - specifies a tag associated with the message
 *        flags1 - option for path
 *                 IPPRTY- specifies if you want to send priority message
 *        buffer - address of send buffer
 *        buflen - length of send buffer
 *        ansbuf - address of buffer to reply with
 *        anslen - length of buffer to reply with
 * Output: msgid - specifies the message ID.
 * Return: b2f0_result - return code from CP
 *         (-EINVAL) - buffer or ansbuf address is NULL
 */
int
iucv_send2way (__u16 pathid,
	       __u32 * msgid,
	       __u32 trgcls,
	       __u32 srccls,
	       __u32 msgtag,
	       int flags1,
	       void *buffer, ulong buflen, void *ansbuf, ulong anslen)
{
	iparml_db *parm;
	ulong b2f0_result;

	iucv_debug(2, "entering");

	if (!buffer || !ansbuf)
		return -EINVAL;

	parm = (iparml_db *)grab_param();

	parm->ippathid = pathid;
	parm->iptrgcls = trgcls;
	parm->ipbfadr1 = (__u32) ((ulong) buffer);
	parm->ipbfln1f = (__u32) buflen;	/* length of message */
	parm->ipbfadr2 = (__u32) ((ulong) ansbuf);
	parm->ipbfln2f = (__u32) anslen;
	parm->ipsrccls = srccls;
	parm->ipmsgtag = msgtag;
	parm->ipflags1 = flags1;	/* priority message */

	b2f0_result = b2f0(SEND, parm);

	if ((!b2f0_result) && (msgid))
		*msgid = parm->ipmsgid;
	release_param(parm);

	iucv_debug(2, "exiting");

	return b2f0_result;
}

/*
 * Name: iucv_send2way_array
 * Purpose: This function transmits data to another application.
 *          The contents of buffer is the address of the array of
 *          addresses and lengths of discontiguous buffers that hold
 *          the message text. 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.
 * Input: pathid - path identification number
 *        trgcls - specifies target class
 *        srccls - specifies the source message class
 *        msgtag - spcifies a tag to be associated with the message
 *        flags1 - option for path
 *                 IPPRTY- specifies if you want to send priority message
 *        buffer - address of array of send buffers
 *        buflen - total length of send buffers
 *        ansbuf - address of buffer to reply with
 *        anslen - length of buffer to reply with
 * Output: msgid - specifies the message ID.
 * Return: b2f0_result - return code from CP
 *         (-EINVAL) - buffer address is NULL
 */
int
iucv_send2way_array (__u16 pathid,
		     __u32 * msgid,
		     __u32 trgcls,
		     __u32 srccls,
		     __u32 msgtag,
		     int flags1,
		     iucv_array_t * buffer,
		     ulong buflen, iucv_array_t * ansbuf, ulong anslen)
{
	iparml_db *parm;
	ulong b2f0_result;

	iucv_debug(2, "entering");

	if (!buffer || !ansbuf)
		return -EINVAL;

	parm = (iparml_db *)grab_param();

	parm->ippathid = pathid;
	parm->iptrgcls = trgcls;
	parm->ipbfadr1 = (__u32) ((ulong) buffer);
	parm->ipbfln1f = (__u32) buflen;	/* length of message */
	parm->ipbfadr2 = (__u32) ((ulong) ansbuf);
	parm->ipbfln2f = (__u32) anslen;
	parm->ipsrccls = srccls;
	parm->ipmsgtag = msgtag;
	parm->ipflags1 = (IPBUFLST | IPANSLST | flags1);
	b2f0_result = b2f0(SEND, parm);
	if ((!b2f0_result) && (msgid))
		*msgid = parm->ipmsgid;
	release_param(parm);

	iucv_debug(2, "exiting");
	return b2f0_result;
}

/*
 * Name: iucv_send2way_prmmsg
 * Purpose: This function transmits data to another application.
 *          Prmmsg specifies that the 8-bytes of data are to be moved
 *          into the parameter list. This is a two-way message and the
 *          receiver of the message is expected to reply. A buffer
 *          is provided into which IUCV moves the reply to this
 *          message.
 * Input: pathid - path identification number
 *        trgcls - specifies target class
 *        srccls - specifies the source message class
 *        msgtag - specifies a tag to be associated with the message
 *        flags1 - option for path
 *                 IPPRTY- specifies if you want to send priority message
 *        prmmsg - 8-bytes of data to be placed in parameter list
 *        ansbuf - address of buffer to reply with
 *        anslen - length of buffer to reply with
 * Output: msgid - specifies the message ID.
 * Return: b2f0_result - return code from CP
 *         (-EINVAL) - buffer address is NULL
*/
int
iucv_send2way_prmmsg (__u16 pathid,
		      __u32 * msgid,
		      __u32 trgcls,
		      __u32 srccls,
		      __u32 msgtag,
		      ulong flags1, __u8 prmmsg[8], void *ansbuf, ulong anslen)
{
	iparml_dpl *parm;
	ulong b2f0_result;

	iucv_debug(2, "entering");

	if (!ansbuf)
		return -EINVAL;

	parm = (iparml_dpl *)grab_param();

	parm->ippathid = pathid;
	parm->iptrgcls = trgcls;
	parm->ipsrccls = srccls;
	parm->ipmsgtag = msgtag;
	parm->ipbfadr2 = (__u32) ((ulong) ansbuf);
	parm->ipbfln2f = (__u32) anslen;
	parm->ipflags1 = (IPRMDATA | flags1);	/* message in prmlist */
	memcpy(parm->iprmmsg, prmmsg, sizeof(parm->iprmmsg));

	b2f0_result = b2f0(SEND, parm);

	if ((!b2f0_result) && (msgid))
		*msgid = parm->ipmsgid;
	release_param(parm);

	iucv_debug(2, "exiting");

	return b2f0_result;
}

/*
 * Name: iucv_send2way_prmmsg_array
 * Purpose: This function transmits data to another application.
 *          Prmmsg specifies that the 8-bytes of data are to be moved
 *          into the parameter list. This is a two-way message and the
 *          receiver of the message is expected to reply. A buffer
 *          is provided into which IUCV moves the reply to this
 *          message. The contents of ansbuf is the address of the
 *          array of addresses and lengths of discontiguous buffers
 *          that contain the reply.
 * Input: pathid - path identification number
 *        trgcls - specifies target class
 *        srccls - specifies the source message class
 *        msgtag - specifies a tag to be associated with the message
 *        flags1 - option for path
 *                 IPPRTY- specifies if you want to send priority message
 *        prmmsg - 8-bytes of data to be placed into the parameter list
 *        ansbuf - address of buffer to reply with
 *        anslen - length of buffer to reply with
 * Output: msgid - specifies the message ID.
 * Return: b2f0_result - return code from CP
 *         (-EINVAL) - ansbuf address is NULL
 */
int
iucv_send2way_prmmsg_array (__u16 pathid,
			    __u32 * msgid,
			    __u32 trgcls,
			    __u32 srccls,
			    __u32 msgtag,
			    int flags1,
			    __u8 prmmsg[8],
			    iucv_array_t * ansbuf, ulong anslen)
{
	iparml_dpl *parm;
	ulong b2f0_result;

	iucv_debug(2, "entering");

	if (!ansbuf)
		return -EINVAL;

	parm = (iparml_dpl *)grab_param();

	parm->ippathid = pathid;
	parm->iptrgcls = trgcls;
	parm->ipsrccls = srccls;
	parm->ipmsgtag = msgtag;
	parm->ipbfadr2 = (__u32) ((ulong) ansbuf);
	parm->ipbfln2f = (__u32) anslen;
	parm->ipflags1 = (IPRMDATA | IPANSLST | flags1);
	memcpy(parm->iprmmsg, prmmsg, sizeof(parm->iprmmsg));
	b2f0_result = b2f0(SEND, parm);
	if ((!b2f0_result) && (msgid))
		*msgid = parm->ipmsgid;
	release_param(parm);

	iucv_debug(2, "exiting");
	return b2f0_result;
}

void
iucv_setmask_cpuid (void *result)
{
        iparml_set_mask *parm;

        iucv_debug(1, "entering");
        parm = (iparml_set_mask *)grab_param();
        parm->ipmask = *((__u8*)result);
        *((ulong *)result) = b2f0(SETMASK, parm);
        release_param(parm);

        iucv_debug(1, "b2f0_result = %ld", *((ulong *)result));
        iucv_debug(1, "exiting");
}

/*
 * Name: iucv_setmask
 * Purpose: This function enables or disables the following IUCV
 *          external interruptions: Nonpriority and priority message
 *          interrupts, nonpriority and priority reply interrupts.
 * Input: SetMaskFlag - options for interrupts
 *           0x80 - Nonpriority_MessagePendingInterruptsFlag
 *           0x40 - Priority_MessagePendingInterruptsFlag
 *           0x20 - Nonpriority_MessageCompletionInterruptsFlag
 *           0x10 - Priority_MessageCompletionInterruptsFlag
 *           0x08 - IUCVControlInterruptsFlag
 * Output: NA
 * Return: b2f0_result - return code from CP
*/
int
iucv_setmask (int SetMaskFlag)
{
	union {
		ulong result;
		__u8  param;
	} u;
	int cpu;

	u.param = SetMaskFlag;
	cpu = get_cpu();
	smp_call_function_on(iucv_setmask_cpuid, &u, 0, 1, iucv_cpuid);
	put_cpu();

	return u.result;
}

/**
 * iucv_sever:
 * @pathid:    Path identification number
 * @user_data: 16-byte of user data
 *
 * This function terminates an iucv path.
 * Returns: return code from CP
 */
int
iucv_sever(__u16 pathid, __u8 user_data[16])
{
	iparml_control *parm;
	ulong b2f0_result = 0;

	iucv_debug(1, "entering");
	parm = (iparml_control *)grab_param();

	memcpy(parm->ipuser, user_data, sizeof(parm->ipuser));
	parm->ippathid = pathid;

	b2f0_result = b2f0(SEVER, parm);

	if (!b2f0_result)
		iucv_remove_pathid(pathid);
	release_param(parm);

	iucv_debug(1, "exiting");
	return b2f0_result;
}

/*
 * Interrupt Handlers
 *******************************************************************************/

/**
 * iucv_irq_handler:
 * @regs: Current registers
 * @code: irq code
 *
 * Handles external interrupts coming in from CP.
 * Places the interrupt buffer on a queue and schedules iucv_tasklet_handler().
 */
static void
iucv_irq_handler(__u16 code)
{
	iucv_irqdata *irqdata;

	irqdata = kmalloc(sizeof(iucv_irqdata), GFP_ATOMIC);
	if (!irqdata) {
		printk(KERN_WARNING "%s: out of memory\n", __FUNCTION__);
		return;
	}

	memcpy(&irqdata->data, iucv_external_int_buffer,
	       sizeof(iucv_GeneralInterrupt));

	spin_lock(&iucv_irq_queue_lock);
	list_add_tail(&irqdata->queue, &iucv_irq_queue);
	spin_unlock(&iucv_irq_queue_lock);

	tasklet_schedule(&iucv_tasklet);
}

/**
 * iucv_do_int:
 * @int_buf: Pointer to copy of external interrupt buffer
 *
 * The workhorse for handling interrupts queued by iucv_irq_handler().
 * This function is called from the bottom half iucv_tasklet_handler().
 */
static void
iucv_do_int(iucv_GeneralInterrupt * int_buf)
{
	handler *h = NULL;
	struct list_head *lh;
	ulong flags;
	iucv_interrupt_ops_t *interrupt = NULL;	/* interrupt addresses */
	__u8 temp_buff1[24], temp_buff2[24];	/* masked handler id. */
	int rc = 0, j = 0;
	__u8 no_listener[16] = "NO LISTENER";

	iucv_debug(2, "entering, pathid %d, type %02X",
		 int_buf->ippathid, int_buf->iptype);
	iucv_dumpit("External Interrupt Buffer:",
		    int_buf, sizeof(iucv_GeneralInterrupt));

	ASCEBC (no_listener, 16);

	if (int_buf->iptype != 01) {
		if ((int_buf->ippathid) > (max_connections - 1)) {
			printk(KERN_WARNING "%s: Got interrupt with pathid %d"
			       " > max_connections (%ld)\n", __FUNCTION__,
			       int_buf->ippathid, max_connections - 1);
		} else {
			h = iucv_pathid_table[int_buf->ippathid];
			interrupt = h->interrupt_table;
			iucv_dumpit("Handler:", h, sizeof(handler));
		}
	}

	/* end of if statement */
	switch (int_buf->iptype) {
		case 0x01:		/* connection pending */
			if (messagesDisabled) {
			    iucv_setmask(~0);
			    messagesDisabled = 0;
			}
			spin_lock_irqsave(&iucv_lock, flags);
			list_for_each(lh, &iucv_handler_table) {
				h = list_entry(lh, handler, list);
				memcpy(temp_buff1, &(int_buf->ipvmid), 24);
				memcpy(temp_buff2, &(h->id.userid), 24);
				for (j = 0; j < 24; j++) {
					temp_buff1[j] &= (h->id.mask)[j];
					temp_buff2[j] &= (h->id.mask)[j];
				}

				iucv_dumpit("temp_buff1:",
					    temp_buff1, sizeof(temp_buff1));
				iucv_dumpit("temp_buff2",
					    temp_buff2, sizeof(temp_buff2));

				if (!memcmp (temp_buff1, temp_buff2, 24)) {

					iucv_debug(2,
						   "found a matching handler");
					break;
				} else
					h = NULL;
			}
			spin_unlock_irqrestore (&iucv_lock, flags);
			if (h) {
				/* ADD PATH TO PATHID TABLE */
				rc = iucv_add_pathid(int_buf->ippathid, h);
				if (rc) {
					iucv_sever (int_buf->ippathid,
						    no_listener);
					iucv_debug(1,
						   "add_pathid failed, rc = %d",
						   rc);
				} else {
					interrupt = h->interrupt_table;
					if (interrupt->ConnectionPending) {
						EBCASC (int_buf->ipvmid, 8);
						interrupt->ConnectionPending(
							(iucv_ConnectionPending *)int_buf,
							h->pgm_data);
					} else
						iucv_sever(int_buf->ippathid,
							   no_listener);
				}
			} else
				iucv_sever(int_buf->ippathid, no_listener);
			break;

		case 0x02:		/*connection complete */
			if (messagesDisabled) {
			    iucv_setmask(~0);
			    messagesDisabled = 0;
			}
			if (h) {
				if (interrupt->ConnectionComplete)
				{
					interrupt->ConnectionComplete(
						(iucv_ConnectionComplete *)int_buf,
						h->pgm_data);
				}
				else
					iucv_debug(1,
						   "ConnectionComplete not called");
			} else
				iucv_sever(int_buf->ippathid, no_listener);
			break;

		case 0x03:		/* connection severed */
			if (messagesDisabled) {
			    iucv_setmask(~0);
			    messagesDisabled = 0;
			}
			if (h) {
				if (interrupt->ConnectionSevered)
					interrupt->ConnectionSevered(
						(iucv_ConnectionSevered *)int_buf,
						h->pgm_data);

				else
					iucv_sever (int_buf->ippathid, no_listener);
			} else
				iucv_sever(int_buf->ippathid, no_listener);
			break;

		case 0x04:		/* connection quiesced */
			if (messagesDisabled) {
			    iucv_setmask(~0);
			    messagesDisabled = 0;
			}
			if (h) {
				if (interrupt->ConnectionQuiesced)
					interrupt->ConnectionQuiesced(
						(iucv_ConnectionQuiesced *)int_buf,
						h->pgm_data);
				else
					iucv_debug(1,
						   "ConnectionQuiesced not called");
			}
			break;

		case 0x05:		/* connection resumed */
			if (messagesDisabled) {
			    iucv_setmask(~0);
			    messagesDisabled = 0;
			}
			if (h) {
				if (interrupt->ConnectionResumed)
					interrupt->ConnectionResumed(
						(iucv_ConnectionResumed *)int_buf,
						h->pgm_data);
				else
					iucv_debug(1,
						   "ConnectionResumed not called");
			}
			break;

		case 0x06:		/* priority message complete */
		case 0x07:		/* nonpriority message complete */
			if (h) {
				if (interrupt->MessageComplete)
					interrupt->MessageComplete(
						(iucv_MessageComplete *)int_buf,
						h->pgm_data);
				else
					iucv_debug(2,
						   "MessageComplete not called");
			}
			break;

		case 0x08:		/* priority message pending  */
		case 0x09:		/* nonpriority message pending  */
			if (h) {
				if (interrupt->MessagePending)
					interrupt->MessagePending(
						(iucv_MessagePending *) int_buf,
						h->pgm_data);
				else
					iucv_debug(2,
						   "MessagePending not called");
			}
			break;
		default:		/* unknown iucv type */
			printk(KERN_WARNING "%s: unknown iucv interrupt\n",
			       __FUNCTION__);
			break;
	}			/* end switch */

	iucv_debug(2, "exiting pathid %d, type %02X",
		 int_buf->ippathid, int_buf->iptype);

	return;
}

/**
 * iucv_tasklet_handler:
 *
 * This function loops over the queue of irq buffers and runs iucv_do_int()
 * on every queue element.
 */
static void
iucv_tasklet_handler(unsigned long ignored)
{
	struct list_head head;
	struct list_head *next;
	ulong  flags;

	spin_lock_irqsave(&iucv_irq_queue_lock, flags);
	list_add(&head, &iucv_irq_queue);
	list_del_init(&iucv_irq_queue);
	spin_unlock_irqrestore (&iucv_irq_queue_lock, flags);

	next = head.next;
	while (next != &head) {
		iucv_irqdata *p = list_entry(next, iucv_irqdata, queue);

		next = next->next;
		iucv_do_int(&p->data);
		kfree(p);
	}

	return;
}

subsys_initcall(iucv_init);
module_exit(iucv_exit);

/**
 * Export all public stuff
 */
EXPORT_SYMBOL (iucv_bus);
EXPORT_SYMBOL (iucv_root);
EXPORT_SYMBOL (iucv_accept);
EXPORT_SYMBOL (iucv_connect);
#if 0
EXPORT_SYMBOL (iucv_purge);
EXPORT_SYMBOL (iucv_query_maxconn);
EXPORT_SYMBOL (iucv_query_bufsize);
EXPORT_SYMBOL (iucv_quiesce);
#endif
EXPORT_SYMBOL (iucv_receive);
#if 0
EXPORT_SYMBOL (iucv_receive_array);
#endif
EXPORT_SYMBOL (iucv_reject);
#if 0
EXPORT_SYMBOL (iucv_reply);
EXPORT_SYMBOL (iucv_reply_array);
EXPORT_SYMBOL (iucv_resume);
#endif
EXPORT_SYMBOL (iucv_reply_prmmsg);
EXPORT_SYMBOL (iucv_send);
EXPORT_SYMBOL (iucv_send2way);
EXPORT_SYMBOL (iucv_send2way_array);
EXPORT_SYMBOL (iucv_send2way_prmmsg);
EXPORT_SYMBOL (iucv_send2way_prmmsg_array);
#if 0
EXPORT_SYMBOL (iucv_send_array);
EXPORT_SYMBOL (iucv_send_prmmsg);
EXPORT_SYMBOL (iucv_setmask);
#endif
EXPORT_SYMBOL (iucv_sever);
EXPORT_SYMBOL (iucv_register_program);
EXPORT_SYMBOL (iucv_unregister_program);
