// SPDX-License-Identifier: GPL-2.0
/*
 * Linux Driver for Mylex DAC960/AcceleRAID/eXtremeRAID PCI RAID Controllers
 *
 * This driver supports the newer, SCSI-based firmware interface only.
 *
 * Copyright 2017 Hannes Reinecke, SUSE Linux GmbH <hare@suse.com>
 *
 * Based on the original DAC960 driver, which has
 * Copyright 1998-2001 by Leonard N. Zubkoff <lnz@dandelion.com>
 * Portions Copyright 2002 by Mylex (An IBM Business Unit)
 */

#include <linux/module.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
#include <linux/raid_class.h>
#include <asm/unaligned.h>
#include <scsi/scsi.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_tcq.h>
#include "myrs.h"

static struct raid_template *myrs_raid_template;

static struct myrs_devstate_name_entry {
	enum myrs_devstate state;
	char *name;
} myrs_devstate_name_list[] = {
	{ MYRS_DEVICE_UNCONFIGURED, "Unconfigured" },
	{ MYRS_DEVICE_ONLINE, "Online" },
	{ MYRS_DEVICE_REBUILD, "Rebuild" },
	{ MYRS_DEVICE_MISSING, "Missing" },
	{ MYRS_DEVICE_SUSPECTED_CRITICAL, "SuspectedCritical" },
	{ MYRS_DEVICE_OFFLINE, "Offline" },
	{ MYRS_DEVICE_CRITICAL, "Critical" },
	{ MYRS_DEVICE_SUSPECTED_DEAD, "SuspectedDead" },
	{ MYRS_DEVICE_COMMANDED_OFFLINE, "CommandedOffline" },
	{ MYRS_DEVICE_STANDBY, "Standby" },
	{ MYRS_DEVICE_INVALID_STATE, "Invalid" },
};

static char *myrs_devstate_name(enum myrs_devstate state)
{
	struct myrs_devstate_name_entry *entry = myrs_devstate_name_list;
	int i;

	for (i = 0; i < ARRAY_SIZE(myrs_devstate_name_list); i++) {
		if (entry[i].state == state)
			return entry[i].name;
	}
	return NULL;
}

static struct myrs_raid_level_name_entry {
	enum myrs_raid_level level;
	char *name;
} myrs_raid_level_name_list[] = {
	{ MYRS_RAID_LEVEL0, "RAID0" },
	{ MYRS_RAID_LEVEL1, "RAID1" },
	{ MYRS_RAID_LEVEL3, "RAID3 right asymmetric parity" },
	{ MYRS_RAID_LEVEL5, "RAID5 right asymmetric parity" },
	{ MYRS_RAID_LEVEL6, "RAID6" },
	{ MYRS_RAID_JBOD, "JBOD" },
	{ MYRS_RAID_NEWSPAN, "New Mylex SPAN" },
	{ MYRS_RAID_LEVEL3F, "RAID3 fixed parity" },
	{ MYRS_RAID_LEVEL3L, "RAID3 left symmetric parity" },
	{ MYRS_RAID_SPAN, "Mylex SPAN" },
	{ MYRS_RAID_LEVEL5L, "RAID5 left symmetric parity" },
	{ MYRS_RAID_LEVELE, "RAIDE (concatenation)" },
	{ MYRS_RAID_PHYSICAL, "Physical device" },
};

static char *myrs_raid_level_name(enum myrs_raid_level level)
{
	struct myrs_raid_level_name_entry *entry = myrs_raid_level_name_list;
	int i;

	for (i = 0; i < ARRAY_SIZE(myrs_raid_level_name_list); i++) {
		if (entry[i].level == level)
			return entry[i].name;
	}
	return NULL;
}

/*
 * myrs_reset_cmd - clears critical fields in struct myrs_cmdblk
 */
static inline void myrs_reset_cmd(struct myrs_cmdblk *cmd_blk)
{
	union myrs_cmd_mbox *mbox = &cmd_blk->mbox;

	memset(mbox, 0, sizeof(union myrs_cmd_mbox));
	cmd_blk->status = 0;
}

/*
 * myrs_qcmd - queues Command for DAC960 V2 Series Controllers.
 */
static void myrs_qcmd(struct myrs_hba *cs, struct myrs_cmdblk *cmd_blk)
{
	void __iomem *base = cs->io_base;
	union myrs_cmd_mbox *mbox = &cmd_blk->mbox;
	union myrs_cmd_mbox *next_mbox = cs->next_cmd_mbox;

	cs->write_cmd_mbox(next_mbox, mbox);

	if (cs->prev_cmd_mbox1->words[0] == 0 ||
	    cs->prev_cmd_mbox2->words[0] == 0)
		cs->get_cmd_mbox(base);

	cs->prev_cmd_mbox2 = cs->prev_cmd_mbox1;
	cs->prev_cmd_mbox1 = next_mbox;

	if (++next_mbox > cs->last_cmd_mbox)
		next_mbox = cs->first_cmd_mbox;

	cs->next_cmd_mbox = next_mbox;
}

/*
 * myrs_exec_cmd - executes V2 Command and waits for completion.
 */
static void myrs_exec_cmd(struct myrs_hba *cs,
		struct myrs_cmdblk *cmd_blk)
{
	DECLARE_COMPLETION_ONSTACK(complete);
	unsigned long flags;

	cmd_blk->complete = &complete;
	spin_lock_irqsave(&cs->queue_lock, flags);
	myrs_qcmd(cs, cmd_blk);
	spin_unlock_irqrestore(&cs->queue_lock, flags);

	WARN_ON(in_interrupt());
	wait_for_completion(&complete);
}

/*
 * myrs_report_progress - prints progress message
 */
static void myrs_report_progress(struct myrs_hba *cs, unsigned short ldev_num,
		unsigned char *msg, unsigned long blocks,
		unsigned long size)
{
	shost_printk(KERN_INFO, cs->host,
		     "Logical Drive %d: %s in Progress: %d%% completed\n",
		     ldev_num, msg,
		     (100 * (int)(blocks >> 7)) / (int)(size >> 7));
}

/*
 * myrs_get_ctlr_info - executes a Controller Information IOCTL Command
 */
static unsigned char myrs_get_ctlr_info(struct myrs_hba *cs)
{
	struct myrs_cmdblk *cmd_blk = &cs->dcmd_blk;
	union myrs_cmd_mbox *mbox = &cmd_blk->mbox;
	dma_addr_t ctlr_info_addr;
	union myrs_sgl *sgl;
	unsigned char status;
	unsigned short ldev_present, ldev_critical, ldev_offline;

	ldev_present = cs->ctlr_info->ldev_present;
	ldev_critical = cs->ctlr_info->ldev_critical;
	ldev_offline = cs->ctlr_info->ldev_offline;

	ctlr_info_addr = dma_map_single(&cs->pdev->dev, cs->ctlr_info,
					sizeof(struct myrs_ctlr_info),
					DMA_FROM_DEVICE);
	if (dma_mapping_error(&cs->pdev->dev, ctlr_info_addr))
		return MYRS_STATUS_FAILED;

	mutex_lock(&cs->dcmd_mutex);
	myrs_reset_cmd(cmd_blk);
	mbox->ctlr_info.id = MYRS_DCMD_TAG;
	mbox->ctlr_info.opcode = MYRS_CMD_OP_IOCTL;
	mbox->ctlr_info.control.dma_ctrl_to_host = true;
	mbox->ctlr_info.control.no_autosense = true;
	mbox->ctlr_info.dma_size = sizeof(struct myrs_ctlr_info);
	mbox->ctlr_info.ctlr_num = 0;
	mbox->ctlr_info.ioctl_opcode = MYRS_IOCTL_GET_CTLR_INFO;
	sgl = &mbox->ctlr_info.dma_addr;
	sgl->sge[0].sge_addr = ctlr_info_addr;
	sgl->sge[0].sge_count = mbox->ctlr_info.dma_size;
	dev_dbg(&cs->host->shost_gendev, "Sending GetControllerInfo\n");
	myrs_exec_cmd(cs, cmd_blk);
	status = cmd_blk->status;
	mutex_unlock(&cs->dcmd_mutex);
	dma_unmap_single(&cs->pdev->dev, ctlr_info_addr,
			 sizeof(struct myrs_ctlr_info), DMA_FROM_DEVICE);
	if (status == MYRS_STATUS_SUCCESS) {
		if (cs->ctlr_info->bg_init_active +
		    cs->ctlr_info->ldev_init_active +
		    cs->ctlr_info->pdev_init_active +
		    cs->ctlr_info->cc_active +
		    cs->ctlr_info->rbld_active +
		    cs->ctlr_info->exp_active != 0)
			cs->needs_update = true;
		if (cs->ctlr_info->ldev_present != ldev_present ||
		    cs->ctlr_info->ldev_critical != ldev_critical ||
		    cs->ctlr_info->ldev_offline != ldev_offline)
			shost_printk(KERN_INFO, cs->host,
				     "Logical drive count changes (%d/%d/%d)\n",
				     cs->ctlr_info->ldev_critical,
				     cs->ctlr_info->ldev_offline,
				     cs->ctlr_info->ldev_present);
	}

	return status;
}

/*
 * myrs_get_ldev_info - executes a Logical Device Information IOCTL Command
 */
static unsigned char myrs_get_ldev_info(struct myrs_hba *cs,
		unsigned short ldev_num, struct myrs_ldev_info *ldev_info)
{
	struct myrs_cmdblk *cmd_blk = &cs->dcmd_blk;
	union myrs_cmd_mbox *mbox = &cmd_blk->mbox;
	dma_addr_t ldev_info_addr;
	struct myrs_ldev_info ldev_info_orig;
	union myrs_sgl *sgl;
	unsigned char status;

	memcpy(&ldev_info_orig, ldev_info, sizeof(struct myrs_ldev_info));
	ldev_info_addr = dma_map_single(&cs->pdev->dev, ldev_info,
					sizeof(struct myrs_ldev_info),
					DMA_FROM_DEVICE);
	if (dma_mapping_error(&cs->pdev->dev, ldev_info_addr))
		return MYRS_STATUS_FAILED;

	mutex_lock(&cs->dcmd_mutex);
	myrs_reset_cmd(cmd_blk);
	mbox->ldev_info.id = MYRS_DCMD_TAG;
	mbox->ldev_info.opcode = MYRS_CMD_OP_IOCTL;
	mbox->ldev_info.control.dma_ctrl_to_host = true;
	mbox->ldev_info.control.no_autosense = true;
	mbox->ldev_info.dma_size = sizeof(struct myrs_ldev_info);
	mbox->ldev_info.ldev.ldev_num = ldev_num;
	mbox->ldev_info.ioctl_opcode = MYRS_IOCTL_GET_LDEV_INFO_VALID;
	sgl = &mbox->ldev_info.dma_addr;
	sgl->sge[0].sge_addr = ldev_info_addr;
	sgl->sge[0].sge_count = mbox->ldev_info.dma_size;
	dev_dbg(&cs->host->shost_gendev,
		"Sending GetLogicalDeviceInfoValid for ldev %d\n", ldev_num);
	myrs_exec_cmd(cs, cmd_blk);
	status = cmd_blk->status;
	mutex_unlock(&cs->dcmd_mutex);
	dma_unmap_single(&cs->pdev->dev, ldev_info_addr,
			 sizeof(struct myrs_ldev_info), DMA_FROM_DEVICE);
	if (status == MYRS_STATUS_SUCCESS) {
		unsigned short ldev_num = ldev_info->ldev_num;
		struct myrs_ldev_info *new = ldev_info;
		struct myrs_ldev_info *old = &ldev_info_orig;
		unsigned long ldev_size = new->cfg_devsize;

		if (new->dev_state != old->dev_state) {
			const char *name;

			name = myrs_devstate_name(new->dev_state);
			shost_printk(KERN_INFO, cs->host,
				     "Logical Drive %d is now %s\n",
				     ldev_num, name ? name : "Invalid");
		}
		if ((new->soft_errs != old->soft_errs) ||
		    (new->cmds_failed != old->cmds_failed) ||
		    (new->deferred_write_errs != old->deferred_write_errs))
			shost_printk(KERN_INFO, cs->host,
				     "Logical Drive %d Errors: Soft = %d, Failed = %d, Deferred Write = %d\n",
				     ldev_num, new->soft_errs,
				     new->cmds_failed,
				     new->deferred_write_errs);
		if (new->bg_init_active)
			myrs_report_progress(cs, ldev_num,
					     "Background Initialization",
					     new->bg_init_lba, ldev_size);
		else if (new->fg_init_active)
			myrs_report_progress(cs, ldev_num,
					     "Foreground Initialization",
					     new->fg_init_lba, ldev_size);
		else if (new->migration_active)
			myrs_report_progress(cs, ldev_num,
					     "Data Migration",
					     new->migration_lba, ldev_size);
		else if (new->patrol_active)
			myrs_report_progress(cs, ldev_num,
					     "Patrol Operation",
					     new->patrol_lba, ldev_size);
		if (old->bg_init_active && !new->bg_init_active)
			shost_printk(KERN_INFO, cs->host,
				     "Logical Drive %d: Background Initialization %s\n",
				     ldev_num,
				     (new->ldev_control.ldev_init_done ?
				      "Completed" : "Failed"));
	}
	return status;
}

/*
 * myrs_get_pdev_info - executes a "Read Physical Device Information" Command
 */
static unsigned char myrs_get_pdev_info(struct myrs_hba *cs,
		unsigned char channel, unsigned char target, unsigned char lun,
		struct myrs_pdev_info *pdev_info)
{
	struct myrs_cmdblk *cmd_blk = &cs->dcmd_blk;
	union myrs_cmd_mbox *mbox = &cmd_blk->mbox;
	dma_addr_t pdev_info_addr;
	union myrs_sgl *sgl;
	unsigned char status;

	pdev_info_addr = dma_map_single(&cs->pdev->dev, pdev_info,
					sizeof(struct myrs_pdev_info),
					DMA_FROM_DEVICE);
	if (dma_mapping_error(&cs->pdev->dev, pdev_info_addr))
		return MYRS_STATUS_FAILED;

	mutex_lock(&cs->dcmd_mutex);
	myrs_reset_cmd(cmd_blk);
	mbox->pdev_info.opcode = MYRS_CMD_OP_IOCTL;
	mbox->pdev_info.id = MYRS_DCMD_TAG;
	mbox->pdev_info.control.dma_ctrl_to_host = true;
	mbox->pdev_info.control.no_autosense = true;
	mbox->pdev_info.dma_size = sizeof(struct myrs_pdev_info);
	mbox->pdev_info.pdev.lun = lun;
	mbox->pdev_info.pdev.target = target;
	mbox->pdev_info.pdev.channel = channel;
	mbox->pdev_info.ioctl_opcode = MYRS_IOCTL_GET_PDEV_INFO_VALID;
	sgl = &mbox->pdev_info.dma_addr;
	sgl->sge[0].sge_addr = pdev_info_addr;
	sgl->sge[0].sge_count = mbox->pdev_info.dma_size;
	dev_dbg(&cs->host->shost_gendev,
		"Sending GetPhysicalDeviceInfoValid for pdev %d:%d:%d\n",
		channel, target, lun);
	myrs_exec_cmd(cs, cmd_blk);
	status = cmd_blk->status;
	mutex_unlock(&cs->dcmd_mutex);
	dma_unmap_single(&cs->pdev->dev, pdev_info_addr,
			 sizeof(struct myrs_pdev_info), DMA_FROM_DEVICE);
	return status;
}

/*
 * myrs_dev_op - executes a "Device Operation" Command
 */
static unsigned char myrs_dev_op(struct myrs_hba *cs,
		enum myrs_ioctl_opcode opcode, enum myrs_opdev opdev)
{
	struct myrs_cmdblk *cmd_blk = &cs->dcmd_blk;
	union myrs_cmd_mbox *mbox = &cmd_blk->mbox;
	unsigned char status;

