/*
 *
 *			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_mbox.c
 * Version	: v2.20.5.1 (Nov 16 2006)
 *
 * Authors:
 * 	Atul Mukker		<Atul.Mukker@lsi.com>
 * 	Sreenivas Bagalkote	<Sreenivas.Bagalkote@lsi.com>
 * 	Manoj Jose		<Manoj.Jose@lsi.com>
 * 	Seokmann Ju
 *
 * List of supported controllers
 *
 * OEM	Product Name			VID	DID	SSVID	SSID
 * ---	------------			---	---	----	----
 * Dell PERC3/QC			101E	1960	1028	0471
 * Dell PERC3/DC			101E	1960	1028	0493
 * Dell PERC3/SC			101E	1960	1028	0475
 * Dell PERC3/Di			1028	1960	1028	0123
 * Dell PERC4/SC			1000	1960	1028	0520
 * Dell PERC4/DC			1000	1960	1028	0518
 * Dell PERC4/QC			1000	0407	1028	0531
 * Dell PERC4/Di			1028	000F	1028	014A
 * Dell PERC 4e/Si			1028	0013	1028	016c
 * Dell PERC 4e/Di			1028	0013	1028	016d
 * Dell PERC 4e/Di			1028	0013	1028	016e
 * Dell PERC 4e/Di			1028	0013	1028	016f
 * Dell PERC 4e/Di			1028	0013	1028	0170
 * Dell PERC 4e/DC			1000	0408	1028	0002
 * Dell PERC 4e/SC			1000	0408	1028	0001
 *
 *
 * LSI MegaRAID SCSI 320-0		1000	1960	1000	A520
 * LSI MegaRAID SCSI 320-1		1000	1960	1000	0520
 * LSI MegaRAID SCSI 320-2		1000	1960	1000	0518
 * LSI MegaRAID SCSI 320-0X		1000	0407	1000	0530
 * LSI MegaRAID SCSI 320-2X		1000	0407	1000	0532
 * LSI MegaRAID SCSI 320-4X		1000	0407	1000	0531
 * LSI MegaRAID SCSI 320-1E		1000	0408	1000	0001
 * LSI MegaRAID SCSI 320-2E		1000	0408	1000	0002
 * LSI MegaRAID SATA 150-4		1000	1960	1000	4523
 * LSI MegaRAID SATA 150-6		1000	1960	1000	0523
 * LSI MegaRAID SATA 300-4X		1000	0409	1000	3004
 * LSI MegaRAID SATA 300-8X		1000	0409	1000	3008
 *
 * INTEL RAID Controller SRCU42X	1000	0407	8086	0532
 * INTEL RAID Controller SRCS16		1000	1960	8086	0523
 * INTEL RAID Controller SRCU42E	1000	0408	8086	0002
 * INTEL RAID Controller SRCZCRX	1000	0407	8086	0530
 * INTEL RAID Controller SRCS28X	1000	0409	8086	3008
 * INTEL RAID Controller SROMBU42E	1000	0408	8086	3431
 * INTEL RAID Controller SROMBU42E	1000	0408	8086	3499
 * INTEL RAID Controller SRCU51L	1000	1960	8086	0520
 *
 * FSC	MegaRAID PCI Express ROMB	1000	0408	1734	1065
 *
 * ACER	MegaRAID ROMB-2E		1000	0408	1025	004D
 *
 * NEC	MegaRAID PCI Express ROMB	1000	0408	1033	8287
 *
 * For history of changes, see Documentation/scsi/ChangeLog.megaraid
 */

#include <linux/slab.h>
#include <linux/module.h>
#include "megaraid_mbox.h"

static int megaraid_init(void);
static void megaraid_exit(void);

static int megaraid_probe_one(struct pci_dev*, const struct pci_device_id *);
static void megaraid_detach_one(struct pci_dev *);
static void megaraid_mbox_shutdown(struct pci_dev *);

static int megaraid_io_attach(adapter_t *);
static void megaraid_io_detach(adapter_t *);

static int megaraid_init_mbox(adapter_t *);
static void megaraid_fini_mbox(adapter_t *);

static int megaraid_alloc_cmd_packets(adapter_t *);
static void megaraid_free_cmd_packets(adapter_t *);

static int megaraid_mbox_setup_dma_pools(adapter_t *);
static void megaraid_mbox_teardown_dma_pools(adapter_t *);

static int megaraid_sysfs_alloc_resources(adapter_t *);
static void megaraid_sysfs_free_resources(adapter_t *);

static int megaraid_abort_handler(struct scsi_cmnd *);
static int megaraid_reset_handler(struct scsi_cmnd *);

static int mbox_post_sync_cmd(adapter_t *, uint8_t []);
static int mbox_post_sync_cmd_fast(adapter_t *, uint8_t []);
static int megaraid_busywait_mbox(mraid_device_t *);
static int megaraid_mbox_product_info(adapter_t *);
static int megaraid_mbox_extended_cdb(adapter_t *);
static int megaraid_mbox_support_ha(adapter_t *, uint16_t *);
static int megaraid_mbox_support_random_del(adapter_t *);
static int megaraid_mbox_get_max_sg(adapter_t *);
static void megaraid_mbox_enum_raid_scsi(adapter_t *);
static void megaraid_mbox_flush_cache(adapter_t *);
static int megaraid_mbox_fire_sync_cmd(adapter_t *);

static void megaraid_mbox_display_scb(adapter_t *, scb_t *);
static void megaraid_mbox_setup_device_map(adapter_t *);

static int megaraid_queue_command(struct Scsi_Host *, struct scsi_cmnd *);
static scb_t *megaraid_mbox_build_cmd(adapter_t *, struct scsi_cmnd *, int *);
static void megaraid_mbox_runpendq(adapter_t *, scb_t *);
static void megaraid_mbox_prepare_pthru(adapter_t *, scb_t *,
		struct scsi_cmnd *);
static void megaraid_mbox_prepare_epthru(adapter_t *, scb_t *,
		struct scsi_cmnd *);

static irqreturn_t megaraid_isr(int, void *);

static void megaraid_mbox_dpc(unsigned long);

static ssize_t megaraid_sysfs_show_app_hndl(struct device *, struct device_attribute *attr, char *);
static ssize_t megaraid_sysfs_show_ldnum(struct device *, struct device_attribute *attr, char *);

static int megaraid_cmm_register(adapter_t *);
static int megaraid_cmm_unregister(adapter_t *);
static int megaraid_mbox_mm_handler(unsigned long, uioc_t *, uint32_t);
static int megaraid_mbox_mm_command(adapter_t *, uioc_t *);
static void megaraid_mbox_mm_done(adapter_t *, scb_t *);
static int gather_hbainfo(adapter_t *, mraid_hba_info_t *);
static int wait_till_fw_empty(adapter_t *);



MODULE_AUTHOR("megaraidlinux@lsi.com");
MODULE_DESCRIPTION("LSI Logic MegaRAID Mailbox Driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(MEGARAID_VERSION);

/*
 * ### modules parameters for driver ###
 */

/*
 * Set to enable driver to expose unconfigured disk to kernel
 */
static int megaraid_expose_unconf_disks = 0;
module_param_named(unconf_disks, megaraid_expose_unconf_disks, int, 0);
MODULE_PARM_DESC(unconf_disks,
	"Set to expose unconfigured disks to kernel (default=0)");

/*
 * driver wait time if the adapter's mailbox is busy
 */
static unsigned int max_mbox_busy_wait = MBOX_BUSY_WAIT;
module_param_named(busy_wait, max_mbox_busy_wait, int, 0);
MODULE_PARM_DESC(busy_wait,
	"Max wait for mailbox in microseconds if busy (default=10)");

/*
 * number of sectors per IO command
 */
static unsigned int megaraid_max_sectors = MBOX_MAX_SECTORS;
module_param_named(max_sectors, megaraid_max_sectors, int, 0);
MODULE_PARM_DESC(max_sectors,
	"Maximum number of sectors per IO command (default=128)");

/*
 * number of commands per logical unit
 */
static unsigned int megaraid_cmd_per_lun = MBOX_DEF_CMD_PER_LUN;
module_param_named(cmd_per_lun, megaraid_cmd_per_lun, int, 0);
MODULE_PARM_DESC(cmd_per_lun,
	"Maximum number of commands per logical unit (default=64)");


/*
 * Fast driver load option, skip scanning for physical devices during load.
 * This would result in non-disk devices being skipped during driver load
 * time. These can be later added though, using /proc/scsi/scsi
 */
static unsigned int megaraid_fast_load = 0;
module_param_named(fast_load, megaraid_fast_load, int, 0);
MODULE_PARM_DESC(fast_load,
	"Faster loading of the driver, skips physical devices! (default=0)");


/*
 * mraid_debug level - threshold for amount of information to be displayed by
 * the driver. This level can be changed through modules parameters, ioctl or
 * sysfs/proc interface. By default, print the announcement messages only.
 */
int mraid_debug_level = CL_ANN;
module_param_named(debug_level, mraid_debug_level, int, 0);
MODULE_PARM_DESC(debug_level, "Debug level for driver (default=0)");

/*
 * ### global data ###
 */
static uint8_t megaraid_mbox_version[8] =
	{ 0x02, 0x20, 0x04, 0x06, 3, 7, 20, 5 };


/*
 * PCI table for all supported controllers.
 */
static struct pci_device_id pci_id_table_g[] =  {
	{
		PCI_VENDOR_ID_DELL,
		PCI_DEVICE_ID_PERC4_DI_DISCOVERY,
		PCI_VENDOR_ID_DELL,
		PCI_SUBSYS_ID_PERC4_DI_DISCOVERY,
	},
	{
		PCI_VENDOR_ID_LSI_LOGIC,
		PCI_DEVICE_ID_PERC4_SC,
		PCI_VENDOR_ID_DELL,
		PCI_SUBSYS_ID_PERC4_SC,
	},
	{
		PCI_VENDOR_ID_LSI_LOGIC,
		PCI_DEVICE_ID_PERC4_DC,
		PCI_VENDOR_ID_DELL,
		PCI_SUBSYS_ID_PERC4_DC,
	},
	{
		PCI_VENDOR_ID_LSI_LOGIC,
		PCI_DEVICE_ID_VERDE,
		PCI_ANY_ID,
		PCI_ANY_ID,
	},
	{
		PCI_VENDOR_ID_DELL,
		PCI_DEVICE_ID_PERC4_DI_EVERGLADES,
		PCI_VENDOR_ID_DELL,
		PCI_SUBSYS_ID_PERC4_DI_EVERGLADES,
	},
	{
		PCI_VENDOR_ID_DELL,
		PCI_DEVICE_ID_PERC4E_SI_BIGBEND,
		PCI_VENDOR_ID_DELL,
		PCI_SUBSYS_ID_PERC4E_SI_BIGBEND,
	},
	{
		PCI_VENDOR_ID_DELL,
		PCI_DEVICE_ID_PERC4E_DI_KOBUK,
		PCI_VENDOR_ID_DELL,
		PCI_SUBSYS_ID_PERC4E_DI_KOBUK,
	},
	{
		PCI_VENDOR_ID_DELL,
		PCI_DEVICE_ID_PERC4E_DI_CORVETTE,
		PCI_VENDOR_ID_DELL,
		PCI_SUBSYS_ID_PERC4E_DI_CORVETTE,
	},
	{
		PCI_VENDOR_ID_DELL,
		PCI_DEVICE_ID_PERC4E_DI_EXPEDITION,
		PCI_VENDOR_ID_DELL,
		PCI_SUBSYS_ID_PERC4E_DI_EXPEDITION,
	},
	{
		PCI_VENDOR_ID_DELL,
		PCI_DEVICE_ID_PERC4E_DI_GUADALUPE,
		PCI_VENDOR_ID_DELL,
		PCI_SUBSYS_ID_PERC4E_DI_GUADALUPE,
	},
	{
		PCI_VENDOR_ID_LSI_LOGIC,
		PCI_DEVICE_ID_DOBSON,
		PCI_ANY_ID,
		PCI_ANY_ID,
	},
	{
		PCI_VENDOR_ID_AMI,
		PCI_DEVICE_ID_AMI_MEGARAID3,
		PCI_ANY_ID,
		PCI_ANY_ID,
	},
	{
		PCI_VENDOR_ID_LSI_LOGIC,
		PCI_DEVICE_ID_AMI_MEGARAID3,
		PCI_ANY_ID,
		PCI_ANY_ID,
	},
	{
		PCI_VENDOR_ID_LSI_LOGIC,
		PCI_DEVICE_ID_LINDSAY,
		PCI_ANY_ID,
		PCI_ANY_ID,
	},
	{0}	/* Terminating entry */
};
MODULE_DEVICE_TABLE(pci, pci_id_table_g);


static struct pci_driver megaraid_pci_driver = {
	.name		= "megaraid",
	.id_table	= pci_id_table_g,
	.probe		= megaraid_probe_one,
	.remove		= megaraid_detach_one,
	.shutdown	= megaraid_mbox_shutdown,
};



// definitions for the device attributes for exporting logical drive number
// for a scsi address (Host, Channel, Id, Lun)

DEVICE_ATTR(megaraid_mbox_app_hndl, S_IRUSR, megaraid_sysfs_show_app_hndl,
		NULL);

// Host template initializer for megaraid mbox sysfs device attributes
static struct device_attribute *megaraid_shost_attrs[] = {
	&dev_attr_megaraid_mbox_app_hndl,
	NULL,
};


DEVICE_ATTR(megaraid_mbox_ld, S_IRUSR, megaraid_sysfs_show_ldnum, NULL);

// Host template initializer for megaraid mbox sysfs device attributes
static struct device_attribute *megaraid_sdev_attrs[] = {
	&dev_attr_megaraid_mbox_ld,
	NULL,
};

/**
 * megaraid_change_queue_depth - Change the device's queue depth
 * @sdev:	scsi device struct
 * @qdepth:	depth to set
 * @reason:	calling context
 *
 * Return value:
 * 	actual depth set
 */
static int megaraid_change_queue_depth(struct scsi_device *sdev, int qdepth,
				       int reason)
{
	if (reason != SCSI_QDEPTH_DEFAULT)
		return -EOPNOTSUPP;

	if (qdepth > MBOX_MAX_SCSI_CMDS)
		qdepth = MBOX_MAX_SCSI_CMDS;
	scsi_adjust_queue_depth(sdev, 0, qdepth);
	return sdev->queue_depth;
}

/*
 * Scsi host template for megaraid unified driver
 */
static struct scsi_host_template megaraid_template_g = {
	.module				= THIS_MODULE,
	.name				= "LSI Logic MegaRAID driver",
	.proc_name			= "megaraid",
	.queuecommand			= megaraid_queue_command,
	.eh_abort_handler		= megaraid_abort_handler,
	.eh_device_reset_handler	= megaraid_reset_handler,
	.eh_bus_reset_handler		= megaraid_reset_handler,
	.eh_host_reset_handler		= megaraid_reset_handler,
	.change_queue_depth		= megaraid_change_queue_depth,
	.use_clustering			= ENABLE_CLUSTERING,
	.sdev_attrs			= megaraid_sdev_attrs,
	.shost_attrs			= megaraid_shost_attrs,
};


/**
 * megaraid_init - module load hook
 *
 * We register ourselves as hotplug enabled module and let PCI subsystem
 * discover our adapters.
 */
static int __init
megaraid_init(void)
{
	int	rval;

	// Announce the driver version
	con_log(CL_ANN, (KERN_INFO "megaraid: %s %s\n", MEGARAID_VERSION,
		MEGARAID_EXT_VERSION));

	// check validity of module parameters
	if (megaraid_cmd_per_lun > MBOX_MAX_SCSI_CMDS) {

		con_log(CL_ANN, (KERN_WARNING
			"megaraid mailbox: max commands per lun reset to %d\n",
			MBOX_MAX_SCSI_CMDS));

		megaraid_cmd_per_lun = MBOX_MAX_SCSI_CMDS;
	}


	// register as a PCI hot-plug driver module
	rval = pci_register_driver(&megaraid_pci_driver);
	if (rval < 0) {
		con_log(CL_ANN, (KERN_WARNING
			"megaraid: could not register hotplug support.\n"));
	}

	return rval;
}


/**
 * megaraid_exit - driver unload entry point
 *
 * We simply unwrap the megaraid_init routine here.
 */
static void __exit
megaraid_exit(void)
{
	con_log(CL_DLEVEL1, (KERN_NOTICE "megaraid: unloading framework\n"));

	// unregister as PCI hotplug driver
	pci_unregister_driver(&megaraid_pci_driver);

	return;
}


/**
 * megaraid_probe_one - PCI hotplug entry point
 * @pdev	: handle to this controller's PCI configuration space
 * @id		: pci device id of the class of controllers
 *
 * This routine should be called whenever a new adapter is detected by the
 * PCI hotplug susbsystem.
 */
static int
megaraid_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
{
	adapter_t	*adapter;


	// detected a new controller
	con_log(CL_ANN, (KERN_INFO
		"megaraid: probe new device %#4.04x:%#4.04x:%#4.04x:%#4.04x: ",
		pdev->vendor, pdev->device, pdev->subsystem_vendor,
		pdev->subsystem_device));

	con_log(CL_ANN, ("bus %d:slot %d:func %d\n", pdev->bus->number,
		PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn)));

	if (pci_enable_device(pdev)) {
		con_log(CL_ANN, (KERN_WARNING
				"megaraid: pci_enable_device failed\n"));

		return -ENODEV;
	}

	// Enable bus-mastering on this controller
	pci_set_master(pdev);

	// Allocate the per driver initialization structure
	adapter = kzalloc(sizeof(adapter_t), GFP_KERNEL);

	if (adapter == NULL) {
		con_log(CL_ANN, (KERN_WARNING
		"megaraid: out of memory, %s %d.\n", __func__, __LINE__));

		goto out_probe_one;
	}


	// set up PCI related soft state and other pre-known parameters
	adapter->unique_id	= pdev->bus->number << 8 | pdev->devfn;
	adapter->irq		= pdev->irq;
	adapter->pdev		= pdev;

	atomic_set(&adapter->being_detached, 0);

	// Setup the default DMA mask. This would be changed later on
	// depending on hardware capabilities
	if (pci_set_dma_mask(adapter->pdev, DMA_BIT_MASK(32)) != 0) {

		con_log(CL_ANN, (KERN_WARNING
			"megaraid: pci_set_dma_mask failed:%d\n", __LINE__));

		goto out_free_adapter;
	}


	// Initialize the synchronization lock for kernel and LLD
	spin_lock_init(&adapter->lock);

	// Initialize the command queues: the list of free SCBs and the list
	// of pending SCBs.
	INIT_LIST_HEAD(&adapter->kscb_pool);
	spin_lock_init(SCSI_FREE_LIST_LOCK(adapter));

	INIT_LIST_HEAD(&adapter->pend_list);
	spin_lock_init(PENDING_LIST_LOCK(adapter));

	INIT_LIST_HEAD(&adapter->completed_list);
	spin_lock_init(COMPLETED_LIST_LOCK(adapter));


	// Start the mailbox based controller
	if (megaraid_init_mbox(adapter) != 0) {
		con_log(CL_ANN, (KERN_WARNING
			"megaraid: maibox adapter did not initialize\n"));

		goto out_free_adapter;
	}

	// Register with LSI Common Management Module
	if (megaraid_cmm_register(adapter) != 0) {

		con_log(CL_ANN, (KERN_WARNING
		"megaraid: could not register with management module\n"));

		goto out_fini_mbox;
	}

	// setup adapter handle in PCI soft state
	pci_set_drvdata(pdev, adapter);

	// attach with scsi mid-layer
	if (megaraid_io_attach(adapter) != 0) {

		con_log(CL_ANN, (KERN_WARNING "megaraid: io attach failed\n"));

		goto out_cmm_unreg;
	}

	return 0;

out_cmm_unreg:
	megaraid_cmm_unregister(adapter);
out_fini_mbox:
	megaraid_fini_mbox(adapter);
out_free_adapter:
	kfree(adapter);
out_probe_one:
	pci_disable_device(pdev);

	return -ENODEV;
}


