/*-
 * Linux port done by David McCullough <david_mccullough@mcafee.com>
 * Copyright (C) 2006-2010 David McCullough
 * Copyright (C) 2004-2005 Intel Corporation.
 * The license and original author are listed below.
 *
 * Redistribution and use in source and binary forms, with or without
 * Copyright (c) 2002-2006 Sam Leffler.  All rights reserved.
 *
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#if 0
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/sys/opencrypto/crypto.c,v 1.27 2007/03/21 03:42:51 sam Exp $");
#endif

/*
 * Cryptographic Subsystem.
 *
 * This code is derived from the Openbsd Cryptographic Framework (OCF)
 * that has the copyright shown below.  Very little of the original
 * code remains.
 */
/*-
 * The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu)
 *
 * This code was written by Angelos D. Keromytis in Athens, Greece, in
 * February 2000. Network Security Technologies Inc. (NSTI) kindly
 * supported the development of this code.
 *
 * Copyright (c) 2000, 2001 Angelos D. Keromytis
 *
 * Permission to use, copy, and modify this software with or without fee
 * is hereby granted, provided that this entire notice is included in
 * all source code copies of any software which is or includes a copy or
 * modification of this software.
 *
 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
 * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
 * PURPOSE.
 *
__FBSDID("$FreeBSD: src/sys/opencrypto/crypto.c,v 1.16 2005/01/07 02:29:16 imp Exp $");
 */


#include <linux/version.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38) && !defined(AUTOCONF_INCLUDED)
#include <linux/config.h>
#endif
#include <linux/module.h>
#include <linux/init.h>
#include <linux/list.h>
#include <linux/slab.h>
#include <linux/wait.h>
#include <linux/sched.h>
#include <linux/spinlock.h>
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,4)
#include <linux/kthread.h>
#endif
#include <cryptodev.h>

/*
 * keep track of whether or not we have been initialised, a big
 * issue if we are linked into the kernel and a driver gets started before
 * us
 */
static int crypto_initted = 0;

/*
 * Crypto drivers register themselves by allocating a slot in the
 * crypto_drivers table with crypto_get_driverid() and then registering
 * each algorithm they support with crypto_register() and crypto_kregister().
 */

/*
 * lock on driver table
 * we track its state as spin_is_locked does not do anything on non-SMP boxes
 */
static spinlock_t	crypto_drivers_lock;
static int			crypto_drivers_locked;		/* for non-SMP boxes */

#define	CRYPTO_DRIVER_LOCK() \
			({ \
				spin_lock_irqsave(&crypto_drivers_lock, d_flags); \
			 	crypto_drivers_locked = 1; \
				dprintk("%s,%d: DRIVER_LOCK()\n", __FILE__, __LINE__); \
			 })
#define	CRYPTO_DRIVER_UNLOCK() \
			({ \
			 	dprintk("%s,%d: DRIVER_UNLOCK()\n", __FILE__, __LINE__); \
			 	crypto_drivers_locked = 0; \
				spin_unlock_irqrestore(&crypto_drivers_lock, d_flags); \
			 })
#define	CRYPTO_DRIVER_ASSERT() \
			({ \
			 	if (!crypto_drivers_locked) { \
					dprintk("%s,%d: DRIVER_ASSERT!\n", __FILE__, __LINE__); \
			 	} \
			 })

/*
 * Crypto device/driver capabilities structure.
 *
 * Synchronization:
 * (d) - protected by CRYPTO_DRIVER_LOCK()
 * (q) - protected by CRYPTO_Q_LOCK()
 * Not tagged fields are read-only.
 */
struct cryptocap {
	device_t	cc_dev;			/* (d) device/driver */
	u_int32_t	cc_sessions;		/* (d) # of sessions */
	u_int32_t	cc_koperations;		/* (d) # os asym operations */
	/*
	 * Largest possible operator length (in bits) for each type of
	 * encryption algorithm. XXX not used
	 */
	u_int16_t	cc_max_op_len[CRYPTO_ALGORITHM_MAX + 1];
	u_int8_t	cc_alg[CRYPTO_ALGORITHM_MAX + 1];
	u_int8_t	cc_kalg[CRK_ALGORITHM_MAX + 1];

	int		cc_flags;		/* (d) flags */
#define CRYPTOCAP_F_CLEANUP	0x80000000	/* needs resource cleanup */
	int		cc_qblocked;		/* (q) symmetric q blocked */
	int		cc_kqblocked;		/* (q) asymmetric q blocked */

	int		cc_unqblocked;		/* (q) symmetric q blocked */
	int		cc_unkqblocked;		/* (q) asymmetric q blocked */
};
static struct cryptocap *crypto_drivers = NULL;
static int crypto_drivers_num = 0;

/*
 * There are two queues for crypto requests; one for symmetric (e.g.
 * cipher) operations and one for asymmetric (e.g. MOD)operations.
 * A single mutex is used to lock access to both queues.  We could
 * have one per-queue but having one simplifies handling of block/unblock
 * operations.
 */
static LIST_HEAD(crp_q);		/* crypto request queue */
static LIST_HEAD(crp_kq);		/* asym request queue */

static spinlock_t crypto_q_lock;

int crypto_all_qblocked = 0;  /* protect with Q_LOCK */
module_param(crypto_all_qblocked, int, 0444);
MODULE_PARM_DESC(crypto_all_qblocked, "Are all crypto queues blocked");

int crypto_all_kqblocked = 0; /* protect with Q_LOCK */
module_param(crypto_all_kqblocked, int, 0444);
MODULE_PARM_DESC(crypto_all_kqblocked, "Are all asym crypto queues blocked");

#define	CRYPTO_Q_LOCK() \
			({ \
				spin_lock_irqsave(&crypto_q_lock, q_flags); \
			 	dprintk("%s,%d: Q_LOCK()\n", __FILE__, __LINE__); \
			 })
#define	CRYPTO_Q_UNLOCK() \
			({ \
			 	dprintk("%s,%d: Q_UNLOCK()\n", __FILE__, __LINE__); \
				spin_unlock_irqrestore(&crypto_q_lock, q_flags); \
			 })

/*
 * There are two queues for processing completed crypto requests; one
 * for the symmetric and one for the asymmetric ops.  We only need one
 * but have two to avoid type futzing (cryptop vs. cryptkop).  A single
 * mutex is used to lock access to both queues.  Note that this lock
 * must be separate from the lock on request queues to insure driver
 * callbacks don't generate lock order reversals.
 */
static LIST_HEAD(crp_ret_q);		/* callback queues */
static LIST_HEAD(crp_ret_kq);

static spinlock_t crypto_ret_q_lock;
#define	CRYPTO_RETQ_LOCK() \
			({ \
				spin_lock_irqsave(&crypto_ret_q_lock, r_flags); \
				dprintk("%s,%d: RETQ_LOCK\n", __FILE__, __LINE__); \
			 })
#define	CRYPTO_RETQ_UNLOCK() \
			({ \
			 	dprintk("%s,%d: RETQ_UNLOCK\n", __FILE__, __LINE__); \
				spin_unlock_irqrestore(&crypto_ret_q_lock, r_flags); \
			 })
#define	CRYPTO_RETQ_EMPTY()	(list_empty(&crp_ret_q) && list_empty(&crp_ret_kq))