	mutex_lock(&cs->dcmd_mutex);
	myrs_reset_cmd(cmd_blk);
	mbox->dev_op.opcode = MYRS_CMD_OP_IOCTL;
	mbox->dev_op.id = MYRS_DCMD_TAG;
	mbox->dev_op.control.dma_ctrl_to_host = true;
	mbox->dev_op.control.no_autosense = true;
	mbox->dev_op.ioctl_opcode = opcode;
	mbox->dev_op.opdev = opdev;
	myrs_exec_cmd(cs, cmd_blk);
	status = cmd_blk->status;
	mutex_unlock(&cs->dcmd_mutex);
	return status;
}

/*
 * myrs_translate_pdev - translates a Physical Device Channel and
 * TargetID into a Logical Device.
 */
static unsigned char myrs_translate_pdev(struct myrs_hba *cs,
		unsigned char channel, unsigned char target, unsigned char lun,
		struct myrs_devmap *devmap)
{
	struct pci_dev *pdev = cs->pdev;
	dma_addr_t devmap_addr;
	struct myrs_cmdblk *cmd_blk;
	union myrs_cmd_mbox *mbox;
	union myrs_sgl *sgl;
	unsigned char status;

	memset(devmap, 0x0, sizeof(struct myrs_devmap));
	devmap_addr = dma_map_single(&pdev->dev, devmap,
				     sizeof(struct myrs_devmap),
				     DMA_FROM_DEVICE);
	if (dma_mapping_error(&pdev->dev, devmap_addr))
		return MYRS_STATUS_FAILED;

	mutex_lock(&cs->dcmd_mutex);
	cmd_blk = &cs->dcmd_blk;
	mbox = &cmd_blk->mbox;
	mbox->pdev_info.opcode = MYRS_CMD_OP_IOCTL;
	mbox->pdev_info.control.dma_ctrl_to_host = true;
	mbox->pdev_info.control.no_autosense = true;
	mbox->pdev_info.dma_size = sizeof(struct myrs_devmap);
	mbox->pdev_info.pdev.target = target;
	mbox->pdev_info.pdev.channel = channel;
	mbox->pdev_info.pdev.lun = lun;
	mbox->pdev_info.ioctl_opcode = MYRS_IOCTL_XLATE_PDEV_TO_LDEV;
	sgl = &mbox->pdev_info.dma_addr;
	sgl->sge[0].sge_addr = devmap_addr;
	sgl->sge[0].sge_count = mbox->pdev_info.dma_size;

	myrs_exec_cmd(cs, cmd_blk);
	status = cmd_blk->status;
	mutex_unlock(&cs->dcmd_mutex);
	dma_unmap_single(&pdev->dev, devmap_addr,
			 sizeof(struct myrs_devmap), DMA_FROM_DEVICE);
	return status;
}

/*
 * myrs_get_event - executes a Get Event Command
 */
static unsigned char myrs_get_event(struct myrs_hba *cs,
		unsigned int event_num, struct myrs_event *event_buf)
{
	struct pci_dev *pdev = cs->pdev;
	dma_addr_t event_addr;
	struct myrs_cmdblk *cmd_blk = &cs->mcmd_blk;
	union myrs_cmd_mbox *mbox = &cmd_blk->mbox;
	union myrs_sgl *sgl;
	unsigned char status;

	event_addr = dma_map_single(&pdev->dev, event_buf,
				    sizeof(struct myrs_event), DMA_FROM_DEVICE);
	if (dma_mapping_error(&pdev->dev, event_addr))
		return MYRS_STATUS_FAILED;

	mbox->get_event.opcode = MYRS_CMD_OP_IOCTL;
	mbox->get_event.dma_size = sizeof(struct myrs_event);
	mbox->get_event.evnum_upper = event_num >> 16;
	mbox->get_event.ctlr_num = 0;
	mbox->get_event.ioctl_opcode = MYRS_IOCTL_GET_EVENT;
	mbox->get_event.evnum_lower = event_num & 0xFFFF;
	sgl = &mbox->get_event.dma_addr;
	sgl->sge[0].sge_addr = event_addr;
	sgl->sge[0].sge_count = mbox->get_event.dma_size;
	myrs_exec_cmd(cs, cmd_blk);
	status = cmd_blk->status;
	dma_unmap_single(&pdev->dev, event_addr,
			 sizeof(struct myrs_event), DMA_FROM_DEVICE);

	return status;
}

/*
 * myrs_get_fwstatus - executes a Get Health Status Command
 */
static unsigned char myrs_get_fwstatus(struct myrs_hba *cs)
{
	struct myrs_cmdblk *cmd_blk = &cs->mcmd_blk;
	union myrs_cmd_mbox *mbox = &cmd_blk->mbox;
	union myrs_sgl *sgl;
	unsigned char status = cmd_blk->status;

	myrs_reset_cmd(cmd_blk);
	mbox->common.opcode = MYRS_CMD_OP_IOCTL;
	mbox->common.id = MYRS_MCMD_TAG;
	mbox->common.control.dma_ctrl_to_host = true;
	mbox->common.control.no_autosense = true;
	mbox->common.dma_size = sizeof(struct myrs_fwstat);
	mbox->common.ioctl_opcode = MYRS_IOCTL_GET_HEALTH_STATUS;
	sgl = &mbox->common.dma_addr;
	sgl->sge[0].sge_addr = cs->fwstat_addr;
	sgl->sge[0].sge_count = mbox->ctlr_info.dma_size;
	dev_dbg(&cs->host->shost_gendev, "Sending GetHealthStatus\n");
	myrs_exec_cmd(cs, cmd_blk);
	status = cmd_blk->status;

	return status;
}

/*
 * myrs_enable_mmio_mbox - enables the Memory Mailbox Interface
 */
static bool myrs_enable_mmio_mbox(struct myrs_hba *cs,
		enable_mbox_t enable_mbox_fn)
{
	void __iomem *base = cs->io_base;
	struct pci_dev *pdev = cs->pdev;
	union myrs_cmd_mbox *cmd_mbox;
	struct myrs_stat_mbox *stat_mbox;
	union myrs_cmd_mbox *mbox;
	dma_addr_t mbox_addr;
	unsigned char status = MYRS_STATUS_FAILED;

	if (dma_set_mask(&pdev->dev, DMA_BIT_MASK(64)))
		if (dma_set_mask(&pdev->dev, DMA_BIT_MASK(32))) {
			dev_err(&pdev->dev, "DMA mask out of range\n");
			return false;
		}

	/* Temporary dma mapping, used only in the scope of this function */
	mbox = dma_alloc_coherent(&pdev->dev, sizeof(union myrs_cmd_mbox),
				  &mbox_addr, GFP_KERNEL);
	if (dma_mapping_error(&pdev->dev, mbox_addr))
		return false;

	/* These are the base addresses for the command memory mailbox array */
	cs->cmd_mbox_size = MYRS_MAX_CMD_MBOX * sizeof(union myrs_cmd_mbox);
	cmd_mbox = dma_alloc_coherent(&pdev->dev, cs->cmd_mbox_size,
				      &cs->cmd_mbox_addr, GFP_KERNEL);
	if (dma_mapping_error(&pdev->dev, cs->cmd_mbox_addr)) {
		dev_err(&pdev->dev, "Failed to map command mailbox\n");
		goto out_free;
	}
	cs->first_cmd_mbox = cmd_mbox;
	cmd_mbox += MYRS_MAX_CMD_MBOX - 1;
	cs->last_cmd_mbox = cmd_mbox;
	cs->next_cmd_mbox = cs->first_cmd_mbox;
	cs->prev_cmd_mbox1 = cs->last_cmd_mbox;
	cs->prev_cmd_mbox2 = cs->last_cmd_mbox - 1;

	/* These are the base addresses for the status memory mailbox array */
	cs->stat_mbox_size = MYRS_MAX_STAT_MBOX * sizeof(struct myrs_stat_mbox);
	stat_mbox = dma_alloc_coherent(&pdev->dev, cs->stat_mbox_size,
				       &cs->stat_mbox_addr, GFP_KERNEL);
	if (dma_mapping_error(&pdev->dev, cs->stat_mbox_addr)) {
		dev_err(&pdev->dev, "Failed to map status mailbox\n");
		goto out_free;
	}

	cs->first_stat_mbox = stat_mbox;
	stat_mbox += MYRS_MAX_STAT_MBOX - 1;
	cs->last_stat_mbox = stat_mbox;
	cs->next_stat_mbox = cs->first_stat_mbox;

	cs->fwstat_buf = dma_alloc_coherent(&pdev->dev,
					    sizeof(struct myrs_fwstat),
					    &cs->fwstat_addr, GFP_KERNEL);
	if (dma_mapping_error(&pdev->dev, cs->fwstat_addr)) {
		dev_err(&pdev->dev, "Failed to map firmware health buffer\n");
		cs->fwstat_buf = NULL;
		goto out_free;
	}
	cs->ctlr_info = kzalloc(sizeof(struct myrs_ctlr_info),
				GFP_KERNEL | GFP_DMA);
	if (!cs->ctlr_info)
		goto out_free;

	cs->event_buf = kzalloc(sizeof(struct myrs_event),
				GFP_KERNEL | GFP_DMA);
	if (!cs->event_buf)
		goto out_free;

	/* Enable the Memory Mailbox Interface. */
	memset(mbox, 0, sizeof(union myrs_cmd_mbox));
	mbox->set_mbox.id = 1;
	mbox->set_mbox.opcode = MYRS_CMD_OP_IOCTL;
	mbox->set_mbox.control.no_autosense = true;
	mbox->set_mbox.first_cmd_mbox_size_kb =
		(MYRS_MAX_CMD_MBOX * sizeof(union myrs_cmd_mbox)) >> 10;
	mbox->set_mbox.first_stat_mbox_size_kb =
		(MYRS_MAX_STAT_MBOX * sizeof(struct myrs_stat_mbox)) >> 10;
	mbox->set_mbox.second_cmd_mbox_size_kb = 0;
	mbox->set_mbox.second_stat_mbox_size_kb = 0;
	mbox->set_mbox.sense_len = 0;
	mbox->set_mbox.ioctl_opcode = MYRS_IOCTL_SET_MEM_MBOX;
	mbox->set_mbox.fwstat_buf_size_kb = 1;
	mbox->set_mbox.fwstat_buf_addr = cs->fwstat_addr;
	mbox->set_mbox.first_cmd_mbox_addr = cs->cmd_mbox_addr;
	mbox->set_mbox.first_stat_mbox_addr = cs->stat_mbox_addr;
	status = enable_mbox_fn(base, mbox_addr);

out_free:
	dma_free_coherent(&pdev->dev, sizeof(union myrs_cmd_mbox),
			  mbox, mbox_addr);
	if (status != MYRS_STATUS_SUCCESS)
		dev_err(&pdev->dev, "Failed to enable mailbox, status %X\n",
			status);
	return (status == MYRS_STATUS_SUCCESS);
}

/*
 * myrs_get_config - reads the Configuration Information
 */
static int myrs_get_config(struct myrs_hba *cs)
{
	struct myrs_ctlr_info *info = cs->ctlr_info;
	struct Scsi_Host *shost = cs->host;
	unsigned char status;
	unsigned char model[20];
	unsigned char fw_version[12];
	int i, model_len;

	/* Get data into dma-able area, then copy into permanent location */
	mutex_lock(&cs->cinfo_mutex);
	status = myrs_get_ctlr_info(cs);
	mutex_unlock(&cs->cinfo_mutex);
	if (status != MYRS_STATUS_SUCCESS) {
		shost_printk(KERN_ERR, shost,
			     "Failed to get controller information\n");
		return -ENODEV;
	}

	/* Initialize the Controller Model Name and Full Model Name fields. */
	model_len = sizeof(info->ctlr_name);
	if (model_len > sizeof(model)-1)
		model_len = sizeof(model)-1;
	memcpy(model, info->ctlr_name, model_len);
	model_len--;
	while (model[model_len] == ' ' || model[model_len] == '\0')
		model_len--;
	model[++model_len] = '\0';
	strcpy(cs->model_name, "DAC960 ");
	strcat(cs->model_name, model);
	/* Initialize the Controller Firmware Version field. */
	sprintf(fw_version, "%d.%02d-%02d",
		info->fw_major_version, info->fw_minor_version,
		info->fw_turn_number);
	if (info->fw_major_version == 6 &&
	    info->fw_minor_version == 0 &&
	    info->fw_turn_number < 1) {
		shost_printk(KERN_WARNING, shost,
			"FIRMWARE VERSION %s DOES NOT PROVIDE THE CONTROLLER\n"
			"STATUS MONITORING FUNCTIONALITY NEEDED BY THIS DRIVER.\n"
			"PLEASE UPGRADE TO VERSION 6.00-01 OR ABOVE.\n",
			fw_version);
		return -ENODEV;
	}
	/* Initialize the Controller Channels and Targets. */
	shost->max_channel = info->physchan_present + info->virtchan_present;
	shost->max_id = info->max_targets[0];
	for (i = 1; i < 16; i++) {
		if (!info->max_targets[i])
			continue;
		if (shost->max_id < info->max_targets[i])
			shost->max_id = info->max_targets[i];
	}

	/*
	 * Initialize the Controller Queue Depth, Driver Queue Depth,
	 * Logical Drive Count, Maximum Blocks per Command, Controller
	 * Scatter/Gather Limit, and Driver Scatter/Gather Limit.
	 * The Driver Queue Depth must be at most three less than
	 * the Controller Queue Depth; tag '1' is reserved for
	 * direct commands, and tag '2' for monitoring commands.
	 */
	shost->can_queue = info->max_tcq - 3;
	if (shost->can_queue > MYRS_MAX_CMD_MBOX - 3)
		shost->can_queue = MYRS_MAX_CMD_MBOX - 3;
	shost->max_sectors = info->max_transfer_size;
	shost->sg_tablesize = info->max_sge;
	if (shost->sg_tablesize > MYRS_SG_LIMIT)
		shost->sg_tablesize = MYRS_SG_LIMIT;

	shost_printk(KERN_INFO, shost,
		"Configuring %s PCI RAID Controller\n", model);
	shost_printk(KERN_INFO, shost,
		"  Firmware Version: %s, Channels: %d, Memory Size: %dMB\n",
		fw_version, info->physchan_present, info->mem_size_mb);

	shost_printk(KERN_INFO, shost,
		     "  Controller Queue Depth: %d, Maximum Blocks per Command: %d\n",
		     shost->can_queue, shost->max_sectors);

	shost_printk(KERN_INFO, shost,
		     "  Driver Queue Depth: %d, Scatter/Gather Limit: %d of %d Segments\n",
		     shost->can_queue, shost->sg_tablesize, MYRS_SG_LIMIT);
	for (i = 0; i < info->physchan_max; i++) {
		if (!info->max_targets[i])
			continue;
		shost_printk(KERN_INFO, shost,
			     "  Device Channel %d: max %d devices\n",
			     i, info->max_targets[i]);
	}
	shost_printk(KERN_INFO, shost,
		     "  Physical: %d/%d channels, %d disks, %d devices\n",
		     info->physchan_present, info->physchan_max,
		     info->pdisk_present, info->pdev_present);

	shost_printk(KERN_INFO, shost,
		     "  Logical: %d/%d channels, %d disks\n",
		     info->virtchan_present, info->virtchan_max,
		     info->ldev_present);
	return 0;
}

/*
 * myrs_log_event - prints a Controller Event message
 */
