/*
 *
 *			Linux MegaRAID device driver
 *
 * Copyright (c) 2003-2004  LSI Logic Corporation.
 *
 *	   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 of the License, or (at your option) any later version.
 *
 * FILE		: megaraid_mm.c
 * Version	: v2.20.2.7 (Jul 16 2006)
 *
 * Common management module
 */
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/mutex.h>
#include "megaraid_mm.h"


// Entry points for char node driver
static DEFINE_MUTEX(mraid_mm_mutex);
static int mraid_mm_open(struct inode *, struct file *);
static long mraid_mm_unlocked_ioctl(struct file *, uint, unsigned long);


// routines to convert to and from the old the format
static int mimd_to_kioc(mimd_t __user *, mraid_mmadp_t *, uioc_t *);
static int kioc_to_mimd(uioc_t *, mimd_t __user *);


// Helper functions
static int handle_drvrcmd(void __user *, uint8_t, int *);
static int lld_ioctl(mraid_mmadp_t *, uioc_t *);
static void ioctl_done(uioc_t *);
static void lld_timedout(struct timer_list *);
static void hinfo_to_cinfo(mraid_hba_info_t *, mcontroller_t *);
static mraid_mmadp_t *mraid_mm_get_adapter(mimd_t __user *, int *);
static uioc_t *mraid_mm_alloc_kioc(mraid_mmadp_t *);
static void mraid_mm_dealloc_kioc(mraid_mmadp_t *, uioc_t *);
static int mraid_mm_attach_buf(mraid_mmadp_t *, uioc_t *, int);
static int mraid_mm_setup_dma_pools(mraid_mmadp_t *);
static void mraid_mm_free_adp_resources(mraid_mmadp_t *);
static void mraid_mm_teardown_dma_pools(mraid_mmadp_t *);

#ifdef CONFIG_COMPAT
static long mraid_mm_compat_ioctl(struct file *, unsigned int, unsigned long);
#endif

MODULE_AUTHOR("LSI Logic Corporation");
MODULE_DESCRIPTION("LSI Logic Management Module");
MODULE_LICENSE("GPL");
MODULE_VERSION(LSI_COMMON_MOD_VERSION);

static int dbglevel = CL_ANN;
module_param_named(dlevel, dbglevel, int, 0);
MODULE_PARM_DESC(dlevel, "Debug level (default=0)");

EXPORT_SYMBOL(mraid_mm_register_adp);
EXPORT_SYMBOL(mraid_mm_unregister_adp);
EXPORT_SYMBOL(mraid_mm_adapter_app_handle);

static uint32_t drvr_ver	= 0x02200207;

static int adapters_count_g;
static struct list_head adapters_list_g;

static wait_queue_head_t wait_q;

static const struct file_operations lsi_fops = {
	.open	= mraid_mm_open,
	.unlocked_ioctl = mraid_mm_unlocked_ioctl,
#ifdef CONFIG_COMPAT
	.compat_ioctl = mraid_mm_compat_ioctl,
#endif
	.owner	= THIS_MODULE,
	.llseek = noop_llseek,
};

static struct miscdevice megaraid_mm_dev = {
	.minor	= MISC_DYNAMIC_MINOR,
	.name   = "megadev0",
	.fops   = &lsi_fops,
};

/**
 * mraid_mm_open - open routine for char node interface
 * @inode	: unused
 * @filep	: unused
 *
 * Allow ioctl operations by apps only if they have superuser privilege.
 */
static int
mraid_mm_open(struct inode *inode, struct file *filep)
{
	/*
	 * Only allow superuser to access private ioctl interface
	 */
	if (!capable(CAP_SYS_ADMIN)) return (-EACCES);

	return 0;
}

/**
 * mraid_mm_ioctl - module entry-point for ioctls
 * @inode	: inode (ignored)
 * @filep	: file operations pointer (ignored)
 * @cmd		: ioctl command
 * @arg		: user ioctl packet
 */
