/*
 * 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(struct pt_regs *, __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)
{
	iucv_dumpit("iparml before b2f0 call:", parm, sizeof(iucv_param));

	asm volatile (
		"LRA   1,0(%1)\n\t"
		"LR    0,%0\n\t"
		".long 0xb2f01000"
		:
		: "d" (code), "a" (parm)
		: "0", "1"
		);

	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)
{
	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.
	 */
	asm volatile (
		"LRA   1,0(%4)\n\t"
		"LR    0,%3\n\t"
		".long 0xb2f01000\n\t"
		"IPM   %0\n\t"
		"SRL   %0,28\n\t"
		"ST    0,%1\n\t"
		"ST    1,%2\n\t"
		: "=d" (ccode), "=m" (bufsize), "=m" (maxconn)
		: "d" (QUERY), "a" (parm)
		: "0", "1", "cc"
		);
	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(struct pt_regs *regs, __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);