static struct {
	int ev_code;
	unsigned char *ev_msg;
} myrs_ev_list[] = {
	/* Physical Device Events (0x0000 - 0x007F) */
	{ 0x0001, "P Online" },
	{ 0x0002, "P Standby" },
	{ 0x0005, "P Automatic Rebuild Started" },
	{ 0x0006, "P Manual Rebuild Started" },
	{ 0x0007, "P Rebuild Completed" },
	{ 0x0008, "P Rebuild Cancelled" },
	{ 0x0009, "P Rebuild Failed for Unknown Reasons" },
	{ 0x000A, "P Rebuild Failed due to New Physical Device" },
	{ 0x000B, "P Rebuild Failed due to Logical Drive Failure" },
	{ 0x000C, "S Offline" },
	{ 0x000D, "P Found" },
	{ 0x000E, "P Removed" },
	{ 0x000F, "P Unconfigured" },
	{ 0x0010, "P Expand Capacity Started" },
	{ 0x0011, "P Expand Capacity Completed" },
	{ 0x0012, "P Expand Capacity Failed" },
	{ 0x0013, "P Command Timed Out" },
	{ 0x0014, "P Command Aborted" },
	{ 0x0015, "P Command Retried" },
	{ 0x0016, "P Parity Error" },
	{ 0x0017, "P Soft Error" },
	{ 0x0018, "P Miscellaneous Error" },
	{ 0x0019, "P Reset" },
	{ 0x001A, "P Active Spare Found" },
	{ 0x001B, "P Warm Spare Found" },
	{ 0x001C, "S Sense Data Received" },
	{ 0x001D, "P Initialization Started" },
	{ 0x001E, "P Initialization Completed" },
	{ 0x001F, "P Initialization Failed" },
	{ 0x0020, "P Initialization Cancelled" },
	{ 0x0021, "P Failed because Write Recovery Failed" },
	{ 0x0022, "P Failed because SCSI Bus Reset Failed" },
	{ 0x0023, "P Failed because of Double Check Condition" },
	{ 0x0024, "P Failed because Device Cannot Be Accessed" },
	{ 0x0025, "P Failed because of Gross Error on SCSI Processor" },
	{ 0x0026, "P Failed because of Bad Tag from Device" },
	{ 0x0027, "P Failed because of Command Timeout" },
	{ 0x0028, "P Failed because of System Reset" },
	{ 0x0029, "P Failed because of Busy Status or Parity Error" },
	{ 0x002A, "P Failed because Host Set Device to Failed State" },
	{ 0x002B, "P Failed because of Selection Timeout" },
	{ 0x002C, "P Failed because of SCSI Bus Phase Error" },
	{ 0x002D, "P Failed because Device Returned Unknown Status" },
	{ 0x002E, "P Failed because Device Not Ready" },
	{ 0x002F, "P Failed because Device Not Found at Startup" },
	{ 0x0030, "P Failed because COD Write Operation Failed" },
	{ 0x0031, "P Failed because BDT Write Operation Failed" },
	{ 0x0039, "P Missing at Startup" },
	{ 0x003A, "P Start Rebuild Failed due to Physical Drive Too Small" },
	{ 0x003C, "P Temporarily Offline Device Automatically Made Online" },
	{ 0x003D, "P Standby Rebuild Started" },
	/* Logical Device Events (0x0080 - 0x00FF) */
	{ 0x0080, "M Consistency Check Started" },
	{ 0x0081, "M Consistency Check Completed" },
	{ 0x0082, "M Consistency Check Cancelled" },
	{ 0x0083, "M Consistency Check Completed With Errors" },
	{ 0x0084, "M Consistency Check Failed due to Logical Drive Failure" },
	{ 0x0085, "M Consistency Check Failed due to Physical Device Failure" },
	{ 0x0086, "L Offline" },
	{ 0x0087, "L Critical" },
	{ 0x0088, "L Online" },
	{ 0x0089, "M Automatic Rebuild Started" },
	{ 0x008A, "M Manual Rebuild Started" },
	{ 0x008B, "M Rebuild Completed" },
	{ 0x008C, "M Rebuild Cancelled" },
	{ 0x008D, "M Rebuild Failed for Unknown Reasons" },
	{ 0x008E, "M Rebuild Failed due to New Physical Device" },
	{ 0x008F, "M Rebuild Failed due to Logical Drive Failure" },
	{ 0x0090, "M Initialization Started" },
	{ 0x0091, "M Initialization Completed" },
	{ 0x0092, "M Initialization Cancelled" },
	{ 0x0093, "M Initialization Failed" },
	{ 0x0094, "L Found" },
	{ 0x0095, "L Deleted" },
	{ 0x0096, "M Expand Capacity Started" },
	{ 0x0097, "M Expand Capacity Completed" },
	{ 0x0098, "M Expand Capacity Failed" },
	{ 0x0099, "L Bad Block Found" },
	{ 0x009A, "L Size Changed" },
	{ 0x009B, "L Type Changed" },
	{ 0x009C, "L Bad Data Block Found" },
	{ 0x009E, "L Read of Data Block in BDT" },
	{ 0x009F, "L Write Back Data for Disk Block Lost" },
	{ 0x00A0, "L Temporarily Offline RAID-5/3 Drive Made Online" },
	{ 0x00A1, "L Temporarily Offline RAID-6/1/0/7 Drive Made Online" },
	{ 0x00A2, "L Standby Rebuild Started" },
	/* Fault Management Events (0x0100 - 0x017F) */
	{ 0x0140, "E Fan %d Failed" },
	{ 0x0141, "E Fan %d OK" },
	{ 0x0142, "E Fan %d Not Present" },
	{ 0x0143, "E Power Supply %d Failed" },
	{ 0x0144, "E Power Supply %d OK" },
	{ 0x0145, "E Power Supply %d Not Present" },
	{ 0x0146, "E Temperature Sensor %d Temperature Exceeds Safe Limit" },
	{ 0x0147, "E Temperature Sensor %d Temperature Exceeds Working Limit" },
	{ 0x0148, "E Temperature Sensor %d Temperature Normal" },
	{ 0x0149, "E Temperature Sensor %d Not Present" },
	{ 0x014A, "E Enclosure Management Unit %d Access Critical" },
	{ 0x014B, "E Enclosure Management Unit %d Access OK" },
	{ 0x014C, "E Enclosure Management Unit %d Access Offline" },
	/* Controller Events (0x0180 - 0x01FF) */
	{ 0x0181, "C Cache Write Back Error" },
	{ 0x0188, "C Battery Backup Unit Found" },
	{ 0x0189, "C Battery Backup Unit Charge Level Low" },
	{ 0x018A, "C Battery Backup Unit Charge Level OK" },
	{ 0x0193, "C Installation Aborted" },
	{ 0x0195, "C Battery Backup Unit Physically Removed" },
	{ 0x0196, "C Memory Error During Warm Boot" },
	{ 0x019E, "C Memory Soft ECC Error Corrected" },
	{ 0x019F, "C Memory Hard ECC Error Corrected" },
	{ 0x01A2, "C Battery Backup Unit Failed" },
	{ 0x01AB, "C Mirror Race Recovery Failed" },
	{ 0x01AC, "C Mirror Race on Critical Drive" },
	/* Controller Internal Processor Events */
	{ 0x0380, "C Internal Controller Hung" },
	{ 0x0381, "C Internal Controller Firmware Breakpoint" },
	{ 0x0390, "C Internal Controller i960 Processor Specific Error" },
	{ 0x03A0, "C Internal Controller StrongARM Processor Specific Error" },
	{ 0, "" }
};

static void myrs_log_event(struct myrs_hba *cs, struct myrs_event *ev)
{
	unsigned char msg_buf[MYRS_LINE_BUFFER_SIZE];
	int ev_idx = 0, ev_code;
	unsigned char ev_type, *ev_msg;
	struct Scsi_Host *shost = cs->host;
	struct scsi_device *sdev;
	struct scsi_sense_hdr sshdr = {0};
	unsigned char sense_info[4];
	unsigned char cmd_specific[4];

	if (ev->ev_code == 0x1C) {
		if (!scsi_normalize_sense(ev->sense_data, 40, &sshdr)) {
			memset(&sshdr, 0x0, sizeof(sshdr));
			memset(sense_info, 0x0, sizeof(sense_info));
			memset(cmd_specific, 0x0, sizeof(cmd_specific));
		} else {
			memcpy(sense_info, &ev->sense_data[3], 4);
			memcpy(cmd_specific, &ev->sense_data[7], 4);
		}
	}
	if (sshdr.sense_key == VENDOR_SPECIFIC &&
	    (sshdr.asc == 0x80 || sshdr.asc == 0x81))
		ev->ev_code = ((sshdr.asc - 0x80) << 8 | sshdr.ascq);
	while (true) {
		ev_code = myrs_ev_list[ev_idx].ev_code;
		if (ev_code == ev->ev_code || ev_code == 0)
			break;
		ev_idx++;
	}
	ev_type = myrs_ev_list[ev_idx].ev_msg[0];
	ev_msg = &myrs_ev_list[ev_idx].ev_msg[2];
	if (ev_code == 0) {
		shost_printk(KERN_WARNING, shost,
			     "Unknown Controller Event Code %04X\n",
			     ev->ev_code);
		return;
	}
	switch (ev_type) {
	case 'P':
		sdev = scsi_device_lookup(shost, ev->channel,
					  ev->target, 0);
		sdev_printk(KERN_INFO, sdev, "event %d: Physical Device %s\n",
			    ev->ev_seq, ev_msg);
		if (sdev && sdev->hostdata &&
		    sdev->channel < cs->ctlr_info->physchan_present) {
			struct myrs_pdev_info *pdev_info = sdev->hostdata;

			switch (ev->ev_code) {
			case 0x0001:
			case 0x0007:
				pdev_info->dev_state = MYRS_DEVICE_ONLINE;
				break;
			case 0x0002:
				pdev_info->dev_state = MYRS_DEVICE_STANDBY;
				break;
			case 0x000C:
				pdev_info->dev_state = MYRS_DEVICE_OFFLINE;
				break;
			case 0x000E:
				pdev_info->dev_state = MYRS_DEVICE_MISSING;
				break;
			case 0x000F:
				pdev_info->dev_state = MYRS_DEVICE_UNCONFIGURED;
				break;
			}
		}
		break;
	case 'L':
		shost_printk(KERN_INFO, shost,
			     "event %d: Logical Drive %d %s\n",
			     ev->ev_seq, ev->lun, ev_msg);
		cs->needs_update = true;
		break;
	case 'M':
		shost_printk(KERN_INFO, shost,
			     "event %d: Logical Drive %d %s\n",
			     ev->ev_seq, ev->lun, ev_msg);
		cs->needs_update = true;
		break;
	case 'S':
		if (sshdr.sense_key == NO_SENSE ||
		    (sshdr.sense_key == NOT_READY &&
		     sshdr.asc == 0x04 && (sshdr.ascq == 0x01 ||
					    sshdr.ascq == 0x02)))
			break;
		shost_printk(KERN_INFO, shost,
			     "event %d: Physical Device %d:%d %s\n",
			     ev->ev_seq, ev->channel, ev->target, ev_msg);
		shost_printk(KERN_INFO, shost,
			     "Physical Device %d:%d Sense Key = %X, ASC = %02X, ASCQ = %02X\n",
			     ev->channel, ev->target,
			     sshdr.sense_key, sshdr.asc, sshdr.ascq);
		shost_printk(KERN_INFO, shost,
			     "Physical Device %d:%d Sense Information = %02X%02X%02X%02X %02X%02X%02X%02X\n",
			     ev->channel, ev->target,
			     sense_info[0], sense_info[1],
			     sense_info[2], sense_info[3],
			     cmd_specific[0], cmd_specific[1],
			     cmd_specific[2], cmd_specific[3]);
		break;
	case 'E':
		if (cs->disable_enc_msg)
			break;
		sprintf(msg_buf, ev_msg, ev->lun);
		shost_printk(KERN_INFO, shost, "event %d: Enclosure %d %s\n",
			     ev->ev_seq, ev->target, msg_buf);
		break;
	case 'C':
		shost_printk(KERN_INFO, shost, "event %d: Controller %s\n",
			     ev->ev_seq, ev_msg);
		break;
	default:
		shost_printk(KERN_INFO, shost,
			     "event %d: Unknown Event Code %04X\n",
			     ev->ev_seq, ev->ev_code);
		break;
	}
}

/*
 * SCSI sysfs interface functions
 */
static ssize_t raid_state_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	struct scsi_device *sdev = to_scsi_device(dev);
	struct myrs_hba *cs = shost_priv(sdev->host);
	int ret;

	if (!sdev->hostdata)
		return snprintf(buf, 16, "Unknown\n");

	if (sdev->channel >= cs->ctlr_info->physchan_present) {
		struct myrs_ldev_info *ldev_info = sdev->hostdata;
		const char *name;

		name = myrs_devstate_name(ldev_info->dev_state);
		if (name)
			ret = snprintf(buf, 32, "%s\n", name);
		else
			ret = snprintf(buf, 32, "Invalid (%02X)\n",
				       ldev_info->dev_state);
	} else {
		struct myrs_pdev_info *pdev_info;
		const char *name;

		pdev_info = sdev->hostdata;
		name = myrs_devstate_name(pdev_info->dev_state);
		if (name)
			ret = snprintf(buf, 32, "%s\n", name);
		else
			ret = snprintf(buf, 32, "Invalid (%02X)\n",
				       pdev_info->dev_state);
	}
	return ret;
}

static ssize_t raid_state_store(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t count)
{
	struct scsi_device *sdev = to_scsi_device(dev);
	struct myrs_hba *cs = shost_priv(sdev->host);
	struct myrs_cmdblk *cmd_blk;
	union myrs_cmd_mbox *mbox;
	enum myrs_devstate new_state;
	unsigned short ldev_num;
	unsigned char status;

	if (!strncmp(buf, "offline", 7) ||
	    !strncmp(buf, "kill", 4))
		new_state = MYRS_DEVICE_OFFLINE;
	else if (!strncmp(buf, "online", 6))
		new_state = MYRS_DEVICE_ONLINE;
	else if (!strncmp(buf, "standby", 7))
		new_state = MYRS_DEVICE_STANDBY;
	else
		return -EINVAL;

	if (sdev->channel < cs->ctlr_info->physchan_present) {
		struct myrs_pdev_info *pdev_info = sdev->hostdata;
		struct myrs_devmap *pdev_devmap =
			(struct myrs_devmap *)&pdev_info->rsvd13;

		if (pdev_info->dev_state == new_state) {
			sdev_printk(KERN_INFO, sdev,
				    "Device already in %s\n",
				    myrs_devstate_name(new_state));
			return count;
		}
		status = myrs_translate_pdev(cs, sdev->channel, sdev->id,
					     sdev->lun, pdev_devmap);
		if (status != MYRS_STATUS_SUCCESS)
			return -ENXIO;
		ldev_num = pdev_devmap->ldev_num;
	} else {
		struct myrs_ldev_info *ldev_info = sdev->hostdata;

		if (ldev_info->dev_state == new_state) {
			sdev_printk(KERN_INFO, sdev,
				    "Device already in %s\n",
				    myrs_devstate_name(new_state));
			return count;
		}
		ldev_num = ldev_info->ldev_num;
	}
	mutex_lock(&cs->dcmd_mutex);
	cmd_blk = &cs->dcmd_blk;
	myrs_reset_cmd(cmd_blk);
	mbox = &cmd_blk->mbox;
	mbox->common.opcode = MYRS_CMD_OP_IOCTL;
	mbox->common.id = MYRS_DCMD_TAG;
	mbox->common.control.dma_ctrl_to_host = true;
	mbox->common.control.no_autosense = true;
	mbox->set_devstate.ioctl_opcode = MYRS_IOCTL_SET_DEVICE_STATE;
	mbox->set_devstate.state = new_state;
	mbox->set_devstate.ldev.ldev_num = ldev_num;
	myrs_exec_cmd(cs, cmd_blk);
	status = cmd_blk->status;
	mutex_unlock(&cs->dcmd_mutex);
	if (status == MYRS_STATUS_SUCCESS) {
		if (sdev->channel < cs->ctlr_info->physchan_present) {
			struct myrs_pdev_info *pdev_info = sdev->hostdata;

			pdev_info->dev_state = new_state;
		} else {
			struct myrs_ldev_info *ldev_info = sdev->hostdata;

			ldev_info->dev_state = new_state;
		}
		sdev_printk(KERN_INFO, sdev,
			    "Set device state to %s\n",
			    myrs_devstate_name(new_state));
		return count;
	}
	sdev_printk(KERN_INFO, sdev,
		    "Failed to set device state to %s, status 0x%02x\n",
		    myrs_devstate_name(new_state), status);
	return -EINVAL;
}
static DEVICE_ATTR_RW(raid_state);