static int
mraid_mm_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
{
	uioc_t		*kioc;
	char		signature[EXT_IOCTL_SIGN_SZ]	= {0};
	int		rval;
	mraid_mmadp_t	*adp;
	uint8_t		old_ioctl;
	int		drvrcmd_rval;
	void __user *argp = (void __user *)arg;

	/*
	 * Make sure only USCSICMD are issued through this interface.
	 * MIMD application would still fire different command.
	 */

	if ((_IOC_TYPE(cmd) != MEGAIOC_MAGIC) && (cmd != USCSICMD)) {
		return (-EINVAL);
	}

	/*
	 * Look for signature to see if this is the new or old ioctl format.
	 */
	if (copy_from_user(signature, argp, EXT_IOCTL_SIGN_SZ)) {
		con_log(CL_ANN, (KERN_WARNING
			"megaraid cmm: copy from usr addr failed\n"));
		return (-EFAULT);
	}

	if (memcmp(signature, EXT_IOCTL_SIGN, EXT_IOCTL_SIGN_SZ) == 0)
		old_ioctl = 0;
	else
		old_ioctl = 1;

	/*
	 * At present, we don't support the new ioctl packet
	 */
	if (!old_ioctl )
		return (-EINVAL);

	/*
	 * If it is a driver ioctl (as opposed to fw ioctls), then we can
	 * handle the command locally. rval > 0 means it is not a drvr cmd
	 */
	rval = handle_drvrcmd(argp, old_ioctl, &drvrcmd_rval);

	if (rval < 0)
		return rval;
	else if (rval == 0)
		return drvrcmd_rval;

	rval = 0;
	if ((adp = mraid_mm_get_adapter(argp, &rval)) == NULL) {
		return rval;
	}

	/*
	 * Check if adapter can accept ioctl. We may have marked it offline
	 * if any previous kioc had timedout on this controller.
	 */
	if (!adp->quiescent) {
		con_log(CL_ANN, (KERN_WARNING
			"megaraid cmm: controller cannot accept cmds due to "
			"earlier errors\n" ));
		return -EFAULT;
	}

	/*
	 * The following call will block till a kioc is available
	 * or return NULL if the list head is empty for the pointer
	 * of type mraid_mmapt passed to mraid_mm_alloc_kioc
	 */
	kioc = mraid_mm_alloc_kioc(adp);
	if (!kioc)
		return -ENXIO;

	/*
	 * User sent the old mimd_t ioctl packet. Convert it to uioc_t.
	 */
	if ((rval = mimd_to_kioc(argp, adp, kioc))) {
		mraid_mm_dealloc_kioc(adp, kioc);
		return rval;
	}

	kioc->done = ioctl_done;

	/*
	 * Issue the IOCTL to the low level driver. After the IOCTL completes
	 * release the kioc if and only if it was _not_ timedout. If it was
	 * timedout, that means that resources are still with low level driver.
	 */
	if ((rval = lld_ioctl(adp, kioc))) {

		if (!kioc->timedout)
			mraid_mm_dealloc_kioc(adp, kioc);

		return rval;
	}

	/*
	 * Convert the kioc back to user space
	 */
	rval = kioc_to_mimd(kioc, argp);

	/*
	 * Return the kioc to free pool
	 */
	mraid_mm_dealloc_kioc(adp, kioc);

	return rval;
}

static long
mraid_mm_unlocked_ioctl(struct file *filep, unsigned int cmd,
		        unsigned long arg)
{
	int err;

	/* inconsistent: mraid_mm_compat_ioctl doesn't take the BKL */
	mutex_lock(&mraid_mm_mutex);
	err = mraid_mm_ioctl(filep, cmd, arg);
	mutex_unlock(&mraid_mm_mutex);

	return err;
}

/**
 * mraid_mm_get_adapter - Returns corresponding adapters for the mimd packet
 * @umimd	: User space mimd_t ioctl packet
 * @rval	: returned success/error status
 *
 * The function return value is a pointer to the located @adapter.
 */
static mraid_mmadp_t *
mraid_mm_get_adapter(mimd_t __user *umimd, int *rval)
{
	mraid_mmadp_t	*adapter;
	mimd_t		mimd;
	uint32_t	adapno;
	int		iterator;


	if (copy_from_user(&mimd, umimd, sizeof(mimd_t))) {
		*rval = -EFAULT;
		return NULL;
	}

	adapno = GETADAP(mimd.ui.fcs.adapno);

	if (adapno >= adapters_count_g) {
		*rval = -ENODEV;
		return NULL;
	}

	adapter = NULL;
	iterator = 0;

	list_for_each_entry(adapter, &adapters_list_g, list) {
		if (iterator++ == adapno) break;
	}

	if (!adapter) {
		*rval = -ENODEV;
		return NULL;
	}

	return adapter;
}

/**
 * handle_drvrcmd - Checks if the opcode is a driver cmd and if it is, handles it.
 * @arg		: packet sent by the user app
 * @old_ioctl	: mimd if 1; uioc otherwise
 * @rval	: pointer for command's returned value (not function status)
 */
