/*
 *
 *			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.5 (Jan 21 2005)
 *
 * Common management module
 */

#include "megaraid_mm.h"
#include <linux/smp_lock.h>


// Entry points for char node driver
static int mraid_mm_open(struct inode *, struct file *);
static int mraid_mm_ioctl(struct inode *, 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(unsigned long);
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 int majorno;
static uint32_t drvr_ver	= 0x02200201;

static int adapters_count_g;
static struct list_head adapters_list_g;

static wait_queue_head_t wait_q;

static struct file_operations lsi_fops = {
	.open	= mraid_mm_open,
	.ioctl	= mraid_mm_ioctl,
#ifdef CONFIG_COMPAT
	.compat_ioctl = mraid_mm_compat_ioctl,
#endif
	.owner	= THIS_MODULE,
};

/**
 * mraid_mm_open - open routine for char node interface
 * @inod	: unused
 * @filep	: unused
 *
 * allow ioctl operations by apps only if they 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 inode *inode, 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
	 */
	kioc = mraid_mm_alloc_kioc(adp);

	/*
	 * 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;
}


/**
 * mraid_mm_get_adapter - Returns corresponding adapters for the mimd packet
 * @umimd	: User space mimd_t ioctl packet
 * @adapter	: pointer to the adapter (OUT)
 */
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 - This routine 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
 */
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
 * @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 (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 	= pci_pool_alloc(pool->handle, GFP_KERNEL,
							&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)
			pci_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 timer_list	timer;
	struct timer_list	*tp = NULL;

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

	if (rval) return rval;

	/*
	 * Start the timer
	 */
	if (adp->timeout > 0) {
		tp		= &timer;
		init_timer(tp);

		tp->function	= lld_timedout;
		tp->data	= (unsigned long)kioc;
		tp->expires	= jiffies + adp->timeout * HZ;

		add_timer(tp);
	}

	/*
	 * 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 (tp) {
		del_timer_sync(tp);
	}

	/*
	 * 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
 *
 * @ptr		: ioctl packet that timed out
 */
static void
lld_timedout(unsigned long ptr)
{
	uioc_t *kioc	= (uioc_t *)ptr;

	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 drvrs
 *
 * @adp	: Adapter objejct
 */
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 = kmalloc(sizeof(mraid_mmadp_t), GFP_KERNEL);

	if (!adapter) {
		rval = -ENOMEM;
		goto memalloc_error;
	}

	memset(adapter, 0, sizeof(mraid_mmadp_t));

	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(sizeof(uioc_t) * lld_adp->max_kioc,
						GFP_KERNEL);
	adapter->mbox_list	= kmalloc(sizeof(mbox64_t) * lld_adp->max_kioc,
						GFP_KERNEL);
	adapter->pthru_dma_pool = pci_pool_create("megaraid mm pthru pool",
						adapter->pdev,
						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", __FUNCTION__,
			__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	= pci_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",
					__FUNCTION__, __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) {
			pci_pool_free(adapter->pthru_dma_pool, kioc->pthru32,
				kioc->pthru32_h);
		}
	}

memalloc_error:

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

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

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

	if (adapter)
		kfree(adapter);

	return rval;
}


/**
 * mraid_mm_adapter_app_handle - return the application handle for this adapter
 *
 * For the given driver data, locate the adadpter in our global list and
 * return the corresponding handle, which is also used by applications to
 * uniquely identify an adapter.
 *
 * @param unique_id : adapter unique identifier
 *
 * @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 = pci_pool_create("megaraid mm data buffer",
						adp->pdev, bufsize, 16, 0);

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

		pool->vaddr = pci_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
 *				  Assume no outstanding ioctls to llds.
 *
 * @unique_id	: UID of the adpater
 */
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;

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

	kfree(adp->kioc_list);

	kfree(adp->mbox_list);

	pci_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)
				pci_pool_free(pool->handle, pool->vaddr,
							pool->paddr);

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

	return;
}

/**
 * mraid_mm_init	: Module entry point
 */
static int __init
mraid_mm_init(void)
{
	// Announce the driver version
	con_log(CL_ANN, (KERN_INFO "megaraid cmm: %s %s\n",
		LSI_COMMON_MOD_VERSION, LSI_COMMON_MOD_EXT_VERSION));

	majorno = register_chrdev(0, "megadev", &lsi_fops);

	if (majorno < 0) {
		con_log(CL_ANN, ("megaraid cmm: cannot get major\n"));
		return majorno;
	}

	init_waitqueue_head(&wait_q);

	INIT_LIST_HEAD(&adapters_list_g);

	return 0;
}


/**
 * mraid_mm_compat_ioctl	: 32bit to 64bit ioctl conversion routine
 */
#ifdef CONFIG_COMPAT
static long
mraid_mm_compat_ioctl(struct file *filep, unsigned int cmd,
		      unsigned long arg)
{
	int err;
	lock_kernel();
	err = mraid_mm_ioctl(NULL, filep, cmd, arg);
	unlock_kernel();
	return err;
}
#endif

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

	unregister_chrdev(majorno, "megadev");
}

module_init(mraid_mm_init);
module_exit(mraid_mm_exit);

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