static ssize_t raid_level_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	struct scsi_device *sdev = to_scsi_device(dev);
	struct myrs_hba *cs = shost_priv(sdev->host);
	const char *name = NULL;

	if (!sdev->hostdata)
		return snprintf(buf, 16, "Unknown\n");

	if (sdev->channel >= cs->ctlr_info->physchan_present) {
		struct myrs_ldev_info *ldev_info;

		ldev_info = sdev->hostdata;
		name = myrs_raid_level_name(ldev_info->raid_level);
		if (!name)
			return snprintf(buf, 32, "Invalid (%02X)\n",
					ldev_info->dev_state);

	} else
		name = myrs_raid_level_name(MYRS_RAID_PHYSICAL);

	return snprintf(buf, 32, "%s\n", name);
}
static DEVICE_ATTR_RO(raid_level);

static ssize_t rebuild_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	struct scsi_device *sdev = to_scsi_device(dev);
	struct myrs_hba *cs = shost_priv(sdev->host);
	struct myrs_ldev_info *ldev_info;
	unsigned short ldev_num;
	unsigned char status;

	if (sdev->channel < cs->ctlr_info->physchan_present)
		return snprintf(buf, 32, "physical device - not rebuilding\n");

	ldev_info = sdev->hostdata;
	ldev_num = ldev_info->ldev_num;
	status = myrs_get_ldev_info(cs, ldev_num, ldev_info);
	if (status != MYRS_STATUS_SUCCESS) {
		sdev_printk(KERN_INFO, sdev,
			    "Failed to get device information, status 0x%02x\n",
			    status);
		return -EIO;
	}
	if (ldev_info->rbld_active) {
		return snprintf(buf, 32, "rebuilding block %zu of %zu\n",
				(size_t)ldev_info->rbld_lba,
				(size_t)ldev_info->cfg_devsize);
	} else
		return snprintf(buf, 32, "not rebuilding\n");
}

static ssize_t rebuild_store(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t count)
{
	struct scsi_device *sdev = to_scsi_device(dev);
	struct myrs_hba *cs = shost_priv(sdev->host);
	struct myrs_ldev_info *ldev_info;
	struct myrs_cmdblk *cmd_blk;
	union myrs_cmd_mbox *mbox;
	unsigned short ldev_num;
	unsigned char status;
	int rebuild, ret;

	if (sdev->channel < cs->ctlr_info->physchan_present)
		return -EINVAL;

	ldev_info = sdev->hostdata;
	if (!ldev_info)
		return -ENXIO;
	ldev_num = ldev_info->ldev_num;

	ret = kstrtoint(buf, 0, &rebuild);
	if (ret)
		return ret;

	status = myrs_get_ldev_info(cs, ldev_num, ldev_info);
	if (status != MYRS_STATUS_SUCCESS) {
		sdev_printk(KERN_INFO, sdev,
			    "Failed to get device information, status 0x%02x\n",
			    status);
		return -EIO;
	}

	if (rebuild && ldev_info->rbld_active) {
		sdev_printk(KERN_INFO, sdev,
			    "Rebuild Not Initiated; already in progress\n");
		return -EALREADY;
	}
	if (!rebuild && !ldev_info->rbld_active) {
		sdev_printk(KERN_INFO, sdev,
			    "Rebuild Not Cancelled; no rebuild in progress\n");
		return count;
	}

	mutex_lock(&cs->dcmd_mutex);
	cmd_blk = &cs->dcmd_blk;
	myrs_reset_cmd(cmd_blk);
	mbox = &cmd_blk->mbox;
	mbox->common.opcode = MYRS_CMD_OP_IOCTL;
	mbox->common.id = MYRS_DCMD_TAG;
	mbox->common.control.dma_ctrl_to_host = true;
	mbox->common.control.no_autosense = true;
	if (rebuild) {
		mbox->ldev_info.ldev.ldev_num = ldev_num;
		mbox->ldev_info.ioctl_opcode = MYRS_IOCTL_RBLD_DEVICE_START;
	} else {
		mbox->ldev_info.ldev.ldev_num = ldev_num;
		mbox->ldev_info.ioctl_opcode = MYRS_IOCTL_RBLD_DEVICE_STOP;
	}
	myrs_exec_cmd(cs, cmd_blk);
	status = cmd_blk->status;
	mutex_unlock(&cs->dcmd_mutex);
	if (status) {
		sdev_printk(KERN_INFO, sdev,
			    "Rebuild Not %s, status 0x%02x\n",
			    rebuild ? "Initiated" : "Cancelled", status);
		ret = -EIO;
	} else {
		sdev_printk(KERN_INFO, sdev, "Rebuild %s\n",
			    rebuild ? "Initiated" : "Cancelled");
		ret = count;
	}

	return ret;
}
static DEVICE_ATTR_RW(rebuild);

static ssize_t consistency_check_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	struct scsi_device *sdev = to_scsi_device(dev);
	struct myrs_hba *cs = shost_priv(sdev->host);
	struct myrs_ldev_info *ldev_info;
	unsigned short ldev_num;
	unsigned char status;

	if (sdev->channel < cs->ctlr_info->physchan_present)
		return snprintf(buf, 32, "physical device - not checking\n");

	ldev_info = sdev->hostdata;
	if (!ldev_info)
		return -ENXIO;
	ldev_num = ldev_info->ldev_num;
	status = myrs_get_ldev_info(cs, ldev_num, ldev_info);
	if (ldev_info->cc_active)
		return snprintf(buf, 32, "checking block %zu of %zu\n",
				(size_t)ldev_info->cc_lba,
				(size_t)ldev_info->cfg_devsize);
	else
		return snprintf(buf, 32, "not checking\n");
}

static ssize_t consistency_check_store(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t count)
{
	struct scsi_device *sdev = to_scsi_device(dev);
	struct myrs_hba *cs = shost_priv(sdev->host);
	struct myrs_ldev_info *ldev_info;
	struct myrs_cmdblk *cmd_blk;
	union myrs_cmd_mbox *mbox;
	unsigned short ldev_num;
	unsigned char status;
	int check, ret;

	if (sdev->channel < cs->ctlr_info->physchan_present)
		return -EINVAL;

	ldev_info = sdev->hostdata;
	if (!ldev_info)
		return -ENXIO;
	ldev_num = ldev_info->ldev_num;

	ret = kstrtoint(buf, 0, &check);
	if (ret)
		return ret;

	status = myrs_get_ldev_info(cs, ldev_num, ldev_info);
	if (status != MYRS_STATUS_SUCCESS) {
		sdev_printk(KERN_INFO, sdev,
			    "Failed to get device information, status 0x%02x\n",
			    status);
		return -EIO;
	}
	if (check && ldev_info->cc_active) {
		sdev_printk(KERN_INFO, sdev,
			    "Consistency Check Not Initiated; "
			    "already in progress\n");
		return -EALREADY;
	}
	if (!check && !ldev_info->cc_active) {
		sdev_printk(KERN_INFO, sdev,
			    "Consistency Check Not Cancelled; "
			    "check not in progress\n");
		return count;
	}

	mutex_lock(&cs->dcmd_mutex);
	cmd_blk = &cs->dcmd_blk;
	myrs_reset_cmd(cmd_blk);
	mbox = &cmd_blk->mbox;
	mbox->common.opcode = MYRS_CMD_OP_IOCTL;
	mbox->common.id = MYRS_DCMD_TAG;
	mbox->common.control.dma_ctrl_to_host = true;
	mbox->common.control.no_autosense = true;
	if (check) {
		mbox->cc.ldev.ldev_num = ldev_num;
		mbox->cc.ioctl_opcode = MYRS_IOCTL_CC_START;
		mbox->cc.restore_consistency = true;
		mbox->cc.initialized_area_only = false;
	} else {
		mbox->cc.ldev.ldev_num = ldev_num;
		mbox->cc.ioctl_opcode = MYRS_IOCTL_CC_STOP;
	}
	myrs_exec_cmd(cs, cmd_blk);
	status = cmd_blk->status;
	mutex_unlock(&cs->dcmd_mutex);
	if (status != MYRS_STATUS_SUCCESS) {
		sdev_printk(KERN_INFO, sdev,
			    "Consistency Check Not %s, status 0x%02x\n",
			    check ? "Initiated" : "Cancelled", status);
		ret = -EIO;
	} else {
		sdev_printk(KERN_INFO, sdev, "Consistency Check %s\n",
			    check ? "Initiated" : "Cancelled");
		ret = count;
	}

	return ret;
}
static DEVICE_ATTR_RW(consistency_check);

static struct device_attribute *myrs_sdev_attrs[] = {
	&dev_attr_consistency_check,
	&dev_attr_rebuild,
	&dev_attr_raid_state,
	&dev_attr_raid_level,
	NULL,
};

static ssize_t serial_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	struct Scsi_Host *shost = class_to_shost(dev);
	struct myrs_hba *cs = shost_priv(shost);
	char serial[17];

	memcpy(serial, cs->ctlr_info->serial_number, 16);
	serial[16] = '\0';
	return snprintf(buf, 16, "%s\n", serial);
}
static DEVICE_ATTR_RO(serial);

static ssize_t ctlr_num_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	struct Scsi_Host *shost = class_to_shost(dev);
	struct myrs_hba *cs = shost_priv(shost);

	return snprintf(buf, 20, "%d\n", cs->host->host_no);
}
static DEVICE_ATTR_RO(ctlr_num);

static struct myrs_cpu_type_tbl {
	enum myrs_cpu_type type;
	char *name;
} myrs_cpu_type_names[] = {
	{ MYRS_CPUTYPE_i960CA, "i960CA" },
	{ MYRS_CPUTYPE_i960RD, "i960RD" },
	{ MYRS_CPUTYPE_i960RN, "i960RN" },
	{ MYRS_CPUTYPE_i960RP, "i960RP" },
	{ MYRS_CPUTYPE_NorthBay, "NorthBay" },
	{ MYRS_CPUTYPE_StrongArm, "StrongARM" },
	{ MYRS_CPUTYPE_i960RM, "i960RM" },
};

static ssize_t processor_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	struct Scsi_Host *shost = class_to_shost(dev);
	struct myrs_hba *cs = shost_priv(shost);
	struct myrs_cpu_type_tbl *tbl;
	const char *first_processor = NULL;
	const char *second_processor = NULL;
	struct myrs_ctlr_info *info = cs->ctlr_info;
	ssize_t ret;
	int i;

	if (info->cpu[0].cpu_count) {
		tbl = myrs_cpu_type_names;
		for (i = 0; i < ARRAY_SIZE(myrs_cpu_type_names); i++) {
			if (tbl[i].type == info->cpu[0].cpu_type) {
				first_processor = tbl[i].name;
				break;
			}
		}
	}
	if (info->cpu[1].cpu_count) {
		tbl = myrs_cpu_type_names;
		for (i = 0; i < ARRAY_SIZE(myrs_cpu_type_names); i++) {
			if (tbl[i].type == info->cpu[1].cpu_type) {
				second_processor = tbl[i].name;
				break;
			}
		}
	}
	if (first_processor && second_processor)
		ret = snprintf(buf, 64, "1: %s (%s, %d cpus)\n"
			       "2: %s (%s, %d cpus)\n",
			       info->cpu[0].cpu_name,
			       first_processor, info->cpu[0].cpu_count,
			       info->cpu[1].cpu_name,
			       second_processor, info->cpu[1].cpu_count);
	else if (first_processor && !second_processor)
		ret = snprintf(buf, 64, "1: %s (%s, %d cpus)\n2: absent\n",
			       info->cpu[0].cpu_name,
			       first_processor, info->cpu[0].cpu_count);
	else if (!first_processor && second_processor)
		ret = snprintf(buf, 64, "1: absent\n2: %s (%s, %d cpus)\n",
			       info->cpu[1].cpu_name,
			       second_processor, info->cpu[1].cpu_count);
	else
		ret = snprintf(buf, 64, "1: absent\n2: absent\n");

	return ret;
}
static DEVICE_ATTR_RO(processor);

static ssize_t model_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	struct Scsi_Host *shost = class_to_shost(dev);
	struct myrs_hba *cs = shost_priv(shost);

	return snprintf(buf, 28, "%s\n", cs->model_name);
}
static DEVICE_ATTR_RO(model);

static ssize_t ctlr_type_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	struct Scsi_Host *shost = class_to_shost(dev);
	struct myrs_hba *cs = shost_priv(shost);

	return snprintf(buf, 4, "%d\n", cs->ctlr_info->ctlr_type);
}
static DEVICE_ATTR_RO(ctlr_type);

static ssize_t cache_size_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	struct Scsi_Host *shost = class_to_shost(dev);
	struct myrs_hba *cs = shost_priv(shost);

	return snprintf(buf, 8, "%d MB\n", cs->ctlr_info->cache_size_mb);
}
static DEVICE_ATTR_RO(cache_size);

static ssize_t firmware_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	struct Scsi_Host *shost = class_to_shost(dev);
	struct myrs_hba *cs = shost_priv(shost);

	return snprintf(buf, 16, "%d.%02d-%02d\n",
			cs->ctlr_info->fw_major_version,
			cs->ctlr_info->fw_minor_version,
			cs->ctlr_info->fw_turn_number);
}
static DEVICE_ATTR_RO(firmware);

static ssize_t discovery_store(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t count)
{
	struct Scsi_Host *shost = class_to_shost(dev);
	struct myrs_hba *cs = shost_priv(shost);
	struct myrs_cmdblk *cmd_blk;
	union myrs_cmd_mbox *mbox;
	unsigned char status;

	mutex_lock(&cs->dcmd_mutex);
	cmd_blk = &cs->dcmd_blk;
	myrs_reset_cmd(cmd_blk);
	mbox = &cmd_blk->mbox;
	mbox->common.opcode = MYRS_CMD_OP_IOCTL;
	mbox->common.id = MYRS_DCMD_TAG;
	mbox->common.control.dma_ctrl_to_host = true;
	mbox->common.control.no_autosense = true;
	mbox->common.ioctl_opcode = MYRS_IOCTL_START_DISCOVERY;
	myrs_exec_cmd(cs, cmd_blk);
	status = cmd_blk->status;
	mutex_unlock(&cs->dcmd_mutex);
	if (status != MYRS_STATUS_SUCCESS) {
		shost_printk(KERN_INFO, shost,
			     "Discovery Not Initiated, status %02X\n",
			     status);
		return -EINVAL;
	}
	shost_printk(KERN_INFO, shost, "Discovery Initiated\n");
	cs->next_evseq = 0;
	cs->needs_update = true;
	queue_delayed_work(cs->work_q, &cs->monitor_work, 1);
	flush_delayed_work(&cs->monitor_work);
	shost_printk(KERN_INFO, shost, "Discovery Completed\n");

	return count;
}
static DEVICE_ATTR_WO(discovery);

static ssize_t flush_cache_store(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t count)
{
	struct Scsi_Host *shost = class_to_shost(dev);
	struct myrs_hba *cs = shost_priv(shost);
	unsigned char status;

	status = myrs_dev_op(cs, MYRS_IOCTL_FLUSH_DEVICE_DATA,
			     MYRS_RAID_CONTROLLER);
	if (status == MYRS_STATUS_SUCCESS) {
		shost_printk(KERN_INFO, shost, "Cache Flush Completed\n");
		return count;
	}
	shost_printk(KERN_INFO, shost,
		     "Cache Flush failed, status 0x%02x\n", status);
	return -EIO;
}
static DEVICE_ATTR_WO(flush_cache);

static ssize_t disable_enclosure_messages_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	struct Scsi_Host *shost = class_to_shost(dev);
	struct myrs_hba *cs = shost_priv(shost);

	return snprintf(buf, 3, "%d\n", cs->disable_enc_msg);
}

static ssize_t disable_enclosure_messages_store(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t count)
{
	struct scsi_device *sdev = to_scsi_device(dev);
	struct myrs_hba *cs = shost_priv(sdev->host);
	int value, ret;

	ret = kstrtoint(buf, 0, &value);
	if (ret)
		return ret;

	if (value > 2)
		return -EINVAL;

	cs->disable_enc_msg = value;
	return count;
}
static DEVICE_ATTR_RW(disable_enclosure_messages);

static struct device_attribute *myrs_shost_attrs[] = {
	&dev_attr_serial,
	&dev_attr_ctlr_num,
	&dev_attr_processor,
	&dev_attr_model,
	&dev_attr_ctlr_type,
	&dev_attr_cache_size,
	&dev_attr_firmware,
	&dev_attr_discovery,
	&dev_attr_flush_cache,
	&dev_attr_disable_enclosure_messages,
	NULL,
};