static int
handle_drvrcmd(void __user *arg, uint8_t old_ioctl, int *rval)
{
	mimd_t		__user *umimd;
	mimd_t		kmimd;
	uint8_t		opcode;
	uint8_t		subopcode;

	if (old_ioctl)
		goto old_packet;
	else
		goto new_packet;

new_packet:
	return (-ENOTSUPP);

old_packet:
	*rval = 0;
	umimd = arg;

	if (copy_from_user(&kmimd, umimd, sizeof(mimd_t)))
		return (-EFAULT);

	opcode		= kmimd.ui.fcs.opcode;
	subopcode	= kmimd.ui.fcs.subopcode;

	/*
	 * If the opcode is 0x82 and the subopcode is either GET_DRVRVER or
	 * GET_NUMADP, then we can handle. Otherwise we should return 1 to
	 * indicate that we cannot handle this.
	 */
	if (opcode != 0x82)
		return 1;

	switch (subopcode) {

	case MEGAIOC_QDRVRVER:

		if (copy_to_user(kmimd.data, &drvr_ver, sizeof(uint32_t)))
			return (-EFAULT);

		return 0;

	case MEGAIOC_QNADAP:

		*rval = adapters_count_g;

		if (copy_to_user(kmimd.data, &adapters_count_g,
				sizeof(uint32_t)))
			return (-EFAULT);

		return 0;

	default:
		/* cannot handle */
		return 1;
	}

	return 0;
}


/**
 * mimd_to_kioc	- Converter from old to new ioctl format
 * @umimd	: user space old MIMD IOCTL
 * @adp		: adapter softstate
 * @kioc	: kernel space new format IOCTL
 *
 * Routine to convert MIMD interface IOCTL to new interface IOCTL packet. The
 * new packet is in kernel space so that driver can perform operations on it
 * freely.
 */

static int
mimd_to_kioc(mimd_t __user *umimd, mraid_mmadp_t *adp, uioc_t *kioc)
{
	mbox64_t		*mbox64;
	mbox_t			*mbox;
	mraid_passthru_t	*pthru32;
	uint32_t		adapno;
	uint8_t			opcode;
	uint8_t			subopcode;
	mimd_t			mimd;

	if (copy_from_user(&mimd, umimd, sizeof(mimd_t)))
		return (-EFAULT);

	/*
	 * Applications are not allowed to send extd pthru
	 */
	if ((mimd.mbox[0] == MBOXCMD_PASSTHRU64) ||
			(mimd.mbox[0] == MBOXCMD_EXTPTHRU))
		return (-EINVAL);

	opcode		= mimd.ui.fcs.opcode;
	subopcode	= mimd.ui.fcs.subopcode;
	adapno		= GETADAP(mimd.ui.fcs.adapno);

	if (adapno >= adapters_count_g)
		return (-ENODEV);

	kioc->adapno	= adapno;
	kioc->mb_type	= MBOX_LEGACY;
	kioc->app_type	= APPTYPE_MIMD;

	switch (opcode) {

	case 0x82:

		if (subopcode == MEGAIOC_QADAPINFO) {

			kioc->opcode	= GET_ADAP_INFO;
			kioc->data_dir	= UIOC_RD;
			kioc->xferlen	= sizeof(mraid_hba_info_t);

			if (mraid_mm_attach_buf(adp, kioc, kioc->xferlen))
				return (-ENOMEM);
		}
		else {
			con_log(CL_ANN, (KERN_WARNING
					"megaraid cmm: Invalid subop\n"));
			return (-EINVAL);
		}

		break;

	case 0x81:

		kioc->opcode		= MBOX_CMD;
		kioc->xferlen		= mimd.ui.fcs.length;
		kioc->user_data_len	= kioc->xferlen;
		kioc->user_data		= mimd.ui.fcs.buffer;

		if (mraid_mm_attach_buf(adp, kioc, kioc->xferlen))
			return (-ENOMEM);

		if (mimd.outlen) kioc->data_dir  = UIOC_RD;
		if (mimd.inlen) kioc->data_dir |= UIOC_WR;

		break;

	case 0x80:

		kioc->opcode		= MBOX_CMD;
		kioc->xferlen		= (mimd.outlen > mimd.inlen) ?
						mimd.outlen : mimd.inlen;
		kioc->user_data_len	= kioc->xferlen;
		kioc->user_data		= mimd.data;

		if (mraid_mm_attach_buf(adp, kioc, kioc->xferlen))
			return (-ENOMEM);

		if (mimd.outlen) kioc->data_dir  = UIOC_RD;
		if (mimd.inlen) kioc->data_dir |= UIOC_WR;

		break;

	default:
		return (-EINVAL);
	}

	/*
	 * If driver command, nothing else to do
	 */
	if (opcode == 0x82)
		return 0;

	/*
	 * This is a mailbox cmd; copy the mailbox from mimd
	 */
	mbox64	= (mbox64_t *)((unsigned long)kioc->cmdbuf);
	mbox	= &mbox64->mbox32;
	memcpy(mbox, mimd.mbox, 14);

	if (mbox->cmd != MBOXCMD_PASSTHRU) {	// regular DCMD

		mbox->xferaddr	= (uint32_t)kioc->buf_paddr;

		if (kioc->data_dir & UIOC_WR) {
			if (copy_from_user(kioc->buf_vaddr, kioc->user_data,
							kioc->xferlen)) {
				return (-EFAULT);
			}
		}

		return 0;
	}

	/*
	 * This is a regular 32-bit pthru cmd; mbox points to pthru struct.
	 * Just like in above case, the beginning for memblk is treated as
	 * a mailbox. The passthru will begin at next 1K boundary. And the
	 * data will start 1K after that.
	 */
	pthru32			= kioc->pthru32;
	kioc->user_pthru	= &umimd->pthru;
	mbox->xferaddr		= (uint32_t)kioc->pthru32_h;

	if (copy_from_user(pthru32, kioc->user_pthru,
			sizeof(mraid_passthru_t))) {
		return (-EFAULT);
	}

	pthru32->dataxferaddr	= kioc->buf_paddr;
	if (kioc->data_dir & UIOC_WR) {
		if (pthru32->dataxferlen > kioc->xferlen)
			return -EINVAL;
		if (copy_from_user(kioc->buf_vaddr, kioc->user_data,
						pthru32->dataxferlen)) {
			return (-EFAULT);
		}
	}

	return 0;
}