#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
static kmem_cache_t *cryptop_zone;
static kmem_cache_t *cryptodesc_zone;
#else
static struct kmem_cache *cryptop_zone;
static struct kmem_cache *cryptodesc_zone;
#endif

#define debug crypto_debug
int crypto_debug = 0;
module_param(crypto_debug, int, 0644);
MODULE_PARM_DESC(crypto_debug, "Enable debug");
EXPORT_SYMBOL(crypto_debug);

/*
 * Maximum number of outstanding crypto requests before we start
 * failing requests.  We need this to prevent DOS when too many
 * requests are arriving for us to keep up.  Otherwise we will
 * run the system out of memory.  Since crypto is slow,  we are
 * usually the bottleneck that needs to say, enough is enough.
 *
 * We cannot print errors when this condition occurs,  we are already too
 * slow,  printing anything will just kill us
 */

static int crypto_q_cnt = 0;
module_param(crypto_q_cnt, int, 0444);
MODULE_PARM_DESC(crypto_q_cnt,
		"Current number of outstanding crypto requests");

static int crypto_q_max = 1000;
module_param(crypto_q_max, int, 0644);
MODULE_PARM_DESC(crypto_q_max,
		"Maximum number of outstanding crypto requests");

#define bootverbose crypto_verbose
static int crypto_verbose = 0;
module_param(crypto_verbose, int, 0644);
MODULE_PARM_DESC(crypto_verbose,
		"Enable verbose crypto startup");

int	crypto_usercrypto = 1;	/* userland may do crypto reqs */
module_param(crypto_usercrypto, int, 0644);
MODULE_PARM_DESC(crypto_usercrypto,
	   "Enable/disable user-mode access to crypto support");

int	crypto_userasymcrypto = 1;	/* userland may do asym crypto reqs */
module_param(crypto_userasymcrypto, int, 0644);
MODULE_PARM_DESC(crypto_userasymcrypto,
	   "Enable/disable user-mode access to asymmetric crypto support");

int	crypto_devallowsoft = 0;	/* only use hardware crypto */
module_param(crypto_devallowsoft, int, 0644);
MODULE_PARM_DESC(crypto_devallowsoft,
	   "Enable/disable use of software crypto support");

/*
 * This parameter controls the maximum number of crypto operations to 
 * do consecutively in the crypto kernel thread before scheduling to allow 
 * other processes to run. Without it, it is possible to get into a 
 * situation where the crypto thread never allows any other processes to run.
 * Default to 1000 which should be less than one second.
 */
static int crypto_max_loopcount = 1000;
module_param(crypto_max_loopcount, int, 0644);
MODULE_PARM_DESC(crypto_max_loopcount,
	   "Maximum number of crypto ops to do before yielding to other processes");

#ifndef CONFIG_NR_CPUS
#define CONFIG_NR_CPUS 1
#endif

static struct task_struct *cryptoproc[CONFIG_NR_CPUS];
static struct task_struct *cryptoretproc[CONFIG_NR_CPUS];
static DECLARE_WAIT_QUEUE_HEAD(cryptoproc_wait);
static DECLARE_WAIT_QUEUE_HEAD(cryptoretproc_wait);

static	int crypto_proc(void *arg);
static	int crypto_ret_proc(void *arg);
static	int crypto_invoke(struct cryptocap *cap, struct cryptop *crp, int hint);
static	int crypto_kinvoke(struct cryptkop *krp, int flags);
static	void crypto_exit(void);
static  int crypto_init(void);

static	struct cryptostats cryptostats;

static struct cryptocap *
crypto_checkdriver(u_int32_t hid)
{
	if (crypto_drivers == NULL)
		return NULL;
	return (hid >= crypto_drivers_num ? NULL : &crypto_drivers[hid]);
}

/*
 * Compare a driver's list of supported algorithms against another
 * list; return non-zero if all algorithms are supported.
 */
static int
driver_suitable(const struct cryptocap *cap, const struct cryptoini *cri)
{
	const struct cryptoini *cr;

	/* See if all the algorithms are supported. */
	for (cr = cri; cr; cr = cr->cri_next)
		if (cap->cc_alg[cr->cri_alg] == 0)
			return 0;
	return 1;
}


/*
 * Select a driver for a new session that supports the specified
 * algorithms and, optionally, is constrained according to the flags.
 * The algorithm we use here is pretty stupid; just use the
 * first driver that supports all the algorithms we need. If there
 * are multiple drivers we choose the driver with the fewest active
 * sessions.  We prefer hardware-backed drivers to software ones.
 *
 * XXX We need more smarts here (in real life too, but that's
 * XXX another story altogether).
 */
static struct cryptocap *
crypto_select_driver(const struct cryptoini *cri, int flags)
{
	struct cryptocap *cap, *best;
	int match, hid;

	CRYPTO_DRIVER_ASSERT();

	/*
	 * Look first for hardware crypto devices if permitted.
	 */
	if (flags & CRYPTOCAP_F_HARDWARE)
		match = CRYPTOCAP_F_HARDWARE;
	else
		match = CRYPTOCAP_F_SOFTWARE;
	best = NULL;
again:
	for (hid = 0; hid < crypto_drivers_num; hid++) {
		cap = &crypto_drivers[hid];
		/*
		 * If it's not initialized, is in the process of
		 * going away, or is not appropriate (hardware
		 * or software based on match), then skip.
		 */
		if (cap->cc_dev == NULL ||
		    (cap->cc_flags & CRYPTOCAP_F_CLEANUP) ||
		    (cap->cc_flags & match) == 0)
			continue;

		/* verify all the algorithms are supported. */
		if (driver_suitable(cap, cri)) {
			if (best == NULL ||
			    cap->cc_sessions < best->cc_sessions)
				best = cap;
		}
	}
	if (best != NULL)
		return best;
	if (match == CRYPTOCAP_F_HARDWARE && (flags & CRYPTOCAP_F_SOFTWARE)) {
		/* sort of an Algol 68-style for loop */
		match = CRYPTOCAP_F_SOFTWARE;
		goto again;
	}
	return best;
}

/*
 * Create a new session.  The crid argument specifies a crypto
 * driver to use or constraints on a driver to select (hardware
 * only, software only, either).  Whatever driver is selected
 * must be capable of the requested crypto algorithms.
 */
int
crypto_newsession(u_int64_t *sid, struct cryptoini *cri, int crid)
{
	struct cryptocap *cap;
	u_int32_t hid, lid;
	int err;
	unsigned long d_flags;

	CRYPTO_DRIVER_LOCK();
	if ((crid & (CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE)) == 0) {
		/*
		 * Use specified driver; verify it is capable.
		 */
		cap = crypto_checkdriver(crid);
		if (cap != NULL && !driver_suitable(cap, cri))
			cap = NULL;
	} else {
		/*
		 * No requested driver; select based on crid flags.
		 */
		cap = crypto_select_driver(cri, crid);
		/*
		 * if NULL then can't do everything in one session.
		 * XXX Fix this. We need to inject a "virtual" session
		 * XXX layer right about here.
		 */
	}
	if (cap != NULL) {
		/* Call the driver initialization routine. */
		hid = cap - crypto_drivers;
		lid = hid;		/* Pass the driver ID. */
		cap->cc_sessions++;
		CRYPTO_DRIVER_UNLOCK();
		err = CRYPTODEV_NEWSESSION(cap->cc_dev, &lid, cri);
		CRYPTO_DRIVER_LOCK();
		if (err == 0) {
			(*sid) = (cap->cc_flags & 0xff000000)
			       | (hid & 0x00ffffff);
			(*sid) <<= 32;
			(*sid) |= (lid & 0xffffffff);
		} else
			cap->cc_sessions--;
	} else
		err = EINVAL;
	CRYPTO_DRIVER_UNLOCK();
	return err;
}