/*
 * SCSI midlayer interface
 */
static int myrs_host_reset(struct scsi_cmnd *scmd)
{
	struct Scsi_Host *shost = scmd->device->host;
	struct myrs_hba *cs = shost_priv(shost);

	cs->reset(cs->io_base);
	return SUCCESS;
}

static void myrs_mode_sense(struct myrs_hba *cs, struct scsi_cmnd *scmd,
		struct myrs_ldev_info *ldev_info)
{
	unsigned char modes[32], *mode_pg;
	bool dbd;
	size_t mode_len;

	dbd = (scmd->cmnd[1] & 0x08) == 0x08;
	if (dbd) {
		mode_len = 24;
		mode_pg = &modes[4];
	} else {
		mode_len = 32;
		mode_pg = &modes[12];
	}
	memset(modes, 0, sizeof(modes));
	modes[0] = mode_len - 1;
	modes[2] = 0x10; /* Enable FUA */
	if (ldev_info->ldev_control.wce == MYRS_LOGICALDEVICE_RO)
		modes[2] |= 0x80;
	if (!dbd) {
		unsigned char *block_desc = &modes[4];

		modes[3] = 8;
		put_unaligned_be32(ldev_info->cfg_devsize, &block_desc[0]);
		put_unaligned_be32(ldev_info->devsize_bytes, &block_desc[5]);
	}
	mode_pg[0] = 0x08;
	mode_pg[1] = 0x12;
	if (ldev_info->ldev_control.rce == MYRS_READCACHE_DISABLED)
		mode_pg[2] |= 0x01;
	if (ldev_info->ldev_control.wce == MYRS_WRITECACHE_ENABLED ||
	    ldev_info->ldev_control.wce == MYRS_INTELLIGENT_WRITECACHE_ENABLED)
		mode_pg[2] |= 0x04;
	if (ldev_info->cacheline_size) {
		mode_pg[2] |= 0x08;
		put_unaligned_be16(1 << ldev_info->cacheline_size,
				   &mode_pg[14]);
	}

	scsi_sg_copy_from_buffer(scmd, modes, mode_len);
}

static int myrs_queuecommand(struct Scsi_Host *shost,
		struct scsi_cmnd *scmd)
{
	struct myrs_hba *cs = shost_priv(shost);
	struct myrs_cmdblk *cmd_blk = scsi_cmd_priv(scmd);
	union myrs_cmd_mbox *mbox = &cmd_blk->mbox;
	struct scsi_device *sdev = scmd->device;
	union myrs_sgl *hw_sge;
	dma_addr_t sense_addr;
	struct scatterlist *sgl;
	unsigned long flags, timeout;
	int nsge;

	if (!scmd->device->hostdata) {
		scmd->result = (DID_NO_CONNECT << 16);
		scmd->scsi_done(scmd);
		return 0;
	}

	switch (scmd->cmnd[0]) {
	case REPORT_LUNS:
		scsi_build_sense_buffer(0, scmd->sense_buffer, ILLEGAL_REQUEST,
					0x20, 0x0);
		scmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION;
		scmd->scsi_done(scmd);
		return 0;
	case MODE_SENSE:
		if (scmd->device->channel >= cs->ctlr_info->physchan_present) {
			struct myrs_ldev_info *ldev_info = sdev->hostdata;

			if ((scmd->cmnd[2] & 0x3F) != 0x3F &&
			    (scmd->cmnd[2] & 0x3F) != 0x08) {
				/* Illegal request, invalid field in CDB */
				scsi_build_sense_buffer(0, scmd->sense_buffer,
					ILLEGAL_REQUEST, 0x24, 0);
				scmd->result = (DRIVER_SENSE << 24) |
					SAM_STAT_CHECK_CONDITION;
			} else {
				myrs_mode_sense(cs, scmd, ldev_info);
				scmd->result = (DID_OK << 16);
			}
			scmd->scsi_done(scmd);
			return 0;
		}
		break;
	}

	myrs_reset_cmd(cmd_blk);
	cmd_blk->sense = dma_pool_alloc(cs->sense_pool, GFP_ATOMIC,
					&sense_addr);
	if (!cmd_blk->sense)
		return SCSI_MLQUEUE_HOST_BUSY;
	cmd_blk->sense_addr = sense_addr;

	timeout = scmd->request->timeout;
	if (scmd->cmd_len <= 10) {
		if (scmd->device->channel >= cs->ctlr_info->physchan_present) {
			struct myrs_ldev_info *ldev_info = sdev->hostdata;

			mbox->SCSI_10.opcode = MYRS_CMD_OP_SCSI_10;
			mbox->SCSI_10.pdev.lun = ldev_info->lun;
			mbox->SCSI_10.pdev.target = ldev_info->target;
			mbox->SCSI_10.pdev.channel = ldev_info->channel;
			mbox->SCSI_10.pdev.ctlr = 0;
		} else {
			mbox->SCSI_10.opcode = MYRS_CMD_OP_SCSI_10_PASSTHRU;
			mbox->SCSI_10.pdev.lun = sdev->lun;
			mbox->SCSI_10.pdev.target = sdev->id;
			mbox->SCSI_10.pdev.channel = sdev->channel;
		}
		mbox->SCSI_10.id = scmd->request->tag + 3;
		mbox->SCSI_10.control.dma_ctrl_to_host =
			(scmd->sc_data_direction == DMA_FROM_DEVICE);
		if (scmd->request->cmd_flags & REQ_FUA)
			mbox->SCSI_10.control.fua = true;
		mbox->SCSI_10.dma_size = scsi_bufflen(scmd);
		mbox->SCSI_10.sense_addr = cmd_blk->sense_addr;
		mbox->SCSI_10.sense_len = MYRS_SENSE_SIZE;
		mbox->SCSI_10.cdb_len = scmd->cmd_len;
		if (timeout > 60) {
			mbox->SCSI_10.tmo.tmo_scale = MYRS_TMO_SCALE_MINUTES;
			mbox->SCSI_10.tmo.tmo_val = timeout / 60;
		} else {
			mbox->SCSI_10.tmo.tmo_scale = MYRS_TMO_SCALE_SECONDS;
			mbox->SCSI_10.tmo.tmo_val = timeout;
		}
		memcpy(&mbox->SCSI_10.cdb, scmd->cmnd, scmd->cmd_len);
		hw_sge = &mbox->SCSI_10.dma_addr;
		cmd_blk->dcdb = NULL;
	} else {
		dma_addr_t dcdb_dma;

		cmd_blk->dcdb = dma_pool_alloc(cs->dcdb_pool, GFP_ATOMIC,
					       &dcdb_dma);
		if (!cmd_blk->dcdb) {
			dma_pool_free(cs->sense_pool, cmd_blk->sense,
				      cmd_blk->sense_addr);
			cmd_blk->sense = NULL;
			cmd_blk->sense_addr = 0;
			return SCSI_MLQUEUE_HOST_BUSY;
		}
		cmd_blk->dcdb_dma = dcdb_dma;
		if (scmd->device->channel >= cs->ctlr_info->physchan_present) {
			struct myrs_ldev_info *ldev_info = sdev->hostdata;

			mbox->SCSI_255.opcode = MYRS_CMD_OP_SCSI_256;
			mbox->SCSI_255.pdev.lun = ldev_info->lun;
			mbox->SCSI_255.pdev.target = ldev_info->target;
			mbox->SCSI_255.pdev.channel = ldev_info->channel;
			mbox->SCSI_255.pdev.ctlr = 0;
		} else {
			mbox->SCSI_255.opcode = MYRS_CMD_OP_SCSI_255_PASSTHRU;
			mbox->SCSI_255.pdev.lun = sdev->lun;
			mbox->SCSI_255.pdev.target = sdev->id;
			mbox->SCSI_255.pdev.channel = sdev->channel;
		}
		mbox->SCSI_255.id = scmd->request->tag + 3;
		mbox->SCSI_255.control.dma_ctrl_to_host =
			(scmd->sc_data_direction == DMA_FROM_DEVICE);
		if (scmd->request->cmd_flags & REQ_FUA)
			mbox->SCSI_255.control.fua = true;
		mbox->SCSI_255.dma_size = scsi_bufflen(scmd);
		mbox->SCSI_255.sense_addr = cmd_blk->sense_addr;
		mbox->SCSI_255.sense_len = MYRS_SENSE_SIZE;
		mbox->SCSI_255.cdb_len = scmd->cmd_len;
		mbox->SCSI_255.cdb_addr = cmd_blk->dcdb_dma;
		if (timeout > 60) {
			mbox->SCSI_255.tmo.tmo_scale = MYRS_TMO_SCALE_MINUTES;
			mbox->SCSI_255.tmo.tmo_val = timeout / 60;
		} else {
			mbox->SCSI_255.tmo.tmo_scale = MYRS_TMO_SCALE_SECONDS;
			mbox->SCSI_255.tmo.tmo_val = timeout;
		}
		memcpy(cmd_blk->dcdb, scmd->cmnd, scmd->cmd_len);
		hw_sge = &mbox->SCSI_255.dma_addr;
	}
	if (scmd->sc_data_direction == DMA_NONE)
		goto submit;
	nsge = scsi_dma_map(scmd);
	if (nsge == 1) {
		sgl = scsi_sglist(scmd);
		hw_sge->sge[0].sge_addr = (u64)sg_dma_address(sgl);
		hw_sge->sge[0].sge_count = (u64)sg_dma_len(sgl);
	} else {
		struct myrs_sge *hw_sgl;
		dma_addr_t hw_sgl_addr;
		int i;

		if (nsge > 2) {
			hw_sgl = dma_pool_alloc(cs->sg_pool, GFP_ATOMIC,
						&hw_sgl_addr);
			if (WARN_ON(!hw_sgl)) {
				if (cmd_blk->dcdb) {
					dma_pool_free(cs->dcdb_pool,
						      cmd_blk->dcdb,
						      cmd_blk->dcdb_dma);
					cmd_blk->dcdb = NULL;
					cmd_blk->dcdb_dma = 0;
				}
				dma_pool_free(cs->sense_pool,
					      cmd_blk->sense,
					      cmd_blk->sense_addr);
				cmd_blk->sense = NULL;
				cmd_blk->sense_addr = 0;
				return SCSI_MLQUEUE_HOST_BUSY;
			}
			cmd_blk->sgl = hw_sgl;
			cmd_blk->sgl_addr = hw_sgl_addr;
			if (scmd->cmd_len <= 10)
				mbox->SCSI_10.control.add_sge_mem = true;
			else
				mbox->SCSI_255.control.add_sge_mem = true;
			hw_sge->ext.sge0_len = nsge;
			hw_sge->ext.sge0_addr = cmd_blk->sgl_addr;
		} else
			hw_sgl = hw_sge->sge;

		scsi_for_each_sg(scmd, sgl, nsge, i) {
			if (WARN_ON(!hw_sgl)) {
				scsi_dma_unmap(scmd);
				scmd->result = (DID_ERROR << 16);
				scmd->scsi_done(scmd);
				return 0;
			}
			hw_sgl->sge_addr = (u64)sg_dma_address(sgl);
			hw_sgl->sge_count = (u64)sg_dma_len(sgl);
			hw_sgl++;
		}
	}
submit:
	spin_lock_irqsave(&cs->queue_lock, flags);
	myrs_qcmd(cs, cmd_blk);
	spin_unlock_irqrestore(&cs->queue_lock, flags);

	return 0;
}

static unsigned short myrs_translate_ldev(struct myrs_hba *cs,
		struct scsi_device *sdev)
{
	unsigned short ldev_num;
	unsigned int chan_offset =
		sdev->channel - cs->ctlr_info->physchan_present;

	ldev_num = sdev->id + chan_offset * sdev->host->max_id;

	return ldev_num;
}

static int myrs_slave_alloc(struct scsi_device *sdev)
{
	struct myrs_hba *cs = shost_priv(sdev->host);
	unsigned char status;

	if (sdev->channel > sdev->host->max_channel)
		return 0;

	if (sdev->channel >= cs->ctlr_info->physchan_present) {
		struct myrs_ldev_info *ldev_info;
		unsigned short ldev_num;

		if (sdev->lun > 0)
			return -ENXIO;

		ldev_num = myrs_translate_ldev(cs, sdev);

		ldev_info = kzalloc(sizeof(*ldev_info), GFP_KERNEL|GFP_DMA);
		if (!ldev_info)
			return -ENOMEM;

		status = myrs_get_ldev_info(cs, ldev_num, ldev_info);
		if (status != MYRS_STATUS_SUCCESS) {
			sdev->hostdata = NULL;
			kfree(ldev_info);
		} else {
			enum raid_level level;

			dev_dbg(&sdev->sdev_gendev,
				"Logical device mapping %d:%d:%d -> %d\n",
				ldev_info->channel, ldev_info->target,
				ldev_info->lun, ldev_info->ldev_num);

			sdev->hostdata = ldev_info;
			switch (ldev_info->raid_level) {
			case MYRS_RAID_LEVEL0:
				level = RAID_LEVEL_LINEAR;
				break;
			case MYRS_RAID_LEVEL1:
				level = RAID_LEVEL_1;
				break;
			case MYRS_RAID_LEVEL3:
			case MYRS_RAID_LEVEL3F:
			case MYRS_RAID_LEVEL3L:
				level = RAID_LEVEL_3;
				break;
			case MYRS_RAID_LEVEL5:
			case MYRS_RAID_LEVEL5L:
				level = RAID_LEVEL_5;
				break;
			case MYRS_RAID_LEVEL6:
				level = RAID_LEVEL_6;
				break;
			case MYRS_RAID_LEVELE:
			case MYRS_RAID_NEWSPAN:
			case MYRS_RAID_SPAN:
				level = RAID_LEVEL_LINEAR;
				break;
			case MYRS_RAID_JBOD:
				level = RAID_LEVEL_JBOD;
				break;
			default:
				level = RAID_LEVEL_UNKNOWN;
				break;
			}
			raid_set_level(myrs_raid_template,
				       &sdev->sdev_gendev, level);
			if (ldev_info->dev_state != MYRS_DEVICE_ONLINE) {
				const char *name;

				name = myrs_devstate_name(ldev_info->dev_state);
				sdev_printk(KERN_DEBUG, sdev,
					    "logical device in state %s\n",
					    name ? name : "Invalid");
			}
		}
	} else {
		struct myrs_pdev_info *pdev_info;

		pdev_info = kzalloc(sizeof(*pdev_info), GFP_KERNEL|GFP_DMA);
		if (!pdev_info)
			return -ENOMEM;

		status = myrs_get_pdev_info(cs, sdev->channel,
					    sdev->id, sdev->lun,
					    pdev_info);
		if (status != MYRS_STATUS_SUCCESS) {
			sdev->hostdata = NULL;
			kfree(pdev_info);
			return -ENXIO;
		}
		sdev->hostdata = pdev_info;
	}
	return 0;
}

static int myrs_slave_configure(struct scsi_device *sdev)
{
	struct myrs_hba *cs = shost_priv(sdev->host);
	struct myrs_ldev_info *ldev_info;

	if (sdev->channel > sdev->host->max_channel)
		return -ENXIO;

	if (sdev->channel < cs->ctlr_info->physchan_present) {
		/* Skip HBA device */
		if (sdev->type == TYPE_RAID)
			return -ENXIO;
		sdev->no_uld_attach = 1;
		return 0;
	}
	if (sdev->lun != 0)
		return -ENXIO;

	ldev_info = sdev->hostdata;
	if (!ldev_info)
		return -ENXIO;
	if (ldev_info->ldev_control.wce == MYRS_WRITECACHE_ENABLED ||
	    ldev_info->ldev_control.wce == MYRS_INTELLIGENT_WRITECACHE_ENABLED)
		sdev->wce_default_on = 1;
	sdev->tagged_supported = 1;
	return 0;
}

static void myrs_slave_destroy(struct scsi_device *sdev)
{
	kfree(sdev->hostdata);
}