/**
 * mraid_mm_attch_buf - Attach a free dma buffer for required size
 * @adp		: Adapter softstate
 * @kioc	: kioc that the buffer needs to be attached to
 * @xferlen	: required length for buffer
 *
 * First we search for a pool with smallest buffer that is >= @xferlen. If
 * that pool has no free buffer, we will try for the next bigger size. If none
 * is available, we will try to allocate the smallest buffer that is >=
 * @xferlen and attach it the pool.
 */
static int
mraid_mm_attach_buf(mraid_mmadp_t *adp, uioc_t *kioc, int xferlen)
{
	mm_dmapool_t	*pool;
	int		right_pool = -1;
	unsigned long	flags;
	int		i;

	kioc->pool_index	= -1;
	kioc->buf_vaddr		= NULL;
	kioc->buf_paddr		= 0;
	kioc->free_buf		= 0;

	/*
	 * We need xferlen amount of memory. See if we can get it from our
	 * dma pools. If we don't get exact size, we will try bigger buffer
	 */

	for (i = 0; i < MAX_DMA_POOLS; i++) {

		pool = &adp->dma_pool_list[i];

		if (xferlen > pool->buf_size)
			continue;

		if (right_pool == -1)
			right_pool = i;

		spin_lock_irqsave(&pool->lock, flags);

		if (!pool->in_use) {

			pool->in_use		= 1;
			kioc->pool_index	= i;
			kioc->buf_vaddr		= pool->vaddr;
			kioc->buf_paddr		= pool->paddr;

			spin_unlock_irqrestore(&pool->lock, flags);
			return 0;
		}
		else {
			spin_unlock_irqrestore(&pool->lock, flags);
			continue;
		}
	}

	/*
	 * If xferlen doesn't match any of our pools, return error
	 */
	if (right_pool == -1)
		return -EINVAL;

	/*
	 * We did not get any buffer from the preallocated pool. Let us try
	 * to allocate one new buffer. NOTE: This is a blocking call.
	 */
	pool = &adp->dma_pool_list[right_pool];

	spin_lock_irqsave(&pool->lock, flags);

	kioc->pool_index	= right_pool;
	kioc->free_buf		= 1;
	kioc->buf_vaddr		= dma_pool_alloc(pool->handle, GFP_ATOMIC,
							&kioc->buf_paddr);
	spin_unlock_irqrestore(&pool->lock, flags);

	if (!kioc->buf_vaddr)
		return -ENOMEM;

	return 0;
}

/**
 * mraid_mm_alloc_kioc - Returns a uioc_t from free list
 * @adp	: Adapter softstate for this module
 *
 * The kioc_semaphore is initialized with number of kioc nodes in the
 * free kioc pool. If the kioc pool is empty, this function blocks till
 * a kioc becomes free.
 */