/**
 * megaraid_detach_one - release framework resources and call LLD release routine
 * @pdev	: handle for our PCI configuration space
 *
 * This routine is called during driver unload. We free all the allocated
 * resources and call the corresponding LLD so that it can also release all
 * its resources.
 *
 * This routine is also called from the PCI hotplug system.
 */
static void
megaraid_detach_one(struct pci_dev *pdev)
{
	adapter_t		*adapter;
	struct Scsi_Host	*host;


	// Start a rollback on this adapter
	adapter = pci_get_drvdata(pdev);

	if (!adapter) {
		con_log(CL_ANN, (KERN_CRIT
		"megaraid: Invalid detach on %#4.04x:%#4.04x:%#4.04x:%#4.04x\n",
			pdev->vendor, pdev->device, pdev->subsystem_vendor,
			pdev->subsystem_device));

		return;
	}
	else {
		con_log(CL_ANN, (KERN_NOTICE
		"megaraid: detaching device %#4.04x:%#4.04x:%#4.04x:%#4.04x\n",
			pdev->vendor, pdev->device, pdev->subsystem_vendor,
			pdev->subsystem_device));
	}


	host = adapter->host;

	// do not allow any more requests from the management module for this
	// adapter.
	// FIXME: How do we account for the request which might still be
	// pending with us?
	atomic_set(&adapter->being_detached, 1);

	// detach from the IO sub-system
	megaraid_io_detach(adapter);

	// Unregister from common management module
	//
	// FIXME: this must return success or failure for conditions if there
	// is a command pending with LLD or not.
	megaraid_cmm_unregister(adapter);

	// finalize the mailbox based controller and release all resources
	megaraid_fini_mbox(adapter);

	kfree(adapter);

	scsi_host_put(host);

	pci_disable_device(pdev);

	return;
}


/**
 * megaraid_mbox_shutdown - PCI shutdown for megaraid HBA
 * @pdev		: generic driver model device
 *
 * Shutdown notification, perform flush cache.
 */
static void
megaraid_mbox_shutdown(struct pci_dev *pdev)
{
	adapter_t		*adapter = pci_get_drvdata(pdev);
	static int		counter;

	if (!adapter) {
		con_log(CL_ANN, (KERN_WARNING
			"megaraid: null device in shutdown\n"));
		return;
	}

	// flush caches now
	con_log(CL_ANN, (KERN_INFO "megaraid: flushing adapter %d...",
		counter++));

	megaraid_mbox_flush_cache(adapter);

	con_log(CL_ANN, ("done\n"));
}


/**
 * megaraid_io_attach - attach a device with the IO subsystem
 * @adapter		: controller's soft state
 *
 * Attach this device with the IO subsystem.
 */
static int
megaraid_io_attach(adapter_t *adapter)
{
	struct Scsi_Host	*host;

	// Initialize SCSI Host structure
	host = scsi_host_alloc(&megaraid_template_g, 8);
	if (!host) {
		con_log(CL_ANN, (KERN_WARNING
			"megaraid mbox: scsi_register failed\n"));

		return -1;
	}

	SCSIHOST2ADAP(host)	= (caddr_t)adapter;
	adapter->host		= host;

	host->irq		= adapter->irq;
	host->unique_id		= adapter->unique_id;
	host->can_queue		= adapter->max_cmds;
	host->this_id		= adapter->init_id;
	host->sg_tablesize	= adapter->sglen;
	host->max_sectors	= adapter->max_sectors;
	host->cmd_per_lun	= adapter->cmd_per_lun;
	host->max_channel	= adapter->max_channel;
	host->max_id		= adapter->max_target;
	host->max_lun		= adapter->max_lun;


	// notify mid-layer about the new controller
	if (scsi_add_host(host, &adapter->pdev->dev)) {

		con_log(CL_ANN, (KERN_WARNING
			"megaraid mbox: scsi_add_host failed\n"));

		scsi_host_put(host);

		return -1;
	}

	scsi_scan_host(host);

	return 0;
}


/**
 * megaraid_io_detach - detach a device from the IO subsystem
 * @adapter		: controller's soft state
 *
 * Detach this device from the IO subsystem.
 */
static void
megaraid_io_detach(adapter_t *adapter)
{
	struct Scsi_Host	*host;

	con_log(CL_DLEVEL1, (KERN_INFO "megaraid: io detach\n"));

	host = adapter->host;

	scsi_remove_host(host);

	return;
}


/*
 * START: Mailbox Low Level Driver
 *
 * This is section specific to the single mailbox based controllers
 */

/**
 * megaraid_init_mbox - initialize controller
 * @adapter		: our soft state
 *
 * - Allocate 16-byte aligned mailbox memory for firmware handshake
 * - Allocate controller's memory resources
 * - Find out all initialization data
 * - Allocate memory required for all the commands
 * - Use internal library of FW routines, build up complete soft state
 */
static int
megaraid_init_mbox(adapter_t *adapter)
{
	struct pci_dev		*pdev;
	mraid_device_t		*raid_dev;
	int			i;
	uint32_t		magic64;


	adapter->ito	= MBOX_TIMEOUT;
	pdev		= adapter->pdev;

	/*
	 * Allocate and initialize the init data structure for mailbox
	 * controllers
	 */
	raid_dev = kzalloc(sizeof(mraid_device_t), GFP_KERNEL);
	if (raid_dev == NULL) return -1;


	/*
	 * Attach the adapter soft state to raid device soft state
	 */
	adapter->raid_device	= (caddr_t)raid_dev;
	raid_dev->fast_load	= megaraid_fast_load;


	// our baseport
	raid_dev->baseport = pci_resource_start(pdev, 0);

	if (pci_request_regions(pdev, "MegaRAID: LSI Logic Corporation") != 0) {

		con_log(CL_ANN, (KERN_WARNING
				"megaraid: mem region busy\n"));

		goto out_free_raid_dev;
	}

	raid_dev->baseaddr = ioremap_nocache(raid_dev->baseport, 128);

	if (!raid_dev->baseaddr) {

		con_log(CL_ANN, (KERN_WARNING
			"megaraid: could not map hba memory\n") );

		goto out_release_regions;
	}

	/* initialize the mutual exclusion lock for the mailbox */
	spin_lock_init(&raid_dev->mailbox_lock);

	/* allocate memory required for commands */
	if (megaraid_alloc_cmd_packets(adapter) != 0)
		goto out_iounmap;

	/*
	 * Issue SYNC cmd to flush the pending cmds in the adapter
	 * and initialize its internal state
	 */

	if (megaraid_mbox_fire_sync_cmd(adapter))
		con_log(CL_ANN, ("megaraid: sync cmd failed\n"));

	/*
	 * Setup the rest of the soft state using the library of
	 * FW routines
	 */

	/* request IRQ and register the interrupt service routine */
	if (request_irq(adapter->irq, megaraid_isr, IRQF_SHARED, "megaraid",
		adapter)) {

		con_log(CL_ANN, (KERN_WARNING
			"megaraid: Couldn't register IRQ %d!\n", adapter->irq));
		goto out_alloc_cmds;

	}

	// Product info
	if (megaraid_mbox_product_info(adapter) != 0)
		goto out_free_irq;

	// Do we support extended CDBs
	adapter->max_cdb_sz = 10;
	if (megaraid_mbox_extended_cdb(adapter) == 0) {
		adapter->max_cdb_sz = 16;
	}

	/*
	 * Do we support cluster environment, if we do, what is the initiator
	 * id.
	 * NOTE: In a non-cluster aware firmware environment, the LLD should
	 * return 7 as initiator id.
	 */
	adapter->ha		= 0;
	adapter->init_id	= -1;
	if (megaraid_mbox_support_ha(adapter, &adapter->init_id) == 0) {
		adapter->ha = 1;
	}

	/*
	 * Prepare the device ids array to have the mapping between the kernel
	 * device address and megaraid device address.
	 * We export the physical devices on their actual addresses. The
	 * logical drives are exported on a virtual SCSI channel
	 */
	megaraid_mbox_setup_device_map(adapter);

	// If the firmware supports random deletion, update the device id map
	if (megaraid_mbox_support_random_del(adapter)) {

		// Change the logical drives numbers in device_ids array one
		// slot in device_ids is reserved for target id, that's why
		// "<=" below
		for (i = 0; i <= MAX_LOGICAL_DRIVES_40LD; i++) {
			adapter->device_ids[adapter->max_channel][i] += 0x80;
		}
		adapter->device_ids[adapter->max_channel][adapter->init_id] =
			0xFF;

		raid_dev->random_del_supported = 1;
	}

	/*
	 * find out the maximum number of scatter-gather elements supported by
	 * this firmware
	 */
	adapter->sglen = megaraid_mbox_get_max_sg(adapter);

	// enumerate RAID and SCSI channels so that all devices on SCSI
	// channels can later be exported, including disk devices
	megaraid_mbox_enum_raid_scsi(adapter);

	/*
	 * Other parameters required by upper layer
	 *
	 * maximum number of sectors per IO command
	 */
	adapter->max_sectors = megaraid_max_sectors;

	/*
	 * number of queued commands per LUN.
	 */
	adapter->cmd_per_lun = megaraid_cmd_per_lun;

	/*
	 * Allocate resources required to issue FW calls, when sysfs is
	 * accessed
	 */
	if (megaraid_sysfs_alloc_resources(adapter) != 0)
		goto out_free_irq;

	// Set the DMA mask to 64-bit. All supported controllers as capable of
	// DMA in this range
	pci_read_config_dword(adapter->pdev, PCI_CONF_AMISIG64, &magic64);

	if (((magic64 == HBA_SIGNATURE_64_BIT) &&
		((adapter->pdev->subsystem_device !=
		PCI_SUBSYS_ID_MEGARAID_SATA_150_6) &&
		(adapter->pdev->subsystem_device !=
		PCI_SUBSYS_ID_MEGARAID_SATA_150_4))) ||
		(adapter->pdev->vendor == PCI_VENDOR_ID_LSI_LOGIC &&
		adapter->pdev->device == PCI_DEVICE_ID_VERDE) ||
		(adapter->pdev->vendor == PCI_VENDOR_ID_LSI_LOGIC &&
		adapter->pdev->device == PCI_DEVICE_ID_DOBSON) ||
		(adapter->pdev->vendor == PCI_VENDOR_ID_LSI_LOGIC &&
		adapter->pdev->device == PCI_DEVICE_ID_LINDSAY) ||
		(adapter->pdev->vendor == PCI_VENDOR_ID_DELL &&
		adapter->pdev->device == PCI_DEVICE_ID_PERC4_DI_EVERGLADES) ||
		(adapter->pdev->vendor == PCI_VENDOR_ID_DELL &&
		adapter->pdev->device == PCI_DEVICE_ID_PERC4E_DI_KOBUK)) {
		if (pci_set_dma_mask(adapter->pdev, DMA_BIT_MASK(64))) {
			con_log(CL_ANN, (KERN_WARNING
				"megaraid: DMA mask for 64-bit failed\n"));

			if (pci_set_dma_mask (adapter->pdev, DMA_BIT_MASK(32))) {
				con_log(CL_ANN, (KERN_WARNING
					"megaraid: 32-bit DMA mask failed\n"));
				goto out_free_sysfs_res;
			}
		}
	}

	// setup tasklet for DPC
	tasklet_init(&adapter->dpc_h, megaraid_mbox_dpc,
			(unsigned long)adapter);

	con_log(CL_DLEVEL1, (KERN_INFO
		"megaraid mbox hba successfully initialized\n"));

	return 0;

out_free_sysfs_res:
	megaraid_sysfs_free_resources(adapter);
out_free_irq:
	free_irq(adapter->irq, adapter);
out_alloc_cmds:
	megaraid_free_cmd_packets(adapter);
out_iounmap:
	iounmap(raid_dev->baseaddr);
out_release_regions:
	pci_release_regions(pdev);
out_free_raid_dev:
	kfree(raid_dev);

	return -1;
}


/**
 * megaraid_fini_mbox - undo controller initialization
 * @adapter		: our soft state
 */
static void
megaraid_fini_mbox(adapter_t *adapter)
{
	mraid_device_t *raid_dev = ADAP2RAIDDEV(adapter);

	// flush all caches
	megaraid_mbox_flush_cache(adapter);

	tasklet_kill(&adapter->dpc_h);

	megaraid_sysfs_free_resources(adapter);

	megaraid_free_cmd_packets(adapter);

	free_irq(adapter->irq, adapter);

	iounmap(raid_dev->baseaddr);

	pci_release_regions(adapter->pdev);

	kfree(raid_dev);

	return;
}


/**
 * megaraid_alloc_cmd_packets - allocate shared mailbox
 * @adapter		: soft state of the raid controller
 *
 * Allocate and align the shared mailbox. This maibox is used to issue
 * all the commands. For IO based controllers, the mailbox is also registered
 * with the FW. Allocate memory for all commands as well.
 * This is our big allocator.
 */