static void
crypto_remove(struct cryptocap *cap)
{
	CRYPTO_DRIVER_ASSERT();
	if (cap->cc_sessions == 0 && cap->cc_koperations == 0)
		bzero(cap, sizeof(*cap));
}

/*
 * Delete an existing session (or a reserved session on an unregistered
 * driver).
 */
int
crypto_freesession(u_int64_t sid)
{
	struct cryptocap *cap;
	u_int32_t hid;
	int err = 0;
	unsigned long d_flags;

	dprintk("%s()\n", __FUNCTION__);
	CRYPTO_DRIVER_LOCK();

	if (crypto_drivers == NULL) {
		err = EINVAL;
		goto done;
	}

	/* Determine two IDs. */
	hid = CRYPTO_SESID2HID(sid);

	if (hid >= crypto_drivers_num) {
		dprintk("%s - INVALID DRIVER NUM %d\n", __FUNCTION__, hid);
		err = ENOENT;
		goto done;
	}
	cap = &crypto_drivers[hid];

	if (cap->cc_dev) {
		CRYPTO_DRIVER_UNLOCK();
		/* Call the driver cleanup routine, if available, unlocked. */
		err = CRYPTODEV_FREESESSION(cap->cc_dev, sid);
		CRYPTO_DRIVER_LOCK();
	}

	if (cap->cc_sessions)
		cap->cc_sessions--;

	if (cap->cc_flags & CRYPTOCAP_F_CLEANUP)
		crypto_remove(cap);

done:
	CRYPTO_DRIVER_UNLOCK();
	return err;
}

/*
 * Return an unused driver id.  Used by drivers prior to registering
 * support for the algorithms they handle.
 */
int32_t
crypto_get_driverid(device_t dev, int flags)
{
	struct cryptocap *newdrv;
	int i;
	unsigned long d_flags;

	if ((flags & (CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE)) == 0) {
		printf("%s: no flags specified when registering driver\n",
		    device_get_nameunit(dev));
		return -1;
	}

	CRYPTO_DRIVER_LOCK();

	for (i = 0; i < crypto_drivers_num; i++) {
		if (crypto_drivers[i].cc_dev == NULL &&
		    (crypto_drivers[i].cc_flags & CRYPTOCAP_F_CLEANUP) == 0) {
			break;
		}
	}

	/* Out of entries, allocate some more. */
	if (i == crypto_drivers_num) {
		/* Be careful about wrap-around. */
		if (2 * crypto_drivers_num <= crypto_drivers_num) {
			CRYPTO_DRIVER_UNLOCK();
			printk("crypto: driver count wraparound!\n");
			return -1;
		}

		newdrv = kmalloc(2 * crypto_drivers_num * sizeof(struct cryptocap),
				GFP_KERNEL);
		if (newdrv == NULL) {
			CRYPTO_DRIVER_UNLOCK();
			printk("crypto: no space to expand driver table!\n");
			return -1;
		}

		memcpy(newdrv, crypto_drivers,
				crypto_drivers_num * sizeof(struct cryptocap));
		memset(&newdrv[crypto_drivers_num], 0,
				crypto_drivers_num * sizeof(struct cryptocap));

		crypto_drivers_num *= 2;

		kfree(crypto_drivers);
		crypto_drivers = newdrv;
	}

	/* NB: state is zero'd on free */
	crypto_drivers[i].cc_sessions = 1;	/* Mark */
	crypto_drivers[i].cc_dev = dev;
	crypto_drivers[i].cc_flags = flags;
	if (bootverbose)
		printf("crypto: assign %s driver id %u, flags %u\n",
		    device_get_nameunit(dev), i, flags);

	CRYPTO_DRIVER_UNLOCK();

	return i;
}

/*
 * Lookup a driver by name.  We match against the full device
 * name and unit, and against just the name.  The latter gives
 * us a simple widlcarding by device name.  On success return the
 * driver/hardware identifier; otherwise return -1.
 */
int
crypto_find_driver(const char *match)
{
	int i, len = strlen(match);
	unsigned long d_flags;

	CRYPTO_DRIVER_LOCK();
	for (i = 0; i < crypto_drivers_num; i++) {
		device_t dev = crypto_drivers[i].cc_dev;
		if (dev == NULL ||
		    (crypto_drivers[i].cc_flags & CRYPTOCAP_F_CLEANUP))
			continue;
		if (strncmp(match, device_get_nameunit(dev), len) == 0 ||
		    strncmp(match, device_get_name(dev), len) == 0)
			break;
	}
	CRYPTO_DRIVER_UNLOCK();
	return i < crypto_drivers_num ? i : -1;
}

/*
 * Return the device_t for the specified driver or NULL
 * if the driver identifier is invalid.
 */
device_t
crypto_find_device_byhid(int hid)
{
	struct cryptocap *cap = crypto_checkdriver(hid);
	return cap != NULL ? cap->cc_dev : NULL;
}

/*
 * Return the device/driver capabilities.
 */
int
crypto_getcaps(int hid)
{
	struct cryptocap *cap = crypto_checkdriver(hid);
	return cap != NULL ? cap->cc_flags : 0;
}

/*
 * Register support for a key-related algorithm.  This routine
 * is called once for each algorithm supported a driver.
 */
int
crypto_kregister(u_int32_t driverid, int kalg, u_int32_t flags)
{
	struct cryptocap *cap;
	int err;
	unsigned long d_flags;

	dprintk("%s()\n", __FUNCTION__);
	CRYPTO_DRIVER_LOCK();

	cap = crypto_checkdriver(driverid);
	if (cap != NULL &&
	    (CRK_ALGORITM_MIN <= kalg && kalg <= CRK_ALGORITHM_MAX)) {
		/*
		 * XXX Do some performance testing to determine placing.
		 * XXX We probably need an auxiliary data structure that
		 * XXX describes relative performances.
		 */

		cap->cc_kalg[kalg] = flags | CRYPTO_ALG_FLAG_SUPPORTED;
		if (bootverbose)
			printf("crypto: %s registers key alg %u flags %u\n"
				, device_get_nameunit(cap->cc_dev)
				, kalg
				, flags
			);
		err = 0;
	} else
		err = EINVAL;

	CRYPTO_DRIVER_UNLOCK();
	return err;
}

/*
 * Register support for a non-key-related algorithm.  This routine
 * is called once for each such algorithm supported by a driver.
 */
int
crypto_register(u_int32_t driverid, int alg, u_int16_t maxoplen,
    u_int32_t flags)
{
	struct cryptocap *cap;
	int err;
	unsigned long d_flags;

	dprintk("%s(id=0x%x, alg=%d, maxoplen=%d, flags=0x%x)\n", __FUNCTION__,
			driverid, alg, maxoplen, flags);

	CRYPTO_DRIVER_LOCK();

	cap = crypto_checkdriver(driverid);
	/* NB: algorithms are in the range [1..max] */
	if (cap != NULL &&
	    (CRYPTO_ALGORITHM_MIN <= alg && alg <= CRYPTO_ALGORITHM_MAX)) {
		/*
		 * XXX Do some performance testing to determine placing.
		 * XXX We probably need an auxiliary data structure that
		 * XXX describes relative performances.
		 */

		cap->cc_alg[alg] = flags | CRYPTO_ALG_FLAG_SUPPORTED;
		cap->cc_max_op_len[alg] = maxoplen;
		if (bootverbose)
			printf("crypto: %s registers alg %u flags %u maxoplen %u\n"
				, device_get_nameunit(cap->cc_dev)
				, alg
				, flags
				, maxoplen
			);
		cap->cc_sessions = 0;		/* Unmark */
		err = 0;
	} else
		err = EINVAL;

	CRYPTO_DRIVER_UNLOCK();
	return err;
}