static uioc_t *
mraid_mm_alloc_kioc(mraid_mmadp_t *adp)
{
	uioc_t			*kioc;
	struct list_head*	head;
	unsigned long		flags;

	down(&adp->kioc_semaphore);

	spin_lock_irqsave(&adp->kioc_pool_lock, flags);

	head = &adp->kioc_pool;

	if (list_empty(head)) {
		up(&adp->kioc_semaphore);
		spin_unlock_irqrestore(&adp->kioc_pool_lock, flags);

		con_log(CL_ANN, ("megaraid cmm: kioc list empty!\n"));
		return NULL;
	}

	kioc = list_entry(head->next, uioc_t, list);
	list_del_init(&kioc->list);

	spin_unlock_irqrestore(&adp->kioc_pool_lock, flags);

	memset((caddr_t)(unsigned long)kioc->cmdbuf, 0, sizeof(mbox64_t));
	memset((caddr_t) kioc->pthru32, 0, sizeof(mraid_passthru_t));

	kioc->buf_vaddr		= NULL;
	kioc->buf_paddr		= 0;
	kioc->pool_index	=-1;
	kioc->free_buf		= 0;
	kioc->user_data		= NULL;
	kioc->user_data_len	= 0;
	kioc->user_pthru	= NULL;
	kioc->timedout		= 0;

	return kioc;
}

/**
 * mraid_mm_dealloc_kioc - Return kioc to free pool
 * @adp		: Adapter softstate
 * @kioc	: uioc_t node to be returned to free pool
 */
static void
mraid_mm_dealloc_kioc(mraid_mmadp_t *adp, uioc_t *kioc)
{
	mm_dmapool_t	*pool;
	unsigned long	flags;

	if (kioc->pool_index != -1) {
		pool = &adp->dma_pool_list[kioc->pool_index];

		/* This routine may be called in non-isr context also */
		spin_lock_irqsave(&pool->lock, flags);

		/*
		 * While attaching the dma buffer, if we didn't get the 
		 * required buffer from the pool, we would have allocated 
		 * it at the run time and set the free_buf flag. We must 
		 * free that buffer. Otherwise, just mark that the buffer is 
		 * not in use
		 */
		if (kioc->free_buf == 1)
			dma_pool_free(pool->handle, kioc->buf_vaddr, 
							kioc->buf_paddr);
		else
			pool->in_use = 0;

		spin_unlock_irqrestore(&pool->lock, flags);
	}

	/* Return the kioc to the free pool */
	spin_lock_irqsave(&adp->kioc_pool_lock, flags);
	list_add(&kioc->list, &adp->kioc_pool);
	spin_unlock_irqrestore(&adp->kioc_pool_lock, flags);

	/* increment the free kioc count */
	up(&adp->kioc_semaphore);

	return;
}

/**
 * lld_ioctl - Routine to issue ioctl to low level drvr
 * @adp		: The adapter handle
 * @kioc	: The ioctl packet with kernel addresses
 */
static int
lld_ioctl(mraid_mmadp_t *adp, uioc_t *kioc)
{
	int			rval;
	struct uioc_timeout	timeout = { };

	kioc->status	= -ENODATA;
	rval		= adp->issue_uioc(adp->drvr_data, kioc, IOCTL_ISSUE);

	if (rval) return rval;

	/*
	 * Start the timer
	 */
	if (adp->timeout > 0) {
		timeout.uioc = kioc;
		timer_setup_on_stack(&timeout.timer, lld_timedout, 0);

		timeout.timer.expires	= jiffies + adp->timeout * HZ;

		add_timer(&timeout.timer);
	}

	/*
	 * Wait till the low level driver completes the ioctl. After this
	 * call, the ioctl either completed successfully or timedout.
	 */
	wait_event(wait_q, (kioc->status != -ENODATA));
	if (timeout.timer.function) {
		del_timer_sync(&timeout.timer);
		destroy_timer_on_stack(&timeout.timer);
	}

	/*
	 * If the command had timedout, we mark the controller offline
	 * before returning
	 */
	if (kioc->timedout) {
		adp->quiescent = 0;
	}

	return kioc->status;
}


/**
 * ioctl_done - callback from the low level driver
 * @kioc	: completed ioctl packet
 */
static void
ioctl_done(uioc_t *kioc)
{
	uint32_t	adapno;
	int		iterator;
	mraid_mmadp_t*	adapter;

	/*
	 * When the kioc returns from driver, make sure it still doesn't
	 * have ENODATA in status. Otherwise, driver will hang on wait_event
	 * forever
	 */
	if (kioc->status == -ENODATA) {
		con_log(CL_ANN, (KERN_WARNING
			"megaraid cmm: lld didn't change status!\n"));

		kioc->status = -EINVAL;
	}

	/*
	 * Check if this kioc was timedout before. If so, nobody is waiting
	 * on this kioc. We don't have to wake up anybody. Instead, we just
	 * have to free the kioc
	 */
	if (kioc->timedout) {
		iterator	= 0;
		adapter		= NULL;
		adapno		= kioc->adapno;

		con_log(CL_ANN, ( KERN_WARNING "megaraid cmm: completed "
					"ioctl that was timedout before\n"));

		list_for_each_entry(adapter, &adapters_list_g, list) {
			if (iterator++ == adapno) break;
		}

		kioc->timedout = 0;

		if (adapter) {
			mraid_mm_dealloc_kioc( adapter, kioc );
		}
	}
	else {
		wake_up(&wait_q);
	}
}