static int
megaraid_alloc_cmd_packets(adapter_t *adapter)
{
	mraid_device_t		*raid_dev = ADAP2RAIDDEV(adapter);
	struct pci_dev		*pdev;
	unsigned long		align;
	scb_t			*scb;
	mbox_ccb_t		*ccb;
	struct mraid_pci_blk	*epthru_pci_blk;
	struct mraid_pci_blk	*sg_pci_blk;
	struct mraid_pci_blk	*mbox_pci_blk;
	int			i;

	pdev = adapter->pdev;

	/*
	 * Setup the mailbox
	 * Allocate the common 16-byte aligned memory for the handshake
	 * mailbox.
	 */
	raid_dev->una_mbox64 = pci_alloc_consistent(adapter->pdev,
			sizeof(mbox64_t), &raid_dev->una_mbox64_dma);

	if (!raid_dev->una_mbox64) {
		con_log(CL_ANN, (KERN_WARNING
			"megaraid: out of memory, %s %d\n", __func__,
			__LINE__));
		return -1;
	}
	memset(raid_dev->una_mbox64, 0, sizeof(mbox64_t));

	/*
	 * Align the mailbox at 16-byte boundary
	 */
	raid_dev->mbox	= &raid_dev->una_mbox64->mbox32;

	raid_dev->mbox	= (mbox_t *)((((unsigned long)raid_dev->mbox) + 15) &
				(~0UL ^ 0xFUL));

	raid_dev->mbox64 = (mbox64_t *)(((unsigned long)raid_dev->mbox) - 8);

	align = ((void *)raid_dev->mbox -
			((void *)&raid_dev->una_mbox64->mbox32));

	raid_dev->mbox_dma = (unsigned long)raid_dev->una_mbox64_dma + 8 +
			align;

	// Allocate memory for commands issued internally
	adapter->ibuf = pci_alloc_consistent(pdev, MBOX_IBUF_SIZE,
				&adapter->ibuf_dma_h);
	if (!adapter->ibuf) {

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

		goto out_free_common_mbox;
	}
	memset(adapter->ibuf, 0, MBOX_IBUF_SIZE);

	// Allocate memory for our SCSI Command Blocks and their associated
	// memory

	/*
	 * Allocate memory for the base list of scb. Later allocate memory for
	 * CCBs and embedded components of each CCB and point the pointers in
	 * scb to the allocated components
	 * NOTE: The code to allocate SCB will be duplicated in all the LLD
	 * since the calling routine does not yet know the number of available
	 * commands.
	 */
	adapter->kscb_list = kcalloc(MBOX_MAX_SCSI_CMDS, sizeof(scb_t), GFP_KERNEL);

	if (adapter->kscb_list == NULL) {
		con_log(CL_ANN, (KERN_WARNING
			"megaraid: out of memory, %s %d\n", __func__,
			__LINE__));
		goto out_free_ibuf;
	}

	// memory allocation for our command packets
	if (megaraid_mbox_setup_dma_pools(adapter) != 0) {
		con_log(CL_ANN, (KERN_WARNING
			"megaraid: out of memory, %s %d\n", __func__,
			__LINE__));
		goto out_free_scb_list;
	}

	// Adjust the scb pointers and link in the free pool
	epthru_pci_blk	= raid_dev->epthru_pool;
	sg_pci_blk	= raid_dev->sg_pool;
	mbox_pci_blk	= raid_dev->mbox_pool;

	for (i = 0; i < MBOX_MAX_SCSI_CMDS; i++) {
		scb			= adapter->kscb_list + i;
		ccb			= raid_dev->ccb_list + i;

		ccb->mbox	= (mbox_t *)(mbox_pci_blk[i].vaddr + 16);
		ccb->raw_mbox	= (uint8_t *)ccb->mbox;
		ccb->mbox64	= (mbox64_t *)(mbox_pci_blk[i].vaddr + 8);
		ccb->mbox_dma_h	= (unsigned long)mbox_pci_blk[i].dma_addr + 16;

		// make sure the mailbox is aligned properly
		if (ccb->mbox_dma_h & 0x0F) {
			con_log(CL_ANN, (KERN_CRIT
				"megaraid mbox: not aligned on 16-bytes\n"));

			goto out_teardown_dma_pools;
		}

		ccb->epthru		= (mraid_epassthru_t *)
						epthru_pci_blk[i].vaddr;
		ccb->epthru_dma_h	= epthru_pci_blk[i].dma_addr;
		ccb->pthru		= (mraid_passthru_t *)ccb->epthru;
		ccb->pthru_dma_h	= ccb->epthru_dma_h;


		ccb->sgl64		= (mbox_sgl64 *)sg_pci_blk[i].vaddr;
		ccb->sgl_dma_h		= sg_pci_blk[i].dma_addr;
		ccb->sgl32		= (mbox_sgl32 *)ccb->sgl64;

		scb->ccb		= (caddr_t)ccb;
		scb->gp			= 0;

		scb->sno		= i;	// command index

		scb->scp		= NULL;
		scb->state		= SCB_FREE;
		scb->dma_direction	= PCI_DMA_NONE;
		scb->dma_type		= MRAID_DMA_NONE;
		scb->dev_channel	= -1;
		scb->dev_target		= -1;

		// put scb in the free pool
		list_add_tail(&scb->list, &adapter->kscb_pool);
	}

	return 0;

out_teardown_dma_pools:
	megaraid_mbox_teardown_dma_pools(adapter);
out_free_scb_list:
	kfree(adapter->kscb_list);
out_free_ibuf:
	pci_free_consistent(pdev, MBOX_IBUF_SIZE, (void *)adapter->ibuf,
		adapter->ibuf_dma_h);
out_free_common_mbox:
	pci_free_consistent(adapter->pdev, sizeof(mbox64_t),
		(caddr_t)raid_dev->una_mbox64, raid_dev->una_mbox64_dma);

	return -1;
}


/**
 * megaraid_free_cmd_packets - free memory
 * @adapter		: soft state of the raid controller
 *
 * Release memory resources allocated for commands.
 */
static void
megaraid_free_cmd_packets(adapter_t *adapter)
{
	mraid_device_t *raid_dev = ADAP2RAIDDEV(adapter);

	megaraid_mbox_teardown_dma_pools(adapter);

	kfree(adapter->kscb_list);

	pci_free_consistent(adapter->pdev, MBOX_IBUF_SIZE,
		(void *)adapter->ibuf, adapter->ibuf_dma_h);

	pci_free_consistent(adapter->pdev, sizeof(mbox64_t),
		(caddr_t)raid_dev->una_mbox64, raid_dev->una_mbox64_dma);
	return;
}


/**
 * megaraid_mbox_setup_dma_pools - setup dma pool for command packets
 * @adapter		: HBA soft state
 *
 * Setup the dma pools for mailbox, passthru and extended passthru structures,
 * and scatter-gather lists.
 */
static int
megaraid_mbox_setup_dma_pools(adapter_t *adapter)
{
	mraid_device_t		*raid_dev = ADAP2RAIDDEV(adapter);
	struct mraid_pci_blk	*epthru_pci_blk;
	struct mraid_pci_blk	*sg_pci_blk;
	struct mraid_pci_blk	*mbox_pci_blk;
	int			i;



	// Allocate memory for 16-bytes aligned mailboxes
	raid_dev->mbox_pool_handle = pci_pool_create("megaraid mbox pool",
						adapter->pdev,
						sizeof(mbox64_t) + 16,
						16, 0);

	if (raid_dev->mbox_pool_handle == NULL) {
		goto fail_setup_dma_pool;
	}

	mbox_pci_blk = raid_dev->mbox_pool;
	for (i = 0; i < MBOX_MAX_SCSI_CMDS; i++) {
		mbox_pci_blk[i].vaddr = pci_pool_alloc(
						raid_dev->mbox_pool_handle,
						GFP_KERNEL,
						&mbox_pci_blk[i].dma_addr);
		if (!mbox_pci_blk[i].vaddr) {
			goto fail_setup_dma_pool;
		}
	}

	/*
	 * Allocate memory for each embedded passthru strucuture pointer
	 * Request for a 128 bytes aligned structure for each passthru command
	 * structure
	 * Since passthru and extended passthru commands are exclusive, they
	 * share common memory pool. Passthru structures piggyback on memory
	 * allocted to extended passthru since passthru is smaller of the two
	 */
	raid_dev->epthru_pool_handle = pci_pool_create("megaraid mbox pthru",
			adapter->pdev, sizeof(mraid_epassthru_t), 128, 0);

	if (raid_dev->epthru_pool_handle == NULL) {
		goto fail_setup_dma_pool;
	}

	epthru_pci_blk = raid_dev->epthru_pool;
	for (i = 0; i < MBOX_MAX_SCSI_CMDS; i++) {
		epthru_pci_blk[i].vaddr = pci_pool_alloc(
						raid_dev->epthru_pool_handle,
						GFP_KERNEL,
						&epthru_pci_blk[i].dma_addr);
		if (!epthru_pci_blk[i].vaddr) {
			goto fail_setup_dma_pool;
		}
	}


	// Allocate memory for each scatter-gather list. Request for 512 bytes
	// alignment for each sg list
	raid_dev->sg_pool_handle = pci_pool_create("megaraid mbox sg",
					adapter->pdev,
					sizeof(mbox_sgl64) * MBOX_MAX_SG_SIZE,
					512, 0);

	if (raid_dev->sg_pool_handle == NULL) {
		goto fail_setup_dma_pool;
	}

	sg_pci_blk = raid_dev->sg_pool;
	for (i = 0; i < MBOX_MAX_SCSI_CMDS; i++) {
		sg_pci_blk[i].vaddr = pci_pool_alloc(
						raid_dev->sg_pool_handle,
						GFP_KERNEL,
						&sg_pci_blk[i].dma_addr);
		if (!sg_pci_blk[i].vaddr) {
			goto fail_setup_dma_pool;
		}
	}

	return 0;

fail_setup_dma_pool:
	megaraid_mbox_teardown_dma_pools(adapter);
	return -1;
}


/**
 * megaraid_mbox_teardown_dma_pools - teardown dma pools for command packets
 * @adapter		: HBA soft state
 *
 * Teardown the dma pool for mailbox, passthru and extended passthru
 * structures, and scatter-gather lists.
 */
static void
megaraid_mbox_teardown_dma_pools(adapter_t *adapter)
{
	mraid_device_t		*raid_dev = ADAP2RAIDDEV(adapter);
	struct mraid_pci_blk	*epthru_pci_blk;
	struct mraid_pci_blk	*sg_pci_blk;
	struct mraid_pci_blk	*mbox_pci_blk;
	int			i;


	sg_pci_blk = raid_dev->sg_pool;
	for (i = 0; i < MBOX_MAX_SCSI_CMDS && sg_pci_blk[i].vaddr; i++) {
		pci_pool_free(raid_dev->sg_pool_handle, sg_pci_blk[i].vaddr,
			sg_pci_blk[i].dma_addr);
	}
	if (raid_dev->sg_pool_handle)
		pci_pool_destroy(raid_dev->sg_pool_handle);


	epthru_pci_blk = raid_dev->epthru_pool;
	for (i = 0; i < MBOX_MAX_SCSI_CMDS && epthru_pci_blk[i].vaddr; i++) {
		pci_pool_free(raid_dev->epthru_pool_handle,
			epthru_pci_blk[i].vaddr, epthru_pci_blk[i].dma_addr);
	}
	if (raid_dev->epthru_pool_handle)
		pci_pool_destroy(raid_dev->epthru_pool_handle);


	mbox_pci_blk = raid_dev->mbox_pool;
	for (i = 0; i < MBOX_MAX_SCSI_CMDS && mbox_pci_blk[i].vaddr; i++) {
		pci_pool_free(raid_dev->mbox_pool_handle,
			mbox_pci_blk[i].vaddr, mbox_pci_blk[i].dma_addr);
	}
	if (raid_dev->mbox_pool_handle)
		pci_pool_destroy(raid_dev->mbox_pool_handle);

	return;
}


/**
 * megaraid_alloc_scb - detach and return a scb from the free list
 * @adapter	: controller's soft state
 * @scp		: pointer to the scsi command to be executed
 *
 * Return the scb from the head of the free list. %NULL if there are none
 * available.
 */
static scb_t *
megaraid_alloc_scb(adapter_t *adapter, struct scsi_cmnd *scp)
{
	struct list_head	*head = &adapter->kscb_pool;
	scb_t			*scb = NULL;
	unsigned long		flags;

	// detach scb from free pool
	spin_lock_irqsave(SCSI_FREE_LIST_LOCK(adapter), flags);

	if (list_empty(head)) {
		spin_unlock_irqrestore(SCSI_FREE_LIST_LOCK(adapter), flags);
		return NULL;
	}

	scb = list_entry(head->next, scb_t, list);
	list_del_init(&scb->list);

	spin_unlock_irqrestore(SCSI_FREE_LIST_LOCK(adapter), flags);

	scb->state	= SCB_ACTIVE;
	scb->scp	= scp;
	scb->dma_type	= MRAID_DMA_NONE;

	return scb;
}


/**
 * megaraid_dealloc_scb - return the scb to the free pool
 * @adapter	: controller's soft state
 * @scb		: scb to be freed
 *
 * Return the scb back to the free list of scbs. The caller must 'flush' the
 * SCB before calling us. E.g., performing pci_unamp and/or pci_sync etc.
 * NOTE NOTE: Make sure the scb is not on any list before calling this
 * routine.
 */
static inline void
megaraid_dealloc_scb(adapter_t *adapter, scb_t *scb)
{
	unsigned long		flags;

	// put scb in the free pool
	scb->state	= SCB_FREE;
	scb->scp	= NULL;
	spin_lock_irqsave(SCSI_FREE_LIST_LOCK(adapter), flags);

	list_add(&scb->list, &adapter->kscb_pool);

	spin_unlock_irqrestore(SCSI_FREE_LIST_LOCK(adapter), flags);

	return;
}


/**
 * megaraid_mbox_mksgl - make the scatter-gather list
 * @adapter	: controller's soft state
 * @scb		: scsi control block
 *
 * Prepare the scatter-gather list.
 */
static int
megaraid_mbox_mksgl(adapter_t *adapter, scb_t *scb)
{
	struct scatterlist	*sgl;
	mbox_ccb_t		*ccb;
	struct scsi_cmnd	*scp;
	int			sgcnt;
	int			i;


	scp	= scb->scp;
	ccb	= (mbox_ccb_t *)scb->ccb;

	sgcnt = scsi_dma_map(scp);
	BUG_ON(sgcnt < 0 || sgcnt > adapter->sglen);

	// no mapping required if no data to be transferred
	if (!sgcnt)
		return 0;

	scb->dma_type = MRAID_DMA_WSG;

	scsi_for_each_sg(scp, sgl, sgcnt, i) {
		ccb->sgl64[i].address	= sg_dma_address(sgl);
		ccb->sgl64[i].length	= sg_dma_len(sgl);
	}

	// Return count of SG nodes
	return sgcnt;
}


/**
 * mbox_post_cmd - issue a mailbox command
 * @adapter	: controller's soft state
 * @scb		: command to be issued
 *
 * Post the command to the controller if mailbox is available.
 */
static int
mbox_post_cmd(adapter_t *adapter, scb_t *scb)
{
	mraid_device_t	*raid_dev = ADAP2RAIDDEV(adapter);
	mbox64_t	*mbox64;
	mbox_t		*mbox;
	mbox_ccb_t	*ccb;
	unsigned long	flags;
	unsigned int	i = 0;


	ccb	= (mbox_ccb_t *)scb->ccb;
	mbox	= raid_dev->mbox;
	mbox64	= raid_dev->mbox64;

	/*
	 * Check for busy mailbox. If it is, return failure - the caller
	 * should retry later.
	 */
	spin_lock_irqsave(MAILBOX_LOCK(raid_dev), flags);

	if (unlikely(mbox->busy)) {
		do {
			udelay(1);
			i++;
			rmb();
		} while(mbox->busy && (i < max_mbox_busy_wait));

		if (mbox->busy) {

			spin_unlock_irqrestore(MAILBOX_LOCK(raid_dev), flags);

			return -1;
		}
	}


	// Copy this command's mailbox data into "adapter's" mailbox
	memcpy((caddr_t)mbox64, (caddr_t)ccb->mbox64, 22);
	mbox->cmdid = scb->sno;

	adapter->outstanding_cmds++;

	if (scb->dma_direction == PCI_DMA_TODEVICE)
		pci_dma_sync_sg_for_device(adapter->pdev,
					   scsi_sglist(scb->scp),
					   scsi_sg_count(scb->scp),
					   PCI_DMA_TODEVICE);

	mbox->busy	= 1;	// Set busy
	mbox->poll	= 0;
	mbox->ack	= 0;
	wmb();

	WRINDOOR(raid_dev, raid_dev->mbox_dma | 0x1);

	spin_unlock_irqrestore(MAILBOX_LOCK(raid_dev), flags);

	return 0;
}