static void
driver_finis(struct cryptocap *cap)
{
	u_int32_t ses, kops;

	CRYPTO_DRIVER_ASSERT();

	ses = cap->cc_sessions;
	kops = cap->cc_koperations;
	bzero(cap, sizeof(*cap));
	if (ses != 0 || kops != 0) {
		/*
		 * If there are pending sessions,
		 * just mark as invalid.
		 */
		cap->cc_flags |= CRYPTOCAP_F_CLEANUP;
		cap->cc_sessions = ses;
		cap->cc_koperations = kops;
	}
}

/*
 * Unregister a crypto driver. If there are pending sessions using it,
 * leave enough information around so that subsequent calls using those
 * sessions will correctly detect the driver has been unregistered and
 * reroute requests.
 */
int
crypto_unregister(u_int32_t driverid, int alg)
{
	struct cryptocap *cap;
	int i, err;
	unsigned long d_flags;

	dprintk("%s()\n", __FUNCTION__);
	CRYPTO_DRIVER_LOCK();

	cap = crypto_checkdriver(driverid);
	if (cap != NULL &&
	    (CRYPTO_ALGORITHM_MIN <= alg && alg <= CRYPTO_ALGORITHM_MAX) &&
	    cap->cc_alg[alg] != 0) {
		cap->cc_alg[alg] = 0;
		cap->cc_max_op_len[alg] = 0;

		/* Was this the last algorithm ? */
		for (i = 1; i <= CRYPTO_ALGORITHM_MAX; i++)
			if (cap->cc_alg[i] != 0)
				break;

		if (i == CRYPTO_ALGORITHM_MAX + 1)
			driver_finis(cap);
		err = 0;
	} else
		err = EINVAL;
	CRYPTO_DRIVER_UNLOCK();
	return err;
}

/*
 * Unregister all algorithms associated with a crypto driver.
 * If there are pending sessions using it, leave enough information
 * around so that subsequent calls using those sessions will
 * correctly detect the driver has been unregistered and reroute
 * requests.
 */
int
crypto_unregister_all(u_int32_t driverid)
{
	struct cryptocap *cap;
	int err;
	unsigned long d_flags;

	dprintk("%s()\n", __FUNCTION__);
	CRYPTO_DRIVER_LOCK();
	cap = crypto_checkdriver(driverid);
	if (cap != NULL) {
		driver_finis(cap);
		err = 0;
	} else
		err = EINVAL;
	CRYPTO_DRIVER_UNLOCK();

	return err;
}

/*
 * Clear blockage on a driver.  The what parameter indicates whether
 * the driver is now ready for cryptop's and/or cryptokop's.
 */
int
crypto_unblock(u_int32_t driverid, int what)
{
	struct cryptocap *cap;
	int err;
	unsigned long q_flags;

	CRYPTO_Q_LOCK();
	cap = crypto_checkdriver(driverid);
	if (cap != NULL) {
		if (what & CRYPTO_SYMQ) {
			cap->cc_qblocked = 0;
			cap->cc_unqblocked = 0;
			crypto_all_qblocked = 0;
		}
		if (what & CRYPTO_ASYMQ) {
			cap->cc_kqblocked = 0;
			cap->cc_unkqblocked = 0;
			crypto_all_kqblocked = 0;
		}
		wake_up_interruptible(&cryptoproc_wait);
		err = 0;
	} else
		err = EINVAL;
	CRYPTO_Q_UNLOCK(); //DAVIDM should this be a driver lock

	return err;
}

/*
 * Add a crypto request to a queue, to be processed by the kernel thread.
 */
int
crypto_dispatch(struct cryptop *crp)
{
	struct cryptocap *cap;
	int result = -1;
	unsigned long q_flags;

	dprintk("%s()\n", __FUNCTION__);

	cryptostats.cs_ops++;

	CRYPTO_Q_LOCK();
	/*if (crypto_q_cnt >= crypto_q_max) {
		cryptostats.cs_drops++;
		CRYPTO_Q_UNLOCK();
		return ENOMEM;
	}*/
	crypto_q_cnt++;

	/* make sure we are starting a fresh run on this crp. */
	crp->crp_flags &= ~CRYPTO_F_DONE;
	crp->crp_etype = 0;

	/*
	 * Caller marked the request to be processed immediately; dispatch
	 * it directly to the driver unless the driver is currently blocked.
	 */
	if ((crp->crp_flags & CRYPTO_F_BATCH) == 0) {
		int hid = CRYPTO_SESID2HID(crp->crp_sid);
		cap = crypto_checkdriver(hid);
		/* Driver cannot disappear when there is an active session. */
		KASSERT(cap != NULL, ("%s: Driver disappeared.", __func__));
		if (!cap->cc_qblocked) {
			crypto_all_qblocked = 0;
			crypto_drivers[hid].cc_unqblocked = 1;
			CRYPTO_Q_UNLOCK();
			result = crypto_invoke(cap, crp, 0);
			CRYPTO_Q_LOCK();
			if (result == ERESTART)
				if (crypto_drivers[hid].cc_unqblocked)
					crypto_drivers[hid].cc_qblocked = 1;
			crypto_drivers[hid].cc_unqblocked = 0;
		}
	}
	if (result == ERESTART) {
		/*
		 * The driver ran out of resources, mark the
		 * driver ``blocked'' for cryptop's and put
		 * the request back in the queue.  It would
		 * best to put the request back where we got
		 * it but that's hard so for now we put it
		 * at the front.  This should be ok; putting
		 * it at the end does not work.
		 */
		list_add(&crp->crp_next, &crp_q);
		cryptostats.cs_blocks++;
		result = 0;
	} else if (result == -1) {
		TAILQ_INSERT_TAIL(&crp_q, crp, crp_next);
		result = 0;
	}
	wake_up_interruptible(&cryptoproc_wait);
	CRYPTO_Q_UNLOCK();
	return result;
}

/*
 * Add an asymetric crypto request to a queue,
 * to be processed by the kernel thread.
 */
int
crypto_kdispatch(struct cryptkop *krp)
{
	int error;
	unsigned long q_flags;

	cryptostats.cs_kops++;

	error = crypto_kinvoke(krp, krp->krp_crid);
	if (error == ERESTART) {
		CRYPTO_Q_LOCK();
		TAILQ_INSERT_TAIL(&crp_kq, krp, krp_next);
		wake_up_interruptible(&cryptoproc_wait);
		CRYPTO_Q_UNLOCK();
		error = 0;
	}
	return error;
}

/*
 * Verify a driver is suitable for the specified operation.
 */
static __inline int
kdriver_suitable(const struct cryptocap *cap, const struct cryptkop *krp)
{
	return (cap->cc_kalg[krp->krp_op] & CRYPTO_ALG_FLAG_SUPPORTED) != 0;
}