/**
 * lld_timedout	- callback from the expired timer
 * @t		: timer that timed out
 */
static void
lld_timedout(struct timer_list *t)
{
	struct uioc_timeout *timeout = from_timer(timeout, t, timer);
	uioc_t *kioc	= timeout->uioc;

	kioc->status 	= -ETIME;
	kioc->timedout	= 1;

	con_log(CL_ANN, (KERN_WARNING "megaraid cmm: ioctl timed out\n"));

	wake_up(&wait_q);
}


/**
 * kioc_to_mimd	- Converter from new back to old format
 * @kioc	: Kernel space IOCTL packet (successfully issued)
 * @mimd	: User space MIMD packet
 */
static int
kioc_to_mimd(uioc_t *kioc, mimd_t __user *mimd)
{
	mimd_t			kmimd;
	uint8_t			opcode;
	uint8_t			subopcode;

	mbox64_t		*mbox64;
	mraid_passthru_t	__user *upthru32;
	mraid_passthru_t	*kpthru32;
	mcontroller_t		cinfo;
	mraid_hba_info_t	*hinfo;


	if (copy_from_user(&kmimd, mimd, sizeof(mimd_t)))
		return (-EFAULT);

	opcode		= kmimd.ui.fcs.opcode;
	subopcode	= kmimd.ui.fcs.subopcode;

	if (opcode == 0x82) {
		switch (subopcode) {

		case MEGAIOC_QADAPINFO:

			hinfo = (mraid_hba_info_t *)(unsigned long)
					kioc->buf_vaddr;

			hinfo_to_cinfo(hinfo, &cinfo);

			if (copy_to_user(kmimd.data, &cinfo, sizeof(cinfo)))
				return (-EFAULT);

			return 0;

		default:
			return (-EINVAL);
		}

		return 0;
	}

	mbox64 = (mbox64_t *)(unsigned long)kioc->cmdbuf;

	if (kioc->user_pthru) {

		upthru32 = kioc->user_pthru;
		kpthru32 = kioc->pthru32;

		if (copy_to_user(&upthru32->scsistatus,
					&kpthru32->scsistatus,
					sizeof(uint8_t))) {
			return (-EFAULT);
		}
	}

	if (kioc->user_data) {
		if (copy_to_user(kioc->user_data, kioc->buf_vaddr,
					kioc->user_data_len)) {
			return (-EFAULT);
		}
	}

	if (copy_to_user(&mimd->mbox[17],
			&mbox64->mbox32.status, sizeof(uint8_t))) {
		return (-EFAULT);
	}

	return 0;
}


/**
 * hinfo_to_cinfo - Convert new format hba info into old format
 * @hinfo	: New format, more comprehensive adapter info
 * @cinfo	: Old format adapter info to support mimd_t apps
 */
static void
hinfo_to_cinfo(mraid_hba_info_t *hinfo, mcontroller_t *cinfo)
{
	if (!hinfo || !cinfo)
		return;

	cinfo->base		= hinfo->baseport;
	cinfo->irq		= hinfo->irq;
	cinfo->numldrv		= hinfo->num_ldrv;
	cinfo->pcibus		= hinfo->pci_bus;
	cinfo->pcidev		= hinfo->pci_slot;
	cinfo->pcifun		= PCI_FUNC(hinfo->pci_dev_fn);
	cinfo->pciid		= hinfo->pci_device_id;
	cinfo->pcivendor	= hinfo->pci_vendor_id;
	cinfo->pcislot		= hinfo->pci_slot;
	cinfo->uid		= hinfo->unique_id;
}


/**
 * mraid_mm_register_adp - Registration routine for low level drivers
 * @lld_adp	: Adapter object
 */