static struct scsi_host_template myrs_template = {
	.module			= THIS_MODULE,
	.name			= "DAC960",
	.proc_name		= "myrs",
	.queuecommand		= myrs_queuecommand,
	.eh_host_reset_handler	= myrs_host_reset,
	.slave_alloc		= myrs_slave_alloc,
	.slave_configure	= myrs_slave_configure,
	.slave_destroy		= myrs_slave_destroy,
	.cmd_size		= sizeof(struct myrs_cmdblk),
	.shost_attrs		= myrs_shost_attrs,
	.sdev_attrs		= myrs_sdev_attrs,
	.this_id		= -1,
};

static struct myrs_hba *myrs_alloc_host(struct pci_dev *pdev,
		const struct pci_device_id *entry)
{
	struct Scsi_Host *shost;
	struct myrs_hba *cs;

	shost = scsi_host_alloc(&myrs_template, sizeof(struct myrs_hba));
	if (!shost)
		return NULL;

	shost->max_cmd_len = 16;
	shost->max_lun = 256;
	cs = shost_priv(shost);
	mutex_init(&cs->dcmd_mutex);
	mutex_init(&cs->cinfo_mutex);
	cs->host = shost;

	return cs;
}

/*
 * RAID template functions
 */

/**
 * myrs_is_raid - return boolean indicating device is raid volume
 * @dev the device struct object
 */
static int
myrs_is_raid(struct device *dev)
{
	struct scsi_device *sdev = to_scsi_device(dev);
	struct myrs_hba *cs = shost_priv(sdev->host);

	return (sdev->channel >= cs->ctlr_info->physchan_present) ? 1 : 0;
}

/**
 * myrs_get_resync - get raid volume resync percent complete
 * @dev the device struct object
 */
static void
myrs_get_resync(struct device *dev)
{
	struct scsi_device *sdev = to_scsi_device(dev);
	struct myrs_hba *cs = shost_priv(sdev->host);
	struct myrs_ldev_info *ldev_info = sdev->hostdata;
	u64 percent_complete = 0;
	u8 status;

	if (sdev->channel < cs->ctlr_info->physchan_present || !ldev_info)
		return;
	if (ldev_info->rbld_active) {
		unsigned short ldev_num = ldev_info->ldev_num;

		status = myrs_get_ldev_info(cs, ldev_num, ldev_info);
		percent_complete = ldev_info->rbld_lba * 100;
		do_div(percent_complete, ldev_info->cfg_devsize);
	}
	raid_set_resync(myrs_raid_template, dev, percent_complete);
}

/**
 * myrs_get_state - get raid volume status
 * @dev the device struct object
 */
static void
myrs_get_state(struct device *dev)
{
	struct scsi_device *sdev = to_scsi_device(dev);
	struct myrs_hba *cs = shost_priv(sdev->host);
	struct myrs_ldev_info *ldev_info = sdev->hostdata;
	enum raid_state state = RAID_STATE_UNKNOWN;

	if (sdev->channel < cs->ctlr_info->physchan_present || !ldev_info)
		state = RAID_STATE_UNKNOWN;
	else {
		switch (ldev_info->dev_state) {
		case MYRS_DEVICE_ONLINE:
			state = RAID_STATE_ACTIVE;
			break;
		case MYRS_DEVICE_SUSPECTED_CRITICAL:
		case MYRS_DEVICE_CRITICAL:
			state = RAID_STATE_DEGRADED;
			break;
		case MYRS_DEVICE_REBUILD:
			state = RAID_STATE_RESYNCING;
			break;
		case MYRS_DEVICE_UNCONFIGURED:
		case MYRS_DEVICE_INVALID_STATE:
			state = RAID_STATE_UNKNOWN;
			break;
		default:
			state = RAID_STATE_OFFLINE;
		}
	}
	raid_set_state(myrs_raid_template, dev, state);
}

static struct raid_function_template myrs_raid_functions = {
	.cookie		= &myrs_template,
	.is_raid	= myrs_is_raid,
	.get_resync	= myrs_get_resync,
	.get_state	= myrs_get_state,
};

/*
 * PCI interface functions
 */
static void myrs_flush_cache(struct myrs_hba *cs)
{
	myrs_dev_op(cs, MYRS_IOCTL_FLUSH_DEVICE_DATA, MYRS_RAID_CONTROLLER);
}

static void myrs_handle_scsi(struct myrs_hba *cs, struct myrs_cmdblk *cmd_blk,
		struct scsi_cmnd *scmd)
{
	unsigned char status;

	if (!cmd_blk)
		return;

	scsi_dma_unmap(scmd);
	status = cmd_blk->status;
	if (cmd_blk->sense) {
		if (status == MYRS_STATUS_FAILED && cmd_blk->sense_len) {
			unsigned int sense_len = SCSI_SENSE_BUFFERSIZE;

			if (sense_len > cmd_blk->sense_len)
				sense_len = cmd_blk->sense_len;
			memcpy(scmd->sense_buffer, cmd_blk->sense, sense_len);
		}
		dma_pool_free(cs->sense_pool, cmd_blk->sense,
			      cmd_blk->sense_addr);
		cmd_blk->sense = NULL;
		cmd_blk->sense_addr = 0;
	}
	if (cmd_blk->dcdb) {
		dma_pool_free(cs->dcdb_pool, cmd_blk->dcdb,
			      cmd_blk->dcdb_dma);
		cmd_blk->dcdb = NULL;
		cmd_blk->dcdb_dma = 0;
	}
	if (cmd_blk->sgl) {
		dma_pool_free(cs->sg_pool, cmd_blk->sgl,
			      cmd_blk->sgl_addr);
		cmd_blk->sgl = NULL;
		cmd_blk->sgl_addr = 0;
	}
	if (cmd_blk->residual)
		scsi_set_resid(scmd, cmd_blk->residual);
	if (status == MYRS_STATUS_DEVICE_NON_RESPONSIVE ||
	    status == MYRS_STATUS_DEVICE_NON_RESPONSIVE2)
		scmd->result = (DID_BAD_TARGET << 16);
	else
		scmd->result = (DID_OK << 16) | status;
	scmd->scsi_done(scmd);
}

static void myrs_handle_cmdblk(struct myrs_hba *cs, struct myrs_cmdblk *cmd_blk)
{
	if (!cmd_blk)
		return;

	if (cmd_blk->complete) {
		complete(cmd_blk->complete);
		cmd_blk->complete = NULL;
	}
}

static void myrs_monitor(struct work_struct *work)
{
	struct myrs_hba *cs = container_of(work, struct myrs_hba,
					   monitor_work.work);
	struct Scsi_Host *shost = cs->host;
	struct myrs_ctlr_info *info = cs->ctlr_info;
	unsigned int epoch = cs->fwstat_buf->epoch;
	unsigned long interval = MYRS_PRIMARY_MONITOR_INTERVAL;
	unsigned char status;

	dev_dbg(&shost->shost_gendev, "monitor tick\n");

	status = myrs_get_fwstatus(cs);

	if (cs->needs_update) {
		cs->needs_update = false;
		mutex_lock(&cs->cinfo_mutex);
		status = myrs_get_ctlr_info(cs);
		mutex_unlock(&cs->cinfo_mutex);
	}
	if (cs->fwstat_buf->next_evseq - cs->next_evseq > 0) {
		status = myrs_get_event(cs, cs->next_evseq,
					cs->event_buf);
		if (status == MYRS_STATUS_SUCCESS) {
			myrs_log_event(cs, cs->event_buf);
			cs->next_evseq++;
			interval = 1;
		}
	}

	if (time_after(jiffies, cs->secondary_monitor_time
		       + MYRS_SECONDARY_MONITOR_INTERVAL))
		cs->secondary_monitor_time = jiffies;

	if (info->bg_init_active +
	    info->ldev_init_active +
	    info->pdev_init_active +
	    info->cc_active +
	    info->rbld_active +
	    info->exp_active != 0) {
		struct scsi_device *sdev;

		shost_for_each_device(sdev, shost) {
			struct myrs_ldev_info *ldev_info;
			int ldev_num;

			if (sdev->channel < info->physchan_present)
				continue;
			ldev_info = sdev->hostdata;
			if (!ldev_info)
				continue;
			ldev_num = ldev_info->ldev_num;
			myrs_get_ldev_info(cs, ldev_num, ldev_info);
		}
		cs->needs_update = true;
	}
	if (epoch == cs->epoch &&
	    cs->fwstat_buf->next_evseq == cs->next_evseq &&
	    (cs->needs_update == false ||
	     time_before(jiffies, cs->primary_monitor_time
			 + MYRS_PRIMARY_MONITOR_INTERVAL))) {
		interval = MYRS_SECONDARY_MONITOR_INTERVAL;
	}

	if (interval > 1)
		cs->primary_monitor_time = jiffies;
	queue_delayed_work(cs->work_q, &cs->monitor_work, interval);
}

static bool myrs_create_mempools(struct pci_dev *pdev, struct myrs_hba *cs)
{
	struct Scsi_Host *shost = cs->host;
	size_t elem_size, elem_align;

	elem_align = sizeof(struct myrs_sge);
	elem_size = shost->sg_tablesize * elem_align;
	cs->sg_pool = dma_pool_create("myrs_sg", &pdev->dev,
				      elem_size, elem_align, 0);
	if (cs->sg_pool == NULL) {
		shost_printk(KERN_ERR, shost,
			     "Failed to allocate SG pool\n");
		return false;
	}

	cs->sense_pool = dma_pool_create("myrs_sense", &pdev->dev,
					 MYRS_SENSE_SIZE, sizeof(int), 0);
	if (cs->sense_pool == NULL) {
		dma_pool_destroy(cs->sg_pool);
		cs->sg_pool = NULL;
		shost_printk(KERN_ERR, shost,
			     "Failed to allocate sense data pool\n");
		return false;
	}

	cs->dcdb_pool = dma_pool_create("myrs_dcdb", &pdev->dev,
					MYRS_DCDB_SIZE,
					sizeof(unsigned char), 0);
	if (!cs->dcdb_pool) {
		dma_pool_destroy(cs->sg_pool);
		cs->sg_pool = NULL;
		dma_pool_destroy(cs->sense_pool);
		cs->sense_pool = NULL;
		shost_printk(KERN_ERR, shost,
			     "Failed to allocate DCDB pool\n");
		return false;
	}

	snprintf(cs->work_q_name, sizeof(cs->work_q_name),
		 "myrs_wq_%d", shost->host_no);
	cs->work_q = create_singlethread_workqueue(cs->work_q_name);
	if (!cs->work_q) {
		dma_pool_destroy(cs->dcdb_pool);
		cs->dcdb_pool = NULL;
		dma_pool_destroy(cs->sg_pool);
		cs->sg_pool = NULL;
		dma_pool_destroy(cs->sense_pool);
		cs->sense_pool = NULL;
		shost_printk(KERN_ERR, shost,
			     "Failed to create workqueue\n");
		return false;
	}

	/* Initialize the Monitoring Timer. */
	INIT_DELAYED_WORK(&cs->monitor_work, myrs_monitor);
	queue_delayed_work(cs->work_q, &cs->monitor_work, 1);

	return true;
}

static void myrs_destroy_mempools(struct myrs_hba *cs)
{
	cancel_delayed_work_sync(&cs->monitor_work);
	destroy_workqueue(cs->work_q);

	dma_pool_destroy(cs->sg_pool);
	dma_pool_destroy(cs->dcdb_pool);
	dma_pool_destroy(cs->sense_pool);
}

static void myrs_unmap(struct myrs_hba *cs)
{
	kfree(cs->event_buf);
	kfree(cs->ctlr_info);
	if (cs->fwstat_buf) {
		dma_free_coherent(&cs->pdev->dev, sizeof(struct myrs_fwstat),
				  cs->fwstat_buf, cs->fwstat_addr);
		cs->fwstat_buf = NULL;
	}
	if (cs->first_stat_mbox) {
		dma_free_coherent(&cs->pdev->dev, cs->stat_mbox_size,
				  cs->first_stat_mbox, cs->stat_mbox_addr);
		cs->first_stat_mbox = NULL;
	}
	if (cs->first_cmd_mbox) {
		dma_free_coherent(&cs->pdev->dev, cs->cmd_mbox_size,
				  cs->first_cmd_mbox, cs->cmd_mbox_addr);
		cs->first_cmd_mbox = NULL;
	}
}

static void myrs_cleanup(struct myrs_hba *cs)
{
	struct pci_dev *pdev = cs->pdev;

	/* Free the memory mailbox, status, and related structures */
	myrs_unmap(cs);

	if (cs->mmio_base) {
		cs->disable_intr(cs);
		iounmap(cs->mmio_base);
	}
	if (cs->irq)
		free_irq(cs->irq, cs);
	if (cs->io_addr)
		release_region(cs->io_addr, 0x80);
	iounmap(cs->mmio_base);
	pci_set_drvdata(pdev, NULL);
	pci_disable_device(pdev);
	scsi_host_put(cs->host);
}

static struct myrs_hba *myrs_detect(struct pci_dev *pdev,
		const struct pci_device_id *entry)
{
	struct myrs_privdata *privdata =
		(struct myrs_privdata *)entry->driver_data;
	irq_handler_t irq_handler = privdata->irq_handler;
	unsigned int mmio_size = privdata->mmio_size;
	struct myrs_hba *cs = NULL;

	cs = myrs_alloc_host(pdev, entry);
	if (!cs) {
		dev_err(&pdev->dev, "Unable to allocate Controller\n");
		return NULL;
	}
	cs->pdev = pdev;

	if (pci_enable_device(pdev))
		goto Failure;

	cs->pci_addr = pci_resource_start(pdev, 0);

	pci_set_drvdata(pdev, cs);
	spin_lock_init(&cs->queue_lock);
	/* Map the Controller Register Window. */
	if (mmio_size < PAGE_SIZE)
		mmio_size = PAGE_SIZE;
	cs->mmio_base = ioremap(cs->pci_addr & PAGE_MASK, mmio_size);
	if (cs->mmio_base == NULL) {
		dev_err(&pdev->dev,
			"Unable to map Controller Register Window\n");
		goto Failure;
	}

	cs->io_base = cs->mmio_base + (cs->pci_addr & ~PAGE_MASK);
	if (privdata->hw_init(pdev, cs, cs->io_base))
		goto Failure;

	/* Acquire shared access to the IRQ Channel. */
	if (request_irq(pdev->irq, irq_handler, IRQF_SHARED, "myrs", cs) < 0) {
		dev_err(&pdev->dev,
			"Unable to acquire IRQ Channel %d\n", pdev->irq);
		goto Failure;
	}
	cs->irq = pdev->irq;
	return cs;

Failure:
	dev_err(&pdev->dev,
		"Failed to initialize Controller\n");
	myrs_cleanup(cs);
	return NULL;
}

/*
 * myrs_err_status reports Controller BIOS Messages passed through
 * the Error Status Register when the driver performs the BIOS handshaking.
 * It returns true for fatal errors and false otherwise.
 */

static bool myrs_err_status(struct myrs_hba *cs, unsigned char status,
		unsigned char parm0, unsigned char parm1)
{
	struct pci_dev *pdev = cs->pdev;

	switch (status) {
	case 0x00:
		dev_info(&pdev->dev,
			 "Physical Device %d:%d Not Responding\n",
			 parm1, parm0);
		break;
	case 0x08:
		dev_notice(&pdev->dev, "Spinning Up Drives\n");
		break;
	case 0x30:
		dev_notice(&pdev->dev, "Configuration Checksum Error\n");
		break;
	case 0x60:
		dev_notice(&pdev->dev, "Mirror Race Recovery Failed\n");
		break;
	case 0x70:
		dev_notice(&pdev->dev, "Mirror Race Recovery In Progress\n");
		break;
	case 0x90:
		dev_notice(&pdev->dev, "Physical Device %d:%d COD Mismatch\n",
			   parm1, parm0);
		break;
	case 0xA0:
		dev_notice(&pdev->dev, "Logical Drive Installation Aborted\n");
		break;
	case 0xB0:
		dev_notice(&pdev->dev, "Mirror Race On A Critical Logical Drive\n");
		break;
	case 0xD0:
		dev_notice(&pdev->dev, "New Controller Configuration Found\n");
		break;
	case 0xF0:
		dev_err(&pdev->dev, "Fatal Memory Parity Error\n");
		return true;
	default:
		dev_err(&pdev->dev, "Unknown Initialization Error %02X\n",
			status);
		return true;
	}
	return false;
}