/*
 * Select a driver for an asym operation.  The driver must
 * support the necessary algorithm.  The caller can constrain
 * which device is selected with the flags parameter.  The
 * algorithm we use here is pretty stupid; just use the first
 * driver that supports the algorithms we need. If there are
 * multiple suitable drivers we choose the driver with the
 * fewest active operations.  We prefer hardware-backed
 * drivers to software ones when either may be used.
 */
static struct cryptocap *
crypto_select_kdriver(const struct cryptkop *krp, int flags)
{
	struct cryptocap *cap, *best, *blocked;
	int match, hid;

	CRYPTO_DRIVER_ASSERT();

	/*
	 * Look first for hardware crypto devices if permitted.
	 */
	if (flags & CRYPTOCAP_F_HARDWARE)
		match = CRYPTOCAP_F_HARDWARE;
	else
		match = CRYPTOCAP_F_SOFTWARE;
	best = NULL;
	blocked = NULL;
again:
	for (hid = 0; hid < crypto_drivers_num; hid++) {
		cap = &crypto_drivers[hid];
		/*
		 * If it's not initialized, is in the process of
		 * going away, or is not appropriate (hardware
		 * or software based on match), then skip.
		 */
		if (cap->cc_dev == NULL ||
		    (cap->cc_flags & CRYPTOCAP_F_CLEANUP) ||
		    (cap->cc_flags & match) == 0)
			continue;

		/* verify all the algorithms are supported. */
		if (kdriver_suitable(cap, krp)) {
			if (best == NULL ||
			    cap->cc_koperations < best->cc_koperations)
				best = cap;
		}
	}
	if (best != NULL)
		return best;
	if (match == CRYPTOCAP_F_HARDWARE && (flags & CRYPTOCAP_F_SOFTWARE)) {
		/* sort of an Algol 68-style for loop */
		match = CRYPTOCAP_F_SOFTWARE;
		goto again;
	}
	return best;
}

/*
 * Dispatch an assymetric crypto request.
 */
static int
crypto_kinvoke(struct cryptkop *krp, int crid)
{
	struct cryptocap *cap = NULL;
	int error;
	unsigned long d_flags;

	KASSERT(krp != NULL, ("%s: krp == NULL", __func__));
	KASSERT(krp->krp_callback != NULL,
	    ("%s: krp->crp_callback == NULL", __func__));

	CRYPTO_DRIVER_LOCK();
	if ((crid & (CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE)) == 0) {
		cap = crypto_checkdriver(crid);
		if (cap != NULL) {
			/*
			 * Driver present, it must support the necessary
			 * algorithm and, if s/w drivers are excluded,
			 * it must be registered as hardware-backed.
			 */
			if (!kdriver_suitable(cap, krp) ||
			    (!crypto_devallowsoft &&
			     (cap->cc_flags & CRYPTOCAP_F_HARDWARE) == 0))
				cap = NULL;
		}
	} else {
		/*
		 * No requested driver; select based on crid flags.
		 */
		if (!crypto_devallowsoft)	/* NB: disallow s/w drivers */
			crid &= ~CRYPTOCAP_F_SOFTWARE;
		cap = crypto_select_kdriver(krp, crid);
	}
	if (cap != NULL && !cap->cc_kqblocked) {
		krp->krp_hid = cap - crypto_drivers;
		cap->cc_koperations++;
		CRYPTO_DRIVER_UNLOCK();
		error = CRYPTODEV_KPROCESS(cap->cc_dev, krp, 0);
		CRYPTO_DRIVER_LOCK();
		if (error == ERESTART) {
			cap->cc_koperations--;
			CRYPTO_DRIVER_UNLOCK();
			return (error);
		}
		/* return the actual device used */
		krp->krp_crid = krp->krp_hid;
	} else {
		/*
		 * NB: cap is !NULL if device is blocked; in
		 *     that case return ERESTART so the operation
		 *     is resubmitted if possible.
		 */
		error = (cap == NULL) ? ENODEV : ERESTART;
	}
	CRYPTO_DRIVER_UNLOCK();

	if (error) {
		krp->krp_status = error;
		crypto_kdone(krp);
	}
	return 0;
}


/*
 * Dispatch a crypto request to the appropriate crypto devices.
 */
static int
crypto_invoke(struct cryptocap *cap, struct cryptop *crp, int hint)
{
	KASSERT(crp != NULL, ("%s: crp == NULL", __func__));
	KASSERT(crp->crp_callback != NULL,
	    ("%s: crp->crp_callback == NULL", __func__));
	KASSERT(crp->crp_desc != NULL, ("%s: crp->crp_desc == NULL", __func__));

	dprintk("%s()\n", __FUNCTION__);

#ifdef CRYPTO_TIMING
	if (crypto_timing)
		crypto_tstat(&cryptostats.cs_invoke, &crp->crp_tstamp);
#endif
	if (cap->cc_flags & CRYPTOCAP_F_CLEANUP) {
		struct cryptodesc *crd;
		u_int64_t nid;

		/*
		 * Driver has unregistered; migrate the session and return
		 * an error to the caller so they'll resubmit the op.
		 *
		 * XXX: What if there are more already queued requests for this
		 *      session?
		 */
		crypto_freesession(crp->crp_sid);

		for (crd = crp->crp_desc; crd->crd_next; crd = crd->crd_next)
			crd->CRD_INI.cri_next = &(crd->crd_next->CRD_INI);

		/* XXX propagate flags from initial session? */
		if (crypto_newsession(&nid, &(crp->crp_desc->CRD_INI),
		    CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE) == 0)
			crp->crp_sid = nid;

		crp->crp_etype = EAGAIN;
		crypto_done(crp);
		return 0;
	} else {
		/*
		 * Invoke the driver to process the request.
		 */
		return CRYPTODEV_PROCESS(cap->cc_dev, crp, hint);
	}
}

/*
 * Release a set of crypto descriptors.
 */
void
crypto_freereq(struct cryptop *crp)
{
	struct cryptodesc *crd;

	if (crp == NULL)
		return;

#ifdef DIAGNOSTIC
	{
		struct cryptop *crp2;
		unsigned long q_flags;

		CRYPTO_Q_LOCK();
		TAILQ_FOREACH(crp2, &crp_q, crp_next) {
			KASSERT(crp2 != crp,
			    ("Freeing cryptop from the crypto queue (%p).",
			    crp));
		}
		CRYPTO_Q_UNLOCK();
		CRYPTO_RETQ_LOCK();
		TAILQ_FOREACH(crp2, &crp_ret_q, crp_next) {
			KASSERT(crp2 != crp,
			    ("Freeing cryptop from the return queue (%p).",
			    crp));
		}
		CRYPTO_RETQ_UNLOCK();
	}
#endif

	while ((crd = crp->crp_desc) != NULL) {
		crp->crp_desc = crd->crd_next;
		kmem_cache_free(cryptodesc_zone, crd);
	}
	kmem_cache_free(cryptop_zone, crp);
}

/*
 * Acquire a set of crypto descriptors.
 */