int
mraid_mm_register_adp(mraid_mmadp_t *lld_adp)
{
	mraid_mmadp_t	*adapter;
	mbox64_t	*mbox_list;
	uioc_t		*kioc;
	uint32_t	rval;
	int		i;


	if (lld_adp->drvr_type != DRVRTYPE_MBOX)
		return (-EINVAL);

	adapter = kzalloc(sizeof(mraid_mmadp_t), GFP_KERNEL);

	if (!adapter)
		return -ENOMEM;


	adapter->unique_id	= lld_adp->unique_id;
	adapter->drvr_type	= lld_adp->drvr_type;
	adapter->drvr_data	= lld_adp->drvr_data;
	adapter->pdev		= lld_adp->pdev;
	adapter->issue_uioc	= lld_adp->issue_uioc;
	adapter->timeout	= lld_adp->timeout;
	adapter->max_kioc	= lld_adp->max_kioc;
	adapter->quiescent	= 1;

	/*
	 * Allocate single blocks of memory for all required kiocs,
	 * mailboxes and passthru structures.
	 */
	adapter->kioc_list	= kmalloc_array(lld_adp->max_kioc,
						  sizeof(uioc_t),
						  GFP_KERNEL);
	adapter->mbox_list	= kmalloc_array(lld_adp->max_kioc,
						  sizeof(mbox64_t),
						  GFP_KERNEL);
	adapter->pthru_dma_pool = dma_pool_create("megaraid mm pthru pool",
						&adapter->pdev->dev,
						sizeof(mraid_passthru_t),
						16, 0);

	if (!adapter->kioc_list || !adapter->mbox_list ||
			!adapter->pthru_dma_pool) {

		con_log(CL_ANN, (KERN_WARNING
			"megaraid cmm: out of memory, %s %d\n", __func__,
			__LINE__));

		rval = (-ENOMEM);

		goto memalloc_error;
	}

	/*
	 * Slice kioc_list and make a kioc_pool with the individiual kiocs
	 */
	INIT_LIST_HEAD(&adapter->kioc_pool);
	spin_lock_init(&adapter->kioc_pool_lock);
	sema_init(&adapter->kioc_semaphore, lld_adp->max_kioc);

	mbox_list	= (mbox64_t *)adapter->mbox_list;

	for (i = 0; i < lld_adp->max_kioc; i++) {

		kioc		= adapter->kioc_list + i;
		kioc->cmdbuf	= (uint64_t)(unsigned long)(mbox_list + i);
		kioc->pthru32	= dma_pool_alloc(adapter->pthru_dma_pool,
						GFP_KERNEL, &kioc->pthru32_h);

		if (!kioc->pthru32) {

			con_log(CL_ANN, (KERN_WARNING
				"megaraid cmm: out of memory, %s %d\n",
					__func__, __LINE__));

			rval = (-ENOMEM);

			goto pthru_dma_pool_error;
		}

		list_add_tail(&kioc->list, &adapter->kioc_pool);
	}

	// Setup the dma pools for data buffers
	if ((rval = mraid_mm_setup_dma_pools(adapter)) != 0) {
		goto dma_pool_error;
	}

	list_add_tail(&adapter->list, &adapters_list_g);

	adapters_count_g++;

	return 0;

dma_pool_error:
	/* Do nothing */

pthru_dma_pool_error:

	for (i = 0; i < lld_adp->max_kioc; i++) {
		kioc = adapter->kioc_list + i;
		if (kioc->pthru32) {
			dma_pool_free(adapter->pthru_dma_pool, kioc->pthru32,
				kioc->pthru32_h);
		}
	}

memalloc_error:

	kfree(adapter->kioc_list);
	kfree(adapter->mbox_list);

	if (adapter->pthru_dma_pool)
		dma_pool_destroy(adapter->pthru_dma_pool);

	kfree(adapter);

	return rval;
}


/**
 * mraid_mm_adapter_app_handle - return the application handle for this adapter
 * @unique_id	: adapter unique identifier
 *
 * For the given driver data, locate the adapter in our global list and
 * return the corresponding handle, which is also used by applications to
 * uniquely identify an adapter.
 *
 * Return adapter handle if found in the list.
 * Return 0 if adapter could not be located, should never happen though.
 */
uint32_t
mraid_mm_adapter_app_handle(uint32_t unique_id)
{
	mraid_mmadp_t	*adapter;
	mraid_mmadp_t	*tmp;
	int		index = 0;

	list_for_each_entry_safe(adapter, tmp, &adapters_list_g, list) {

		if (adapter->unique_id == unique_id) {

			return MKADAP(index);
		}

		index++;
	}

	return 0;
}


/**
 * mraid_mm_setup_dma_pools - Set up dma buffer pools per adapter
 * @adp	: Adapter softstate
 *
 * We maintain a pool of dma buffers per each adapter. Each pool has one
 * buffer. E.g, we may have 5 dma pools - one each for 4k, 8k ... 64k buffers.
 * We have just one 4k buffer in 4k pool, one 8k buffer in 8k pool etc. We
 * dont' want to waste too much memory by allocating more buffers per each
 * pool.
 */