/**
 * megaraid_queue_command - generic queue entry point for all LLDs
 * @scp		: pointer to the scsi command to be executed
 * @done	: callback routine to be called after the cmd has be completed
 *
 * Queue entry point for mailbox based controllers.
 */
static int
megaraid_queue_command_lck(struct scsi_cmnd *scp, void (*done)(struct scsi_cmnd *))
{
	adapter_t	*adapter;
	scb_t		*scb;
	int		if_busy;

	adapter		= SCP2ADAPTER(scp);
	scp->scsi_done	= done;
	scp->result	= 0;

	/*
	 * Allocate and build a SCB request
	 * if_busy flag will be set if megaraid_mbox_build_cmd() command could
	 * not allocate scb. We will return non-zero status in that case.
	 * NOTE: scb can be null even though certain commands completed
	 * successfully, e.g., MODE_SENSE and TEST_UNIT_READY, it would
	 * return 0 in that case, and we would do the callback right away.
	 */
	if_busy	= 0;
	scb = megaraid_mbox_build_cmd(adapter, scp, &if_busy);
	if (!scb) {	// command already completed
		done(scp);
		return 0;
	}

	megaraid_mbox_runpendq(adapter, scb);
	return if_busy;
}

static DEF_SCSI_QCMD(megaraid_queue_command)

/**
 * megaraid_mbox_build_cmd - transform the mid-layer scsi commands
 * @adapter	: controller's soft state
 * @scp		: mid-layer scsi command pointer
 * @busy	: set if request could not be completed because of lack of
 *		resources
 *
 * Transform the mid-layer scsi command to megaraid firmware lingua.
 * Convert the command issued by mid-layer to format understood by megaraid
 * firmware. We also complete certain commands without sending them to firmware.
 */
static scb_t *
megaraid_mbox_build_cmd(adapter_t *adapter, struct scsi_cmnd *scp, int *busy)
{
	mraid_device_t		*rdev = ADAP2RAIDDEV(adapter);
	int			channel;
	int			target;
	int			islogical;
	mbox_ccb_t		*ccb;
	mraid_passthru_t	*pthru;
	mbox64_t		*mbox64;
	mbox_t			*mbox;
	scb_t			*scb;
	char			skip[] = "skipping";
	char			scan[] = "scanning";
	char			*ss;


	/*
	 * Get the appropriate device map for the device this command is
	 * intended for
	 */
	MRAID_GET_DEVICE_MAP(adapter, scp, channel, target, islogical);

	/*
	 * Logical drive commands
	 */
	if (islogical) {
		switch (scp->cmnd[0]) {
		case TEST_UNIT_READY:
			/*
			 * Do we support clustering and is the support enabled
			 * If no, return success always
			 */
			if (!adapter->ha) {
				scp->result = (DID_OK << 16);
				return NULL;
			}

			if (!(scb = megaraid_alloc_scb(adapter, scp))) {
				scp->result = (DID_ERROR << 16);
				*busy = 1;
				return NULL;
			}

			scb->dma_direction	= scp->sc_data_direction;
			scb->dev_channel	= 0xFF;
			scb->dev_target		= target;
			ccb			= (mbox_ccb_t *)scb->ccb;

			/*
			 * The command id will be provided by the command
			 * issuance routine
			 */
			ccb->raw_mbox[0]	= CLUSTER_CMD;
			ccb->raw_mbox[2]	= RESERVATION_STATUS;
			ccb->raw_mbox[3]	= target;

			return scb;

		case MODE_SENSE:
		{
			struct scatterlist	*sgl;
			caddr_t			vaddr;

			sgl = scsi_sglist(scp);
			if (sg_page(sgl)) {
				vaddr = (caddr_t) sg_virt(&sgl[0]);

				memset(vaddr, 0, scp->cmnd[4]);
			}
			else {
				con_log(CL_ANN, (KERN_WARNING
						 "megaraid mailbox: invalid sg:%d\n",
						 __LINE__));
			}
		}
		scp->result = (DID_OK << 16);
		return NULL;

		case INQUIRY:
			/*
			 * Display the channel scan for logical drives
			 * Do not display scan for a channel if already done.
			 */
			if (!(rdev->last_disp & (1L << SCP2CHANNEL(scp)))) {

				con_log(CL_ANN, (KERN_INFO
					"scsi[%d]: scanning scsi channel %d",
					adapter->host->host_no,
					SCP2CHANNEL(scp)));

				con_log(CL_ANN, (
					" [virtual] for logical drives\n"));

				rdev->last_disp |= (1L << SCP2CHANNEL(scp));
			}

			if (scp->cmnd[1] & MEGA_SCSI_INQ_EVPD) {
				scp->sense_buffer[0] = 0x70;
				scp->sense_buffer[2] = ILLEGAL_REQUEST;
				scp->sense_buffer[12] = MEGA_INVALID_FIELD_IN_CDB;
				scp->result = CHECK_CONDITION << 1;
				return NULL;
			}

			/* Fall through */

		case READ_CAPACITY:
			/*
			 * Do not allow LUN > 0 for logical drives and
			 * requests for more than 40 logical drives
			 */
			if (SCP2LUN(scp)) {
				scp->result = (DID_BAD_TARGET << 16);
				return NULL;
			}
			if ((target % 0x80) >= MAX_LOGICAL_DRIVES_40LD) {
				scp->result = (DID_BAD_TARGET << 16);
				return NULL;
			}


			/* Allocate a SCB and initialize passthru */
			if (!(scb = megaraid_alloc_scb(adapter, scp))) {
				scp->result = (DID_ERROR << 16);
				*busy = 1;
				return NULL;
			}

			ccb			= (mbox_ccb_t *)scb->ccb;
			scb->dev_channel	= 0xFF;
			scb->dev_target		= target;
			pthru			= ccb->pthru;
			mbox			= ccb->mbox;
			mbox64			= ccb->mbox64;

			pthru->timeout		= 0;
			pthru->ars		= 1;
			pthru->reqsenselen	= 14;
			pthru->islogical	= 1;
			pthru->logdrv		= target;
			pthru->cdblen		= scp->cmd_len;
			memcpy(pthru->cdb, scp->cmnd, scp->cmd_len);

			mbox->cmd		= MBOXCMD_PASSTHRU64;
			scb->dma_direction	= scp->sc_data_direction;

			pthru->dataxferlen	= scsi_bufflen(scp);
			pthru->dataxferaddr	= ccb->sgl_dma_h;
			pthru->numsge		= megaraid_mbox_mksgl(adapter,
							scb);

			mbox->xferaddr		= 0xFFFFFFFF;
			mbox64->xferaddr_lo	= (uint32_t )ccb->pthru_dma_h;
			mbox64->xferaddr_hi	= 0;

			return scb;

		case READ_6:
		case WRITE_6:
		case READ_10:
		case WRITE_10:
		case READ_12:
		case WRITE_12:

			/*
			 * Allocate a SCB and initialize mailbox
			 */
			if (!(scb = megaraid_alloc_scb(adapter, scp))) {
				scp->result = (DID_ERROR << 16);
				*busy = 1;
				return NULL;
			}
			ccb			= (mbox_ccb_t *)scb->ccb;
			scb->dev_channel	= 0xFF;
			scb->dev_target		= target;
			mbox			= ccb->mbox;
			mbox64			= ccb->mbox64;
			mbox->logdrv		= target;

			/*
			 * A little HACK: 2nd bit is zero for all scsi read
			 * commands and is set for all scsi write commands
			 */
			mbox->cmd = (scp->cmnd[0] & 0x02) ?  MBOXCMD_LWRITE64:
					MBOXCMD_LREAD64 ;

			/*
			 * 6-byte READ(0x08) or WRITE(0x0A) cdb
			 */
			if (scp->cmd_len == 6) {
				mbox->numsectors = (uint32_t)scp->cmnd[4];
				mbox->lba =
					((uint32_t)scp->cmnd[1] << 16)	|
					((uint32_t)scp->cmnd[2] << 8)	|
					(uint32_t)scp->cmnd[3];

				mbox->lba &= 0x1FFFFF;
			}

			/*
			 * 10-byte READ(0x28) or WRITE(0x2A) cdb
			 */
			else if (scp->cmd_len == 10) {
				mbox->numsectors =
					(uint32_t)scp->cmnd[8] |
					((uint32_t)scp->cmnd[7] << 8);
				mbox->lba =
					((uint32_t)scp->cmnd[2] << 24) |
					((uint32_t)scp->cmnd[3] << 16) |
					((uint32_t)scp->cmnd[4] << 8) |
					(uint32_t)scp->cmnd[5];
			}

			/*
			 * 12-byte READ(0xA8) or WRITE(0xAA) cdb
			 */
			else if (scp->cmd_len == 12) {
				mbox->lba =
					((uint32_t)scp->cmnd[2] << 24) |
					((uint32_t)scp->cmnd[3] << 16) |
					((uint32_t)scp->cmnd[4] << 8) |
					(uint32_t)scp->cmnd[5];

				mbox->numsectors =
					((uint32_t)scp->cmnd[6] << 24) |
					((uint32_t)scp->cmnd[7] << 16) |
					((uint32_t)scp->cmnd[8] << 8) |
					(uint32_t)scp->cmnd[9];
			}
			else {
				con_log(CL_ANN, (KERN_WARNING
					"megaraid: unsupported CDB length\n"));

				megaraid_dealloc_scb(adapter, scb);

				scp->result = (DID_ERROR << 16);
				return NULL;
			}

			scb->dma_direction = scp->sc_data_direction;

			// Calculate Scatter-Gather info
			mbox64->xferaddr_lo	= (uint32_t )ccb->sgl_dma_h;
			mbox->numsge		= megaraid_mbox_mksgl(adapter,
							scb);
			mbox->xferaddr		= 0xFFFFFFFF;
			mbox64->xferaddr_hi	= 0;

			return scb;

		case RESERVE:
		case RELEASE:
			/*
			 * Do we support clustering and is the support enabled
			 */
			if (!adapter->ha) {
				scp->result = (DID_BAD_TARGET << 16);
				return NULL;
			}

			/*
			 * Allocate a SCB and initialize mailbox
			 */
			if (!(scb = megaraid_alloc_scb(adapter, scp))) {
				scp->result = (DID_ERROR << 16);
				*busy = 1;
				return NULL;
			}

			ccb			= (mbox_ccb_t *)scb->ccb;
			scb->dev_channel	= 0xFF;
			scb->dev_target		= target;
			ccb->raw_mbox[0]	= CLUSTER_CMD;
			ccb->raw_mbox[2]	=  (scp->cmnd[0] == RESERVE) ?
						RESERVE_LD : RELEASE_LD;

			ccb->raw_mbox[3]	= target;
			scb->dma_direction	= scp->sc_data_direction;

			return scb;

		default:
			scp->result = (DID_BAD_TARGET << 16);
			return NULL;
		}
	}
	else { // Passthru device commands

		// Do not allow access to target id > 15 or LUN > 7
		if (target > 15 || SCP2LUN(scp) > 7) {
			scp->result = (DID_BAD_TARGET << 16);
			return NULL;
		}

		// if fast load option was set and scan for last device is
		// over, reset the fast_load flag so that during a possible
		// next scan, devices can be made available
		if (rdev->fast_load && (target == 15) &&
			(SCP2CHANNEL(scp) == adapter->max_channel -1)) {

			con_log(CL_ANN, (KERN_INFO
			"megaraid[%d]: physical device scan re-enabled\n",
				adapter->host->host_no));
			rdev->fast_load = 0;
		}

		/*
		 * Display the channel scan for physical devices
		 */
		if (!(rdev->last_disp & (1L << SCP2CHANNEL(scp)))) {

			ss = rdev->fast_load ? skip : scan;

			con_log(CL_ANN, (KERN_INFO
				"scsi[%d]: %s scsi channel %d [Phy %d]",
				adapter->host->host_no, ss, SCP2CHANNEL(scp),
				channel));

			con_log(CL_ANN, (
				" for non-raid devices\n"));

			rdev->last_disp |= (1L << SCP2CHANNEL(scp));
		}

		// disable channel sweep if fast load option given
		if (rdev->fast_load) {
			scp->result = (DID_BAD_TARGET << 16);
			return NULL;
		}

		// Allocate a SCB and initialize passthru
		if (!(scb = megaraid_alloc_scb(adapter, scp))) {
			scp->result = (DID_ERROR << 16);
			*busy = 1;
			return NULL;
		}

		ccb			= (mbox_ccb_t *)scb->ccb;
		scb->dev_channel	= channel;
		scb->dev_target		= target;
		scb->dma_direction	= scp->sc_data_direction;
		mbox			= ccb->mbox;
		mbox64			= ccb->mbox64;

		// Does this firmware support extended CDBs
		if (adapter->max_cdb_sz == 16) {
			mbox->cmd		= MBOXCMD_EXTPTHRU;

			megaraid_mbox_prepare_epthru(adapter, scb, scp);

			mbox64->xferaddr_lo	= (uint32_t)ccb->epthru_dma_h;
			mbox64->xferaddr_hi	= 0;
			mbox->xferaddr		= 0xFFFFFFFF;
		}
		else {
			mbox->cmd = MBOXCMD_PASSTHRU64;

			megaraid_mbox_prepare_pthru(adapter, scb, scp);

			mbox64->xferaddr_lo	= (uint32_t)ccb->pthru_dma_h;
			mbox64->xferaddr_hi	= 0;
			mbox->xferaddr		= 0xFFFFFFFF;
		}
		return scb;
	}

	// NOT REACHED
}


/**
 * megaraid_mbox_runpendq - execute commands queued in the pending queue
 * @adapter	: controller's soft state
 * @scb_q	: SCB to be queued in the pending list
 *
 * Scan the pending list for commands which are not yet issued and try to
 * post to the controller. The SCB can be a null pointer, which would indicate
 * no SCB to be queue, just try to execute the ones in the pending list.
 *
 * NOTE: We do not actually traverse the pending list. The SCBs are plucked
 * out from the head of the pending list. If it is successfully issued, the
 * next SCB is at the head now.
 */
static void
megaraid_mbox_runpendq(adapter_t *adapter, scb_t *scb_q)
{
	scb_t			*scb;
	unsigned long		flags;

	spin_lock_irqsave(PENDING_LIST_LOCK(adapter), flags);

	if (scb_q) {
		scb_q->state = SCB_PENDQ;
		list_add_tail(&scb_q->list, &adapter->pend_list);
	}

	// if the adapter in not in quiescent mode, post the commands to FW
	if (adapter->quiescent) {
		spin_unlock_irqrestore(PENDING_LIST_LOCK(adapter), flags);
		return;
	}

	while (!list_empty(&adapter->pend_list)) {

		assert_spin_locked(PENDING_LIST_LOCK(adapter));

		scb = list_entry(adapter->pend_list.next, scb_t, list);

		// remove the scb from the pending list and try to
		// issue. If we are unable to issue it, put back in
		// the pending list and return

		list_del_init(&scb->list);

		spin_unlock_irqrestore(PENDING_LIST_LOCK(adapter), flags);

		// if mailbox was busy, return SCB back to pending
		// list. Make sure to add at the head, since that's
		// where it would have been removed from

		scb->state = SCB_ISSUED;

		if (mbox_post_cmd(adapter, scb) != 0) {

			spin_lock_irqsave(PENDING_LIST_LOCK(adapter), flags);

			scb->state = SCB_PENDQ;

			list_add(&scb->list, &adapter->pend_list);

			spin_unlock_irqrestore(PENDING_LIST_LOCK(adapter),
				flags);

			return;
		}

		spin_lock_irqsave(PENDING_LIST_LOCK(adapter), flags);
	}

	spin_unlock_irqrestore(PENDING_LIST_LOCK(adapter), flags);


	return;
}


/**
 * megaraid_mbox_prepare_pthru - prepare a command for physical devices
 * @adapter	: pointer to controller's soft state
 * @scb		: scsi control block
 * @scp		: scsi command from the mid-layer
 *
 * Prepare a command for the scsi physical devices.
 */
static void
megaraid_mbox_prepare_pthru(adapter_t *adapter, scb_t *scb,
		struct scsi_cmnd *scp)
{
	mbox_ccb_t		*ccb;
	mraid_passthru_t	*pthru;
	uint8_t			channel;
	uint8_t			target;

	ccb	= (mbox_ccb_t *)scb->ccb;
	pthru	= ccb->pthru;
	channel	= scb->dev_channel;
	target	= scb->dev_target;