struct cryptop *
crypto_getreq(int num)
{
	struct cryptodesc *crd;
	struct cryptop *crp;

	crp = kmem_cache_alloc(cryptop_zone, SLAB_ATOMIC);
	if (crp != NULL) {
		memset(crp, 0, sizeof(*crp));
		INIT_LIST_HEAD(&crp->crp_next);
		init_waitqueue_head(&crp->crp_waitq);
		while (num--) {
			crd = kmem_cache_alloc(cryptodesc_zone, SLAB_ATOMIC);
			if (crd == NULL) {
				crypto_freereq(crp);
				return NULL;
			}
			memset(crd, 0, sizeof(*crd));
			crd->crd_next = crp->crp_desc;
			crp->crp_desc = crd;
		}
	}
	return crp;
}

/*
 * Invoke the callback on behalf of the driver.
 */
void
crypto_done(struct cryptop *crp)
{
	unsigned long q_flags;

	dprintk("%s()\n", __FUNCTION__);
	if ((crp->crp_flags & CRYPTO_F_DONE) == 0) {
		crp->crp_flags |= CRYPTO_F_DONE;
		CRYPTO_Q_LOCK();
		crypto_q_cnt--;
		CRYPTO_Q_UNLOCK();
	} else
		printk("crypto: crypto_done op already done, flags 0x%x",
				crp->crp_flags);
	if (crp->crp_etype != 0)
		cryptostats.cs_errs++;
	/*
	 * CBIMM means unconditionally do the callback immediately;
	 * CBIFSYNC means do the callback immediately only if the
	 * operation was done synchronously.  Both are used to avoid
	 * doing extraneous context switches; the latter is mostly
	 * used with the software crypto driver.
	 */
	if ((crp->crp_flags & CRYPTO_F_CBIMM) ||
	    ((crp->crp_flags & CRYPTO_F_CBIFSYNC) &&
	     (CRYPTO_SESID2CAPS(crp->crp_sid) & CRYPTOCAP_F_SYNC))) {
		/*
		 * Do the callback directly.  This is ok when the
		 * callback routine does very little (e.g. the
		 * /dev/crypto callback method just does a wakeup).
		 */
		crp->crp_callback(crp);
	} else {
		unsigned long r_flags;
		/*
		 * Normal case; queue the callback for the thread.
		 */
		CRYPTO_RETQ_LOCK();
		wake_up_interruptible(&cryptoretproc_wait);/* shared wait channel */
		TAILQ_INSERT_TAIL(&crp_ret_q, crp, crp_next);
		CRYPTO_RETQ_UNLOCK();
	}
}

/*
 * Invoke the callback on behalf of the driver.
 */
void
crypto_kdone(struct cryptkop *krp)
{
	struct cryptocap *cap;
	unsigned long d_flags;

	if ((krp->krp_flags & CRYPTO_KF_DONE) != 0)
		printk("crypto: crypto_kdone op already done, flags 0x%x",
				krp->krp_flags);
	krp->krp_flags |= CRYPTO_KF_DONE;
	if (krp->krp_status != 0)
		cryptostats.cs_kerrs++;

	CRYPTO_DRIVER_LOCK();
	/* XXX: What if driver is loaded in the meantime? */
	if (krp->krp_hid < crypto_drivers_num) {
		cap = &crypto_drivers[krp->krp_hid];
		cap->cc_koperations--;
		KASSERT(cap->cc_koperations >= 0, ("cc_koperations < 0"));
		if (cap->cc_flags & CRYPTOCAP_F_CLEANUP)
			crypto_remove(cap);
	}
	CRYPTO_DRIVER_UNLOCK();

	/*
	 * CBIMM means unconditionally do the callback immediately;
	 * This is used to avoid doing extraneous context switches
	 */
	if ((krp->krp_flags & CRYPTO_KF_CBIMM)) {
		/*
		 * Do the callback directly.  This is ok when the
		 * callback routine does very little (e.g. the
		 * /dev/crypto callback method just does a wakeup).
		 */
		krp->krp_callback(krp);
	} else {
		unsigned long r_flags;
		/*
		 * Normal case; queue the callback for the thread.
		 */
		CRYPTO_RETQ_LOCK();
		wake_up_interruptible(&cryptoretproc_wait);/* shared wait channel */
		TAILQ_INSERT_TAIL(&crp_ret_kq, krp, krp_next);
		CRYPTO_RETQ_UNLOCK();
	}
}

int
crypto_getfeat(int *featp)
{
	int hid, kalg, feat = 0;
	unsigned long d_flags;

	CRYPTO_DRIVER_LOCK();
	for (hid = 0; hid < crypto_drivers_num; hid++) {
		const struct cryptocap *cap = &crypto_drivers[hid];

		if ((cap->cc_flags & CRYPTOCAP_F_SOFTWARE) &&
		    !crypto_devallowsoft) {
			continue;
		}
		for (kalg = 0; kalg < CRK_ALGORITHM_MAX; kalg++)
			if (cap->cc_kalg[kalg] & CRYPTO_ALG_FLAG_SUPPORTED)
				feat |=  1 << kalg;
	}
	CRYPTO_DRIVER_UNLOCK();
	*featp = feat;
	return (0);
}

/*
 * Crypto thread, dispatches crypto requests.
 */