static int
mraid_mm_setup_dma_pools(mraid_mmadp_t *adp)
{
	mm_dmapool_t	*pool;
	int		bufsize;
	int		i;

	/*
	 * Create MAX_DMA_POOLS number of pools
	 */
	bufsize = MRAID_MM_INIT_BUFF_SIZE;

	for (i = 0; i < MAX_DMA_POOLS; i++){

		pool = &adp->dma_pool_list[i];

		pool->buf_size = bufsize;
		spin_lock_init(&pool->lock);

		pool->handle = dma_pool_create("megaraid mm data buffer",
						&adp->pdev->dev, bufsize,
						16, 0);

		if (!pool->handle) {
			goto dma_pool_setup_error;
		}

		pool->vaddr = dma_pool_alloc(pool->handle, GFP_KERNEL,
							&pool->paddr);

		if (!pool->vaddr)
			goto dma_pool_setup_error;

		bufsize = bufsize * 2;
	}

	return 0;

dma_pool_setup_error:

	mraid_mm_teardown_dma_pools(adp);
	return (-ENOMEM);
}


/**
 * mraid_mm_unregister_adp - Unregister routine for low level drivers
 * @unique_id	: UID of the adpater
 *
 * Assumes no outstanding ioctls to llds.
 */
int
mraid_mm_unregister_adp(uint32_t unique_id)
{
	mraid_mmadp_t	*adapter;
	mraid_mmadp_t	*tmp;

	list_for_each_entry_safe(adapter, tmp, &adapters_list_g, list) {


		if (adapter->unique_id == unique_id) {

			adapters_count_g--;

			list_del_init(&adapter->list);

			mraid_mm_free_adp_resources(adapter);

			kfree(adapter);

			con_log(CL_ANN, (
				"megaraid cmm: Unregistered one adapter:%#x\n",
				unique_id));

			return 0;
		}
	}

	return (-ENODEV);
}

/**
 * mraid_mm_free_adp_resources - Free adapter softstate
 * @adp	: Adapter softstate
 */
static void
mraid_mm_free_adp_resources(mraid_mmadp_t *adp)
{
	uioc_t	*kioc;
	int	i;

	mraid_mm_teardown_dma_pools(adp);

	for (i = 0; i < adp->max_kioc; i++) {

		kioc = adp->kioc_list + i;

		dma_pool_free(adp->pthru_dma_pool, kioc->pthru32,
				kioc->pthru32_h);
	}

	kfree(adp->kioc_list);
	kfree(adp->mbox_list);

	dma_pool_destroy(adp->pthru_dma_pool);


	return;
}


/**
 * mraid_mm_teardown_dma_pools - Free all per adapter dma buffers
 * @adp	: Adapter softstate
 */
static void
mraid_mm_teardown_dma_pools(mraid_mmadp_t *adp)
{
	int		i;
	mm_dmapool_t	*pool;

	for (i = 0; i < MAX_DMA_POOLS; i++) {

		pool = &adp->dma_pool_list[i];

		if (pool->handle) {

			if (pool->vaddr)
				dma_pool_free(pool->handle, pool->vaddr,
							pool->paddr);

			dma_pool_destroy(pool->handle);
			pool->handle = NULL;
		}
	}

	return;
}

/**
 * mraid_mm_init	- Module entry point
 */
static int __init
mraid_mm_init(void)
{
	int err;

	// Announce the driver version
	con_log(CL_ANN, (KERN_INFO "megaraid cmm: %s %s\n",
		LSI_COMMON_MOD_VERSION, LSI_COMMON_MOD_EXT_VERSION));

	err = misc_register(&megaraid_mm_dev);
	if (err < 0) {
		con_log(CL_ANN, ("megaraid cmm: cannot register misc device\n"));
		return err;
	}

	init_waitqueue_head(&wait_q);

	INIT_LIST_HEAD(&adapters_list_g);

	return 0;
}


#ifdef CONFIG_COMPAT
/**
 * mraid_mm_compat_ioctl	- 32bit to 64bit ioctl conversion routine
 * @filep	: file operations pointer (ignored)
 * @cmd		: ioctl command
 * @arg		: user ioctl packet
 */
static long
mraid_mm_compat_ioctl(struct file *filep, unsigned int cmd,
		      unsigned long arg)
{
	int err;

	err = mraid_mm_ioctl(filep, cmd, arg);

	return err;
}
#endif

/**
 * mraid_mm_exit	- Module exit point
 */
static void __exit
mraid_mm_exit(void)
{
	con_log(CL_DLEVEL1 , ("exiting common mod\n"));

	misc_deregister(&megaraid_mm_dev);
}

module_init(mraid_mm_init);
module_exit(mraid_mm_exit);

/* vi: set ts=8 sw=8 tw=78: */