	// 0=6sec, 1=60sec, 2=10min, 3=3hrs, 4=NO timeout
	pthru->timeout		= 4;	
	pthru->ars		= 1;
	pthru->islogical	= 0;
	pthru->channel		= 0;
	pthru->target		= (channel << 4) | target;
	pthru->logdrv		= SCP2LUN(scp);
	pthru->reqsenselen	= 14;
	pthru->cdblen		= scp->cmd_len;

	memcpy(pthru->cdb, scp->cmnd, scp->cmd_len);

	if (scsi_bufflen(scp)) {
		pthru->dataxferlen	= scsi_bufflen(scp);
		pthru->dataxferaddr	= ccb->sgl_dma_h;
		pthru->numsge		= megaraid_mbox_mksgl(adapter, scb);
	}
	else {
		pthru->dataxferaddr	= 0;
		pthru->dataxferlen	= 0;
		pthru->numsge		= 0;
	}
	return;
}


/**
 * megaraid_mbox_prepare_epthru - prepare a command for physical devices
 * @adapter	: pointer to controller's soft state
 * @scb		: scsi control block
 * @scp		: scsi command from the mid-layer
 *
 * Prepare a command for the scsi physical devices. This routine prepares
 * commands for devices which can take extended CDBs (>10 bytes).
 */
static void
megaraid_mbox_prepare_epthru(adapter_t *adapter, scb_t *scb,
		struct scsi_cmnd *scp)
{
	mbox_ccb_t		*ccb;
	mraid_epassthru_t	*epthru;
	uint8_t			channel;
	uint8_t			target;

	ccb	= (mbox_ccb_t *)scb->ccb;
	epthru	= ccb->epthru;
	channel	= scb->dev_channel;
	target	= scb->dev_target;

	// 0=6sec, 1=60sec, 2=10min, 3=3hrs, 4=NO timeout
	epthru->timeout		= 4;	
	epthru->ars		= 1;
	epthru->islogical	= 0;
	epthru->channel		= 0;
	epthru->target		= (channel << 4) | target;
	epthru->logdrv		= SCP2LUN(scp);
	epthru->reqsenselen	= 14;
	epthru->cdblen		= scp->cmd_len;

	memcpy(epthru->cdb, scp->cmnd, scp->cmd_len);

	if (scsi_bufflen(scp)) {
		epthru->dataxferlen	= scsi_bufflen(scp);
		epthru->dataxferaddr	= ccb->sgl_dma_h;
		epthru->numsge		= megaraid_mbox_mksgl(adapter, scb);
	}
	else {
		epthru->dataxferaddr	= 0;
		epthru->dataxferlen	= 0;
		epthru->numsge		= 0;
	}
	return;
}


/**
 * megaraid_ack_sequence - interrupt ack sequence for memory mapped HBAs
 * @adapter	: controller's soft state
 *
 * Interrupt acknowledgement sequence for memory mapped HBAs. Find out the
 * completed command and put them on the completed list for later processing.
 *
 * Returns:	1 if the interrupt is valid, 0 otherwise
 */
static int
megaraid_ack_sequence(adapter_t *adapter)
{
	mraid_device_t		*raid_dev = ADAP2RAIDDEV(adapter);
	mbox_t			*mbox;
	scb_t			*scb;
	uint8_t			nstatus;
	uint8_t			completed[MBOX_MAX_FIRMWARE_STATUS];
	struct list_head	clist;
	int			handled;
	uint32_t		dword;
	unsigned long		flags;
	int			i, j;


	mbox	= raid_dev->mbox;

	// move the SCBs from the firmware completed array to our local list
	INIT_LIST_HEAD(&clist);

	// loop till F/W has more commands for us to complete
	handled = 0;
	spin_lock_irqsave(MAILBOX_LOCK(raid_dev), flags);
	do {
		/*
		 * Check if a valid interrupt is pending. If found, force the
		 * interrupt line low.
		 */
		dword = RDOUTDOOR(raid_dev);
		if (dword != 0x10001234) break;

		handled = 1;

		WROUTDOOR(raid_dev, 0x10001234);

		nstatus = 0;
		// wait for valid numstatus to post
		for (i = 0; i < 0xFFFFF; i++) {
			if (mbox->numstatus != 0xFF) {
				nstatus = mbox->numstatus;
				break;
			}
			rmb();
		}
		mbox->numstatus = 0xFF;

		adapter->outstanding_cmds -= nstatus;

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

			// wait for valid command index to post
			for (j = 0; j < 0xFFFFF; j++) {
				if (mbox->completed[i] != 0xFF) break;
				rmb();
			}
			completed[i]		= mbox->completed[i];
			mbox->completed[i]	= 0xFF;

			if (completed[i] == 0xFF) {
				con_log(CL_ANN, (KERN_CRIT
				"megaraid: command posting timed out\n"));

				BUG();
				continue;
			}

			// Get SCB associated with this command id
			if (completed[i] >= MBOX_MAX_SCSI_CMDS) {
				// a cmm command
				scb = adapter->uscb_list + (completed[i] -
						MBOX_MAX_SCSI_CMDS);
			}
			else {
				// an os command
				scb = adapter->kscb_list + completed[i];
			}

			scb->status = mbox->status;
			list_add_tail(&scb->list, &clist);
		}

		// Acknowledge interrupt
		WRINDOOR(raid_dev, 0x02);

	} while(1);

	spin_unlock_irqrestore(MAILBOX_LOCK(raid_dev), flags);


	// put the completed commands in the completed list. DPC would
	// complete these commands later
	spin_lock_irqsave(COMPLETED_LIST_LOCK(adapter), flags);

	list_splice(&clist, &adapter->completed_list);

	spin_unlock_irqrestore(COMPLETED_LIST_LOCK(adapter), flags);


	// schedule the DPC if there is some work for it
	if (handled)
		tasklet_schedule(&adapter->dpc_h);

	return handled;
}


/**
 * megaraid_isr - isr for memory based mailbox based controllers
 * @irq		: irq
 * @devp	: pointer to our soft state
 *
 * Interrupt service routine for memory-mapped mailbox controllers.
 */
static irqreturn_t
megaraid_isr(int irq, void *devp)
{
	adapter_t	*adapter = devp;
	int		handled;

	handled = megaraid_ack_sequence(adapter);

	/* Loop through any pending requests */
	if (!adapter->quiescent) {
		megaraid_mbox_runpendq(adapter, NULL);
	}

	return IRQ_RETVAL(handled);
}


/**
 * megaraid_mbox_sync_scb - sync kernel buffers
 * @adapter	: controller's soft state
 * @scb		: pointer to the resource packet
 *
 * DMA sync if required.
 */
static void
megaraid_mbox_sync_scb(adapter_t *adapter, scb_t *scb)
{
	mbox_ccb_t	*ccb;

	ccb	= (mbox_ccb_t *)scb->ccb;

	if (scb->dma_direction == PCI_DMA_FROMDEVICE)
		pci_dma_sync_sg_for_cpu(adapter->pdev,
					scsi_sglist(scb->scp),
					scsi_sg_count(scb->scp),
					PCI_DMA_FROMDEVICE);

	scsi_dma_unmap(scb->scp);
	return;
}


/**
 * megaraid_mbox_dpc - the tasklet to complete the commands from completed list
 * @devp	: pointer to HBA soft state
 *
 * Pick up the commands from the completed list and send back to the owners.
 * This is a reentrant function and does not assume any locks are held while
 * it is being called.
 */
static void
megaraid_mbox_dpc(unsigned long devp)
{
	adapter_t		*adapter = (adapter_t *)devp;
	mraid_device_t		*raid_dev;
	struct list_head	clist;
	struct scatterlist	*sgl;
	scb_t			*scb;
	scb_t			*tmp;
	struct scsi_cmnd	*scp;
	mraid_passthru_t	*pthru;
	mraid_epassthru_t	*epthru;
	mbox_ccb_t		*ccb;
	int			islogical;
	int			pdev_index;
	int			pdev_state;
	mbox_t			*mbox;
	unsigned long		flags;
	uint8_t			c;
	int			status;
	uioc_t			*kioc;


	if (!adapter) return;

	raid_dev = ADAP2RAIDDEV(adapter);

	// move the SCBs from the completed list to our local list
	INIT_LIST_HEAD(&clist);

	spin_lock_irqsave(COMPLETED_LIST_LOCK(adapter), flags);

	list_splice_init(&adapter->completed_list, &clist);

	spin_unlock_irqrestore(COMPLETED_LIST_LOCK(adapter), flags);


	list_for_each_entry_safe(scb, tmp, &clist, list) {

		status		= scb->status;
		scp		= scb->scp;
		ccb		= (mbox_ccb_t *)scb->ccb;
		pthru		= ccb->pthru;
		epthru		= ccb->epthru;
		mbox		= ccb->mbox;

		// Make sure f/w has completed a valid command
		if (scb->state != SCB_ISSUED) {
			con_log(CL_ANN, (KERN_CRIT
			"megaraid critical err: invalid command %d:%d:%p\n",
				scb->sno, scb->state, scp));
			BUG();
			continue;	// Must never happen!
		}

		// check for the management command and complete it right away
		if (scb->sno >= MBOX_MAX_SCSI_CMDS) {
			scb->state	= SCB_FREE;
			scb->status	= status;

			// remove from local clist
			list_del_init(&scb->list);

			kioc			= (uioc_t *)scb->gp;
			kioc->status		= 0;

			megaraid_mbox_mm_done(adapter, scb);

			continue;
		}

		// Was an abort issued for this command earlier
		if (scb->state & SCB_ABORT) {
			con_log(CL_ANN, (KERN_NOTICE
			"megaraid: aborted cmd [%x] completed\n",
				scb->sno));
		}

		/*
		 * If the inquiry came of a disk drive which is not part of
		 * any RAID array, expose it to the kernel. For this to be
		 * enabled, user must set the "megaraid_expose_unconf_disks"
		 * flag to 1 by specifying it on module parameter list.
		 * This would enable data migration off drives from other
		 * configurations.
		 */
		islogical = MRAID_IS_LOGICAL(adapter, scp);
		if (scp->cmnd[0] == INQUIRY && status == 0 && islogical == 0
				&& IS_RAID_CH(raid_dev, scb->dev_channel)) {

			sgl = scsi_sglist(scp);
			if (sg_page(sgl)) {
				c = *(unsigned char *) sg_virt(&sgl[0]);
			} else {
				con_log(CL_ANN, (KERN_WARNING
						 "megaraid mailbox: invalid sg:%d\n",
						 __LINE__));
				c = 0;
			}

			if ((c & 0x1F ) == TYPE_DISK) {
				pdev_index = (scb->dev_channel * 16) +
					scb->dev_target;
				pdev_state =
					raid_dev->pdrv_state[pdev_index] & 0x0F;

				if (pdev_state == PDRV_ONLINE		||
					pdev_state == PDRV_FAILED	||
					pdev_state == PDRV_RBLD		||
					pdev_state == PDRV_HOTSPARE	||
					megaraid_expose_unconf_disks == 0) {

					status = 0xF0;
				}
			}
		}

		// Convert MegaRAID status to Linux error code
		switch (status) {

		case 0x00:

			scp->result = (DID_OK << 16);
			break;

		case 0x02:

			/* set sense_buffer and result fields */
			if (mbox->cmd == MBOXCMD_PASSTHRU ||
				mbox->cmd == MBOXCMD_PASSTHRU64) {

				memcpy(scp->sense_buffer, pthru->reqsensearea,
						14);

				scp->result = DRIVER_SENSE << 24 |
					DID_OK << 16 | CHECK_CONDITION << 1;
			}
			else {
				if (mbox->cmd == MBOXCMD_EXTPTHRU) {

					memcpy(scp->sense_buffer,
						epthru->reqsensearea, 14);

					scp->result = DRIVER_SENSE << 24 |
						DID_OK << 16 |
						CHECK_CONDITION << 1;
				} else {
					scp->sense_buffer[0] = 0x70;
					scp->sense_buffer[2] = ABORTED_COMMAND;
					scp->result = CHECK_CONDITION << 1;
				}
			}
			break;

		case 0x08:

			scp->result = DID_BUS_BUSY << 16 | status;
			break;

		default:

			/*
			 * If TEST_UNIT_READY fails, we know RESERVATION_STATUS
			 * failed
			 */
			if (scp->cmnd[0] == TEST_UNIT_READY) {
				scp->result = DID_ERROR << 16 |
					RESERVATION_CONFLICT << 1;
			}
			else
			/*
			 * Error code returned is 1 if Reserve or Release
			 * failed or the input parameter is invalid
			 */
			if (status == 1 && (scp->cmnd[0] == RESERVE ||
					 scp->cmnd[0] == RELEASE)) {

				scp->result = DID_ERROR << 16 |
					RESERVATION_CONFLICT << 1;
			}
			else {
				scp->result = DID_BAD_TARGET << 16 | status;
			}
		}

		// print a debug message for all failed commands
		if (status) {
			megaraid_mbox_display_scb(adapter, scb);
		}

		// Free our internal resources and call the mid-layer callback
		// routine
		megaraid_mbox_sync_scb(adapter, scb);

		// remove from local clist
		list_del_init(&scb->list);

		// put back in free list
		megaraid_dealloc_scb(adapter, scb);

		// send the scsi packet back to kernel
		scp->scsi_done(scp);
	}

	return;
}


/**
 * megaraid_abort_handler - abort the scsi command
 * @scp		: command to be aborted
 *
 * Abort a previous SCSI request. Only commands on the pending list can be
 * aborted. All the commands issued to the F/W must complete.
 **/
static int
megaraid_abort_handler(struct scsi_cmnd *scp)
{
	adapter_t		*adapter;
	mraid_device_t		*raid_dev;
	scb_t			*scb;
	scb_t			*tmp;
	int			found;
	unsigned long		flags;
	int			i;


	adapter		= SCP2ADAPTER(scp);
	raid_dev	= ADAP2RAIDDEV(adapter);

	con_log(CL_ANN, (KERN_WARNING
		"megaraid: aborting cmd=%x <c=%d t=%d l=%d>\n",
		scp->cmnd[0], SCP2CHANNEL(scp),
		SCP2TARGET(scp), SCP2LUN(scp)));

	// If FW has stopped responding, simply return failure
	if (raid_dev->hw_error) {
		con_log(CL_ANN, (KERN_NOTICE
			"megaraid: hw error, not aborting\n"));
		return FAILED;
	}

	// There might a race here, where the command was completed by the
	// firmware and now it is on the completed list. Before we could
	// complete the command to the kernel in dpc, the abort came.
	// Find out if this is the case to avoid the race.
	scb = NULL;
	spin_lock_irqsave(COMPLETED_LIST_LOCK(adapter), flags);
	list_for_each_entry_safe(scb, tmp, &adapter->completed_list, list) {

		if (scb->scp == scp) {	// Found command

			list_del_init(&scb->list);	// from completed list

			con_log(CL_ANN, (KERN_WARNING
			"megaraid: %d[%d:%d], abort from completed list\n",
				scb->sno, scb->dev_channel, scb->dev_target));

			scp->result = (DID_ABORT << 16);
			scp->scsi_done(scp);

			megaraid_dealloc_scb(adapter, scb);

			spin_unlock_irqrestore(COMPLETED_LIST_LOCK(adapter),
				flags);

			return SUCCESS;
		}
	}
	spin_unlock_irqrestore(COMPLETED_LIST_LOCK(adapter), flags);


	// Find out if this command is still on the pending list. If it is and
	// was never issued, abort and return success. If the command is owned
	// by the firmware, we must wait for it to complete by the FW.
	spin_lock_irqsave(PENDING_LIST_LOCK(adapter), flags);
	list_for_each_entry_safe(scb, tmp, &adapter->pend_list, list) {

		if (scb->scp == scp) {	// Found command

			list_del_init(&scb->list);	// from pending list

			ASSERT(!(scb->state & SCB_ISSUED));

			con_log(CL_ANN, (KERN_WARNING
				"megaraid abort: [%d:%d], driver owner\n",
				scb->dev_channel, scb->dev_target));

			scp->result = (DID_ABORT << 16);
			scp->scsi_done(scp);

			megaraid_dealloc_scb(adapter, scb);

			spin_unlock_irqrestore(PENDING_LIST_LOCK(adapter),
				flags);

			return SUCCESS;
		}
	}
	spin_unlock_irqrestore(PENDING_LIST_LOCK(adapter), flags);


	// Check do we even own this command, in which case this would be
	// owned by the firmware. The only way to locate the FW scb is to
	// traverse through the list of all SCB, since driver does not
	// maintain these SCBs on any list
	found = 0;
	spin_lock_irq(&adapter->lock);
	for (i = 0; i < MBOX_MAX_SCSI_CMDS; i++) {
		scb = adapter->kscb_list + i;

		if (scb->scp == scp) {

			found = 1;

			if (!(scb->state & SCB_ISSUED)) {
				con_log(CL_ANN, (KERN_WARNING
				"megaraid abort: %d[%d:%d], invalid state\n",
				scb->sno, scb->dev_channel, scb->dev_target));
				BUG();
			}
			else {
				con_log(CL_ANN, (KERN_WARNING
				"megaraid abort: %d[%d:%d], fw owner\n",
				scb->sno, scb->dev_channel, scb->dev_target));
			}
		}
	}
	spin_unlock_irq(&adapter->lock);

	if (!found) {
		con_log(CL_ANN, (KERN_WARNING "megaraid abort: do now own\n"));

		// FIXME: Should there be a callback for this command?
		return SUCCESS;
	}

	// We cannot actually abort a command owned by firmware, return
	// failure and wait for reset. In host reset handler, we will find out
	// if the HBA is still live
	return FAILED;
}