static int
crypto_proc(void *arg)
{
	struct cryptop *crp, *submit;
	struct cryptkop *krp, *krpp;
	struct cryptocap *cap;
	u_int32_t hid;
	int result, hint;
	unsigned long q_flags;
	int loopcount = 0;

	set_current_state(TASK_INTERRUPTIBLE);

	CRYPTO_Q_LOCK();
	for (;;) {
		/*
		 * we need to make sure we don't get into a busy loop with nothing
		 * to do,  the two crypto_all_*blocked vars help us find out when
		 * we are all full and can do nothing on any driver or Q.  If so we
		 * wait for an unblock.
		 */
		crypto_all_qblocked  = !list_empty(&crp_q);

		/*
		 * Find the first element in the queue that can be
		 * processed and look-ahead to see if multiple ops
		 * are ready for the same driver.
		 */
		submit = NULL;
		hint = 0;
		list_for_each_entry(crp, &crp_q, crp_next) {
			hid = CRYPTO_SESID2HID(crp->crp_sid);
			cap = crypto_checkdriver(hid);
			/*
			 * Driver cannot disappear when there is an active
			 * session.
			 */
			KASSERT(cap != NULL, ("%s:%u Driver disappeared.",
			    __func__, __LINE__));
			if (cap == NULL || cap->cc_dev == NULL) {
				/* Op needs to be migrated, process it. */
				if (submit == NULL)
					submit = crp;
				break;
			}
			if (!cap->cc_qblocked) {
				if (submit != NULL) {
					/*
					 * We stop on finding another op,
					 * regardless whether its for the same
					 * driver or not.  We could keep
					 * searching the queue but it might be
					 * better to just use a per-driver
					 * queue instead.
					 */
					if (CRYPTO_SESID2HID(submit->crp_sid) == hid)
						hint = CRYPTO_HINT_MORE;
					break;
				} else {
					submit = crp;
					if ((submit->crp_flags & CRYPTO_F_BATCH) == 0)
						break;
					/* keep scanning for more are q'd */
				}
			}
		}
		if (submit != NULL) {
			hid = CRYPTO_SESID2HID(submit->crp_sid);
			crypto_all_qblocked = 0;
			list_del(&submit->crp_next);
			crypto_drivers[hid].cc_unqblocked = 1;
			cap = crypto_checkdriver(hid);
			CRYPTO_Q_UNLOCK();
			KASSERT(cap != NULL, ("%s:%u Driver disappeared.",
			    __func__, __LINE__));
			result = crypto_invoke(cap, submit, hint);
			CRYPTO_Q_LOCK();
			if (result == ERESTART) {
				/*
				 * The driver ran out of resources, mark the
				 * driver ``blocked'' for cryptop's and put
				 * the request back in the queue.  It would
				 * best to put the request back where we got
				 * it but that's hard so for now we put it
				 * at the front.  This should be ok; putting
				 * it at the end does not work.
				 */
				/* XXX validate sid again? */
				list_add(&submit->crp_next, &crp_q);
				cryptostats.cs_blocks++;
				if (crypto_drivers[hid].cc_unqblocked)
					crypto_drivers[hid].cc_qblocked=0;
				crypto_drivers[hid].cc_unqblocked=0;
			}
			crypto_drivers[hid].cc_unqblocked = 0;
		}

		crypto_all_kqblocked = !list_empty(&crp_kq);

		/* As above, but for key ops */
		krp = NULL;
		list_for_each_entry(krpp, &crp_kq, krp_next) {
			cap = crypto_checkdriver(krpp->krp_hid);
			if (cap == NULL || cap->cc_dev == NULL) {
				/*
				 * Operation needs to be migrated, invalidate
				 * the assigned device so it will reselect a
				 * new one below.  Propagate the original
				 * crid selection flags if supplied.
				 */
				krp->krp_hid = krp->krp_crid &
				    (CRYPTOCAP_F_SOFTWARE|CRYPTOCAP_F_HARDWARE);
				if (krp->krp_hid == 0)
					krp->krp_hid =
				    CRYPTOCAP_F_SOFTWARE|CRYPTOCAP_F_HARDWARE;
				break;
			}
			if (!cap->cc_kqblocked) {
				krp = krpp;
				break;
			}
		}
		if (krp != NULL) {
			crypto_all_kqblocked = 0;
			list_del(&krp->krp_next);
			crypto_drivers[krp->krp_hid].cc_kqblocked = 1;
			CRYPTO_Q_UNLOCK();
			result = crypto_kinvoke(krp, krp->krp_hid);
			CRYPTO_Q_LOCK();
			if (result == ERESTART) {
				/*
				 * The driver ran out of resources, mark the
				 * driver ``blocked'' for cryptkop's and put
				 * the request back in the queue.  It would
				 * best to put the request back where we got
				 * it but that's hard so for now we put it
				 * at the front.  This should be ok; putting
				 * it at the end does not work.
				 */
				/* XXX validate sid again? */
				list_add(&krp->krp_next, &crp_kq);
				cryptostats.cs_kblocks++;
			} else
				crypto_drivers[krp->krp_hid].cc_kqblocked = 0;
		}

		if (submit == NULL && krp == NULL) {
			/*
			 * Nothing more to be processed.  Sleep until we're
			 * woken because there are more ops to process.
			 * This happens either by submission or by a driver
			 * becoming unblocked and notifying us through
			 * crypto_unblock.  Note that when we wakeup we
			 * start processing each queue again from the
			 * front. It's not clear that it's important to
			 * preserve this ordering since ops may finish
			 * out of order if dispatched to different devices
			 * and some become blocked while others do not.
			 */
			dprintk("%s - sleeping (qe=%d qb=%d kqe=%d kqb=%d)\n",
					__FUNCTION__,
					list_empty(&crp_q), crypto_all_qblocked,
					list_empty(&crp_kq), crypto_all_kqblocked);
			loopcount = 0;
			CRYPTO_Q_UNLOCK();
			wait_event_interruptible(cryptoproc_wait,
					!(list_empty(&crp_q) || crypto_all_qblocked) ||
					!(list_empty(&crp_kq) || crypto_all_kqblocked) ||
					kthread_should_stop());
			if (signal_pending (current)) {
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
				spin_lock_irq(&current->sigmask_lock);
#endif
				flush_signals(current);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
				spin_unlock_irq(&current->sigmask_lock);
#endif
			}
			CRYPTO_Q_LOCK();
			dprintk("%s - awake\n", __FUNCTION__);
			if (kthread_should_stop())
				break;
			cryptostats.cs_intrs++;
		} else if (loopcount > crypto_max_loopcount) {
			/*
			 * Give other processes a chance to run if we've 
			 * been using the CPU exclusively for a while.
			 */
			loopcount = 0;
			CRYPTO_Q_UNLOCK();
			schedule();
			CRYPTO_Q_LOCK();
		}
		loopcount++;
	}
	CRYPTO_Q_UNLOCK();
	return 0;
}

/*
 * Crypto returns thread, does callbacks for processed crypto requests.
 * Callbacks are done here, rather than in the crypto drivers, because
 * callbacks typically are expensive and would slow interrupt handling.
 */
static int
crypto_ret_proc(void *arg)
{
	struct cryptop *crpt;
	struct cryptkop *krpt;
	unsigned long  r_flags;

	set_current_state(TASK_INTERRUPTIBLE);

	CRYPTO_RETQ_LOCK();
	for (;;) {
		/* Harvest return q's for completed ops */
		crpt = NULL;
		if (!list_empty(&crp_ret_q))
			crpt = list_entry(crp_ret_q.next, typeof(*crpt), crp_next);
		if (crpt != NULL)
			list_del(&crpt->crp_next);

		krpt = NULL;
		if (!list_empty(&crp_ret_kq))
			krpt = list_entry(crp_ret_kq.next, typeof(*krpt), krp_next);
		if (krpt != NULL)
			list_del(&krpt->krp_next);

		if (crpt != NULL || krpt != NULL) {
			CRYPTO_RETQ_UNLOCK();
			/*
			 * Run callbacks unlocked.
			 */
			if (crpt != NULL)
				crpt->crp_callback(crpt);
			if (krpt != NULL)
				krpt->krp_callback(krpt);
			CRYPTO_RETQ_LOCK();
		} else {
			/*
			 * Nothing more to be processed.  Sleep until we're
			 * woken because there are more returns to process.
			 */
			dprintk("%s - sleeping\n", __FUNCTION__);
			CRYPTO_RETQ_UNLOCK();
			wait_event_interruptible(cryptoretproc_wait,
					!list_empty(&crp_ret_q) ||
					!list_empty(&crp_ret_kq) ||
					kthread_should_stop());
			if (signal_pending (current)) {
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
				spin_lock_irq(&current->sigmask_lock);
#endif
				flush_signals(current);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
				spin_unlock_irq(&current->sigmask_lock);
#endif
			}
			CRYPTO_RETQ_LOCK();
			dprintk("%s - awake\n", __FUNCTION__);
			if (kthread_should_stop()) {
				dprintk("%s - EXITING!\n", __FUNCTION__);
				break;
			}
			cryptostats.cs_rets++;
		}
	}
	CRYPTO_RETQ_UNLOCK();
	return 0;
}


#if 0 /* should put this into /proc or something */
static void
db_show_drivers(void)
{
	int hid;

	db_printf("%12s %4s %4s %8s %2s %2s\n"
		, "Device"
		, "Ses"
		, "Kops"
		, "Flags"
		, "QB"
		, "KB"
	);
	for (hid = 0; hid < crypto_drivers_num; hid++) {
		const struct cryptocap *cap = &crypto_drivers[hid];
		if (cap->cc_dev == NULL)
			continue;
		db_printf("%-12s %4u %4u %08x %2u %2u\n"
		    , device_get_nameunit(cap->cc_dev)
		    , cap->cc_sessions
		    , cap->cc_koperations
		    , cap->cc_flags
		    , cap->cc_qblocked
		    , cap->cc_kqblocked
		);
	}
}