/*
 * Hardware-specific functions
 */

/*
 * DAC960 GEM Series Controllers.
 */

static inline void DAC960_GEM_hw_mbox_new_cmd(void __iomem *base)
{
	__le32 val = cpu_to_le32(DAC960_GEM_IDB_HWMBOX_NEW_CMD << 24);

	writel(val, base + DAC960_GEM_IDB_READ_OFFSET);
}

static inline void DAC960_GEM_ack_hw_mbox_status(void __iomem *base)
{
	__le32 val = cpu_to_le32(DAC960_GEM_IDB_HWMBOX_ACK_STS << 24);

	writel(val, base + DAC960_GEM_IDB_CLEAR_OFFSET);
}

static inline void DAC960_GEM_gen_intr(void __iomem *base)
{
	__le32 val = cpu_to_le32(DAC960_GEM_IDB_GEN_IRQ << 24);

	writel(val, base + DAC960_GEM_IDB_READ_OFFSET);
}

static inline void DAC960_GEM_reset_ctrl(void __iomem *base)
{
	__le32 val = cpu_to_le32(DAC960_GEM_IDB_CTRL_RESET << 24);

	writel(val, base + DAC960_GEM_IDB_READ_OFFSET);
}

static inline void DAC960_GEM_mem_mbox_new_cmd(void __iomem *base)
{
	__le32 val = cpu_to_le32(DAC960_GEM_IDB_HWMBOX_NEW_CMD << 24);

	writel(val, base + DAC960_GEM_IDB_READ_OFFSET);
}

static inline bool DAC960_GEM_hw_mbox_is_full(void __iomem *base)
{
	__le32 val;

	val = readl(base + DAC960_GEM_IDB_READ_OFFSET);
	return (le32_to_cpu(val) >> 24) & DAC960_GEM_IDB_HWMBOX_FULL;
}

static inline bool DAC960_GEM_init_in_progress(void __iomem *base)
{
	__le32 val;

	val = readl(base + DAC960_GEM_IDB_READ_OFFSET);
	return (le32_to_cpu(val) >> 24) & DAC960_GEM_IDB_INIT_IN_PROGRESS;
}

static inline void DAC960_GEM_ack_hw_mbox_intr(void __iomem *base)
{
	__le32 val = cpu_to_le32(DAC960_GEM_ODB_HWMBOX_ACK_IRQ << 24);

	writel(val, base + DAC960_GEM_ODB_CLEAR_OFFSET);
}

static inline void DAC960_GEM_ack_mem_mbox_intr(void __iomem *base)
{
	__le32 val = cpu_to_le32(DAC960_GEM_ODB_MMBOX_ACK_IRQ << 24);

	writel(val, base + DAC960_GEM_ODB_CLEAR_OFFSET);
}

static inline void DAC960_GEM_ack_intr(void __iomem *base)
{
	__le32 val = cpu_to_le32((DAC960_GEM_ODB_HWMBOX_ACK_IRQ |
				  DAC960_GEM_ODB_MMBOX_ACK_IRQ) << 24);

	writel(val, base + DAC960_GEM_ODB_CLEAR_OFFSET);
}

static inline bool DAC960_GEM_hw_mbox_status_available(void __iomem *base)
{
	__le32 val;

	val = readl(base + DAC960_GEM_ODB_READ_OFFSET);
	return (le32_to_cpu(val) >> 24) & DAC960_GEM_ODB_HWMBOX_STS_AVAIL;
}

static inline bool DAC960_GEM_mem_mbox_status_available(void __iomem *base)
{
	__le32 val;

	val = readl(base + DAC960_GEM_ODB_READ_OFFSET);
	return (le32_to_cpu(val) >> 24) & DAC960_GEM_ODB_MMBOX_STS_AVAIL;
}

static inline void DAC960_GEM_enable_intr(void __iomem *base)
{
	__le32 val = cpu_to_le32((DAC960_GEM_IRQMASK_HWMBOX_IRQ |
				  DAC960_GEM_IRQMASK_MMBOX_IRQ) << 24);
	writel(val, base + DAC960_GEM_IRQMASK_CLEAR_OFFSET);
}

static inline void DAC960_GEM_disable_intr(void __iomem *base)
{
	__le32 val = 0;

	writel(val, base + DAC960_GEM_IRQMASK_READ_OFFSET);
}

static inline bool DAC960_GEM_intr_enabled(void __iomem *base)
{
	__le32 val;

	val = readl(base + DAC960_GEM_IRQMASK_READ_OFFSET);
	return !((le32_to_cpu(val) >> 24) &
		 (DAC960_GEM_IRQMASK_HWMBOX_IRQ |
		  DAC960_GEM_IRQMASK_MMBOX_IRQ));
}

static inline void DAC960_GEM_write_cmd_mbox(union myrs_cmd_mbox *mem_mbox,
		union myrs_cmd_mbox *mbox)
{
	memcpy(&mem_mbox->words[1], &mbox->words[1],
	       sizeof(union myrs_cmd_mbox) - sizeof(unsigned int));
	/* Barrier to avoid reordering */
	wmb();
	mem_mbox->words[0] = mbox->words[0];
	/* Barrier to force PCI access */
	mb();
}

static inline void DAC960_GEM_write_hw_mbox(void __iomem *base,
		dma_addr_t cmd_mbox_addr)
{
	dma_addr_writeql(cmd_mbox_addr, base + DAC960_GEM_CMDMBX_OFFSET);
}

static inline unsigned short DAC960_GEM_read_cmd_ident(void __iomem *base)
{
	return readw(base + DAC960_GEM_CMDSTS_OFFSET);
}

static inline unsigned char DAC960_GEM_read_cmd_status(void __iomem *base)
{
	return readw(base + DAC960_GEM_CMDSTS_OFFSET + 2);
}

static inline bool
DAC960_GEM_read_error_status(void __iomem *base, unsigned char *error,
		unsigned char *param0, unsigned char *param1)
{
	__le32 val;

	val = readl(base + DAC960_GEM_ERRSTS_READ_OFFSET);
	if (!((le32_to_cpu(val) >> 24) & DAC960_GEM_ERRSTS_PENDING))
		return false;
	*error = val & ~(DAC960_GEM_ERRSTS_PENDING << 24);
	*param0 = readb(base + DAC960_GEM_CMDMBX_OFFSET + 0);
	*param1 = readb(base + DAC960_GEM_CMDMBX_OFFSET + 1);
	writel(0x03000000, base + DAC960_GEM_ERRSTS_CLEAR_OFFSET);
	return true;
}

static inline unsigned char
DAC960_GEM_mbox_init(void __iomem *base, dma_addr_t mbox_addr)
{
	unsigned char status;

	while (DAC960_GEM_hw_mbox_is_full(base))
		udelay(1);
	DAC960_GEM_write_hw_mbox(base, mbox_addr);
	DAC960_GEM_hw_mbox_new_cmd(base);
	while (!DAC960_GEM_hw_mbox_status_available(base))
		udelay(1);
	status = DAC960_GEM_read_cmd_status(base);
	DAC960_GEM_ack_hw_mbox_intr(base);
	DAC960_GEM_ack_hw_mbox_status(base);

	return status;
}

static int DAC960_GEM_hw_init(struct pci_dev *pdev,
		struct myrs_hba *cs, void __iomem *base)
{
	int timeout = 0;
	unsigned char status, parm0, parm1;

	DAC960_GEM_disable_intr(base);
	DAC960_GEM_ack_hw_mbox_status(base);
	udelay(1000);
	while (DAC960_GEM_init_in_progress(base) &&
	       timeout < MYRS_MAILBOX_TIMEOUT) {
		if (DAC960_GEM_read_error_status(base, &status,
						 &parm0, &parm1) &&
		    myrs_err_status(cs, status, parm0, parm1))
			return -EIO;
		udelay(10);
		timeout++;
	}
	if (timeout == MYRS_MAILBOX_TIMEOUT) {
		dev_err(&pdev->dev,
			"Timeout waiting for Controller Initialisation\n");
		return -ETIMEDOUT;
	}
	if (!myrs_enable_mmio_mbox(cs, DAC960_GEM_mbox_init)) {
		dev_err(&pdev->dev,
			"Unable to Enable Memory Mailbox Interface\n");
		DAC960_GEM_reset_ctrl(base);
		return -EAGAIN;
	}
	DAC960_GEM_enable_intr(base);
	cs->write_cmd_mbox = DAC960_GEM_write_cmd_mbox;
	cs->get_cmd_mbox = DAC960_GEM_mem_mbox_new_cmd;
	cs->disable_intr = DAC960_GEM_disable_intr;
	cs->reset = DAC960_GEM_reset_ctrl;
	return 0;
}

static irqreturn_t DAC960_GEM_intr_handler(int irq, void *arg)
{
	struct myrs_hba *cs = arg;
	void __iomem *base = cs->io_base;
	struct myrs_stat_mbox *next_stat_mbox;
	unsigned long flags;

	spin_lock_irqsave(&cs->queue_lock, flags);
	DAC960_GEM_ack_intr(base);
	next_stat_mbox = cs->next_stat_mbox;
	while (next_stat_mbox->id > 0) {
		unsigned short id = next_stat_mbox->id;
		struct scsi_cmnd *scmd = NULL;
		struct myrs_cmdblk *cmd_blk = NULL;

		if (id == MYRS_DCMD_TAG)
			cmd_blk = &cs->dcmd_blk;
		else if (id == MYRS_MCMD_TAG)
			cmd_blk = &cs->mcmd_blk;
		else {
			scmd = scsi_host_find_tag(cs->host, id - 3);
			if (scmd)
				cmd_blk = scsi_cmd_priv(scmd);
		}
		if (cmd_blk) {
			cmd_blk->status = next_stat_mbox->status;
			cmd_blk->sense_len = next_stat_mbox->sense_len;
			cmd_blk->residual = next_stat_mbox->residual;
		} else
			dev_err(&cs->pdev->dev,
				"Unhandled command completion %d\n", id);

		memset(next_stat_mbox, 0, sizeof(struct myrs_stat_mbox));
		if (++next_stat_mbox > cs->last_stat_mbox)
			next_stat_mbox = cs->first_stat_mbox;

		if (cmd_blk) {
			if (id < 3)
				myrs_handle_cmdblk(cs, cmd_blk);
			else
				myrs_handle_scsi(cs, cmd_blk, scmd);
		}
	}
	cs->next_stat_mbox = next_stat_mbox;
	spin_unlock_irqrestore(&cs->queue_lock, flags);
	return IRQ_HANDLED;
}

struct myrs_privdata DAC960_GEM_privdata = {
	.hw_init =		DAC960_GEM_hw_init,
	.irq_handler =		DAC960_GEM_intr_handler,
	.mmio_size =		DAC960_GEM_mmio_size,
};

/*
 * DAC960 BA Series Controllers.
 */

static inline void DAC960_BA_hw_mbox_new_cmd(void __iomem *base)
{
	writeb(DAC960_BA_IDB_HWMBOX_NEW_CMD, base + DAC960_BA_IDB_OFFSET);
}

static inline void DAC960_BA_ack_hw_mbox_status(void __iomem *base)
{
	writeb(DAC960_BA_IDB_HWMBOX_ACK_STS, base + DAC960_BA_IDB_OFFSET);
}

static inline void DAC960_BA_gen_intr(void __iomem *base)
{
	writeb(DAC960_BA_IDB_GEN_IRQ, base + DAC960_BA_IDB_OFFSET);
}

static inline void DAC960_BA_reset_ctrl(void __iomem *base)
{
	writeb(DAC960_BA_IDB_CTRL_RESET, base + DAC960_BA_IDB_OFFSET);
}

static inline void DAC960_BA_mem_mbox_new_cmd(void __iomem *base)
{
	writeb(DAC960_BA_IDB_MMBOX_NEW_CMD, base + DAC960_BA_IDB_OFFSET);
}

static inline bool DAC960_BA_hw_mbox_is_full(void __iomem *base)
{
	u8 val;

	val = readb(base + DAC960_BA_IDB_OFFSET);
	return !(val & DAC960_BA_IDB_HWMBOX_EMPTY);
}

static inline bool DAC960_BA_init_in_progress(void __iomem *base)
{
	u8 val;

	val = readb(base + DAC960_BA_IDB_OFFSET);
	return !(val & DAC960_BA_IDB_INIT_DONE);
}

static inline void DAC960_BA_ack_hw_mbox_intr(void __iomem *base)
{
	writeb(DAC960_BA_ODB_HWMBOX_ACK_IRQ, base + DAC960_BA_ODB_OFFSET);
}

static inline void DAC960_BA_ack_mem_mbox_intr(void __iomem *base)
{
	writeb(DAC960_BA_ODB_MMBOX_ACK_IRQ, base + DAC960_BA_ODB_OFFSET);
}

static inline void DAC960_BA_ack_intr(void __iomem *base)
{
	writeb(DAC960_BA_ODB_HWMBOX_ACK_IRQ | DAC960_BA_ODB_MMBOX_ACK_IRQ,
	       base + DAC960_BA_ODB_OFFSET);
}

static inline bool DAC960_BA_hw_mbox_status_available(void __iomem *base)
{
	u8 val;

	val = readb(base + DAC960_BA_ODB_OFFSET);
	return val & DAC960_BA_ODB_HWMBOX_STS_AVAIL;
}

static inline bool DAC960_BA_mem_mbox_status_available(void __iomem *base)
{
	u8 val;

	val = readb(base + DAC960_BA_ODB_OFFSET);
	return val & DAC960_BA_ODB_MMBOX_STS_AVAIL;
}

static inline void DAC960_BA_enable_intr(void __iomem *base)
{
	writeb(~DAC960_BA_IRQMASK_DISABLE_IRQ, base + DAC960_BA_IRQMASK_OFFSET);
}

static inline void DAC960_BA_disable_intr(void __iomem *base)
{
	writeb(0xFF, base + DAC960_BA_IRQMASK_OFFSET);
}

static inline bool DAC960_BA_intr_enabled(void __iomem *base)
{
	u8 val;

	val = readb(base + DAC960_BA_IRQMASK_OFFSET);
	return !(val & DAC960_BA_IRQMASK_DISABLE_IRQ);
}

static inline void DAC960_BA_write_cmd_mbox(union myrs_cmd_mbox *mem_mbox,
		union myrs_cmd_mbox *mbox)
{
	memcpy(&mem_mbox->words[1], &mbox->words[1],
	       sizeof(union myrs_cmd_mbox) - sizeof(unsigned int));
	/* Barrier to avoid reordering */
	wmb();
	mem_mbox->words[0] = mbox->words[0];
	/* Barrier to force PCI access */
	mb();
}


static inline void DAC960_BA_write_hw_mbox(void __iomem *base,
		dma_addr_t cmd_mbox_addr)
{
	dma_addr_writeql(cmd_mbox_addr, base + DAC960_BA_CMDMBX_OFFSET);
}

static inline unsigned short DAC960_BA_read_cmd_ident(void __iomem *base)
{
	return readw(base + DAC960_BA_CMDSTS_OFFSET);
}

static inline unsigned char DAC960_BA_read_cmd_status(void __iomem *base)
{
	return readw(base + DAC960_BA_CMDSTS_OFFSET + 2);
}

static inline bool
DAC960_BA_read_error_status(void __iomem *base, unsigned char *error,
		unsigned char *param0, unsigned char *param1)
{
	u8 val;

	val = readb(base + DAC960_BA_ERRSTS_OFFSET);
	if (!(val & DAC960_BA_ERRSTS_PENDING))
		return false;
	val &= ~DAC960_BA_ERRSTS_PENDING;
	*error = val;
	*param0 = readb(base + DAC960_BA_CMDMBX_OFFSET + 0);
	*param1 = readb(base + DAC960_BA_CMDMBX_OFFSET + 1);
	writeb(0xFF, base + DAC960_BA_ERRSTS_OFFSET);
	return true;
}