/**
 * megaraid_reset_handler - device reset handler for mailbox based driver
 * @scp		: reference command
 *
 * Reset handler for the mailbox based controller. First try to find out if
 * the FW is still live, in which case the outstanding commands counter mut go
 * down to 0. If that happens, also issue the reservation reset command to
 * relinquish (possible) reservations on the logical drives connected to this
 * host.
 **/
static int
megaraid_reset_handler(struct scsi_cmnd *scp)
{
	adapter_t	*adapter;
	scb_t		*scb;
	scb_t		*tmp;
	mraid_device_t	*raid_dev;
	unsigned long	flags;
	uint8_t		raw_mbox[sizeof(mbox_t)];
	int		rval;
	int		recovery_window;
	int		recovering;
	int		i;
	uioc_t		*kioc;

	adapter		= SCP2ADAPTER(scp);
	raid_dev	= ADAP2RAIDDEV(adapter);

	// return failure if adapter is not responding
	if (raid_dev->hw_error) {
		con_log(CL_ANN, (KERN_NOTICE
			"megaraid: hw error, cannot reset\n"));
		return FAILED;
	}


	// Under exceptional conditions, FW can take up to 3 minutes to
	// complete command processing. Wait for additional 2 minutes for the
	// pending commands counter to go down to 0. If it doesn't, let the
	// controller be marked offline
	// Also, reset all the commands currently owned by the driver
	spin_lock_irqsave(PENDING_LIST_LOCK(adapter), flags);
	list_for_each_entry_safe(scb, tmp, &adapter->pend_list, list) {
		list_del_init(&scb->list);	// from pending list

		if (scb->sno >= MBOX_MAX_SCSI_CMDS) {
			con_log(CL_ANN, (KERN_WARNING
			"megaraid: IOCTL packet with %d[%d:%d] being reset\n",
			scb->sno, scb->dev_channel, scb->dev_target));

			scb->status = -1;

			kioc			= (uioc_t *)scb->gp;
			kioc->status		= -EFAULT;

			megaraid_mbox_mm_done(adapter, scb);
		} else {
			if (scb->scp == scp) {	// Found command
				con_log(CL_ANN, (KERN_WARNING
					"megaraid: %d[%d:%d], reset from pending list\n",
					scb->sno, scb->dev_channel, scb->dev_target));
			} else {
				con_log(CL_ANN, (KERN_WARNING
				"megaraid: IO packet with %d[%d:%d] being reset\n",
				scb->sno, scb->dev_channel, scb->dev_target));
			}

			scb->scp->result = (DID_RESET << 16);
			scb->scp->scsi_done(scb->scp);

			megaraid_dealloc_scb(adapter, scb);
		}
	}
	spin_unlock_irqrestore(PENDING_LIST_LOCK(adapter), flags);

	if (adapter->outstanding_cmds) {
		con_log(CL_ANN, (KERN_NOTICE
			"megaraid: %d outstanding commands. Max wait %d sec\n",
			adapter->outstanding_cmds,
			(MBOX_RESET_WAIT + MBOX_RESET_EXT_WAIT)));
	}

	recovery_window = MBOX_RESET_WAIT + MBOX_RESET_EXT_WAIT;

	recovering = adapter->outstanding_cmds;

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

		megaraid_ack_sequence(adapter);

		// print a message once every 5 seconds only
		if (!(i % 5)) {
			con_log(CL_ANN, (
			"megaraid mbox: Wait for %d commands to complete:%d\n",
				adapter->outstanding_cmds,
				(MBOX_RESET_WAIT + MBOX_RESET_EXT_WAIT) - i));
		}

		// bailout if no recovery happened in reset time
		if (adapter->outstanding_cmds == 0) {
			break;
		}

		msleep(1000);
	}

	spin_lock(&adapter->lock);

	// If still outstanding commands, bail out
	if (adapter->outstanding_cmds) {
		con_log(CL_ANN, (KERN_WARNING
			"megaraid mbox: critical hardware error!\n"));

		raid_dev->hw_error = 1;

		rval = FAILED;
		goto out;
	}
	else {
		con_log(CL_ANN, (KERN_NOTICE
		"megaraid mbox: reset sequence completed successfully\n"));
	}


	// If the controller supports clustering, reset reservations
	if (!adapter->ha) {
		rval = SUCCESS;
		goto out;
	}

	// clear reservations if any
	raw_mbox[0] = CLUSTER_CMD;
	raw_mbox[2] = RESET_RESERVATIONS;

	rval = SUCCESS;
	if (mbox_post_sync_cmd_fast(adapter, raw_mbox) == 0) {
		con_log(CL_ANN,
			(KERN_INFO "megaraid: reservation reset\n"));
	}
	else {
		rval = FAILED;
		con_log(CL_ANN, (KERN_WARNING
				"megaraid: reservation reset failed\n"));
	}

 out:
	spin_unlock(&adapter->lock);
	return rval;
}

/*
 * START: internal commands library
 *
 * This section of the driver has the common routine used by the driver and
 * also has all the FW routines
 */

/**
 * mbox_post_sync_cmd() - blocking command to the mailbox based controllers
 * @adapter	: controller's soft state
 * @raw_mbox	: the mailbox
 *
 * Issue a scb in synchronous and non-interrupt mode for mailbox based
 * controllers.
 */
static int
mbox_post_sync_cmd(adapter_t *adapter, uint8_t raw_mbox[])
{
	mraid_device_t	*raid_dev = ADAP2RAIDDEV(adapter);
	mbox64_t	*mbox64;
	mbox_t		*mbox;
	uint8_t		status;
	int		i;


	mbox64	= raid_dev->mbox64;
	mbox	= raid_dev->mbox;

	/*
	 * Wait until mailbox is free
	 */
	if (megaraid_busywait_mbox(raid_dev) != 0)
		goto blocked_mailbox;

	/*
	 * Copy mailbox data into host structure
	 */
	memcpy((caddr_t)mbox, (caddr_t)raw_mbox, 16);
	mbox->cmdid		= 0xFE;
	mbox->busy		= 1;
	mbox->poll		= 0;
	mbox->ack		= 0;
	mbox->numstatus		= 0xFF;
	mbox->status		= 0xFF;

	wmb();
	WRINDOOR(raid_dev, raid_dev->mbox_dma | 0x1);

	// wait for maximum 1 second for status to post. If the status is not
	// available within 1 second, assume FW is initializing and wait
	// for an extended amount of time
	if (mbox->numstatus == 0xFF) {	// status not yet available
		udelay(25);

		for (i = 0; mbox->numstatus == 0xFF && i < 1000; i++) {
			rmb();
			msleep(1);
		}


		if (i == 1000) {
			con_log(CL_ANN, (KERN_NOTICE
				"megaraid mailbox: wait for FW to boot      "));

			for (i = 0; (mbox->numstatus == 0xFF) &&
					(i < MBOX_RESET_WAIT); i++) {
				rmb();
				con_log(CL_ANN, ("\b\b\b\b\b[%03d]",
							MBOX_RESET_WAIT - i));
				msleep(1000);
			}

			if (i == MBOX_RESET_WAIT) {

				con_log(CL_ANN, (
				"\nmegaraid mailbox: status not available\n"));

				return -1;
			}
			con_log(CL_ANN, ("\b\b\b\b\b[ok] \n"));
		}
	}

	// wait for maximum 1 second for poll semaphore
	if (mbox->poll != 0x77) {
		udelay(25);

		for (i = 0; (mbox->poll != 0x77) && (i < 1000); i++) {
			rmb();
			msleep(1);
		}

		if (i == 1000) {
			con_log(CL_ANN, (KERN_WARNING
			"megaraid mailbox: could not get poll semaphore\n"));
			return -1;
		}
	}

	WRINDOOR(raid_dev, raid_dev->mbox_dma | 0x2);
	wmb();

	// wait for maximum 1 second for acknowledgement
	if (RDINDOOR(raid_dev) & 0x2) {
		udelay(25);

		for (i = 0; (RDINDOOR(raid_dev) & 0x2) && (i < 1000); i++) {
			rmb();
			msleep(1);
		}

		if (i == 1000) {
			con_log(CL_ANN, (KERN_WARNING
				"megaraid mailbox: could not acknowledge\n"));
			return -1;
		}
	}
	mbox->poll	= 0;
	mbox->ack	= 0x77;

	status = mbox->status;

	// invalidate the completed command id array. After command
	// completion, firmware would write the valid id.
	mbox->numstatus	= 0xFF;
	mbox->status	= 0xFF;
	for (i = 0; i < MBOX_MAX_FIRMWARE_STATUS; i++) {
		mbox->completed[i] = 0xFF;
	}

	return status;

blocked_mailbox:

	con_log(CL_ANN, (KERN_WARNING "megaraid: blocked mailbox\n") );
	return -1;
}


/**
 * mbox_post_sync_cmd_fast - blocking command to the mailbox based controllers
 * @adapter	: controller's soft state
 * @raw_mbox	: the mailbox
 *
 * Issue a scb in synchronous and non-interrupt mode for mailbox based
 * controllers. This is a faster version of the synchronous command and
 * therefore can be called in interrupt-context as well.
 */
static int
mbox_post_sync_cmd_fast(adapter_t *adapter, uint8_t raw_mbox[])
{
	mraid_device_t	*raid_dev = ADAP2RAIDDEV(adapter);
	mbox_t		*mbox;
	long		i;


	mbox	= raid_dev->mbox;

	// return immediately if the mailbox is busy
	if (mbox->busy) return -1;

	// Copy mailbox data into host structure
	memcpy((caddr_t)mbox, (caddr_t)raw_mbox, 14);
	mbox->cmdid		= 0xFE;
	mbox->busy		= 1;
	mbox->poll		= 0;
	mbox->ack		= 0;
	mbox->numstatus		= 0xFF;
	mbox->status		= 0xFF;

	wmb();
	WRINDOOR(raid_dev, raid_dev->mbox_dma | 0x1);

	for (i = 0; i < MBOX_SYNC_WAIT_CNT; i++) {
		if (mbox->numstatus != 0xFF) break;
		rmb();
		udelay(MBOX_SYNC_DELAY_200);
	}

	if (i == MBOX_SYNC_WAIT_CNT) {
		// We may need to re-calibrate the counter
		con_log(CL_ANN, (KERN_CRIT
			"megaraid: fast sync command timed out\n"));
	}

	WRINDOOR(raid_dev, raid_dev->mbox_dma | 0x2);
	wmb();

	return mbox->status;
}


/**
 * megaraid_busywait_mbox() - Wait until the controller's mailbox is available
 * @raid_dev	: RAID device (HBA) soft state
 *
 * Wait until the controller's mailbox is available to accept more commands.
 * Wait for at most 1 second.
 */
static int
megaraid_busywait_mbox(mraid_device_t *raid_dev)
{
	mbox_t	*mbox = raid_dev->mbox;
	int	i = 0;

	if (mbox->busy) {
		udelay(25);
		for (i = 0; mbox->busy && i < 1000; i++)
			msleep(1);
	}

	if (i < 1000) return 0;
	else return -1;
}


/**
 * megaraid_mbox_product_info - some static information about the controller
 * @adapter	: our soft state
 *
 * Issue commands to the controller to grab some parameters required by our
 * caller.
 */
static int
megaraid_mbox_product_info(adapter_t *adapter)
{
	mraid_device_t		*raid_dev = ADAP2RAIDDEV(adapter);
	mbox_t			*mbox;
	uint8_t			raw_mbox[sizeof(mbox_t)];
	mraid_pinfo_t		*pinfo;
	dma_addr_t		pinfo_dma_h;
	mraid_inquiry3_t	*mraid_inq3;
	int			i;


	memset((caddr_t)raw_mbox, 0, sizeof(raw_mbox));
	mbox = (mbox_t *)raw_mbox;

	/*
	 * Issue an ENQUIRY3 command to find out certain adapter parameters,
	 * e.g., max channels, max commands etc.
	 */
	pinfo = pci_alloc_consistent(adapter->pdev, sizeof(mraid_pinfo_t),
			&pinfo_dma_h);

	if (pinfo == NULL) {
		con_log(CL_ANN, (KERN_WARNING
			"megaraid: out of memory, %s %d\n", __func__,
			__LINE__));

		return -1;
	}
	memset(pinfo, 0, sizeof(mraid_pinfo_t));

	mbox->xferaddr = (uint32_t)adapter->ibuf_dma_h;
	memset((void *)adapter->ibuf, 0, MBOX_IBUF_SIZE);

	raw_mbox[0] = FC_NEW_CONFIG;
	raw_mbox[2] = NC_SUBOP_ENQUIRY3;
	raw_mbox[3] = ENQ3_GET_SOLICITED_FULL;

	// Issue the command
	if (mbox_post_sync_cmd(adapter, raw_mbox) != 0) {

		con_log(CL_ANN, (KERN_WARNING "megaraid: Inquiry3 failed\n"));

		pci_free_consistent(adapter->pdev, sizeof(mraid_pinfo_t),
			pinfo, pinfo_dma_h);

		return -1;
	}

	/*
	 * Collect information about state of each physical drive
	 * attached to the controller. We will expose all the disks
	 * which are not part of RAID
	 */
	mraid_inq3 = (mraid_inquiry3_t *)adapter->ibuf;
	for (i = 0; i < MBOX_MAX_PHYSICAL_DRIVES; i++) {
		raid_dev->pdrv_state[i] = mraid_inq3->pdrv_state[i];
	}

	/*
	 * Get product info for information like number of channels,
	 * maximum commands supported.
	 */
	memset((caddr_t)raw_mbox, 0, sizeof(raw_mbox));
	mbox->xferaddr = (uint32_t)pinfo_dma_h;

	raw_mbox[0] = FC_NEW_CONFIG;
	raw_mbox[2] = NC_SUBOP_PRODUCT_INFO;

	if (mbox_post_sync_cmd(adapter, raw_mbox) != 0) {

		con_log(CL_ANN, (KERN_WARNING
			"megaraid: product info failed\n"));

		pci_free_consistent(adapter->pdev, sizeof(mraid_pinfo_t),
			pinfo, pinfo_dma_h);

		return -1;
	}

	/*
	 * Setup some parameters for host, as required by our caller
	 */
	adapter->max_channel = pinfo->nchannels;

	/*
	 * we will export all the logical drives on a single channel.
	 * Add 1 since inquires do not come for inititor ID
	 */
	adapter->max_target	= MAX_LOGICAL_DRIVES_40LD + 1;
	adapter->max_lun	= 8;	// up to 8 LUNs for non-disk devices

	/*
	 * These are the maximum outstanding commands for the scsi-layer
	 */
	adapter->max_cmds	= MBOX_MAX_SCSI_CMDS;

	memset(adapter->fw_version, 0, VERSION_SIZE);
	memset(adapter->bios_version, 0, VERSION_SIZE);

	memcpy(adapter->fw_version, pinfo->fw_version, 4);
	adapter->fw_version[4] = 0;

	memcpy(adapter->bios_version, pinfo->bios_version, 4);
	adapter->bios_version[4] = 0;

	con_log(CL_ANN, (KERN_NOTICE
		"megaraid: fw version:[%s] bios version:[%s]\n",
		adapter->fw_version, adapter->bios_version));

	pci_free_consistent(adapter->pdev, sizeof(mraid_pinfo_t), pinfo,
			pinfo_dma_h);

	return 0;
}



/**
 * megaraid_mbox_extended_cdb - check for support for extended CDBs
 * @adapter	: soft state for the controller
 *
 * This routine check whether the controller in question supports extended
 * ( > 10 bytes ) CDBs.
 */