DB_SHOW_COMMAND(crypto, db_show_crypto)
{
	struct cryptop *crp;

	db_show_drivers();
	db_printf("\n");

	db_printf("%4s %8s %4s %4s %4s %4s %8s %8s\n",
	    "HID", "Caps", "Ilen", "Olen", "Etype", "Flags",
	    "Desc", "Callback");
	TAILQ_FOREACH(crp, &crp_q, crp_next) {
		db_printf("%4u %08x %4u %4u %4u %04x %8p %8p\n"
		    , (int) CRYPTO_SESID2HID(crp->crp_sid)
		    , (int) CRYPTO_SESID2CAPS(crp->crp_sid)
		    , crp->crp_ilen, crp->crp_olen
		    , crp->crp_etype
		    , crp->crp_flags
		    , crp->crp_desc
		    , crp->crp_callback
		);
	}
	if (!TAILQ_EMPTY(&crp_ret_q)) {
		db_printf("\n%4s %4s %4s %8s\n",
		    "HID", "Etype", "Flags", "Callback");
		TAILQ_FOREACH(crp, &crp_ret_q, crp_next) {
			db_printf("%4u %4u %04x %8p\n"
			    , (int) CRYPTO_SESID2HID(crp->crp_sid)
			    , crp->crp_etype
			    , crp->crp_flags
			    , crp->crp_callback
			);
		}
	}
}

DB_SHOW_COMMAND(kcrypto, db_show_kcrypto)
{
	struct cryptkop *krp;

	db_show_drivers();
	db_printf("\n");

	db_printf("%4s %5s %4s %4s %8s %4s %8s\n",
	    "Op", "Status", "#IP", "#OP", "CRID", "HID", "Callback");
	TAILQ_FOREACH(krp, &crp_kq, krp_next) {
		db_printf("%4u %5u %4u %4u %08x %4u %8p\n"
		    , krp->krp_op
		    , krp->krp_status
		    , krp->krp_iparams, krp->krp_oparams
		    , krp->krp_crid, krp->krp_hid
		    , krp->krp_callback
		);
	}
	if (!TAILQ_EMPTY(&crp_ret_q)) {
		db_printf("%4s %5s %8s %4s %8s\n",
		    "Op", "Status", "CRID", "HID", "Callback");
		TAILQ_FOREACH(krp, &crp_ret_kq, krp_next) {
			db_printf("%4u %5u %08x %4u %8p\n"
			    , krp->krp_op
			    , krp->krp_status
			    , krp->krp_crid, krp->krp_hid
			    , krp->krp_callback
			);
		}
	}
}
#endif


static int
crypto_init(void)
{
	int error;
	unsigned long cpu;

	dprintk("%s(%p)\n", __FUNCTION__, (void *) crypto_init);

	if (crypto_initted)
		return 0;
	crypto_initted = 1;

	spin_lock_init(&crypto_drivers_lock);
	spin_lock_init(&crypto_q_lock);
	spin_lock_init(&crypto_ret_q_lock);

	cryptop_zone = kmem_cache_create("cryptop", sizeof(struct cryptop),
				       0, SLAB_HWCACHE_ALIGN, NULL
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
				       , NULL
#endif
					);

	cryptodesc_zone = kmem_cache_create("cryptodesc", sizeof(struct cryptodesc),
				       0, SLAB_HWCACHE_ALIGN, NULL
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
				       , NULL
#endif
					);

	if (cryptodesc_zone == NULL || cryptop_zone == NULL) {
		printk("crypto: crypto_init cannot setup crypto zones\n");
		error = ENOMEM;
		goto bad;
	}

	crypto_drivers_num = CRYPTO_DRIVERS_INITIAL;
	crypto_drivers = kmalloc(crypto_drivers_num * sizeof(struct cryptocap),
			GFP_KERNEL);
	if (crypto_drivers == NULL) {
		printk("crypto: crypto_init cannot setup crypto drivers\n");
		error = ENOMEM;
		goto bad;
	}

	memset(crypto_drivers, 0, crypto_drivers_num * sizeof(struct cryptocap));

	ocf_for_each_cpu(cpu) {
		cryptoproc[cpu] = kthread_create(crypto_proc, (void *) cpu,
									"ocf_%d", (int) cpu);
		if (IS_ERR(cryptoproc[cpu])) {
			error = PTR_ERR(cryptoproc[cpu]);
			printk("crypto: crypto_init cannot start crypto thread; error %d",
				error);
			goto bad;
		}
		kthread_bind(cryptoproc[cpu], cpu);
		wake_up_process(cryptoproc[cpu]);

		cryptoretproc[cpu] = kthread_create(crypto_ret_proc, (void *) cpu,
									"ocf_ret_%d", (int) cpu);
		if (IS_ERR(cryptoretproc[cpu])) {
			error = PTR_ERR(cryptoretproc[cpu]);
			printk("crypto: crypto_init cannot start cryptoret thread; error %d",
					error);
			goto bad;
		}
		kthread_bind(cryptoretproc[cpu], cpu);
		wake_up_process(cryptoretproc[cpu]);
	}

	return 0;
bad:
	crypto_exit();
	return error;
}


static void
crypto_exit(void)
{
	int cpu;

	dprintk("%s()\n", __FUNCTION__);

	/*
	 * Terminate any crypto threads.
	 */
	ocf_for_each_cpu(cpu) {
		kthread_stop(cryptoproc[cpu]);
		kthread_stop(cryptoretproc[cpu]);
	}

	/* 
	 * Reclaim dynamically allocated resources.
	 */
	if (crypto_drivers != NULL)
		kfree(crypto_drivers);

	if (cryptodesc_zone != NULL)
		kmem_cache_destroy(cryptodesc_zone);
	if (cryptop_zone != NULL)
		kmem_cache_destroy(cryptop_zone);
}


EXPORT_SYMBOL(crypto_newsession);
EXPORT_SYMBOL(crypto_freesession);
EXPORT_SYMBOL(crypto_get_driverid);
EXPORT_SYMBOL(crypto_kregister);
EXPORT_SYMBOL(crypto_register);
EXPORT_SYMBOL(crypto_unregister);
EXPORT_SYMBOL(crypto_unregister_all);
EXPORT_SYMBOL(crypto_unblock);
EXPORT_SYMBOL(crypto_dispatch);
EXPORT_SYMBOL(crypto_kdispatch);
EXPORT_SYMBOL(crypto_freereq);
EXPORT_SYMBOL(crypto_getreq);
EXPORT_SYMBOL(crypto_done);
EXPORT_SYMBOL(crypto_kdone);
EXPORT_SYMBOL(crypto_getfeat);
EXPORT_SYMBOL(crypto_userasymcrypto);
EXPORT_SYMBOL(crypto_getcaps);
EXPORT_SYMBOL(crypto_find_driver);
EXPORT_SYMBOL(crypto_find_device_byhid);

module_init(crypto_init);
module_exit(crypto_exit);

MODULE_LICENSE("BSD");
MODULE_AUTHOR("David McCullough <david_mccullough@mcafee.com>");
MODULE_DESCRIPTION("OCF (OpenBSD Cryptographic Framework)");