static inline unsigned char
DAC960_BA_mbox_init(void __iomem *base, dma_addr_t mbox_addr)
{
	unsigned char status;

	while (DAC960_BA_hw_mbox_is_full(base))
		udelay(1);
	DAC960_BA_write_hw_mbox(base, mbox_addr);
	DAC960_BA_hw_mbox_new_cmd(base);
	while (!DAC960_BA_hw_mbox_status_available(base))
		udelay(1);
	status = DAC960_BA_read_cmd_status(base);
	DAC960_BA_ack_hw_mbox_intr(base);
	DAC960_BA_ack_hw_mbox_status(base);

	return status;
}

static int DAC960_BA_hw_init(struct pci_dev *pdev,
		struct myrs_hba *cs, void __iomem *base)
{
	int timeout = 0;
	unsigned char status, parm0, parm1;

	DAC960_BA_disable_intr(base);
	DAC960_BA_ack_hw_mbox_status(base);
	udelay(1000);
	while (DAC960_BA_init_in_progress(base) &&
	       timeout < MYRS_MAILBOX_TIMEOUT) {
		if (DAC960_BA_read_error_status(base, &status,
					      &parm0, &parm1) &&
		    myrs_err_status(cs, status, parm0, parm1))
			return -EIO;
		udelay(10);
		timeout++;
	}
	if (timeout == MYRS_MAILBOX_TIMEOUT) {
		dev_err(&pdev->dev,
			"Timeout waiting for Controller Initialisation\n");
		return -ETIMEDOUT;
	}
	if (!myrs_enable_mmio_mbox(cs, DAC960_BA_mbox_init)) {
		dev_err(&pdev->dev,
			"Unable to Enable Memory Mailbox Interface\n");
		DAC960_BA_reset_ctrl(base);
		return -EAGAIN;
	}
	DAC960_BA_enable_intr(base);
	cs->write_cmd_mbox = DAC960_BA_write_cmd_mbox;
	cs->get_cmd_mbox = DAC960_BA_mem_mbox_new_cmd;
	cs->disable_intr = DAC960_BA_disable_intr;
	cs->reset = DAC960_BA_reset_ctrl;
	return 0;
}

static irqreturn_t DAC960_BA_intr_handler(int irq, void *arg)
{
	struct myrs_hba *cs = arg;
	void __iomem *base = cs->io_base;
	struct myrs_stat_mbox *next_stat_mbox;
	unsigned long flags;

	spin_lock_irqsave(&cs->queue_lock, flags);
	DAC960_BA_ack_intr(base);
	next_stat_mbox = cs->next_stat_mbox;
	while (next_stat_mbox->id > 0) {
		unsigned short id = next_stat_mbox->id;
		struct scsi_cmnd *scmd = NULL;
		struct myrs_cmdblk *cmd_blk = NULL;

		if (id == MYRS_DCMD_TAG)
			cmd_blk = &cs->dcmd_blk;
		else if (id == MYRS_MCMD_TAG)
			cmd_blk = &cs->mcmd_blk;
		else {
			scmd = scsi_host_find_tag(cs->host, id - 3);
			if (scmd)
				cmd_blk = scsi_cmd_priv(scmd);
		}
		if (cmd_blk) {
			cmd_blk->status = next_stat_mbox->status;
			cmd_blk->sense_len = next_stat_mbox->sense_len;
			cmd_blk->residual = next_stat_mbox->residual;
		} else
			dev_err(&cs->pdev->dev,
				"Unhandled command completion %d\n", id);

		memset(next_stat_mbox, 0, sizeof(struct myrs_stat_mbox));
		if (++next_stat_mbox > cs->last_stat_mbox)
			next_stat_mbox = cs->first_stat_mbox;

		if (cmd_blk) {
			if (id < 3)
				myrs_handle_cmdblk(cs, cmd_blk);
			else
				myrs_handle_scsi(cs, cmd_blk, scmd);
		}
	}
	cs->next_stat_mbox = next_stat_mbox;
	spin_unlock_irqrestore(&cs->queue_lock, flags);
	return IRQ_HANDLED;
}

struct myrs_privdata DAC960_BA_privdata = {
	.hw_init =		DAC960_BA_hw_init,
	.irq_handler =		DAC960_BA_intr_handler,
	.mmio_size =		DAC960_BA_mmio_size,
};

/*
 * DAC960 LP Series Controllers.
 */

static inline void DAC960_LP_hw_mbox_new_cmd(void __iomem *base)
{
	writeb(DAC960_LP_IDB_HWMBOX_NEW_CMD, base + DAC960_LP_IDB_OFFSET);
}

static inline void DAC960_LP_ack_hw_mbox_status(void __iomem *base)
{
	writeb(DAC960_LP_IDB_HWMBOX_ACK_STS, base + DAC960_LP_IDB_OFFSET);
}

static inline void DAC960_LP_gen_intr(void __iomem *base)
{
	writeb(DAC960_LP_IDB_GEN_IRQ, base + DAC960_LP_IDB_OFFSET);
}

static inline void DAC960_LP_reset_ctrl(void __iomem *base)
{
	writeb(DAC960_LP_IDB_CTRL_RESET, base + DAC960_LP_IDB_OFFSET);
}

static inline void DAC960_LP_mem_mbox_new_cmd(void __iomem *base)
{
	writeb(DAC960_LP_IDB_MMBOX_NEW_CMD, base + DAC960_LP_IDB_OFFSET);
}

static inline bool DAC960_LP_hw_mbox_is_full(void __iomem *base)
{
	u8 val;

	val = readb(base + DAC960_LP_IDB_OFFSET);
	return val & DAC960_LP_IDB_HWMBOX_FULL;
}

static inline bool DAC960_LP_init_in_progress(void __iomem *base)
{
	u8 val;

	val = readb(base + DAC960_LP_IDB_OFFSET);
	return val & DAC960_LP_IDB_INIT_IN_PROGRESS;
}

static inline void DAC960_LP_ack_hw_mbox_intr(void __iomem *base)
{
	writeb(DAC960_LP_ODB_HWMBOX_ACK_IRQ, base + DAC960_LP_ODB_OFFSET);
}

static inline void DAC960_LP_ack_mem_mbox_intr(void __iomem *base)
{
	writeb(DAC960_LP_ODB_MMBOX_ACK_IRQ, base + DAC960_LP_ODB_OFFSET);
}

static inline void DAC960_LP_ack_intr(void __iomem *base)
{
	writeb(DAC960_LP_ODB_HWMBOX_ACK_IRQ | DAC960_LP_ODB_MMBOX_ACK_IRQ,
	       base + DAC960_LP_ODB_OFFSET);
}

static inline bool DAC960_LP_hw_mbox_status_available(void __iomem *base)
{
	u8 val;

	val = readb(base + DAC960_LP_ODB_OFFSET);
	return val & DAC960_LP_ODB_HWMBOX_STS_AVAIL;
}

static inline bool DAC960_LP_mem_mbox_status_available(void __iomem *base)
{
	u8 val;

	val = readb(base + DAC960_LP_ODB_OFFSET);
	return val & DAC960_LP_ODB_MMBOX_STS_AVAIL;
}

static inline void DAC960_LP_enable_intr(void __iomem *base)
{
	writeb(~DAC960_LP_IRQMASK_DISABLE_IRQ, base + DAC960_LP_IRQMASK_OFFSET);
}

static inline void DAC960_LP_disable_intr(void __iomem *base)
{
	writeb(0xFF, base + DAC960_LP_IRQMASK_OFFSET);
}

static inline bool DAC960_LP_intr_enabled(void __iomem *base)
{
	u8 val;

	val = readb(base + DAC960_LP_IRQMASK_OFFSET);
	return !(val & DAC960_LP_IRQMASK_DISABLE_IRQ);
}

static inline void DAC960_LP_write_cmd_mbox(union myrs_cmd_mbox *mem_mbox,
		union myrs_cmd_mbox *mbox)
{
	memcpy(&mem_mbox->words[1], &mbox->words[1],
	       sizeof(union myrs_cmd_mbox) - sizeof(unsigned int));
	/* Barrier to avoid reordering */
	wmb();
	mem_mbox->words[0] = mbox->words[0];
	/* Barrier to force PCI access */
	mb();
}

static inline void DAC960_LP_write_hw_mbox(void __iomem *base,
		dma_addr_t cmd_mbox_addr)
{
	dma_addr_writeql(cmd_mbox_addr, base + DAC960_LP_CMDMBX_OFFSET);
}

static inline unsigned short DAC960_LP_read_cmd_ident(void __iomem *base)
{
	return readw(base + DAC960_LP_CMDSTS_OFFSET);
}

static inline unsigned char DAC960_LP_read_cmd_status(void __iomem *base)
{
	return readw(base + DAC960_LP_CMDSTS_OFFSET + 2);
}

static inline bool
DAC960_LP_read_error_status(void __iomem *base, unsigned char *error,
		unsigned char *param0, unsigned char *param1)
{
	u8 val;

	val = readb(base + DAC960_LP_ERRSTS_OFFSET);
	if (!(val & DAC960_LP_ERRSTS_PENDING))
		return false;
	val &= ~DAC960_LP_ERRSTS_PENDING;
	*error = val;
	*param0 = readb(base + DAC960_LP_CMDMBX_OFFSET + 0);
	*param1 = readb(base + DAC960_LP_CMDMBX_OFFSET + 1);
	writeb(0xFF, base + DAC960_LP_ERRSTS_OFFSET);
	return true;
}

static inline unsigned char
DAC960_LP_mbox_init(void __iomem *base, dma_addr_t mbox_addr)
{
	unsigned char status;

	while (DAC960_LP_hw_mbox_is_full(base))
		udelay(1);
	DAC960_LP_write_hw_mbox(base, mbox_addr);
	DAC960_LP_hw_mbox_new_cmd(base);
	while (!DAC960_LP_hw_mbox_status_available(base))
		udelay(1);
	status = DAC960_LP_read_cmd_status(base);
	DAC960_LP_ack_hw_mbox_intr(base);
	DAC960_LP_ack_hw_mbox_status(base);

	return status;
}

static int DAC960_LP_hw_init(struct pci_dev *pdev,
		struct myrs_hba *cs, void __iomem *base)
{
	int timeout = 0;
	unsigned char status, parm0, parm1;

	DAC960_LP_disable_intr(base);
	DAC960_LP_ack_hw_mbox_status(base);
	udelay(1000);
	while (DAC960_LP_init_in_progress(base) &&
	       timeout < MYRS_MAILBOX_TIMEOUT) {
		if (DAC960_LP_read_error_status(base, &status,
					      &parm0, &parm1) &&
		    myrs_err_status(cs, status, parm0, parm1))
			return -EIO;
		udelay(10);
		timeout++;
	}
	if (timeout == MYRS_MAILBOX_TIMEOUT) {
		dev_err(&pdev->dev,
			"Timeout waiting for Controller Initialisation\n");
		return -ETIMEDOUT;
	}
	if (!myrs_enable_mmio_mbox(cs, DAC960_LP_mbox_init)) {
		dev_err(&pdev->dev,
			"Unable to Enable Memory Mailbox Interface\n");
		DAC960_LP_reset_ctrl(base);
		return -ENODEV;
	}
	DAC960_LP_enable_intr(base);
	cs->write_cmd_mbox = DAC960_LP_write_cmd_mbox;
	cs->get_cmd_mbox = DAC960_LP_mem_mbox_new_cmd;
	cs->disable_intr = DAC960_LP_disable_intr;
	cs->reset = DAC960_LP_reset_ctrl;

	return 0;
}

static irqreturn_t DAC960_LP_intr_handler(int irq, void *arg)
{
	struct myrs_hba *cs = arg;
	void __iomem *base = cs->io_base;
	struct myrs_stat_mbox *next_stat_mbox;
	unsigned long flags;

	spin_lock_irqsave(&cs->queue_lock, flags);
	DAC960_LP_ack_intr(base);
	next_stat_mbox = cs->next_stat_mbox;
	while (next_stat_mbox->id > 0) {
		unsigned short id = next_stat_mbox->id;
		struct scsi_cmnd *scmd = NULL;
		struct myrs_cmdblk *cmd_blk = NULL;

		if (id == MYRS_DCMD_TAG)
			cmd_blk = &cs->dcmd_blk;
		else if (id == MYRS_MCMD_TAG)
			cmd_blk = &cs->mcmd_blk;
		else {
			scmd = scsi_host_find_tag(cs->host, id - 3);
			if (scmd)
				cmd_blk = scsi_cmd_priv(scmd);
		}
		if (cmd_blk) {
			cmd_blk->status = next_stat_mbox->status;
			cmd_blk->sense_len = next_stat_mbox->sense_len;
			cmd_blk->residual = next_stat_mbox->residual;
		} else
			dev_err(&cs->pdev->dev,
				"Unhandled command completion %d\n", id);

		memset(next_stat_mbox, 0, sizeof(struct myrs_stat_mbox));
		if (++next_stat_mbox > cs->last_stat_mbox)
			next_stat_mbox = cs->first_stat_mbox;

		if (cmd_blk) {
			if (id < 3)
				myrs_handle_cmdblk(cs, cmd_blk);
			else
				myrs_handle_scsi(cs, cmd_blk, scmd);
		}
	}
	cs->next_stat_mbox = next_stat_mbox;
	spin_unlock_irqrestore(&cs->queue_lock, flags);
	return IRQ_HANDLED;
}

struct myrs_privdata DAC960_LP_privdata = {
	.hw_init =		DAC960_LP_hw_init,
	.irq_handler =		DAC960_LP_intr_handler,
	.mmio_size =		DAC960_LP_mmio_size,
};

/*
 * Module functions
 */
static int
myrs_probe(struct pci_dev *dev, const struct pci_device_id *entry)
{
	struct myrs_hba *cs;
	int ret;

	cs = myrs_detect(dev, entry);
	if (!cs)
		return -ENODEV;

	ret = myrs_get_config(cs);
	if (ret < 0) {
		myrs_cleanup(cs);
		return ret;
	}

	if (!myrs_create_mempools(dev, cs)) {
		ret = -ENOMEM;
		goto failed;
	}

	ret = scsi_add_host(cs->host, &dev->dev);
	if (ret) {
		dev_err(&dev->dev, "scsi_add_host failed with %d\n", ret);
		myrs_destroy_mempools(cs);
		goto failed;
	}
	scsi_scan_host(cs->host);
	return 0;
failed:
	myrs_cleanup(cs);
	return ret;
}


static void myrs_remove(struct pci_dev *pdev)
{
	struct myrs_hba *cs = pci_get_drvdata(pdev);

	if (cs == NULL)
		return;

	shost_printk(KERN_NOTICE, cs->host, "Flushing Cache...");
	myrs_flush_cache(cs);
	myrs_destroy_mempools(cs);
	myrs_cleanup(cs);
}


static const struct pci_device_id myrs_id_table[] = {
	{
		PCI_DEVICE_SUB(PCI_VENDOR_ID_MYLEX,
			       PCI_DEVICE_ID_MYLEX_DAC960_GEM,
			       PCI_VENDOR_ID_MYLEX, PCI_ANY_ID),
		.driver_data	= (unsigned long) &DAC960_GEM_privdata,
	},
	{
		PCI_DEVICE_DATA(MYLEX, DAC960_BA, &DAC960_BA_privdata),
	},
	{
		PCI_DEVICE_DATA(MYLEX, DAC960_LP, &DAC960_LP_privdata),
	},
	{0, },
};

MODULE_DEVICE_TABLE(pci, myrs_id_table);

static struct pci_driver myrs_pci_driver = {
	.name		= "myrs",
	.id_table	= myrs_id_table,
	.probe		= myrs_probe,
	.remove		= myrs_remove,
};

static int __init myrs_init_module(void)
{
	int ret;

	myrs_raid_template = raid_class_attach(&myrs_raid_functions);
	if (!myrs_raid_template)
		return -ENODEV;

	ret = pci_register_driver(&myrs_pci_driver);
	if (ret)
		raid_class_release(myrs_raid_template);

	return ret;
}

static void __exit myrs_cleanup_module(void)
{
	pci_unregister_driver(&myrs_pci_driver);
	raid_class_release(myrs_raid_template);
}

module_init(myrs_init_module);
module_exit(myrs_cleanup_module);

MODULE_DESCRIPTION("Mylex DAC960/AcceleRAID/eXtremeRAID driver (SCSI Interface)");
MODULE_AUTHOR("Hannes Reinecke <hare@suse.com>");
MODULE_LICENSE("GPL");