static int
megaraid_mbox_extended_cdb(adapter_t *adapter)
{
	mbox_t		*mbox;
	uint8_t		raw_mbox[sizeof(mbox_t)];
	int		rval;

	mbox = (mbox_t *)raw_mbox;

	memset((caddr_t)raw_mbox, 0, sizeof(raw_mbox));
	mbox->xferaddr	= (uint32_t)adapter->ibuf_dma_h;

	memset((void *)adapter->ibuf, 0, MBOX_IBUF_SIZE);

	raw_mbox[0] = MAIN_MISC_OPCODE;
	raw_mbox[2] = SUPPORT_EXT_CDB;

	/*
	 * Issue the command
	 */
	rval = 0;
	if (mbox_post_sync_cmd(adapter, raw_mbox) != 0) {
		rval = -1;
	}

	return rval;
}


/**
 * megaraid_mbox_support_ha - Do we support clustering
 * @adapter	: soft state for the controller
 * @init_id	: ID of the initiator
 *
 * Determine if the firmware supports clustering and the ID of the initiator.
 */
static int
megaraid_mbox_support_ha(adapter_t *adapter, uint16_t *init_id)
{
	mbox_t		*mbox;
	uint8_t		raw_mbox[sizeof(mbox_t)];
	int		rval;


	mbox = (mbox_t *)raw_mbox;

	memset((caddr_t)raw_mbox, 0, sizeof(raw_mbox));

	mbox->xferaddr = (uint32_t)adapter->ibuf_dma_h;

	memset((void *)adapter->ibuf, 0, MBOX_IBUF_SIZE);

	raw_mbox[0] = GET_TARGET_ID;

	// Issue the command
	*init_id = 7;
	rval =  -1;
	if (mbox_post_sync_cmd(adapter, raw_mbox) == 0) {

		*init_id = *(uint8_t *)adapter->ibuf;

		con_log(CL_ANN, (KERN_INFO
			"megaraid: cluster firmware, initiator ID: %d\n",
			*init_id));

		rval =  0;
	}

	return rval;
}


/**
 * megaraid_mbox_support_random_del - Do we support random deletion
 * @adapter	: soft state for the controller
 *
 * Determine if the firmware supports random deletion.
 * Return:	1 is operation supported, 0 otherwise
 */
static int
megaraid_mbox_support_random_del(adapter_t *adapter)
{
	mbox_t		*mbox;
	uint8_t		raw_mbox[sizeof(mbox_t)];
	int		rval;

	/*
	 * Newer firmware on Dell CERC expect a different
	 * random deletion handling, so disable it.
	 */
	if (adapter->pdev->vendor == PCI_VENDOR_ID_AMI &&
	    adapter->pdev->device == PCI_DEVICE_ID_AMI_MEGARAID3 &&
	    adapter->pdev->subsystem_vendor == PCI_VENDOR_ID_DELL &&
	    adapter->pdev->subsystem_device == PCI_SUBSYS_ID_CERC_ATA100_4CH &&
	    (adapter->fw_version[0] > '6' ||
	     (adapter->fw_version[0] == '6' &&
	      adapter->fw_version[2] > '6') ||
	     (adapter->fw_version[0] == '6'
	      && adapter->fw_version[2] == '6'
	      && adapter->fw_version[3] > '1'))) {
		con_log(CL_DLEVEL1, ("megaraid: disable random deletion\n"));
		return 0;
	}

	mbox = (mbox_t *)raw_mbox;

	memset((caddr_t)raw_mbox, 0, sizeof(mbox_t));

	raw_mbox[0] = FC_DEL_LOGDRV;
	raw_mbox[2] = OP_SUP_DEL_LOGDRV;

	// Issue the command
	rval = 0;
	if (mbox_post_sync_cmd(adapter, raw_mbox) == 0) {

		con_log(CL_DLEVEL1, ("megaraid: supports random deletion\n"));

		rval =  1;
	}

	return rval;
}


/**
 * megaraid_mbox_get_max_sg - maximum sg elements supported by the firmware
 * @adapter	: soft state for the controller
 *
 * Find out the maximum number of scatter-gather elements supported by the
 * firmware.
 */
static int
megaraid_mbox_get_max_sg(adapter_t *adapter)
{
	mbox_t		*mbox;
	uint8_t		raw_mbox[sizeof(mbox_t)];
	int		nsg;


	mbox = (mbox_t *)raw_mbox;

	memset((caddr_t)raw_mbox, 0, sizeof(mbox_t));

	mbox->xferaddr = (uint32_t)adapter->ibuf_dma_h;

	memset((void *)adapter->ibuf, 0, MBOX_IBUF_SIZE);

	raw_mbox[0] = MAIN_MISC_OPCODE;
	raw_mbox[2] = GET_MAX_SG_SUPPORT;

	// Issue the command
	if (mbox_post_sync_cmd(adapter, raw_mbox) == 0) {
		nsg =  *(uint8_t *)adapter->ibuf;
	}
	else {
		nsg =  MBOX_DEFAULT_SG_SIZE;
	}

	if (nsg > MBOX_MAX_SG_SIZE) nsg = MBOX_MAX_SG_SIZE;

	return nsg;
}


/**
 * megaraid_mbox_enum_raid_scsi - enumerate the RAID and SCSI channels
 * @adapter	: soft state for the controller
 *
 * Enumerate the RAID and SCSI channels for ROMB platforms so that channels
 * can be exported as regular SCSI channels.
 */
static void
megaraid_mbox_enum_raid_scsi(adapter_t *adapter)
{
	mraid_device_t	*raid_dev = ADAP2RAIDDEV(adapter);
	mbox_t		*mbox;
	uint8_t		raw_mbox[sizeof(mbox_t)];


	mbox = (mbox_t *)raw_mbox;

	memset((caddr_t)raw_mbox, 0, sizeof(mbox_t));

	mbox->xferaddr = (uint32_t)adapter->ibuf_dma_h;

	memset((void *)adapter->ibuf, 0, MBOX_IBUF_SIZE);

	raw_mbox[0] = CHNL_CLASS;
	raw_mbox[2] = GET_CHNL_CLASS;

	// Issue the command. If the command fails, all channels are RAID
	// channels
	raid_dev->channel_class = 0xFF;
	if (mbox_post_sync_cmd(adapter, raw_mbox) == 0) {
		raid_dev->channel_class =  *(uint8_t *)adapter->ibuf;
	}

	return;
}


/**
 * megaraid_mbox_flush_cache - flush adapter and disks cache
 * @adapter		: soft state for the controller
 *
 * Flush adapter cache followed by disks cache.
 */
static void
megaraid_mbox_flush_cache(adapter_t *adapter)
{
	mbox_t	*mbox;
	uint8_t	raw_mbox[sizeof(mbox_t)];


	mbox = (mbox_t *)raw_mbox;

	memset((caddr_t)raw_mbox, 0, sizeof(mbox_t));

	raw_mbox[0] = FLUSH_ADAPTER;

	if (mbox_post_sync_cmd(adapter, raw_mbox) != 0) {
		con_log(CL_ANN, ("megaraid: flush adapter failed\n"));
	}

	raw_mbox[0] = FLUSH_SYSTEM;

	if (mbox_post_sync_cmd(adapter, raw_mbox) != 0) {
		con_log(CL_ANN, ("megaraid: flush disks cache failed\n"));
	}

	return;
}


/**
 * megaraid_mbox_fire_sync_cmd - fire the sync cmd
 * @adapter		: soft state for the controller
 *
 * Clears the pending cmds in FW and reinits its RAID structs.
 */
static int
megaraid_mbox_fire_sync_cmd(adapter_t *adapter)
{
	mbox_t	*mbox;
	uint8_t	raw_mbox[sizeof(mbox_t)];
	mraid_device_t	*raid_dev = ADAP2RAIDDEV(adapter);
	mbox64_t *mbox64;
	int	status = 0;
	int i;
	uint32_t dword;

	mbox = (mbox_t *)raw_mbox;

	memset((caddr_t)raw_mbox, 0, sizeof(mbox_t));

	raw_mbox[0] = 0xFF;

	mbox64	= raid_dev->mbox64;
	mbox	= raid_dev->mbox;

	/* Wait until mailbox is free */
	if (megaraid_busywait_mbox(raid_dev) != 0) {
		status = 1;
		goto blocked_mailbox;
	}

	/* Copy mailbox data into host structure */
	memcpy((caddr_t)mbox, (caddr_t)raw_mbox, 16);
	mbox->cmdid		= 0xFE;
	mbox->busy		= 1;
	mbox->poll		= 0;
	mbox->ack		= 0;
	mbox->numstatus		= 0;
	mbox->status		= 0;

	wmb();
	WRINDOOR(raid_dev, raid_dev->mbox_dma | 0x1);

	/* Wait for maximum 1 min for status to post.
	 * If the Firmware SUPPORTS the ABOVE COMMAND,
	 * mbox->cmd will be set to 0
	 * else
	 * the firmware will reject the command with
	 * mbox->numstatus set to 1
	 */

	i = 0;
	status = 0;
	while (!mbox->numstatus && mbox->cmd == 0xFF) {
		rmb();
		msleep(1);
		i++;
		if (i > 1000 * 60) {
			status = 1;
			break;
		}
	}
	if (mbox->numstatus == 1)
		status = 1; /*cmd not supported*/

	/* Check for interrupt line */
	dword = RDOUTDOOR(raid_dev);
	WROUTDOOR(raid_dev, dword);
	WRINDOOR(raid_dev,2);

	return status;

blocked_mailbox:
	con_log(CL_ANN, (KERN_WARNING "megaraid: blocked mailbox\n"));
	return status;
}

/**
 * megaraid_mbox_display_scb - display SCB information, mostly debug purposes
 * @adapter		: controller's soft state
 * @scb			: SCB to be displayed
 * @level		: debug level for console print
 *
 * Diplay information about the given SCB iff the current debug level is
 * verbose.
 */
static void
megaraid_mbox_display_scb(adapter_t *adapter, scb_t *scb)
{
	mbox_ccb_t		*ccb;
	struct scsi_cmnd	*scp;
	mbox_t			*mbox;
	int			level;
	int			i;


	ccb	= (mbox_ccb_t *)scb->ccb;
	scp	= scb->scp;
	mbox	= ccb->mbox;

	level = CL_DLEVEL3;

	con_log(level, (KERN_NOTICE
		"megaraid mailbox: status:%#x cmd:%#x id:%#x ", scb->status,
		mbox->cmd, scb->sno));

	con_log(level, ("sec:%#x lba:%#x addr:%#x ld:%d sg:%d\n",
		mbox->numsectors, mbox->lba, mbox->xferaddr, mbox->logdrv,
		mbox->numsge));

	if (!scp) return;

	con_log(level, (KERN_NOTICE "scsi cmnd: "));

	for (i = 0; i < scp->cmd_len; i++) {
		con_log(level, ("%#2.02x ", scp->cmnd[i]));
	}

	con_log(level, ("\n"));

	return;
}


/**
 * megaraid_mbox_setup_device_map - manage device ids
 * @adapter	: Driver's soft state
 *
 * Manage the device ids to have an appropriate mapping between the kernel
 * scsi addresses and megaraid scsi and logical drive addresses. We export
 * scsi devices on their actual addresses, whereas the logical drives are
 * exported on a virtual scsi channel.
 */
static void
megaraid_mbox_setup_device_map(adapter_t *adapter)
{
	uint8_t		c;
	uint8_t		t;

	/*
	 * First fill the values on the logical drive channel
	 */
	for (t = 0; t < LSI_MAX_LOGICAL_DRIVES_64LD; t++)
		adapter->device_ids[adapter->max_channel][t] =
			(t < adapter->init_id) ?  t : t - 1;

	adapter->device_ids[adapter->max_channel][adapter->init_id] = 0xFF;

	/*
	 * Fill the values on the physical devices channels
	 */
	for (c = 0; c < adapter->max_channel; c++)
		for (t = 0; t < LSI_MAX_LOGICAL_DRIVES_64LD; t++)
			adapter->device_ids[c][t] = (c << 8) | t;
}


/*
 * END: internal commands library
 */

/*
 * START: Interface for the common management module
 *
 * This is the module, which interfaces with the common management module to
 * provide support for ioctl and sysfs
 */

/**
 * megaraid_cmm_register - register with the management module
 * @adapter		: HBA soft state
 *
 * Register with the management module, which allows applications to issue
 * ioctl calls to the drivers. This interface is used by the management module
 * to setup sysfs support as well.
 */
static int
megaraid_cmm_register(adapter_t *adapter)
{
	mraid_device_t	*raid_dev = ADAP2RAIDDEV(adapter);
	mraid_mmadp_t	adp;
	scb_t		*scb;
	mbox_ccb_t	*ccb;
	int		rval;
	int		i;

	// Allocate memory for the base list of scb for management module.
	adapter->uscb_list = kcalloc(MBOX_MAX_USER_CMDS, sizeof(scb_t), GFP_KERNEL);

	if (adapter->uscb_list == NULL) {
		con_log(CL_ANN, (KERN_WARNING
			"megaraid: out of memory, %s %d\n", __func__,
			__LINE__));
		return -1;
	}


	// Initialize the synchronization parameters for resources for
	// commands for management module
	INIT_LIST_HEAD(&adapter->uscb_pool);

	spin_lock_init(USER_FREE_LIST_LOCK(adapter));



	// link all the packets. Note, CCB for commands, coming from the
	// commom management module, mailbox physical address are already
	// setup by it. We just need placeholder for that in our local command
	// control blocks
	for (i = 0; i < MBOX_MAX_USER_CMDS; i++) {

		scb			= adapter->uscb_list + i;
		ccb			= raid_dev->uccb_list + i;

		scb->ccb		= (caddr_t)ccb;
		ccb->mbox64		= raid_dev->umbox64 + i;
		ccb->mbox		= &ccb->mbox64->mbox32;
		ccb->raw_mbox		= (uint8_t *)ccb->mbox;

		scb->gp			= 0;

		// COMMAND ID 0 - (MBOX_MAX_SCSI_CMDS-1) ARE RESERVED FOR
		// COMMANDS COMING FROM IO SUBSYSTEM (MID-LAYER)
		scb->sno		= i + MBOX_MAX_SCSI_CMDS;

		scb->scp		= NULL;
		scb->state		= SCB_FREE;
		scb->dma_direction	= PCI_DMA_NONE;
		scb->dma_type		= MRAID_DMA_NONE;
		scb->dev_channel	= -1;
		scb->dev_target		= -1;

		// put scb in the free pool
		list_add_tail(&scb->list, &adapter->uscb_pool);
	}

	adp.unique_id		= adapter->unique_id;
	adp.drvr_type		= DRVRTYPE_MBOX;
	adp.drvr_data		= (unsigned long)adapter;
	adp.pdev		= adapter->pdev;
	adp.issue_uioc		= megaraid_mbox_mm_handler;
	adp.timeout		= MBOX_RESET_WAIT + MBOX_RESET_EXT_WAIT;
	adp.max_kioc		= MBOX_MAX_USER_CMDS;

	if ((rval = mraid_mm_register_adp(&adp)) != 0) {

		con_log(CL_ANN, (KERN_WARNING
			"megaraid mbox: did not register with CMM\n"));

		kfree(adapter->uscb_list);
	}

	return rval;
}


/**
 * megaraid_cmm_unregister - un-register with the management module
 * @adapter		: HBA soft state
 *
 * Un-register with the management module.
 * FIXME: mgmt module must return failure for unregister if it has pending
 * commands in LLD.
 */
static int
megaraid_cmm_unregister(adapter_t *adapter)
{
	kfree(adapter->uscb_list);
	mraid_mm_unregister_adp(adapter->unique_id);
	return 0;
}


/**
 * megaraid_mbox_mm_handler - interface for CMM to issue commands to LLD
 * @drvr_data		: LLD specific data
 * @kioc		: CMM interface packet
 * @action		: command action
 *
 * This routine is invoked whenever the Common Management Module (CMM) has a
 * command for us. The 'action' parameter specifies if this is a new command
 * or otherwise.
 */
static int
megaraid_mbox_mm_handler(unsigned long drvr_data, uioc_t *kioc, uint32_t action)
{
	adapter_t *adapter;

	if (action != IOCTL_ISSUE) {
		con_log(CL_ANN, (KERN_WARNING
			"megaraid: unsupported management action:%#2x\n",
			action));
		return (-ENOTSUPP);
	}

	adapter = (adapter_t *)drvr_data;

	// make sure this adapter is not being detached right now.
	if (atomic_read(&adapter->being_detached)) {
		con_log(CL_ANN, (KERN_WARNING
			"megaraid: reject management request, detaching\n"));
		return (-ENODEV);
	}

	switch (kioc->opcode) {

	case GET_ADAP_INFO:

		kioc->status =  gather_hbainfo(adapter, (mraid_hba_info_t *)
					(unsigned long)kioc->buf_vaddr);

		kioc->done(kioc);

		return kioc->status;

	case MBOX_CMD:

		return megaraid_mbox_mm_command(adapter, kioc);

	default:
		kioc->status = (-EINVAL);
		kioc->done(kioc);
		return (-EINVAL);
	}

	return 0;	// not reached
}

/**
 * megaraid_mbox_mm_command - issues commands routed through CMM
 * @adapter		: HBA soft state
 * @kioc		: management command packet
 *
 * Issues commands, which are routed through the management module.
 */
static int
megaraid_mbox_mm_command(adapter_t *adapter, uioc_t *kioc)
{
	struct list_head	*head = &adapter->uscb_pool;
	mbox64_t		*mbox64;
	uint8_t			*raw_mbox;
	scb_t			*scb;
	mbox_ccb_t		*ccb;
	unsigned long		flags;

	// detach one scb from free pool
	spin_lock_irqsave(USER_FREE_LIST_LOCK(adapter), flags);

	if (list_empty(head)) {	// should never happen because of CMM

		con_log(CL_ANN, (KERN_WARNING
			"megaraid mbox: bug in cmm handler, lost resources\n"));

		spin_unlock_irqrestore(USER_FREE_LIST_LOCK(adapter), flags);

		return (-EINVAL);
	}

	scb = list_entry(head->next, scb_t, list);
	list_del_init(&scb->list);

	spin_unlock_irqrestore(USER_FREE_LIST_LOCK(adapter), flags);

	scb->state		= SCB_ACTIVE;
	scb->dma_type		= MRAID_DMA_NONE;
	scb->dma_direction	= PCI_DMA_NONE;

	ccb		= (mbox_ccb_t *)scb->ccb;
	mbox64		= (mbox64_t *)(unsigned long)kioc->cmdbuf;
	raw_mbox	= (uint8_t *)&mbox64->mbox32;

	memcpy(ccb->mbox64, mbox64, sizeof(mbox64_t));

	scb->gp		= (unsigned long)kioc;

	/*
	 * If it is a logdrv random delete operation, we have to wait till
	 * there are no outstanding cmds at the fw and then issue it directly
	 */
	if (raw_mbox[0] == FC_DEL_LOGDRV && raw_mbox[2] == OP_DEL_LOGDRV) {

		if (wait_till_fw_empty(adapter)) {
			con_log(CL_ANN, (KERN_NOTICE
				"megaraid mbox: LD delete, timed out\n"));

			kioc->status = -ETIME;

			scb->status = -1;

			megaraid_mbox_mm_done(adapter, scb);

			return (-ETIME);
		}

		INIT_LIST_HEAD(&scb->list);

		scb->state = SCB_ISSUED;
		if (mbox_post_cmd(adapter, scb) != 0) {

			con_log(CL_ANN, (KERN_NOTICE
				"megaraid mbox: LD delete, mailbox busy\n"));

			kioc->status = -EBUSY;

			scb->status = -1;

			megaraid_mbox_mm_done(adapter, scb);

			return (-EBUSY);
		}

		return 0;
	}

	// put the command on the pending list and execute
	megaraid_mbox_runpendq(adapter, scb);

	return 0;
}


static int
wait_till_fw_empty(adapter_t *adapter)
{
	unsigned long	flags = 0;
	int		i;


	/*
	 * Set the quiescent flag to stop issuing cmds to FW.
	 */
	spin_lock_irqsave(&adapter->lock, flags);
	adapter->quiescent++;
	spin_unlock_irqrestore(&adapter->lock, flags);

	/*
	 * Wait till there are no more cmds outstanding at FW. Try for at most
	 * 60 seconds
	 */
	for (i = 0; i < 60 && adapter->outstanding_cmds; i++) {
		con_log(CL_DLEVEL1, (KERN_INFO
			"megaraid: FW has %d pending commands\n",
			adapter->outstanding_cmds));

		msleep(1000);
	}

	return adapter->outstanding_cmds;
}


/**
 * megaraid_mbox_mm_done - callback for CMM commands
 * @adapter	: HBA soft state
 * @scb		: completed command
 *
 * Callback routine for internal commands originated from the management
 * module.
 */
static void
megaraid_mbox_mm_done(adapter_t *adapter, scb_t *scb)
{
	uioc_t			*kioc;
	mbox64_t		*mbox64;
	uint8_t			*raw_mbox;
	unsigned long		flags;

	kioc			= (uioc_t *)scb->gp;
	mbox64			= (mbox64_t *)(unsigned long)kioc->cmdbuf;
	mbox64->mbox32.status	= scb->status;
	raw_mbox		= (uint8_t *)&mbox64->mbox32;


	// put scb in the free pool
	scb->state	= SCB_FREE;
	scb->scp	= NULL;

	spin_lock_irqsave(USER_FREE_LIST_LOCK(adapter), flags);

	list_add(&scb->list, &adapter->uscb_pool);

	spin_unlock_irqrestore(USER_FREE_LIST_LOCK(adapter), flags);

	// if a delete logical drive operation succeeded, restart the
	// controller
	if (raw_mbox[0] == FC_DEL_LOGDRV && raw_mbox[2] == OP_DEL_LOGDRV) {

		adapter->quiescent--;

		megaraid_mbox_runpendq(adapter, NULL);
	}

	kioc->done(kioc);

	return;
}


/**
 * gather_hbainfo - HBA characteristics for the applications
 * @adapter		: HBA soft state
 * @hinfo		: pointer to the caller's host info strucuture
 */
static int
gather_hbainfo(adapter_t *adapter, mraid_hba_info_t *hinfo)
{
	uint8_t	dmajor;

	dmajor			= megaraid_mbox_version[0];

	hinfo->pci_vendor_id	= adapter->pdev->vendor;
	hinfo->pci_device_id	= adapter->pdev->device;
	hinfo->subsys_vendor_id	= adapter->pdev->subsystem_vendor;
	hinfo->subsys_device_id	= adapter->pdev->subsystem_device;

	hinfo->pci_bus		= adapter->pdev->bus->number;
	hinfo->pci_dev_fn	= adapter->pdev->devfn;
	hinfo->pci_slot		= PCI_SLOT(adapter->pdev->devfn);
	hinfo->irq		= adapter->host->irq;
	hinfo->baseport		= ADAP2RAIDDEV(adapter)->baseport;

	hinfo->unique_id	= (hinfo->pci_bus << 8) | adapter->pdev->devfn;
	hinfo->host_no		= adapter->host->host_no;

	return 0;
}

/*
 * END: Interface for the common management module
 */



/**
 * megaraid_sysfs_alloc_resources - allocate sysfs related resources
 * @adapter	: controller's soft state
 *
 * Allocate packets required to issue FW calls whenever the sysfs attributes
 * are read. These attributes would require up-to-date information from the
 * FW. Also set up resources for mutual exclusion to share these resources and
 * the wait queue.
 *
 * Return 0 on success.
 * Return -ERROR_CODE on failure.
 */
static int
megaraid_sysfs_alloc_resources(adapter_t *adapter)
{
	mraid_device_t	*raid_dev = ADAP2RAIDDEV(adapter);
	int		rval = 0;

	raid_dev->sysfs_uioc = kmalloc(sizeof(uioc_t), GFP_KERNEL);

	raid_dev->sysfs_mbox64 = kmalloc(sizeof(mbox64_t), GFP_KERNEL);

	raid_dev->sysfs_buffer = pci_alloc_consistent(adapter->pdev,
			PAGE_SIZE, &raid_dev->sysfs_buffer_dma);

	if (!raid_dev->sysfs_uioc || !raid_dev->sysfs_mbox64 ||
		!raid_dev->sysfs_buffer) {

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

		rval = -ENOMEM;

		megaraid_sysfs_free_resources(adapter);
	}

	mutex_init(&raid_dev->sysfs_mtx);

	init_waitqueue_head(&raid_dev->sysfs_wait_q);

	return rval;
}


/**
 * megaraid_sysfs_free_resources - free sysfs related resources
 * @adapter	: controller's soft state
 *
 * Free packets allocated for sysfs FW commands
 */
static void
megaraid_sysfs_free_resources(adapter_t *adapter)
{
	mraid_device_t	*raid_dev = ADAP2RAIDDEV(adapter);

	kfree(raid_dev->sysfs_uioc);
	kfree(raid_dev->sysfs_mbox64);

	if (raid_dev->sysfs_buffer) {
		pci_free_consistent(adapter->pdev, PAGE_SIZE,
			raid_dev->sysfs_buffer, raid_dev->sysfs_buffer_dma);
	}
}


/**
 * megaraid_sysfs_get_ldmap_done - callback for get ldmap
 * @uioc	: completed packet
 *
 * Callback routine called in the ISR/tasklet context for get ldmap call
 */
static void
megaraid_sysfs_get_ldmap_done(uioc_t *uioc)
{
	adapter_t	*adapter = (adapter_t *)uioc->buf_vaddr;
	mraid_device_t	*raid_dev = ADAP2RAIDDEV(adapter);

	uioc->status = 0;

	wake_up(&raid_dev->sysfs_wait_q);
}


/**
 * megaraid_sysfs_get_ldmap_timeout - timeout handling for get ldmap
 * @data	: timed out packet
 *
 * Timeout routine to recover and return to application, in case the adapter
 * has stopped responding. A timeout of 60 seconds for this command seems like
 * a good value.
 */
static void
megaraid_sysfs_get_ldmap_timeout(unsigned long data)
{
	uioc_t		*uioc = (uioc_t *)data;
	adapter_t	*adapter = (adapter_t *)uioc->buf_vaddr;
	mraid_device_t	*raid_dev = ADAP2RAIDDEV(adapter);

	uioc->status = -ETIME;

	wake_up(&raid_dev->sysfs_wait_q);
}


/**
 * megaraid_sysfs_get_ldmap - get update logical drive map
 * @adapter	: controller's soft state
 *
 * This routine will be called whenever user reads the logical drive
 * attributes, go get the current logical drive mapping table from the
 * firmware. We use the management API's to issue commands to the controller.
 *
 * NOTE: The commands issuance functionality is not generalized and
 * implemented in context of "get ld map" command only. If required, the
 * command issuance logical can be trivially pulled out and implemented as a
 * standalone library. For now, this should suffice since there is no other
 * user of this interface.
 *
 * Return 0 on success.
 * Return -1 on failure.
 */
static int
megaraid_sysfs_get_ldmap(adapter_t *adapter)
{
	mraid_device_t		*raid_dev = ADAP2RAIDDEV(adapter);
	uioc_t			*uioc;
	mbox64_t		*mbox64;
	mbox_t			*mbox;
	char			*raw_mbox;
	struct timer_list	sysfs_timer;
	struct timer_list	*timerp;
	caddr_t			ldmap;
	int			rval = 0;

	/*
	 * Allow only one read at a time to go through the sysfs attributes
	 */
	mutex_lock(&raid_dev->sysfs_mtx);

	uioc	= raid_dev->sysfs_uioc;
	mbox64	= raid_dev->sysfs_mbox64;
	ldmap	= raid_dev->sysfs_buffer;

	memset(uioc, 0, sizeof(uioc_t));
	memset(mbox64, 0, sizeof(mbox64_t));
	memset(ldmap, 0, sizeof(raid_dev->curr_ldmap));

	mbox		= &mbox64->mbox32;
	raw_mbox	= (char *)mbox;
	uioc->cmdbuf    = (uint64_t)(unsigned long)mbox64;
	uioc->buf_vaddr	= (caddr_t)adapter;
	uioc->status	= -ENODATA;
	uioc->done	= megaraid_sysfs_get_ldmap_done;

	/*
	 * Prepare the mailbox packet to get the current logical drive mapping
	 * table
	 */
	mbox->xferaddr = (uint32_t)raid_dev->sysfs_buffer_dma;

	raw_mbox[0] = FC_DEL_LOGDRV;
	raw_mbox[2] = OP_GET_LDID_MAP;

	/*
	 * Setup a timer to recover from a non-responding controller
	 */
	timerp	= &sysfs_timer;
	init_timer(timerp);

	timerp->function	= megaraid_sysfs_get_ldmap_timeout;
	timerp->data		= (unsigned long)uioc;
	timerp->expires		= jiffies + 60 * HZ;

	add_timer(timerp);

	/*
	 * Send the command to the firmware
	 */
	rval = megaraid_mbox_mm_command(adapter, uioc);

	if (rval == 0) {	// command successfully issued
		wait_event(raid_dev->sysfs_wait_q, (uioc->status != -ENODATA));

		/*
		 * Check if the command timed out
		 */
		if (uioc->status == -ETIME) {
			con_log(CL_ANN, (KERN_NOTICE
				"megaraid: sysfs get ld map timed out\n"));

			rval = -ETIME;
		}
		else {
			rval = mbox->status;
		}

		if (rval == 0) {
			memcpy(raid_dev->curr_ldmap, ldmap,
				sizeof(raid_dev->curr_ldmap));
		}
		else {
			con_log(CL_ANN, (KERN_NOTICE
				"megaraid: get ld map failed with %x\n", rval));
		}
	}
	else {
		con_log(CL_ANN, (KERN_NOTICE
			"megaraid: could not issue ldmap command:%x\n", rval));
	}


	del_timer_sync(timerp);

	mutex_unlock(&raid_dev->sysfs_mtx);

	return rval;
}


/**
 * megaraid_sysfs_show_app_hndl - display application handle for this adapter
 * @cdev	: class device object representation for the host
 * @buf		: buffer to send data to
 *
 * Display the handle used by the applications while executing management
 * tasks on the adapter. We invoke a management module API to get the adapter
 * handle, since we do not interface with applications directly.
 */
static ssize_t
megaraid_sysfs_show_app_hndl(struct device *dev, struct device_attribute *attr,
			     char *buf)
{
	struct Scsi_Host *shost = class_to_shost(dev);
	adapter_t	*adapter = (adapter_t *)SCSIHOST2ADAP(shost);
	uint32_t	app_hndl;

	app_hndl = mraid_mm_adapter_app_handle(adapter->unique_id);

	return snprintf(buf, 8, "%u\n", app_hndl);
}


/**
 * megaraid_sysfs_show_ldnum - display the logical drive number for this device
 * @dev		: device object representation for the scsi device
 * @attr	: device attribute to show
 * @buf		: buffer to send data to
 *
 * Display the logical drive number for the device in question, if it a valid
 * logical drive. For physical devices, "-1" is returned.
 *
 * The logical drive number is displayed in following format:
 *
 * <SCSI ID> <LD NUM> <LD STICKY ID> <APP ADAPTER HANDLE>
 *
 *   <int>     <int>       <int>            <int>
 */
static ssize_t
megaraid_sysfs_show_ldnum(struct device *dev, struct device_attribute *attr, char *buf)
{
	struct scsi_device *sdev = to_scsi_device(dev);
	adapter_t	*adapter = (adapter_t *)SCSIHOST2ADAP(sdev->host);
	mraid_device_t	*raid_dev = ADAP2RAIDDEV(adapter);
	int		scsi_id = -1;
	int		logical_drv = -1;
	int		ldid_map = -1;
	uint32_t	app_hndl = 0;
	int		mapped_sdev_id;
	int		rval;
	int		i;

	if (raid_dev->random_del_supported &&
			MRAID_IS_LOGICAL_SDEV(adapter, sdev)) {

		rval = megaraid_sysfs_get_ldmap(adapter);
		if (rval == 0) {

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

				mapped_sdev_id = sdev->id;

				if (sdev->id > adapter->init_id) {
					mapped_sdev_id -= 1;
				}

				if (raid_dev->curr_ldmap[i] == mapped_sdev_id) {

					scsi_id = sdev->id;

					logical_drv = i;

					ldid_map = raid_dev->curr_ldmap[i];

					app_hndl = mraid_mm_adapter_app_handle(
							adapter->unique_id);

					break;
				}
			}
		}
		else {
			con_log(CL_ANN, (KERN_NOTICE
				"megaraid: sysfs get ld map failed: %x\n",
				rval));
		}
	}

	return snprintf(buf, 36, "%d %d %d %d\n", scsi_id, logical_drv,
			ldid_map, app_hndl);
}


/*
 * END: Mailbox Low Level Driver
 */
module_init(megaraid_init);
module_exit(megaraid_exit);

/* vim: set ts=8 sw=8 tw=78 ai si: */
