// SPDX-License-Identifier: GPL-2.0
/*
 * Linux Driver for Mylex DAC960/AcceleRAID/eXtremeRAID PCI RAID Controllers
 *
 * Copyright 2017 Hannes Reinecke, SUSE Linux GmbH <hare@suse.com>
 *
 * Based on the original DAC960 driver,
 * 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 "myrb.h"

static struct raid_template *myrb_raid_template;

static void myrb_monitor(struct work_struct *work);
static inline void myrb_translate_devstate(void *DeviceState);

static inline int myrb_logical_channel(struct Scsi_Host *shost)
{
	return shost->max_channel - 1;
}

static struct myrb_devstate_name_entry {
	enum myrb_devstate state;
	const char *name;
} myrb_devstate_name_list[] = {
	{ MYRB_DEVICE_DEAD, "Dead" },
	{ MYRB_DEVICE_WO, "WriteOnly" },
	{ MYRB_DEVICE_ONLINE, "Online" },
	{ MYRB_DEVICE_CRITICAL, "Critical" },
	{ MYRB_DEVICE_STANDBY, "Standby" },
	{ MYRB_DEVICE_OFFLINE, "Offline" },
};

static const char *myrb_devstate_name(enum myrb_devstate state)
{
	struct myrb_devstate_name_entry *entry = myrb_devstate_name_list;
	int i;

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

static struct myrb_raidlevel_name_entry {
	enum myrb_raidlevel level;
	const char *name;
} myrb_raidlevel_name_list[] = {
	{ MYRB_RAID_LEVEL0, "RAID0" },
	{ MYRB_RAID_LEVEL1, "RAID1" },
	{ MYRB_RAID_LEVEL3, "RAID3" },
	{ MYRB_RAID_LEVEL5, "RAID5" },
	{ MYRB_RAID_LEVEL6, "RAID6" },
	{ MYRB_RAID_JBOD, "JBOD" },
};

static const char *myrb_raidlevel_name(enum myrb_raidlevel level)
{
	struct myrb_raidlevel_name_entry *entry = myrb_raidlevel_name_list;
	int i;

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

/**
 * myrb_create_mempools - allocates auxiliary data structures
 *
 * Return: true on success, false otherwise.
 */
static bool myrb_create_mempools(struct pci_dev *pdev, struct myrb_hba *cb)
{
	size_t elem_size, elem_align;

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

	cb->dcdb_pool = dma_pool_create("myrb_dcdb", &pdev->dev,
				       sizeof(struct myrb_dcdb),
				       sizeof(unsigned int), 0);
	if (!cb->dcdb_pool) {
		dma_pool_destroy(cb->sg_pool);
		cb->sg_pool = NULL;
		shost_printk(KERN_ERR, cb->host,
			     "Failed to allocate DCDB pool\n");
		return false;
	}

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

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

	return true;
}

/**
 * myrb_destroy_mempools - tears down the memory pools for the controller
 */
static void myrb_destroy_mempools(struct myrb_hba *cb)
{
	cancel_delayed_work_sync(&cb->monitor_work);
	destroy_workqueue(cb->work_q);

	dma_pool_destroy(cb->sg_pool);
	dma_pool_destroy(cb->dcdb_pool);
}

/**
 * myrb_reset_cmd - reset command block
 */
static inline void myrb_reset_cmd(struct myrb_cmdblk *cmd_blk)
{
	union myrb_cmd_mbox *mbox = &cmd_blk->mbox;

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

/**
 * myrb_qcmd - queues command block for execution
 */
static void myrb_qcmd(struct myrb_hba *cb, struct myrb_cmdblk *cmd_blk)
{
	void __iomem *base = cb->io_base;
	union myrb_cmd_mbox *mbox = &cmd_blk->mbox;
	union myrb_cmd_mbox *next_mbox = cb->next_cmd_mbox;

	cb->write_cmd_mbox(next_mbox, mbox);
	if (cb->prev_cmd_mbox1->words[0] == 0 ||
	    cb->prev_cmd_mbox2->words[0] == 0)
		cb->get_cmd_mbox(base);
	cb->prev_cmd_mbox2 = cb->prev_cmd_mbox1;
	cb->prev_cmd_mbox1 = next_mbox;
	if (++next_mbox > cb->last_cmd_mbox)
		next_mbox = cb->first_cmd_mbox;
	cb->next_cmd_mbox = next_mbox;
}

/**
 * myrb_exec_cmd - executes command block and waits for completion.
 *
 * Return: command status
 */
static unsigned short myrb_exec_cmd(struct myrb_hba *cb,
		struct myrb_cmdblk *cmd_blk)
{
	DECLARE_COMPLETION_ONSTACK(cmpl);
	unsigned long flags;

	cmd_blk->completion = &cmpl;

	spin_lock_irqsave(&cb->queue_lock, flags);
	cb->qcmd(cb, cmd_blk);
	spin_unlock_irqrestore(&cb->queue_lock, flags);

	WARN_ON(in_interrupt());
	wait_for_completion(&cmpl);
	return cmd_blk->status;
}

/**
 * myrb_exec_type3 - executes a type 3 command and waits for completion.
 *
 * Return: command status
 */
static unsigned short myrb_exec_type3(struct myrb_hba *cb,
		enum myrb_cmd_opcode op, dma_addr_t addr)
{
	struct myrb_cmdblk *cmd_blk = &cb->dcmd_blk;
	union myrb_cmd_mbox *mbox = &cmd_blk->mbox;
	unsigned short status;

	mutex_lock(&cb->dcmd_mutex);
	myrb_reset_cmd(cmd_blk);
	mbox->type3.id = MYRB_DCMD_TAG;
	mbox->type3.opcode = op;
	mbox->type3.addr = addr;
	status = myrb_exec_cmd(cb, cmd_blk);
	mutex_unlock(&cb->dcmd_mutex);
	return status;
}

/**
 * myrb_exec_type3D - executes a type 3D command and waits for completion.
 *
 * Return: command status
 */
static unsigned short myrb_exec_type3D(struct myrb_hba *cb,
		enum myrb_cmd_opcode op, struct scsi_device *sdev,
		struct myrb_pdev_state *pdev_info)
{
	struct myrb_cmdblk *cmd_blk = &cb->dcmd_blk;
	union myrb_cmd_mbox *mbox = &cmd_blk->mbox;
	unsigned short status;
	dma_addr_t pdev_info_addr;

	pdev_info_addr = dma_map_single(&cb->pdev->dev, pdev_info,
					sizeof(struct myrb_pdev_state),
					DMA_FROM_DEVICE);
	if (dma_mapping_error(&cb->pdev->dev, pdev_info_addr))
		return MYRB_STATUS_SUBSYS_FAILED;

	mutex_lock(&cb->dcmd_mutex);
	myrb_reset_cmd(cmd_blk);
	mbox->type3D.id = MYRB_DCMD_TAG;
	mbox->type3D.opcode = op;
	mbox->type3D.channel = sdev->channel;
	mbox->type3D.target = sdev->id;
	mbox->type3D.addr = pdev_info_addr;
	status = myrb_exec_cmd(cb, cmd_blk);
	mutex_unlock(&cb->dcmd_mutex);
	dma_unmap_single(&cb->pdev->dev, pdev_info_addr,
			 sizeof(struct myrb_pdev_state), DMA_FROM_DEVICE);
	if (status == MYRB_STATUS_SUCCESS &&
	    mbox->type3D.opcode == MYRB_CMD_GET_DEVICE_STATE_OLD)
		myrb_translate_devstate(pdev_info);

	return status;
}

static char *myrb_event_msg[] = {
	"killed because write recovery failed",
	"killed because of SCSI bus reset failure",
	"killed because of double check condition",
	"killed because it was removed",
	"killed because of gross error on SCSI chip",
	"killed because of bad tag returned from drive",
	"killed because of timeout on SCSI command",
	"killed because of reset SCSI command issued from system",
	"killed because busy or parity error count exceeded limit",
	"killed because of 'kill drive' command from system",
	"killed because of selection timeout",
	"killed due to SCSI phase sequence error",
	"killed due to unknown status",
};

/**
 * myrb_get_event - get event log from HBA
 * @cb: pointer to the hba structure
 * @event: number of the event
 *
 * Execute a type 3E command and logs the event message
 */
static void myrb_get_event(struct myrb_hba *cb, unsigned int event)
{
	struct myrb_cmdblk *cmd_blk = &cb->mcmd_blk;
	union myrb_cmd_mbox *mbox = &cmd_blk->mbox;
	struct myrb_log_entry *ev_buf;
	dma_addr_t ev_addr;
	unsigned short status;

	ev_buf = dma_alloc_coherent(&cb->pdev->dev,
				    sizeof(struct myrb_log_entry),
				    &ev_addr, GFP_KERNEL);
	if (!ev_buf)
		return;

	myrb_reset_cmd(cmd_blk);
	mbox->type3E.id = MYRB_MCMD_TAG;
	mbox->type3E.opcode = MYRB_CMD_EVENT_LOG_OPERATION;
	mbox->type3E.optype = DAC960_V1_GetEventLogEntry;
	mbox->type3E.opqual = 1;
	mbox->type3E.ev_seq = event;
	mbox->type3E.addr = ev_addr;
	status = myrb_exec_cmd(cb, cmd_blk);
	if (status != MYRB_STATUS_SUCCESS)
		shost_printk(KERN_INFO, cb->host,
			     "Failed to get event log %d, status %04x\n",
			     event, status);

	else if (ev_buf->seq_num == event) {
		struct scsi_sense_hdr sshdr;

		memset(&sshdr, 0, sizeof(sshdr));
		scsi_normalize_sense(ev_buf->sense, 32, &sshdr);

		if (sshdr.sense_key == VENDOR_SPECIFIC &&
		    sshdr.asc == 0x80 &&
		    sshdr.ascq < ARRAY_SIZE(myrb_event_msg))
			shost_printk(KERN_CRIT, cb->host,
				     "Physical drive %d:%d: %s\n",
				     ev_buf->channel, ev_buf->target,
				     myrb_event_msg[sshdr.ascq]);
		else
			shost_printk(KERN_CRIT, cb->host,
				     "Physical drive %d:%d: Sense: %X/%02X/%02X\n",
				     ev_buf->channel, ev_buf->target,
				     sshdr.sense_key, sshdr.asc, sshdr.ascq);
	}

	dma_free_coherent(&cb->pdev->dev, sizeof(struct myrb_log_entry),
			  ev_buf, ev_addr);
}

/**
 * myrb_get_errtable - retrieves the error table from the controller
 *
 * Executes a type 3 command and logs the error table from the controller.
 */
static void myrb_get_errtable(struct myrb_hba *cb)
{
	struct myrb_cmdblk *cmd_blk = &cb->mcmd_blk;
	union myrb_cmd_mbox *mbox = &cmd_blk->mbox;
	unsigned short status;
	struct myrb_error_entry old_table[MYRB_MAX_CHANNELS * MYRB_MAX_TARGETS];

	memcpy(&old_table, cb->err_table, sizeof(old_table));

	myrb_reset_cmd(cmd_blk);
	mbox->type3.id = MYRB_MCMD_TAG;
	mbox->type3.opcode = MYRB_CMD_GET_ERROR_TABLE;
	mbox->type3.addr = cb->err_table_addr;
	status = myrb_exec_cmd(cb, cmd_blk);
	if (status == MYRB_STATUS_SUCCESS) {
		struct myrb_error_entry *table = cb->err_table;
		struct myrb_error_entry *new, *old;
		size_t err_table_offset;
		struct scsi_device *sdev;

		shost_for_each_device(sdev, cb->host) {
			if (sdev->channel >= myrb_logical_channel(cb->host))
				continue;
			err_table_offset = sdev->channel * MYRB_MAX_TARGETS
				+ sdev->id;
			new = table + err_table_offset;
			old = &old_table[err_table_offset];
			if (new->parity_err == old->parity_err &&
			    new->soft_err == old->soft_err &&
			    new->hard_err == old->hard_err &&
			    new->misc_err == old->misc_err)
				continue;
			sdev_printk(KERN_CRIT, sdev,
				    "Errors: Parity = %d, Soft = %d, Hard = %d, Misc = %d\n",
				    new->parity_err, new->soft_err,
				    new->hard_err, new->misc_err);
		}
	}
}

/**
 * myrb_get_ldev_info - retrieves the logical device table from the controller
 *
 * Executes a type 3 command and updates the logical device table.
 *
 * Return: command status
 */
static unsigned short myrb_get_ldev_info(struct myrb_hba *cb)
{
	unsigned short status;
	int ldev_num, ldev_cnt = cb->enquiry->ldev_count;
	struct Scsi_Host *shost = cb->host;

	status = myrb_exec_type3(cb, MYRB_CMD_GET_LDEV_INFO,
				 cb->ldev_info_addr);
	if (status != MYRB_STATUS_SUCCESS)
		return status;

	for (ldev_num = 0; ldev_num < ldev_cnt; ldev_num++) {
		struct myrb_ldev_info *old = NULL;
		struct myrb_ldev_info *new = cb->ldev_info_buf + ldev_num;
		struct scsi_device *sdev;

		sdev = scsi_device_lookup(shost, myrb_logical_channel(shost),
					  ldev_num, 0);
		if (!sdev) {
			if (new->state == MYRB_DEVICE_OFFLINE)
				continue;
			shost_printk(KERN_INFO, shost,
				     "Adding Logical Drive %d in state %s\n",
				     ldev_num, myrb_devstate_name(new->state));
			scsi_add_device(shost, myrb_logical_channel(shost),
					ldev_num, 0);
			continue;
		}
		old = sdev->hostdata;
		if (new->state != old->state)
			shost_printk(KERN_INFO, shost,
				     "Logical Drive %d is now %s\n",
				     ldev_num, myrb_devstate_name(new->state));
		if (new->wb_enabled != old->wb_enabled)
			sdev_printk(KERN_INFO, sdev,
				    "Logical Drive is now WRITE %s\n",
				    (new->wb_enabled ? "BACK" : "THRU"));
		memcpy(old, new, sizeof(*new));
		scsi_device_put(sdev);
	}
	return status;
}

/**
 * myrb_get_rbld_progress - get rebuild progress information
 *
 * Executes a type 3 command and returns the rebuild progress
 * information.
 *
 * Return: command status
 */
static unsigned short myrb_get_rbld_progress(struct myrb_hba *cb,
		struct myrb_rbld_progress *rbld)
{
	struct myrb_cmdblk *cmd_blk = &cb->mcmd_blk;
	union myrb_cmd_mbox *mbox = &cmd_blk->mbox;
	struct myrb_rbld_progress *rbld_buf;
	dma_addr_t rbld_addr;
	unsigned short status;

	rbld_buf = dma_alloc_coherent(&cb->pdev->dev,
				      sizeof(struct myrb_rbld_progress),
				      &rbld_addr, GFP_KERNEL);
	if (!rbld_buf)
		return MYRB_STATUS_RBLD_NOT_CHECKED;

	myrb_reset_cmd(cmd_blk);
	mbox->type3.id = MYRB_MCMD_TAG;
	mbox->type3.opcode = MYRB_CMD_GET_REBUILD_PROGRESS;
	mbox->type3.addr = rbld_addr;
	status = myrb_exec_cmd(cb, cmd_blk);
	if (rbld)
		memcpy(rbld, rbld_buf, sizeof(struct myrb_rbld_progress));
	dma_free_coherent(&cb->pdev->dev, sizeof(struct myrb_rbld_progress),
			  rbld_buf, rbld_addr);
	return status;
}

/**
 * myrb_update_rbld_progress - updates the rebuild status
 *
 * Updates the rebuild status for the attached logical devices.
 *
 */
static void myrb_update_rbld_progress(struct myrb_hba *cb)
{
	struct myrb_rbld_progress rbld_buf;
	unsigned short status;

	status = myrb_get_rbld_progress(cb, &rbld_buf);
	if (status == MYRB_NO_STDBY_RBLD_OR_CHECK_IN_PROGRESS &&
	    cb->last_rbld_status == MYRB_STATUS_SUCCESS)
		status = MYRB_STATUS_RBLD_SUCCESS;
	if (status != MYRB_NO_STDBY_RBLD_OR_CHECK_IN_PROGRESS) {
		unsigned int blocks_done =
			rbld_buf.ldev_size - rbld_buf.blocks_left;
		struct scsi_device *sdev;

		sdev = scsi_device_lookup(cb->host,
					  myrb_logical_channel(cb->host),
					  rbld_buf.ldev_num, 0);
		if (!sdev)
			return;

		switch (status) {
		case MYRB_STATUS_SUCCESS:
			sdev_printk(KERN_INFO, sdev,
				    "Rebuild in Progress, %d%% completed\n",
				    (100 * (blocks_done >> 7))
				    / (rbld_buf.ldev_size >> 7));
			break;
		case MYRB_STATUS_RBLD_FAILED_LDEV_FAILURE:
			sdev_printk(KERN_INFO, sdev,
				    "Rebuild Failed due to Logical Drive Failure\n");
			break;
		case MYRB_STATUS_RBLD_FAILED_BADBLOCKS:
			sdev_printk(KERN_INFO, sdev,
				    "Rebuild Failed due to Bad Blocks on Other Drives\n");
			break;
		case MYRB_STATUS_RBLD_FAILED_NEW_DRIVE_FAILED:
			sdev_printk(KERN_INFO, sdev,
				    "Rebuild Failed due to Failure of Drive Being Rebuilt\n");
			break;
		case MYRB_STATUS_RBLD_SUCCESS:
			sdev_printk(KERN_INFO, sdev,
				    "Rebuild Completed Successfully\n");
			break;
		case MYRB_STATUS_RBLD_SUCCESS_TERMINATED:
			sdev_printk(KERN_INFO, sdev,
				     "Rebuild Successfully Terminated\n");
			break;
		default:
			break;
		}
		scsi_device_put(sdev);
	}
	cb->last_rbld_status = status;
}

/**
 * myrb_get_cc_progress - retrieve the rebuild status
 *
 * Execute a type 3 Command and fetch the rebuild / consistency check
 * status.
 */
static void myrb_get_cc_progress(struct myrb_hba *cb)
{
	struct myrb_cmdblk *cmd_blk = &cb->mcmd_blk;
	union myrb_cmd_mbox *mbox = &cmd_blk->mbox;
	struct myrb_rbld_progress *rbld_buf;
	dma_addr_t rbld_addr;
	unsigned short status;

	rbld_buf = dma_alloc_coherent(&cb->pdev->dev,
				      sizeof(struct myrb_rbld_progress),
				      &rbld_addr, GFP_KERNEL);
	if (!rbld_buf) {
		cb->need_cc_status = true;
		return;
	}
	myrb_reset_cmd(cmd_blk);
	mbox->type3.id = MYRB_MCMD_TAG;
	mbox->type3.opcode = MYRB_CMD_REBUILD_STAT;
	mbox->type3.addr = rbld_addr;
	status = myrb_exec_cmd(cb, cmd_blk);
	if (status == MYRB_STATUS_SUCCESS) {
		unsigned int ldev_num = rbld_buf->ldev_num;
		unsigned int ldev_size = rbld_buf->ldev_size;
		unsigned int blocks_done =
			ldev_size - rbld_buf->blocks_left;
		struct scsi_device *sdev;

		sdev = scsi_device_lookup(cb->host,
					  myrb_logical_channel(cb->host),
					  ldev_num, 0);
		if (sdev) {
			sdev_printk(KERN_INFO, sdev,
				    "Consistency Check in Progress: %d%% completed\n",
				    (100 * (blocks_done >> 7))
				    / (ldev_size >> 7));
			scsi_device_put(sdev);
		}
	}
	dma_free_coherent(&cb->pdev->dev, sizeof(struct myrb_rbld_progress),
			  rbld_buf, rbld_addr);
}

/**
 * myrb_bgi_control - updates background initialisation status
 *
 * Executes a type 3B command and updates the background initialisation status
 */
static void myrb_bgi_control(struct myrb_hba *cb)
{
	struct myrb_cmdblk *cmd_blk = &cb->mcmd_blk;
	union myrb_cmd_mbox *mbox = &cmd_blk->mbox;
	struct myrb_bgi_status *bgi, *last_bgi;
	dma_addr_t bgi_addr;
	struct scsi_device *sdev = NULL;
	unsigned short status;

	bgi = dma_alloc_coherent(&cb->pdev->dev, sizeof(struct myrb_bgi_status),
				 &bgi_addr, GFP_KERNEL);
	if (!bgi) {
		shost_printk(KERN_ERR, cb->host,
			     "Failed to allocate bgi memory\n");
		return;
	}
	myrb_reset_cmd(cmd_blk);
	mbox->type3B.id = MYRB_DCMD_TAG;
	mbox->type3B.opcode = MYRB_CMD_BGI_CONTROL;
	mbox->type3B.optype = 0x20;
	mbox->type3B.addr = bgi_addr;
	status = myrb_exec_cmd(cb, cmd_blk);
	last_bgi = &cb->bgi_status;
	sdev = scsi_device_lookup(cb->host,
				  myrb_logical_channel(cb->host),
				  bgi->ldev_num, 0);
	switch (status) {
	case MYRB_STATUS_SUCCESS:
		switch (bgi->status) {
		case MYRB_BGI_INVALID:
			break;
		case MYRB_BGI_STARTED:
			if (!sdev)
				break;
			sdev_printk(KERN_INFO, sdev,
				    "Background Initialization Started\n");
			break;
		case MYRB_BGI_INPROGRESS:
			if (!sdev)
				break;
			if (bgi->blocks_done == last_bgi->blocks_done &&
			    bgi->ldev_num == last_bgi->ldev_num)
				break;
			sdev_printk(KERN_INFO, sdev,
				 "Background Initialization in Progress: %d%% completed\n",
				 (100 * (bgi->blocks_done >> 7))
				 / (bgi->ldev_size >> 7));
			break;
		case MYRB_BGI_SUSPENDED:
			if (!sdev)
				break;
			sdev_printk(KERN_INFO, sdev,
				    "Background Initialization Suspended\n");
			break;
		case MYRB_BGI_CANCELLED:
			if (!sdev)
				break;
			sdev_printk(KERN_INFO, sdev,
				    "Background Initialization Cancelled\n");
			break;
		}
		memcpy(&cb->bgi_status, bgi, sizeof(struct myrb_bgi_status));
		break;
	case MYRB_STATUS_BGI_SUCCESS:
		if (sdev && cb->bgi_status.status == MYRB_BGI_INPROGRESS)
			sdev_printk(KERN_INFO, sdev,
				    "Background Initialization Completed Successfully\n");
		cb->bgi_status.status = MYRB_BGI_INVALID;
		break;
	case MYRB_STATUS_BGI_ABORTED:
		if (sdev && cb->bgi_status.status == MYRB_BGI_INPROGRESS)
			sdev_printk(KERN_INFO, sdev,
				    "Background Initialization Aborted\n");
		fallthrough;
	case MYRB_STATUS_NO_BGI_INPROGRESS:
		cb->bgi_status.status = MYRB_BGI_INVALID;
		break;
	}
	if (sdev)
		scsi_device_put(sdev);
	dma_free_coherent(&cb->pdev->dev, sizeof(struct myrb_bgi_status),
			  bgi, bgi_addr);
}

/**
 * myrb_hba_enquiry - updates the controller status
 *
 * Executes a DAC_V1_Enquiry command and updates the controller status.
 *
 * Return: command status
 */
static unsigned short myrb_hba_enquiry(struct myrb_hba *cb)
{
	struct myrb_enquiry old, *new;
	unsigned short status;

	memcpy(&old, cb->enquiry, sizeof(struct myrb_enquiry));

	status = myrb_exec_type3(cb, MYRB_CMD_ENQUIRY, cb->enquiry_addr);
	if (status != MYRB_STATUS_SUCCESS)
		return status;

	new = cb->enquiry;
	if (new->ldev_count > old.ldev_count) {
		int ldev_num = old.ldev_count - 1;

		while (++ldev_num < new->ldev_count)
			shost_printk(KERN_CRIT, cb->host,
				     "Logical Drive %d Now Exists\n",
				     ldev_num);
	}
	if (new->ldev_count < old.ldev_count) {
		int ldev_num = new->ldev_count - 1;

		while (++ldev_num < old.ldev_count)
			shost_printk(KERN_CRIT, cb->host,
				     "Logical Drive %d No Longer Exists\n",
				     ldev_num);
	}
	if (new->status.deferred != old.status.deferred)
		shost_printk(KERN_CRIT, cb->host,
			     "Deferred Write Error Flag is now %s\n",
			     (new->status.deferred ? "TRUE" : "FALSE"));
	if (new->ev_seq != old.ev_seq) {
		cb->new_ev_seq = new->ev_seq;
		cb->need_err_info = true;
		shost_printk(KERN_INFO, cb->host,
			     "Event log %d/%d (%d/%d) available\n",
			     cb->old_ev_seq, cb->new_ev_seq,
			     old.ev_seq, new->ev_seq);
	}
	if ((new->ldev_critical > 0 &&
	     new->ldev_critical != old.ldev_critical) ||
	    (new->ldev_offline > 0 &&
	     new->ldev_offline != old.ldev_offline) ||
	    (new->ldev_count != old.ldev_count)) {
		shost_printk(KERN_INFO, cb->host,
			     "Logical drive count changed (%d/%d/%d)\n",
			     new->ldev_critical,
			     new->ldev_offline,
			     new->ldev_count);
		cb->need_ldev_info = true;
	}
	if (new->pdev_dead > 0 ||
	    new->pdev_dead != old.pdev_dead ||
	    time_after_eq(jiffies, cb->secondary_monitor_time
			  + MYRB_SECONDARY_MONITOR_INTERVAL)) {
		cb->need_bgi_status = cb->bgi_status_supported;
		cb->secondary_monitor_time = jiffies;
	}
	if (new->rbld == MYRB_STDBY_RBLD_IN_PROGRESS ||
	    new->rbld == MYRB_BG_RBLD_IN_PROGRESS ||
	    old.rbld == MYRB_STDBY_RBLD_IN_PROGRESS ||
	    old.rbld == MYRB_BG_RBLD_IN_PROGRESS) {
		cb->need_rbld = true;
		cb->rbld_first = (new->ldev_critical < old.ldev_critical);
	}
	if (old.rbld == MYRB_BG_CHECK_IN_PROGRESS)
		switch (new->rbld) {
		case MYRB_NO_STDBY_RBLD_OR_CHECK_IN_PROGRESS:
			shost_printk(KERN_INFO, cb->host,
				     "Consistency Check Completed Successfully\n");
			break;
		case MYRB_STDBY_RBLD_IN_PROGRESS:
		case MYRB_BG_RBLD_IN_PROGRESS:
			break;
		case MYRB_BG_CHECK_IN_PROGRESS:
			cb->need_cc_status = true;
			break;
		case MYRB_STDBY_RBLD_COMPLETED_WITH_ERROR:
			shost_printk(KERN_INFO, cb->host,
				     "Consistency Check Completed with Error\n");
			break;
		case MYRB_BG_RBLD_OR_CHECK_FAILED_DRIVE_FAILED:
			shost_printk(KERN_INFO, cb->host,
				     "Consistency Check Failed - Physical Device Failed\n");
			break;
		case MYRB_BG_RBLD_OR_CHECK_FAILED_LDEV_FAILED:
			shost_printk(KERN_INFO, cb->host,
				     "Consistency Check Failed - Logical Drive Failed\n");
			break;
		case MYRB_BG_RBLD_OR_CHECK_FAILED_OTHER:
			shost_printk(KERN_INFO, cb->host,
				     "Consistency Check Failed - Other Causes\n");
			break;
		case MYRB_BG_RBLD_OR_CHECK_SUCCESS_TERMINATED:
			shost_printk(KERN_INFO, cb->host,
				     "Consistency Check Successfully Terminated\n");
			break;
		}
	else if (new->rbld == MYRB_BG_CHECK_IN_PROGRESS)
		cb->need_cc_status = true;

	return MYRB_STATUS_SUCCESS;
}

/**
 * myrb_set_pdev_state - sets the device state for a physical device
 *
 * Return: command status
 */
static unsigned short myrb_set_pdev_state(struct myrb_hba *cb,
		struct scsi_device *sdev, enum myrb_devstate state)
{
	struct myrb_cmdblk *cmd_blk = &cb->dcmd_blk;
	union myrb_cmd_mbox *mbox = &cmd_blk->mbox;
	unsigned short status;

	mutex_lock(&cb->dcmd_mutex);
	mbox->type3D.opcode = MYRB_CMD_START_DEVICE;
	mbox->type3D.id = MYRB_DCMD_TAG;
	mbox->type3D.channel = sdev->channel;
	mbox->type3D.target = sdev->id;
	mbox->type3D.state = state & 0x1F;
	status = myrb_exec_cmd(cb, cmd_blk);
	mutex_unlock(&cb->dcmd_mutex);

	return status;
}

/**
 * myrb_enable_mmio - enables the Memory Mailbox Interface
 *
 * PD and P controller types have no memory mailbox, but still need the
 * other dma mapped memory.
 *
 * Return: true on success, false otherwise.
 */
static bool myrb_enable_mmio(struct myrb_hba *cb, mbox_mmio_init_t mmio_init_fn)
{
	void __iomem *base = cb->io_base;
	struct pci_dev *pdev = cb->pdev;
	size_t err_table_size;
	size_t ldev_info_size;
	union myrb_cmd_mbox *cmd_mbox_mem;
	struct myrb_stat_mbox *stat_mbox_mem;
	union myrb_cmd_mbox mbox;
	unsigned short status;

	memset(&mbox, 0, sizeof(union myrb_cmd_mbox));

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

	cb->enquiry = dma_alloc_coherent(&pdev->dev,
					 sizeof(struct myrb_enquiry),
					 &cb->enquiry_addr, GFP_KERNEL);
	if (!cb->enquiry)
		return false;

	err_table_size = sizeof(struct myrb_error_entry) *
		MYRB_MAX_CHANNELS * MYRB_MAX_TARGETS;
	cb->err_table = dma_alloc_coherent(&pdev->dev, err_table_size,
					   &cb->err_table_addr, GFP_KERNEL);
	if (!cb->err_table)
		return false;

	ldev_info_size = sizeof(struct myrb_ldev_info) * MYRB_MAX_LDEVS;
	cb->ldev_info_buf = dma_alloc_coherent(&pdev->dev, ldev_info_size,
					       &cb->ldev_info_addr, GFP_KERNEL);
	if (!cb->ldev_info_buf)
		return false;

	/*
	 * Skip mailbox initialisation for PD and P Controllers
	 */
	if (!mmio_init_fn)
		return true;

	/* These are the base addresses for the command memory mailbox array */
	cb->cmd_mbox_size =  MYRB_CMD_MBOX_COUNT * sizeof(union myrb_cmd_mbox);
	cb->first_cmd_mbox = dma_alloc_coherent(&pdev->dev,
						cb->cmd_mbox_size,
						&cb->cmd_mbox_addr,
						GFP_KERNEL);
	if (!cb->first_cmd_mbox)
		return false;

	cmd_mbox_mem = cb->first_cmd_mbox;
	cmd_mbox_mem += MYRB_CMD_MBOX_COUNT - 1;
	cb->last_cmd_mbox = cmd_mbox_mem;
	cb->next_cmd_mbox = cb->first_cmd_mbox;
	cb->prev_cmd_mbox1 = cb->last_cmd_mbox;
	cb->prev_cmd_mbox2 = cb->last_cmd_mbox - 1;

	/* These are the base addresses for the status memory mailbox array */
	cb->stat_mbox_size = MYRB_STAT_MBOX_COUNT *
	    sizeof(struct myrb_stat_mbox);
	cb->first_stat_mbox = dma_alloc_coherent(&pdev->dev,
						 cb->stat_mbox_size,
						 &cb->stat_mbox_addr,
						 GFP_KERNEL);
	if (!cb->first_stat_mbox)
		return false;

	stat_mbox_mem = cb->first_stat_mbox;
	stat_mbox_mem += MYRB_STAT_MBOX_COUNT - 1;
	cb->last_stat_mbox = stat_mbox_mem;
	cb->next_stat_mbox = cb->first_stat_mbox;

	/* Enable the Memory Mailbox Interface. */
	cb->dual_mode_interface = true;
	mbox.typeX.opcode = 0x2B;
	mbox.typeX.id = 0;
	mbox.typeX.opcode2 = 0x14;
	mbox.typeX.cmd_mbox_addr = cb->cmd_mbox_addr;
	mbox.typeX.stat_mbox_addr = cb->stat_mbox_addr;

	status = mmio_init_fn(pdev, base, &mbox);
	if (status != MYRB_STATUS_SUCCESS) {
		cb->dual_mode_interface = false;
		mbox.typeX.opcode2 = 0x10;
		status = mmio_init_fn(pdev, base, &mbox);
		if (status != MYRB_STATUS_SUCCESS) {
			dev_err(&pdev->dev,
				"Failed to enable mailbox, statux %02X\n",
				status);
			return false;
		}
	}
	return true;
}

/**
 * myrb_get_hba_config - reads the configuration information
 *
 * Reads the configuration information from the controller and
 * initializes the controller structure.
 *
 * Return: 0 on success, errno otherwise
 */
static int myrb_get_hba_config(struct myrb_hba *cb)
{
	struct myrb_enquiry2 *enquiry2;
	dma_addr_t enquiry2_addr;
	struct myrb_config2 *config2;
	dma_addr_t config2_addr;
	struct Scsi_Host *shost = cb->host;
	struct pci_dev *pdev = cb->pdev;
	int pchan_max = 0, pchan_cur = 0;
	unsigned short status;
	int ret = -ENODEV, memsize = 0;

	enquiry2 = dma_alloc_coherent(&pdev->dev, sizeof(struct myrb_enquiry2),
				      &enquiry2_addr, GFP_KERNEL);
	if (!enquiry2) {
		shost_printk(KERN_ERR, cb->host,
			     "Failed to allocate V1 enquiry2 memory\n");
		return -ENOMEM;
	}
	config2 = dma_alloc_coherent(&pdev->dev, sizeof(struct myrb_config2),
				     &config2_addr, GFP_KERNEL);
	if (!config2) {
		shost_printk(KERN_ERR, cb->host,
			     "Failed to allocate V1 config2 memory\n");
		dma_free_coherent(&pdev->dev, sizeof(struct myrb_enquiry2),
				  enquiry2, enquiry2_addr);
		return -ENOMEM;
	}
	mutex_lock(&cb->dma_mutex);
	status = myrb_hba_enquiry(cb);
	mutex_unlock(&cb->dma_mutex);
	if (status != MYRB_STATUS_SUCCESS) {
		shost_printk(KERN_WARNING, cb->host,
			     "Failed it issue V1 Enquiry\n");
		goto out_free;
	}

	status = myrb_exec_type3(cb, MYRB_CMD_ENQUIRY2, enquiry2_addr);
	if (status != MYRB_STATUS_SUCCESS) {
		shost_printk(KERN_WARNING, cb->host,
			     "Failed to issue V1 Enquiry2\n");
		goto out_free;
	}

	status = myrb_exec_type3(cb, MYRB_CMD_READ_CONFIG2, config2_addr);
	if (status != MYRB_STATUS_SUCCESS) {
		shost_printk(KERN_WARNING, cb->host,
			     "Failed to issue ReadConfig2\n");
		goto out_free;
	}

	status = myrb_get_ldev_info(cb);
	if (status != MYRB_STATUS_SUCCESS) {
		shost_printk(KERN_WARNING, cb->host,
			     "Failed to get logical drive information\n");
		goto out_free;
	}

	/*
	 * Initialize the Controller Model Name and Full Model Name fields.
	 */
	switch (enquiry2->hw.sub_model) {
	case DAC960_V1_P_PD_PU:
		if (enquiry2->scsi_cap.bus_speed == MYRB_SCSI_SPEED_ULTRA)
			strcpy(cb->model_name, "DAC960PU");
		else
			strcpy(cb->model_name, "DAC960PD");
		break;
	case DAC960_V1_PL:
		strcpy(cb->model_name, "DAC960PL");
		break;
	case DAC960_V1_PG:
		strcpy(cb->model_name, "DAC960PG");
		break;
	case DAC960_V1_PJ:
		strcpy(cb->model_name, "DAC960PJ");
		break;
	case DAC960_V1_PR:
		strcpy(cb->model_name, "DAC960PR");
		break;
	case DAC960_V1_PT:
		strcpy(cb->model_name, "DAC960PT");
		break;
	case DAC960_V1_PTL0:
		strcpy(cb->model_name, "DAC960PTL0");
		break;
	case DAC960_V1_PRL:
		strcpy(cb->model_name, "DAC960PRL");
		break;
	case DAC960_V1_PTL1:
		strcpy(cb->model_name, "DAC960PTL1");
		break;
	case DAC960_V1_1164P:
		strcpy(cb->model_name, "eXtremeRAID 1100");
		break;
	default:
		shost_printk(KERN_WARNING, cb->host,
			     "Unknown Model %X\n",
			     enquiry2->hw.sub_model);
		goto out;
	}
	/*
	 * Initialize the Controller Firmware Version field and verify that it
	 * is a supported firmware version.
	 * The supported firmware versions are:
	 *
	 * DAC1164P		    5.06 and above
	 * DAC960PTL/PRL/PJ/PG	    4.06 and above
	 * DAC960PU/PD/PL	    3.51 and above
	 * DAC960PU/PD/PL/P	    2.73 and above
	 */
#if defined(CONFIG_ALPHA)
	/*
	 * DEC Alpha machines were often equipped with DAC960 cards that were
	 * OEMed from Mylex, and had their own custom firmware. Version 2.70,
	 * the last custom FW revision to be released by DEC for these older
	 * controllers, appears to work quite well with this driver.
	 *
	 * Cards tested successfully were several versions each of the PD and
	 * PU, called by DEC the KZPSC and KZPAC, respectively, and having
	 * the Manufacturer Numbers (from Mylex), usually on a sticker on the
	 * back of the board, of:
	 *
	 * KZPSC:  D040347 (1-channel) or D040348 (2-channel)
	 *         or D040349 (3-channel)
	 * KZPAC:  D040395 (1-channel) or D040396 (2-channel)
	 *         or D040397 (3-channel)
	 */
# define FIRMWARE_27X	"2.70"
#else
# define FIRMWARE_27X	"2.73"
#endif

	if (enquiry2->fw.major_version == 0) {
		enquiry2->fw.major_version = cb->enquiry->fw_major_version;
		enquiry2->fw.minor_version = cb->enquiry->fw_minor_version;
		enquiry2->fw.firmware_type = '0';
		enquiry2->fw.turn_id = 0;
	}
	snprintf(cb->fw_version, sizeof(cb->fw_version),
		"%d.%02d-%c-%02d",
		enquiry2->fw.major_version,
		enquiry2->fw.minor_version,
		enquiry2->fw.firmware_type,
		enquiry2->fw.turn_id);
	if (!((enquiry2->fw.major_version == 5 &&
	       enquiry2->fw.minor_version >= 6) ||
	      (enquiry2->fw.major_version == 4 &&
	       enquiry2->fw.minor_version >= 6) ||
	      (enquiry2->fw.major_version == 3 &&
	       enquiry2->fw.minor_version >= 51) ||
	      (enquiry2->fw.major_version == 2 &&
	       strcmp(cb->fw_version, FIRMWARE_27X) >= 0))) {
		shost_printk(KERN_WARNING, cb->host,
			"Firmware Version '%s' unsupported\n",
			cb->fw_version);
		goto out;
	}
	/*
	 * Initialize the Channels, Targets, Memory Size, and SAF-TE
	 * Enclosure Management Enabled fields.
	 */
	switch (enquiry2->hw.model) {
	case MYRB_5_CHANNEL_BOARD:
		pchan_max = 5;
		break;
	case MYRB_3_CHANNEL_BOARD:
	case MYRB_3_CHANNEL_ASIC_DAC:
		pchan_max = 3;
		break;
	case MYRB_2_CHANNEL_BOARD:
		pchan_max = 2;
		break;
	default:
		pchan_max = enquiry2->cfg_chan;
		break;
	}
	pchan_cur = enquiry2->cur_chan;
	if (enquiry2->scsi_cap.bus_width == MYRB_WIDTH_WIDE_32BIT)
		cb->bus_width = 32;
	else if (enquiry2->scsi_cap.bus_width == MYRB_WIDTH_WIDE_16BIT)
		cb->bus_width = 16;
	else
		cb->bus_width = 8;
	cb->ldev_block_size = enquiry2->ldev_block_size;
	shost->max_channel = pchan_cur;
	shost->max_id = enquiry2->max_targets;
	memsize = enquiry2->mem_size >> 20;
	cb->safte_enabled = (enquiry2->fault_mgmt == MYRB_FAULT_SAFTE);
	/*
	 * 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 one less than the
	 * Controller Queue Depth to allow for an automatic drive
	 * rebuild operation.
	 */
	shost->can_queue = cb->enquiry->max_tcq;
	if (shost->can_queue < 3)
		shost->can_queue = enquiry2->max_cmds;
	if (shost->can_queue < 3)
		/* Play safe and disable TCQ */
		shost->can_queue = 1;

	if (shost->can_queue > MYRB_CMD_MBOX_COUNT - 2)
		shost->can_queue = MYRB_CMD_MBOX_COUNT - 2;
	shost->max_sectors = enquiry2->max_sectors;
	shost->sg_tablesize = enquiry2->max_sge;
	if (shost->sg_tablesize > MYRB_SCATTER_GATHER_LIMIT)
		shost->sg_tablesize = MYRB_SCATTER_GATHER_LIMIT;
	/*
	 * Initialize the Stripe Size, Segment Size, and Geometry Translation.
	 */
	cb->stripe_size = config2->blocks_per_stripe * config2->block_factor
		>> (10 - MYRB_BLKSIZE_BITS);
	cb->segment_size = config2->blocks_per_cacheline * config2->block_factor
		>> (10 - MYRB_BLKSIZE_BITS);
	/* Assume 255/63 translation */
	cb->ldev_geom_heads = 255;
	cb->ldev_geom_sectors = 63;
	if (config2->drive_geometry) {
		cb->ldev_geom_heads = 128;
		cb->ldev_geom_sectors = 32;
	}

	/*
	 * Initialize the Background Initialization Status.
	 */
	if ((cb->fw_version[0] == '4' &&
	     strcmp(cb->fw_version, "4.08") >= 0) ||
	    (cb->fw_version[0] == '5' &&
	     strcmp(cb->fw_version, "5.08") >= 0)) {
		cb->bgi_status_supported = true;
		myrb_bgi_control(cb);
	}
	cb->last_rbld_status = MYRB_NO_STDBY_RBLD_OR_CHECK_IN_PROGRESS;
	ret = 0;

out:
	shost_printk(KERN_INFO, cb->host,
		"Configuring %s PCI RAID Controller\n", cb->model_name);
	shost_printk(KERN_INFO, cb->host,
		"  Firmware Version: %s, Memory Size: %dMB\n",
		cb->fw_version, memsize);
	if (cb->io_addr == 0)
		shost_printk(KERN_INFO, cb->host,
			"  I/O Address: n/a, PCI Address: 0x%lX, IRQ Channel: %d\n",
			(unsigned long)cb->pci_addr, cb->irq);
	else
		shost_printk(KERN_INFO, cb->host,
			"  I/O Address: 0x%lX, PCI Address: 0x%lX, IRQ Channel: %d\n",
			(unsigned long)cb->io_addr, (unsigned long)cb->pci_addr,
			cb->irq);
	shost_printk(KERN_INFO, cb->host,
		"  Controller Queue Depth: %d, Maximum Blocks per Command: %d\n",
		cb->host->can_queue, cb->host->max_sectors);
	shost_printk(KERN_INFO, cb->host,
		     "  Driver Queue Depth: %d, Scatter/Gather Limit: %d of %d Segments\n",
		     cb->host->can_queue, cb->host->sg_tablesize,
		     MYRB_SCATTER_GATHER_LIMIT);
	shost_printk(KERN_INFO, cb->host,
		     "  Stripe Size: %dKB, Segment Size: %dKB, BIOS Geometry: %d/%d%s\n",
		     cb->stripe_size, cb->segment_size,
		     cb->ldev_geom_heads, cb->ldev_geom_sectors,
		     cb->safte_enabled ?
		     "  SAF-TE Enclosure Management Enabled" : "");
	shost_printk(KERN_INFO, cb->host,
		     "  Physical: %d/%d channels %d/%d/%d devices\n",
		     pchan_cur, pchan_max, 0, cb->enquiry->pdev_dead,
		     cb->host->max_id);

	shost_printk(KERN_INFO, cb->host,
		     "  Logical: 1/1 channels, %d/%d disks\n",
		     cb->enquiry->ldev_count, MYRB_MAX_LDEVS);

out_free:
	dma_free_coherent(&pdev->dev, sizeof(struct myrb_enquiry2),
			  enquiry2, enquiry2_addr);
	dma_free_coherent(&pdev->dev, sizeof(struct myrb_config2),
			  config2, config2_addr);

	return ret;
}

/**
 * myrb_unmap - unmaps controller structures
 */
static void myrb_unmap(struct myrb_hba *cb)
{
	if (cb->ldev_info_buf) {
		size_t ldev_info_size = sizeof(struct myrb_ldev_info) *
			MYRB_MAX_LDEVS;
		dma_free_coherent(&cb->pdev->dev, ldev_info_size,
				  cb->ldev_info_buf, cb->ldev_info_addr);
		cb->ldev_info_buf = NULL;
	}
	if (cb->err_table) {
		size_t err_table_size = sizeof(struct myrb_error_entry) *
			MYRB_MAX_CHANNELS * MYRB_MAX_TARGETS;
		dma_free_coherent(&cb->pdev->dev, err_table_size,
				  cb->err_table, cb->err_table_addr);
		cb->err_table = NULL;
	}
	if (cb->enquiry) {
		dma_free_coherent(&cb->pdev->dev, sizeof(struct myrb_enquiry),
				  cb->enquiry, cb->enquiry_addr);
		cb->enquiry = NULL;
	}
	if (cb->first_stat_mbox) {
		dma_free_coherent(&cb->pdev->dev, cb->stat_mbox_size,
				  cb->first_stat_mbox, cb->stat_mbox_addr);
		cb->first_stat_mbox = NULL;
	}
	if (cb->first_cmd_mbox) {
		dma_free_coherent(&cb->pdev->dev, cb->cmd_mbox_size,
				  cb->first_cmd_mbox, cb->cmd_mbox_addr);
		cb->first_cmd_mbox = NULL;
	}
}

/**
 * myrb_cleanup - cleanup controller structures
 */
static void myrb_cleanup(struct myrb_hba *cb)
{
	struct pci_dev *pdev = cb->pdev;

	/* Free the memory mailbox, status, and related structures */
	myrb_unmap(cb);

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

static int myrb_host_reset(struct scsi_cmnd *scmd)
{
	struct Scsi_Host *shost = scmd->device->host;
	struct myrb_hba *cb = shost_priv(shost);

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

static int myrb_pthru_queuecommand(struct Scsi_Host *shost,
		struct scsi_cmnd *scmd)
{
	struct myrb_hba *cb = shost_priv(shost);
	struct myrb_cmdblk *cmd_blk = scsi_cmd_priv(scmd);
	union myrb_cmd_mbox *mbox = &cmd_blk->mbox;
	struct myrb_dcdb *dcdb;
	dma_addr_t dcdb_addr;
	struct scsi_device *sdev = scmd->device;
	struct scatterlist *sgl;
	unsigned long flags;
	int nsge;

	myrb_reset_cmd(cmd_blk);
	dcdb = dma_pool_alloc(cb->dcdb_pool, GFP_ATOMIC, &dcdb_addr);
	if (!dcdb)
		return SCSI_MLQUEUE_HOST_BUSY;
	nsge = scsi_dma_map(scmd);
	if (nsge > 1) {
		dma_pool_free(cb->dcdb_pool, dcdb, dcdb_addr);
		scmd->result = (DID_ERROR << 16);
		scmd->scsi_done(scmd);
		return 0;
	}

	mbox->type3.opcode = MYRB_CMD_DCDB;
	mbox->type3.id = scmd->request->tag + 3;
	mbox->type3.addr = dcdb_addr;
	dcdb->channel = sdev->channel;
	dcdb->target = sdev->id;
	switch (scmd->sc_data_direction) {
	case DMA_NONE:
		dcdb->data_xfer = MYRB_DCDB_XFER_NONE;
		break;
	case DMA_TO_DEVICE:
		dcdb->data_xfer = MYRB_DCDB_XFER_SYSTEM_TO_DEVICE;
		break;
	case DMA_FROM_DEVICE:
		dcdb->data_xfer = MYRB_DCDB_XFER_DEVICE_TO_SYSTEM;
		break;
	default:
		dcdb->data_xfer = MYRB_DCDB_XFER_ILLEGAL;
		break;
	}
	dcdb->early_status = false;
	if (scmd->request->timeout <= 10)
		dcdb->timeout = MYRB_DCDB_TMO_10_SECS;
	else if (scmd->request->timeout <= 60)
		dcdb->timeout = MYRB_DCDB_TMO_60_SECS;
	else if (scmd->request->timeout <= 600)
		dcdb->timeout = MYRB_DCDB_TMO_10_MINS;
	else
		dcdb->timeout = MYRB_DCDB_TMO_24_HRS;
	dcdb->no_autosense = false;
	dcdb->allow_disconnect = true;
	sgl = scsi_sglist(scmd);
	dcdb->dma_addr = sg_dma_address(sgl);
	if (sg_dma_len(sgl) > USHRT_MAX) {
		dcdb->xfer_len_lo = sg_dma_len(sgl) & 0xffff;
		dcdb->xfer_len_hi4 = sg_dma_len(sgl) >> 16;
	} else {
		dcdb->xfer_len_lo = sg_dma_len(sgl);
		dcdb->xfer_len_hi4 = 0;
	}
	dcdb->cdb_len = scmd->cmd_len;
	dcdb->sense_len = sizeof(dcdb->sense);
	memcpy(&dcdb->cdb, scmd->cmnd, scmd->cmd_len);

	spin_lock_irqsave(&cb->queue_lock, flags);
	cb->qcmd(cb, cmd_blk);
	spin_unlock_irqrestore(&cb->queue_lock, flags);
	return 0;
}

static void myrb_inquiry(struct myrb_hba *cb,
		struct scsi_cmnd *scmd)
{
	unsigned char inq[36] = {
		0x00, 0x00, 0x03, 0x02, 0x20, 0x00, 0x01, 0x00,
		0x4d, 0x59, 0x4c, 0x45, 0x58, 0x20, 0x20, 0x20,
		0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
		0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
		0x20, 0x20, 0x20, 0x20,
	};

	if (cb->bus_width > 16)
		inq[7] |= 1 << 6;
	if (cb->bus_width > 8)
		inq[7] |= 1 << 5;
	memcpy(&inq[16], cb->model_name, 16);
	memcpy(&inq[32], cb->fw_version, 1);
	memcpy(&inq[33], &cb->fw_version[2], 2);
	memcpy(&inq[35], &cb->fw_version[7], 1);

	scsi_sg_copy_from_buffer(scmd, (void *)inq, 36);
}

static void
myrb_mode_sense(struct myrb_hba *cb, struct scsi_cmnd *scmd,
		struct myrb_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;
	if (!dbd) {
		unsigned char *block_desc = &modes[4];

		modes[3] = 8;
		put_unaligned_be32(ldev_info->size, &block_desc[0]);
		put_unaligned_be32(cb->ldev_block_size, &block_desc[5]);
	}
	mode_pg[0] = 0x08;
	mode_pg[1] = 0x12;
	if (ldev_info->wb_enabled)
		mode_pg[2] |= 0x04;
	if (cb->segment_size) {
		mode_pg[2] |= 0x08;
		put_unaligned_be16(cb->segment_size, &mode_pg[14]);
	}

	scsi_sg_copy_from_buffer(scmd, modes, mode_len);
}

static void myrb_request_sense(struct myrb_hba *cb,
		struct scsi_cmnd *scmd)
{
	scsi_build_sense_buffer(0, scmd->sense_buffer,
				NO_SENSE, 0, 0);
	scsi_sg_copy_from_buffer(scmd, scmd->sense_buffer,
				 SCSI_SENSE_BUFFERSIZE);
}

static void myrb_read_capacity(struct myrb_hba *cb, struct scsi_cmnd *scmd,
		struct myrb_ldev_info *ldev_info)
{
	unsigned char data[8];

	dev_dbg(&scmd->device->sdev_gendev,
		"Capacity %u, blocksize %u\n",
		ldev_info->size, cb->ldev_block_size);
	put_unaligned_be32(ldev_info->size - 1, &data[0]);
	put_unaligned_be32(cb->ldev_block_size, &data[4]);
	scsi_sg_copy_from_buffer(scmd, data, 8);
}

static int myrb_ldev_queuecommand(struct Scsi_Host *shost,
		struct scsi_cmnd *scmd)
{
	struct myrb_hba *cb = shost_priv(shost);
	struct myrb_cmdblk *cmd_blk = scsi_cmd_priv(scmd);
	union myrb_cmd_mbox *mbox = &cmd_blk->mbox;
	struct myrb_ldev_info *ldev_info;
	struct scsi_device *sdev = scmd->device;
	struct scatterlist *sgl;
	unsigned long flags;
	u64 lba;
	u32 block_cnt;
	int nsge;

	ldev_info = sdev->hostdata;
	if (ldev_info->state != MYRB_DEVICE_ONLINE &&
	    ldev_info->state != MYRB_DEVICE_WO) {
		dev_dbg(&shost->shost_gendev, "ldev %u in state %x, skip\n",
			sdev->id, ldev_info ? ldev_info->state : 0xff);
		scmd->result = (DID_BAD_TARGET << 16);
		scmd->scsi_done(scmd);
		return 0;
	}
	switch (scmd->cmnd[0]) {
	case TEST_UNIT_READY:
		scmd->result = (DID_OK << 16);
		scmd->scsi_done(scmd);
		return 0;
	case INQUIRY:
		if (scmd->cmnd[1] & 1) {
			/* 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 {
			myrb_inquiry(cb, scmd);
			scmd->result = (DID_OK << 16);
		}
		scmd->scsi_done(scmd);
		return 0;
	case SYNCHRONIZE_CACHE:
		scmd->result = (DID_OK << 16);
		scmd->scsi_done(scmd);
		return 0;
	case MODE_SENSE:
		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 {
			myrb_mode_sense(cb, scmd, ldev_info);
			scmd->result = (DID_OK << 16);
		}
		scmd->scsi_done(scmd);
		return 0;
	case READ_CAPACITY:
		if ((scmd->cmnd[1] & 1) ||
		    (scmd->cmnd[8] & 1)) {
			/* 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;
			scmd->scsi_done(scmd);
			return 0;
		}
		lba = get_unaligned_be32(&scmd->cmnd[2]);
		if (lba) {
			/* 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;
			scmd->scsi_done(scmd);
			return 0;
		}
		myrb_read_capacity(cb, scmd, ldev_info);
		scmd->scsi_done(scmd);
		return 0;
	case REQUEST_SENSE:
		myrb_request_sense(cb, scmd);
		scmd->result = (DID_OK << 16);
		return 0;
	case SEND_DIAGNOSTIC:
		if (scmd->cmnd[1] != 0x04) {
			/* 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 {
			/* Assume good status */
			scmd->result = (DID_OK << 16);
		}
		scmd->scsi_done(scmd);
		return 0;
	case READ_6:
		if (ldev_info->state == MYRB_DEVICE_WO) {
			/* Data protect, attempt to read invalid data */
			scsi_build_sense_buffer(0, scmd->sense_buffer,
						DATA_PROTECT, 0x21, 0x06);
			scmd->result = (DRIVER_SENSE << 24) |
				SAM_STAT_CHECK_CONDITION;
			scmd->scsi_done(scmd);
			return 0;
		}
		fallthrough;
	case WRITE_6:
		lba = (((scmd->cmnd[1] & 0x1F) << 16) |
		       (scmd->cmnd[2] << 8) |
		       scmd->cmnd[3]);
		block_cnt = scmd->cmnd[4];
		break;
	case READ_10:
		if (ldev_info->state == MYRB_DEVICE_WO) {
			/* Data protect, attempt to read invalid data */
			scsi_build_sense_buffer(0, scmd->sense_buffer,
						DATA_PROTECT, 0x21, 0x06);
			scmd->result = (DRIVER_SENSE << 24) |
				SAM_STAT_CHECK_CONDITION;
			scmd->scsi_done(scmd);
			return 0;
		}
		fallthrough;
	case WRITE_10:
	case VERIFY:		/* 0x2F */
	case WRITE_VERIFY:	/* 0x2E */
		lba = get_unaligned_be32(&scmd->cmnd[2]);
		block_cnt = get_unaligned_be16(&scmd->cmnd[7]);
		break;
	case READ_12:
		if (ldev_info->state == MYRB_DEVICE_WO) {
			/* Data protect, attempt to read invalid data */
			scsi_build_sense_buffer(0, scmd->sense_buffer,
						DATA_PROTECT, 0x21, 0x06);
			scmd->result = (DRIVER_SENSE << 24) |
				SAM_STAT_CHECK_CONDITION;
			scmd->scsi_done(scmd);
			return 0;
		}
		fallthrough;
	case WRITE_12:
	case VERIFY_12: /* 0xAF */
	case WRITE_VERIFY_12:	/* 0xAE */
		lba = get_unaligned_be32(&scmd->cmnd[2]);
		block_cnt = get_unaligned_be32(&scmd->cmnd[6]);
		break;
	default:
		/* Illegal request, invalid opcode */
		scsi_build_sense_buffer(0, scmd->sense_buffer,
					ILLEGAL_REQUEST, 0x20, 0);
		scmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION;
		scmd->scsi_done(scmd);
		return 0;
	}

	myrb_reset_cmd(cmd_blk);
	mbox->type5.id = scmd->request->tag + 3;
	if (scmd->sc_data_direction == DMA_NONE)
		goto submit;
	nsge = scsi_dma_map(scmd);
	if (nsge == 1) {
		sgl = scsi_sglist(scmd);
		if (scmd->sc_data_direction == DMA_FROM_DEVICE)
			mbox->type5.opcode = MYRB_CMD_READ;
		else
			mbox->type5.opcode = MYRB_CMD_WRITE;

		mbox->type5.ld.xfer_len = block_cnt;
		mbox->type5.ld.ldev_num = sdev->id;
		mbox->type5.lba = lba;
		mbox->type5.addr = (u32)sg_dma_address(sgl);
	} else {
		struct myrb_sge *hw_sgl;
		dma_addr_t hw_sgl_addr;
		int i;

		hw_sgl = dma_pool_alloc(cb->sg_pool, GFP_ATOMIC, &hw_sgl_addr);
		if (!hw_sgl)
			return SCSI_MLQUEUE_HOST_BUSY;

		cmd_blk->sgl = hw_sgl;
		cmd_blk->sgl_addr = hw_sgl_addr;

		if (scmd->sc_data_direction == DMA_FROM_DEVICE)
			mbox->type5.opcode = MYRB_CMD_READ_SG;
		else
			mbox->type5.opcode = MYRB_CMD_WRITE_SG;

		mbox->type5.ld.xfer_len = block_cnt;
		mbox->type5.ld.ldev_num = sdev->id;
		mbox->type5.lba = lba;
		mbox->type5.addr = hw_sgl_addr;
		mbox->type5.sg_count = nsge;

		scsi_for_each_sg(scmd, sgl, nsge, i) {
			hw_sgl->sge_addr = (u32)sg_dma_address(sgl);
			hw_sgl->sge_count = (u32)sg_dma_len(sgl);
			hw_sgl++;
		}
	}
submit:
	spin_lock_irqsave(&cb->queue_lock, flags);
	cb->qcmd(cb, cmd_blk);
	spin_unlock_irqrestore(&cb->queue_lock, flags);

	return 0;
}

static int myrb_queuecommand(struct Scsi_Host *shost,
		struct scsi_cmnd *scmd)
{
	struct scsi_device *sdev = scmd->device;

	if (sdev->channel > myrb_logical_channel(shost)) {
		scmd->result = (DID_BAD_TARGET << 16);
		scmd->scsi_done(scmd);
		return 0;
	}
	if (sdev->channel == myrb_logical_channel(shost))
		return myrb_ldev_queuecommand(shost, scmd);

	return myrb_pthru_queuecommand(shost, scmd);
}

static int myrb_ldev_slave_alloc(struct scsi_device *sdev)
{
	struct myrb_hba *cb = shost_priv(sdev->host);
	struct myrb_ldev_info *ldev_info;
	unsigned short ldev_num = sdev->id;
	enum raid_level level;

	ldev_info = cb->ldev_info_buf + ldev_num;
	if (!ldev_info)
		return -ENXIO;

	sdev->hostdata = kzalloc(sizeof(*ldev_info), GFP_KERNEL);
	if (!sdev->hostdata)
		return -ENOMEM;
	dev_dbg(&sdev->sdev_gendev,
		"slave alloc ldev %d state %x\n",
		ldev_num, ldev_info->state);
	memcpy(sdev->hostdata, ldev_info,
	       sizeof(*ldev_info));
	switch (ldev_info->raid_level) {
	case MYRB_RAID_LEVEL0:
		level = RAID_LEVEL_LINEAR;
		break;
	case MYRB_RAID_LEVEL1:
		level = RAID_LEVEL_1;
		break;
	case MYRB_RAID_LEVEL3:
		level = RAID_LEVEL_3;
		break;
	case MYRB_RAID_LEVEL5:
		level = RAID_LEVEL_5;
		break;
	case MYRB_RAID_LEVEL6:
		level = RAID_LEVEL_6;
		break;
	case MYRB_RAID_JBOD:
		level = RAID_LEVEL_JBOD;
		break;
	default:
		level = RAID_LEVEL_UNKNOWN;
		break;
	}
	raid_set_level(myrb_raid_template, &sdev->sdev_gendev, level);
	return 0;
}

static int myrb_pdev_slave_alloc(struct scsi_device *sdev)
{
	struct myrb_hba *cb = shost_priv(sdev->host);
	struct myrb_pdev_state *pdev_info;
	unsigned short status;

	if (sdev->id > MYRB_MAX_TARGETS)
		return -ENXIO;

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

	status = myrb_exec_type3D(cb, MYRB_CMD_GET_DEVICE_STATE,
				  sdev, pdev_info);
	if (status != MYRB_STATUS_SUCCESS) {
		dev_dbg(&sdev->sdev_gendev,
			"Failed to get device state, status %x\n",
			status);
		kfree(pdev_info);
		return -ENXIO;
	}
	if (!pdev_info->present) {
		dev_dbg(&sdev->sdev_gendev,
			"device not present, skip\n");
		kfree(pdev_info);
		return -ENXIO;
	}
	dev_dbg(&sdev->sdev_gendev,
		"slave alloc pdev %d:%d state %x\n",
		sdev->channel, sdev->id, pdev_info->state);
	sdev->hostdata = pdev_info;

	return 0;
}

static int myrb_slave_alloc(struct scsi_device *sdev)
{
	if (sdev->channel > myrb_logical_channel(sdev->host))
		return -ENXIO;

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

	if (sdev->channel == myrb_logical_channel(sdev->host))
		return myrb_ldev_slave_alloc(sdev);

	return myrb_pdev_slave_alloc(sdev);
}

static int myrb_slave_configure(struct scsi_device *sdev)
{
	struct myrb_ldev_info *ldev_info;

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

	if (sdev->channel < myrb_logical_channel(sdev->host)) {
		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->state != MYRB_DEVICE_ONLINE)
		sdev_printk(KERN_INFO, sdev,
			    "Logical drive is %s\n",
			    myrb_devstate_name(ldev_info->state));

	sdev->tagged_supported = 1;
	return 0;
}

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

static int myrb_biosparam(struct scsi_device *sdev, struct block_device *bdev,
		sector_t capacity, int geom[])
{
	struct myrb_hba *cb = shost_priv(sdev->host);

	geom[0] = cb->ldev_geom_heads;
	geom[1] = cb->ldev_geom_sectors;
	geom[2] = sector_div(capacity, geom[0] * geom[1]);

	return 0;
}

static ssize_t raid_state_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	struct scsi_device *sdev = to_scsi_device(dev);
	struct myrb_hba *cb = shost_priv(sdev->host);
	int ret;

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

	if (sdev->channel == myrb_logical_channel(sdev->host)) {
		struct myrb_ldev_info *ldev_info = sdev->hostdata;
		const char *name;

		name = myrb_devstate_name(ldev_info->state);
		if (name)
			ret = snprintf(buf, 32, "%s\n", name);
		else
			ret = snprintf(buf, 32, "Invalid (%02X)\n",
				       ldev_info->state);
	} else {
		struct myrb_pdev_state *pdev_info = sdev->hostdata;
		unsigned short status;
		const char *name;

		status = myrb_exec_type3D(cb, MYRB_CMD_GET_DEVICE_STATE,
					  sdev, pdev_info);
		if (status != MYRB_STATUS_SUCCESS)
			sdev_printk(KERN_INFO, sdev,
				    "Failed to get device state, status %x\n",
				    status);

		if (!pdev_info->present)
			name = "Removed";
		else
			name = myrb_devstate_name(pdev_info->state);
		if (name)
			ret = snprintf(buf, 32, "%s\n", name);
		else
			ret = snprintf(buf, 32, "Invalid (%02X)\n",
				       pdev_info->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 myrb_hba *cb = shost_priv(sdev->host);
	struct myrb_pdev_state *pdev_info;
	enum myrb_devstate new_state;
	unsigned short status;

	if (!strncmp(buf, "kill", 4) ||
	    !strncmp(buf, "offline", 7))
		new_state = MYRB_DEVICE_DEAD;
	else if (!strncmp(buf, "online", 6))
		new_state = MYRB_DEVICE_ONLINE;
	else if (!strncmp(buf, "standby", 7))
		new_state = MYRB_DEVICE_STANDBY;
	else
		return -EINVAL;

	pdev_info = sdev->hostdata;
	if (!pdev_info) {
		sdev_printk(KERN_INFO, sdev,
			    "Failed - no physical device information\n");
		return -ENXIO;
	}
	if (!pdev_info->present) {
		sdev_printk(KERN_INFO, sdev,
			    "Failed - device not present\n");
		return -ENXIO;
	}

	if (pdev_info->state == new_state)
		return count;

	status = myrb_set_pdev_state(cb, sdev, new_state);
	switch (status) {
	case MYRB_STATUS_SUCCESS:
		break;
	case MYRB_STATUS_START_DEVICE_FAILED:
		sdev_printk(KERN_INFO, sdev,
			     "Failed - Unable to Start Device\n");
		count = -EAGAIN;
		break;
	case MYRB_STATUS_NO_DEVICE:
		sdev_printk(KERN_INFO, sdev,
			    "Failed - No Device at Address\n");
		count = -ENODEV;
		break;
	case MYRB_STATUS_INVALID_CHANNEL_OR_TARGET:
		sdev_printk(KERN_INFO, sdev,
			 "Failed - Invalid Channel or Target or Modifier\n");
		count = -EINVAL;
		break;
	case MYRB_STATUS_CHANNEL_BUSY:
		sdev_printk(KERN_INFO, sdev,
			 "Failed - Channel Busy\n");
		count = -EBUSY;
		break;
	default:
		sdev_printk(KERN_INFO, sdev,
			 "Failed - Unexpected Status %04X\n", status);
		count = -EIO;
		break;
	}
	return count;
}
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);

	if (sdev->channel == myrb_logical_channel(sdev->host)) {
		struct myrb_ldev_info *ldev_info = sdev->hostdata;
		const char *name;

		if (!ldev_info)
			return -ENXIO;

		name = myrb_raidlevel_name(ldev_info->raid_level);
		if (!name)
			return snprintf(buf, 32, "Invalid (%02X)\n",
					ldev_info->state);
		return snprintf(buf, 32, "%s\n", name);
	}
	return snprintf(buf, 32, "Physical Drive\n");
}
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 myrb_hba *cb = shost_priv(sdev->host);
	struct myrb_rbld_progress rbld_buf;
	unsigned char status;

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

	status = myrb_get_rbld_progress(cb, &rbld_buf);

	if (rbld_buf.ldev_num != sdev->id ||
	    status != MYRB_STATUS_SUCCESS)
		return snprintf(buf, 32, "not rebuilding\n");

	return snprintf(buf, 32, "rebuilding block %u of %u\n",
			rbld_buf.ldev_size - rbld_buf.blocks_left,
			rbld_buf.ldev_size);
}

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 myrb_hba *cb = shost_priv(sdev->host);
	struct myrb_cmdblk *cmd_blk;
	union myrb_cmd_mbox *mbox;
	unsigned short status;
	int rc, start;
	const char *msg;

	rc = kstrtoint(buf, 0, &start);
	if (rc)
		return rc;

	if (sdev->channel >= myrb_logical_channel(sdev->host))
		return -ENXIO;

	status = myrb_get_rbld_progress(cb, NULL);
	if (start) {
		if (status == MYRB_STATUS_SUCCESS) {
			sdev_printk(KERN_INFO, sdev,
				    "Rebuild Not Initiated; already in progress\n");
			return -EALREADY;
		}
		mutex_lock(&cb->dcmd_mutex);
		cmd_blk = &cb->dcmd_blk;
		myrb_reset_cmd(cmd_blk);
		mbox = &cmd_blk->mbox;
		mbox->type3D.opcode = MYRB_CMD_REBUILD_ASYNC;
		mbox->type3D.id = MYRB_DCMD_TAG;
		mbox->type3D.channel = sdev->channel;
		mbox->type3D.target = sdev->id;
		status = myrb_exec_cmd(cb, cmd_blk);
		mutex_unlock(&cb->dcmd_mutex);
	} else {
		struct pci_dev *pdev = cb->pdev;
		unsigned char *rate;
		dma_addr_t rate_addr;

		if (status != MYRB_STATUS_SUCCESS) {
			sdev_printk(KERN_INFO, sdev,
				    "Rebuild Not Cancelled; not in progress\n");
			return 0;
		}

		rate = dma_alloc_coherent(&pdev->dev, sizeof(char),
					  &rate_addr, GFP_KERNEL);
		if (rate == NULL) {
			sdev_printk(KERN_INFO, sdev,
				    "Cancellation of Rebuild Failed - Out of Memory\n");
			return -ENOMEM;
		}
		mutex_lock(&cb->dcmd_mutex);
		cmd_blk = &cb->dcmd_blk;
		myrb_reset_cmd(cmd_blk);
		mbox = &cmd_blk->mbox;
		mbox->type3R.opcode = MYRB_CMD_REBUILD_CONTROL;
		mbox->type3R.id = MYRB_DCMD_TAG;
		mbox->type3R.rbld_rate = 0xFF;
		mbox->type3R.addr = rate_addr;
		status = myrb_exec_cmd(cb, cmd_blk);
		dma_free_coherent(&pdev->dev, sizeof(char), rate, rate_addr);
		mutex_unlock(&cb->dcmd_mutex);
	}
	if (status == MYRB_STATUS_SUCCESS) {
		sdev_printk(KERN_INFO, sdev, "Rebuild %s\n",
			    start ? "Initiated" : "Cancelled");
		return count;
	}
	if (!start) {
		sdev_printk(KERN_INFO, sdev,
			    "Rebuild Not Cancelled, status 0x%x\n",
			    status);
		return -EIO;
	}

	switch (status) {
	case MYRB_STATUS_ATTEMPT_TO_RBLD_ONLINE_DRIVE:
		msg = "Attempt to Rebuild Online or Unresponsive Drive";
		break;
	case MYRB_STATUS_RBLD_NEW_DISK_FAILED:
		msg = "New Disk Failed During Rebuild";
		break;
	case MYRB_STATUS_INVALID_ADDRESS:
		msg = "Invalid Device Address";
		break;
	case MYRB_STATUS_RBLD_OR_CHECK_INPROGRESS:
		msg = "Already in Progress";
		break;
	default:
		msg = NULL;
		break;
	}
	if (msg)
		sdev_printk(KERN_INFO, sdev,
			    "Rebuild Failed - %s\n", msg);
	else
		sdev_printk(KERN_INFO, sdev,
			    "Rebuild Failed, status 0x%x\n", status);

	return -EIO;
}
static DEVICE_ATTR_RW(rebuild);

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 myrb_hba *cb = shost_priv(sdev->host);
	struct myrb_rbld_progress rbld_buf;
	struct myrb_cmdblk *cmd_blk;
	union myrb_cmd_mbox *mbox;
	unsigned short ldev_num = 0xFFFF;
	unsigned short status;
	int rc, start;
	const char *msg;

	rc = kstrtoint(buf, 0, &start);
	if (rc)
		return rc;

	if (sdev->channel < myrb_logical_channel(sdev->host))
		return -ENXIO;

	status = myrb_get_rbld_progress(cb, &rbld_buf);
	if (start) {
		if (status == MYRB_STATUS_SUCCESS) {
			sdev_printk(KERN_INFO, sdev,
				    "Check Consistency Not Initiated; already in progress\n");
			return -EALREADY;
		}
		mutex_lock(&cb->dcmd_mutex);
		cmd_blk = &cb->dcmd_blk;
		myrb_reset_cmd(cmd_blk);
		mbox = &cmd_blk->mbox;
		mbox->type3C.opcode = MYRB_CMD_CHECK_CONSISTENCY_ASYNC;
		mbox->type3C.id = MYRB_DCMD_TAG;
		mbox->type3C.ldev_num = sdev->id;
		mbox->type3C.auto_restore = true;

		status = myrb_exec_cmd(cb, cmd_blk);
		mutex_unlock(&cb->dcmd_mutex);
	} else {
		struct pci_dev *pdev = cb->pdev;
		unsigned char *rate;
		dma_addr_t rate_addr;

		if (ldev_num != sdev->id) {
			sdev_printk(KERN_INFO, sdev,
				    "Check Consistency Not Cancelled; not in progress\n");
			return 0;
		}
		rate = dma_alloc_coherent(&pdev->dev, sizeof(char),
					  &rate_addr, GFP_KERNEL);
		if (rate == NULL) {
			sdev_printk(KERN_INFO, sdev,
				    "Cancellation of Check Consistency Failed - Out of Memory\n");
			return -ENOMEM;
		}
		mutex_lock(&cb->dcmd_mutex);
		cmd_blk = &cb->dcmd_blk;
		myrb_reset_cmd(cmd_blk);
		mbox = &cmd_blk->mbox;
		mbox->type3R.opcode = MYRB_CMD_REBUILD_CONTROL;
		mbox->type3R.id = MYRB_DCMD_TAG;
		mbox->type3R.rbld_rate = 0xFF;
		mbox->type3R.addr = rate_addr;
		status = myrb_exec_cmd(cb, cmd_blk);
		dma_free_coherent(&pdev->dev, sizeof(char), rate, rate_addr);
		mutex_unlock(&cb->dcmd_mutex);
	}
	if (status == MYRB_STATUS_SUCCESS) {
		sdev_printk(KERN_INFO, sdev, "Check Consistency %s\n",
			    start ? "Initiated" : "Cancelled");
		return count;
	}
	if (!start) {
		sdev_printk(KERN_INFO, sdev,
			    "Check Consistency Not Cancelled, status 0x%x\n",
			    status);
		return -EIO;
	}

	switch (status) {
	case MYRB_STATUS_ATTEMPT_TO_RBLD_ONLINE_DRIVE:
		msg = "Dependent Physical Device is DEAD";
		break;
	case MYRB_STATUS_RBLD_NEW_DISK_FAILED:
		msg = "New Disk Failed During Rebuild";
		break;
	case MYRB_STATUS_INVALID_ADDRESS:
		msg = "Invalid or Nonredundant Logical Drive";
		break;
	case MYRB_STATUS_RBLD_OR_CHECK_INPROGRESS:
		msg = "Already in Progress";
		break;
	default:
		msg = NULL;
		break;
	}
	if (msg)
		sdev_printk(KERN_INFO, sdev,
			    "Check Consistency Failed - %s\n", msg);
	else
		sdev_printk(KERN_INFO, sdev,
			    "Check Consistency Failed, status 0x%x\n", status);

	return -EIO;
}

static ssize_t consistency_check_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	return rebuild_show(dev, attr, buf);
}
static DEVICE_ATTR_RW(consistency_check);

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

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

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

	return snprintf(buf, 16, "%s\n", cb->fw_version);
}
static DEVICE_ATTR_RO(firmware);

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

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

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 myrb_hba *cb = shost_priv(shost);
	unsigned short status;

	status = myrb_exec_type3(cb, MYRB_CMD_FLUSH, 0);
	if (status == MYRB_STATUS_SUCCESS) {
		shost_printk(KERN_INFO, shost,
			     "Cache Flush Completed\n");
		return count;
	}
	shost_printk(KERN_INFO, shost,
		     "Cache Flush Failed, status %x\n", status);
	return -EIO;
}
static DEVICE_ATTR_WO(flush_cache);

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

static struct device_attribute *myrb_shost_attrs[] = {
	&dev_attr_ctlr_num,
	&dev_attr_model,
	&dev_attr_firmware,
	&dev_attr_flush_cache,
	NULL,
};

struct scsi_host_template myrb_template = {
	.module			= THIS_MODULE,
	.name			= "DAC960",
	.proc_name		= "myrb",
	.queuecommand		= myrb_queuecommand,
	.eh_host_reset_handler	= myrb_host_reset,
	.slave_alloc		= myrb_slave_alloc,
	.slave_configure	= myrb_slave_configure,
	.slave_destroy		= myrb_slave_destroy,
	.bios_param		= myrb_biosparam,
	.cmd_size		= sizeof(struct myrb_cmdblk),
	.shost_attrs		= myrb_shost_attrs,
	.sdev_attrs		= myrb_sdev_attrs,
	.this_id		= -1,
};

/**
 * myrb_is_raid - return boolean indicating device is raid volume
 * @dev the device struct object
 */
static int myrb_is_raid(struct device *dev)
{
	struct scsi_device *sdev = to_scsi_device(dev);

	return sdev->channel == myrb_logical_channel(sdev->host);
}

/**
 * myrb_get_resync - get raid volume resync percent complete
 * @dev the device struct object
 */
static void myrb_get_resync(struct device *dev)
{
	struct scsi_device *sdev = to_scsi_device(dev);
	struct myrb_hba *cb = shost_priv(sdev->host);
	struct myrb_rbld_progress rbld_buf;
	unsigned int percent_complete = 0;
	unsigned short status;
	unsigned int ldev_size = 0, remaining = 0;

	if (sdev->channel < myrb_logical_channel(sdev->host))
		return;
	status = myrb_get_rbld_progress(cb, &rbld_buf);
	if (status == MYRB_STATUS_SUCCESS) {
		if (rbld_buf.ldev_num == sdev->id) {
			ldev_size = rbld_buf.ldev_size;
			remaining = rbld_buf.blocks_left;
		}
	}
	if (remaining && ldev_size)
		percent_complete = (ldev_size - remaining) * 100 / ldev_size;
	raid_set_resync(myrb_raid_template, dev, percent_complete);
}

/**
 * myrb_get_state - get raid volume status
 * @dev the device struct object
 */
static void myrb_get_state(struct device *dev)
{
	struct scsi_device *sdev = to_scsi_device(dev);
	struct myrb_hba *cb = shost_priv(sdev->host);
	struct myrb_ldev_info *ldev_info = sdev->hostdata;
	enum raid_state state = RAID_STATE_UNKNOWN;
	unsigned short status;

	if (sdev->channel < myrb_logical_channel(sdev->host) || !ldev_info)
		state = RAID_STATE_UNKNOWN;
	else {
		status = myrb_get_rbld_progress(cb, NULL);
		if (status == MYRB_STATUS_SUCCESS)
			state = RAID_STATE_RESYNCING;
		else {
			switch (ldev_info->state) {
			case MYRB_DEVICE_ONLINE:
				state = RAID_STATE_ACTIVE;
				break;
			case MYRB_DEVICE_WO:
			case MYRB_DEVICE_CRITICAL:
				state = RAID_STATE_DEGRADED;
				break;
			default:
				state = RAID_STATE_OFFLINE;
			}
		}
	}
	raid_set_state(myrb_raid_template, dev, state);
}

struct raid_function_template myrb_raid_functions = {
	.cookie		= &myrb_template,
	.is_raid	= myrb_is_raid,
	.get_resync	= myrb_get_resync,
	.get_state	= myrb_get_state,
};

static void myrb_handle_scsi(struct myrb_hba *cb, struct myrb_cmdblk *cmd_blk,
		struct scsi_cmnd *scmd)
{
	unsigned short status;

	if (!cmd_blk)
		return;

	scsi_dma_unmap(scmd);

	if (cmd_blk->dcdb) {
		memcpy(scmd->sense_buffer, &cmd_blk->dcdb->sense, 64);
		dma_pool_free(cb->dcdb_pool, cmd_blk->dcdb,
			      cmd_blk->dcdb_addr);
		cmd_blk->dcdb = NULL;
	}
	if (cmd_blk->sgl) {
		dma_pool_free(cb->sg_pool, cmd_blk->sgl, cmd_blk->sgl_addr);
		cmd_blk->sgl = NULL;
		cmd_blk->sgl_addr = 0;
	}
	status = cmd_blk->status;
	switch (status) {
	case MYRB_STATUS_SUCCESS:
	case MYRB_STATUS_DEVICE_BUSY:
		scmd->result = (DID_OK << 16) | status;
		break;
	case MYRB_STATUS_BAD_DATA:
		dev_dbg(&scmd->device->sdev_gendev,
			"Bad Data Encountered\n");
		if (scmd->sc_data_direction == DMA_FROM_DEVICE)
			/* Unrecovered read error */
			scsi_build_sense_buffer(0, scmd->sense_buffer,
						MEDIUM_ERROR, 0x11, 0);
		else
			/* Write error */
			scsi_build_sense_buffer(0, scmd->sense_buffer,
						MEDIUM_ERROR, 0x0C, 0);
		scmd->result = (DID_OK << 16) | SAM_STAT_CHECK_CONDITION;
		break;
	case MYRB_STATUS_IRRECOVERABLE_DATA_ERROR:
		scmd_printk(KERN_ERR, scmd, "Irrecoverable Data Error\n");
		if (scmd->sc_data_direction == DMA_FROM_DEVICE)
			/* Unrecovered read error, auto-reallocation failed */
			scsi_build_sense_buffer(0, scmd->sense_buffer,
						MEDIUM_ERROR, 0x11, 0x04);
		else
			/* Write error, auto-reallocation failed */
			scsi_build_sense_buffer(0, scmd->sense_buffer,
						MEDIUM_ERROR, 0x0C, 0x02);
		scmd->result = (DID_OK << 16) | SAM_STAT_CHECK_CONDITION;
		break;
	case MYRB_STATUS_LDRV_NONEXISTENT_OR_OFFLINE:
		dev_dbg(&scmd->device->sdev_gendev,
			    "Logical Drive Nonexistent or Offline");
		scmd->result = (DID_BAD_TARGET << 16);
		break;
	case MYRB_STATUS_ACCESS_BEYOND_END_OF_LDRV:
		dev_dbg(&scmd->device->sdev_gendev,
			    "Attempt to Access Beyond End of Logical Drive");
		/* Logical block address out of range */
		scsi_build_sense_buffer(0, scmd->sense_buffer,
					NOT_READY, 0x21, 0);
		break;
	case MYRB_STATUS_DEVICE_NONRESPONSIVE:
		dev_dbg(&scmd->device->sdev_gendev, "Device nonresponsive\n");
		scmd->result = (DID_BAD_TARGET << 16);
		break;
	default:
		scmd_printk(KERN_ERR, scmd,
			    "Unexpected Error Status %04X", status);
		scmd->result = (DID_ERROR << 16);
		break;
	}
	scmd->scsi_done(scmd);
}

static void myrb_handle_cmdblk(struct myrb_hba *cb, struct myrb_cmdblk *cmd_blk)
{
	if (!cmd_blk)
		return;

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

static void myrb_monitor(struct work_struct *work)
{
	struct myrb_hba *cb = container_of(work,
			struct myrb_hba, monitor_work.work);
	struct Scsi_Host *shost = cb->host;
	unsigned long interval = MYRB_PRIMARY_MONITOR_INTERVAL;

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

	if (cb->new_ev_seq > cb->old_ev_seq) {
		int event = cb->old_ev_seq;

		dev_dbg(&shost->shost_gendev,
			"get event log no %d/%d\n",
			cb->new_ev_seq, event);
		myrb_get_event(cb, event);
		cb->old_ev_seq = event + 1;
		interval = 10;
	} else if (cb->need_err_info) {
		cb->need_err_info = false;
		dev_dbg(&shost->shost_gendev, "get error table\n");
		myrb_get_errtable(cb);
		interval = 10;
	} else if (cb->need_rbld && cb->rbld_first) {
		cb->need_rbld = false;
		dev_dbg(&shost->shost_gendev,
			"get rebuild progress\n");
		myrb_update_rbld_progress(cb);
		interval = 10;
	} else if (cb->need_ldev_info) {
		cb->need_ldev_info = false;
		dev_dbg(&shost->shost_gendev,
			"get logical drive info\n");
		myrb_get_ldev_info(cb);
		interval = 10;
	} else if (cb->need_rbld) {
		cb->need_rbld = false;
		dev_dbg(&shost->shost_gendev,
			"get rebuild progress\n");
		myrb_update_rbld_progress(cb);
		interval = 10;
	} else if (cb->need_cc_status) {
		cb->need_cc_status = false;
		dev_dbg(&shost->shost_gendev,
			"get consistency check progress\n");
		myrb_get_cc_progress(cb);
		interval = 10;
	} else if (cb->need_bgi_status) {
		cb->need_bgi_status = false;
		dev_dbg(&shost->shost_gendev, "get background init status\n");
		myrb_bgi_control(cb);
		interval = 10;
	} else {
		dev_dbg(&shost->shost_gendev, "new enquiry\n");
		mutex_lock(&cb->dma_mutex);
		myrb_hba_enquiry(cb);
		mutex_unlock(&cb->dma_mutex);
		if ((cb->new_ev_seq - cb->old_ev_seq > 0) ||
		    cb->need_err_info || cb->need_rbld ||
		    cb->need_ldev_info || cb->need_cc_status ||
		    cb->need_bgi_status) {
			dev_dbg(&shost->shost_gendev,
				"reschedule monitor\n");
			interval = 0;
		}
	}
	if (interval > 1)
		cb->primary_monitor_time = jiffies;
	queue_delayed_work(cb->work_q, &cb->monitor_work, interval);
}

/**
 * myrb_err_status - reports controller BIOS messages
 *
 * Controller BIOS messages are passed through the Error Status Register
 * when the driver performs the BIOS handshaking.
 *
 * Return: true for fatal errors and false otherwise.
 */
bool myrb_err_status(struct myrb_hba *cb, unsigned char error,
		unsigned char parm0, unsigned char parm1)
{
	struct pci_dev *pdev = cb->pdev;

	switch (error) {
	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",
			error);
		return true;
	}
	return false;
}

/*
 * Hardware-specific functions
 */

/*
 * DAC960 LA Series Controllers
 */

static inline void DAC960_LA_hw_mbox_new_cmd(void __iomem *base)
{
	writeb(DAC960_LA_IDB_HWMBOX_NEW_CMD, base + DAC960_LA_IDB_OFFSET);
}

static inline void DAC960_LA_ack_hw_mbox_status(void __iomem *base)
{
	writeb(DAC960_LA_IDB_HWMBOX_ACK_STS, base + DAC960_LA_IDB_OFFSET);
}

static inline void DAC960_LA_gen_intr(void __iomem *base)
{
	writeb(DAC960_LA_IDB_GEN_IRQ, base + DAC960_LA_IDB_OFFSET);
}

static inline void DAC960_LA_reset_ctrl(void __iomem *base)
{
	writeb(DAC960_LA_IDB_CTRL_RESET, base + DAC960_LA_IDB_OFFSET);
}

static inline void DAC960_LA_mem_mbox_new_cmd(void __iomem *base)
{
	writeb(DAC960_LA_IDB_MMBOX_NEW_CMD, base + DAC960_LA_IDB_OFFSET);
}

static inline bool DAC960_LA_hw_mbox_is_full(void __iomem *base)
{
	unsigned char idb = readb(base + DAC960_LA_IDB_OFFSET);

	return !(idb & DAC960_LA_IDB_HWMBOX_EMPTY);
}

static inline bool DAC960_LA_init_in_progress(void __iomem *base)
{
	unsigned char idb = readb(base + DAC960_LA_IDB_OFFSET);

	return !(idb & DAC960_LA_IDB_INIT_DONE);
}

static inline void DAC960_LA_ack_hw_mbox_intr(void __iomem *base)
{
	writeb(DAC960_LA_ODB_HWMBOX_ACK_IRQ, base + DAC960_LA_ODB_OFFSET);
}

static inline void DAC960_LA_ack_mem_mbox_intr(void __iomem *base)
{
	writeb(DAC960_LA_ODB_MMBOX_ACK_IRQ, base + DAC960_LA_ODB_OFFSET);
}

static inline void DAC960_LA_ack_intr(void __iomem *base)
{
	writeb(DAC960_LA_ODB_HWMBOX_ACK_IRQ | DAC960_LA_ODB_MMBOX_ACK_IRQ,
	       base + DAC960_LA_ODB_OFFSET);
}

static inline bool DAC960_LA_hw_mbox_status_available(void __iomem *base)
{
	unsigned char odb = readb(base + DAC960_LA_ODB_OFFSET);

	return odb & DAC960_LA_ODB_HWMBOX_STS_AVAIL;
}

static inline bool DAC960_LA_mem_mbox_status_available(void __iomem *base)
{
	unsigned char odb = readb(base + DAC960_LA_ODB_OFFSET);

	return odb & DAC960_LA_ODB_MMBOX_STS_AVAIL;
}

static inline void DAC960_LA_enable_intr(void __iomem *base)
{
	unsigned char odb = 0xFF;

	odb &= ~DAC960_LA_IRQMASK_DISABLE_IRQ;
	writeb(odb, base + DAC960_LA_IRQMASK_OFFSET);
}

static inline void DAC960_LA_disable_intr(void __iomem *base)
{
	unsigned char odb = 0xFF;

	odb |= DAC960_LA_IRQMASK_DISABLE_IRQ;
	writeb(odb, base + DAC960_LA_IRQMASK_OFFSET);
}

static inline bool DAC960_LA_intr_enabled(void __iomem *base)
{
	unsigned char imask = readb(base + DAC960_LA_IRQMASK_OFFSET);

	return !(imask & DAC960_LA_IRQMASK_DISABLE_IRQ);
}

static inline void DAC960_LA_write_cmd_mbox(union myrb_cmd_mbox *mem_mbox,
		union myrb_cmd_mbox *mbox)
{
	mem_mbox->words[1] = mbox->words[1];
	mem_mbox->words[2] = mbox->words[2];
	mem_mbox->words[3] = mbox->words[3];
	/* Memory barrier to prevent reordering */
	wmb();
	mem_mbox->words[0] = mbox->words[0];
	/* Memory barrier to force PCI access */
	mb();
}

static inline void DAC960_LA_write_hw_mbox(void __iomem *base,
		union myrb_cmd_mbox *mbox)
{
	writel(mbox->words[0], base + DAC960_LA_CMDOP_OFFSET);
	writel(mbox->words[1], base + DAC960_LA_MBOX4_OFFSET);
	writel(mbox->words[2], base + DAC960_LA_MBOX8_OFFSET);
	writeb(mbox->bytes[12], base + DAC960_LA_MBOX12_OFFSET);
}

static inline unsigned char DAC960_LA_read_status_cmd_ident(void __iomem *base)
{
	return readb(base + DAC960_LA_STSID_OFFSET);
}

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

static inline bool
DAC960_LA_read_error_status(void __iomem *base, unsigned char *error,
		unsigned char *param0, unsigned char *param1)
{
	unsigned char errsts = readb(base + DAC960_LA_ERRSTS_OFFSET);

	if (!(errsts & DAC960_LA_ERRSTS_PENDING))
		return false;
	errsts &= ~DAC960_LA_ERRSTS_PENDING;

	*error = errsts;
	*param0 = readb(base + DAC960_LA_CMDOP_OFFSET);
	*param1 = readb(base + DAC960_LA_CMDID_OFFSET);
	writeb(0xFF, base + DAC960_LA_ERRSTS_OFFSET);
	return true;
}

static inline unsigned short
DAC960_LA_mbox_init(struct pci_dev *pdev, void __iomem *base,
		union myrb_cmd_mbox *mbox)
{
	unsigned short status;
	int timeout = 0;

	while (timeout < MYRB_MAILBOX_TIMEOUT) {
		if (!DAC960_LA_hw_mbox_is_full(base))
			break;
		udelay(10);
		timeout++;
	}
	if (DAC960_LA_hw_mbox_is_full(base)) {
		dev_err(&pdev->dev,
			"Timeout waiting for empty mailbox\n");
		return MYRB_STATUS_SUBSYS_TIMEOUT;
	}
	DAC960_LA_write_hw_mbox(base, mbox);
	DAC960_LA_hw_mbox_new_cmd(base);
	timeout = 0;
	while (timeout < MYRB_MAILBOX_TIMEOUT) {
		if (DAC960_LA_hw_mbox_status_available(base))
			break;
		udelay(10);
		timeout++;
	}
	if (!DAC960_LA_hw_mbox_status_available(base)) {
		dev_err(&pdev->dev, "Timeout waiting for mailbox status\n");
		return MYRB_STATUS_SUBSYS_TIMEOUT;
	}
	status = DAC960_LA_read_status(base);
	DAC960_LA_ack_hw_mbox_intr(base);
	DAC960_LA_ack_hw_mbox_status(base);

	return status;
}

static int DAC960_LA_hw_init(struct pci_dev *pdev,
		struct myrb_hba *cb, void __iomem *base)
{
	int timeout = 0;
	unsigned char error, parm0, parm1;

	DAC960_LA_disable_intr(base);
	DAC960_LA_ack_hw_mbox_status(base);
	udelay(1000);
	timeout = 0;
	while (DAC960_LA_init_in_progress(base) &&
	       timeout < MYRB_MAILBOX_TIMEOUT) {
		if (DAC960_LA_read_error_status(base, &error,
					      &parm0, &parm1) &&
		    myrb_err_status(cb, error, parm0, parm1))
			return -ENODEV;
		udelay(10);
		timeout++;
	}
	if (timeout == MYRB_MAILBOX_TIMEOUT) {
		dev_err(&pdev->dev,
			"Timeout waiting for Controller Initialisation\n");
		return -ETIMEDOUT;
	}
	if (!myrb_enable_mmio(cb, DAC960_LA_mbox_init)) {
		dev_err(&pdev->dev,
			"Unable to Enable Memory Mailbox Interface\n");
		DAC960_LA_reset_ctrl(base);
		return -ENODEV;
	}
	DAC960_LA_enable_intr(base);
	cb->qcmd = myrb_qcmd;
	cb->write_cmd_mbox = DAC960_LA_write_cmd_mbox;
	if (cb->dual_mode_interface)
		cb->get_cmd_mbox = DAC960_LA_mem_mbox_new_cmd;
	else
		cb->get_cmd_mbox = DAC960_LA_hw_mbox_new_cmd;
	cb->disable_intr = DAC960_LA_disable_intr;
	cb->reset = DAC960_LA_reset_ctrl;

	return 0;
}

static irqreturn_t DAC960_LA_intr_handler(int irq, void *arg)
{
	struct myrb_hba *cb = arg;
	void __iomem *base = cb->io_base;
	struct myrb_stat_mbox *next_stat_mbox;
	unsigned long flags;

	spin_lock_irqsave(&cb->queue_lock, flags);
	DAC960_LA_ack_intr(base);
	next_stat_mbox = cb->next_stat_mbox;
	while (next_stat_mbox->valid) {
		unsigned char id = next_stat_mbox->id;
		struct scsi_cmnd *scmd = NULL;
		struct myrb_cmdblk *cmd_blk = NULL;

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

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

		if (cmd_blk) {
			if (id < 3)
				myrb_handle_cmdblk(cb, cmd_blk);
			else
				myrb_handle_scsi(cb, cmd_blk, scmd);
		}
	}
	cb->next_stat_mbox = next_stat_mbox;
	spin_unlock_irqrestore(&cb->queue_lock, flags);
	return IRQ_HANDLED;
}

struct myrb_privdata DAC960_LA_privdata = {
	.hw_init =	DAC960_LA_hw_init,
	.irq_handler =	DAC960_LA_intr_handler,
	.mmio_size =	DAC960_LA_mmio_size,
};

/*
 * DAC960 PG Series Controllers
 */
static inline void DAC960_PG_hw_mbox_new_cmd(void __iomem *base)
{
	writel(DAC960_PG_IDB_HWMBOX_NEW_CMD, base + DAC960_PG_IDB_OFFSET);
}

static inline void DAC960_PG_ack_hw_mbox_status(void __iomem *base)
{
	writel(DAC960_PG_IDB_HWMBOX_ACK_STS, base + DAC960_PG_IDB_OFFSET);
}

static inline void DAC960_PG_gen_intr(void __iomem *base)
{
	writel(DAC960_PG_IDB_GEN_IRQ, base + DAC960_PG_IDB_OFFSET);
}

static inline void DAC960_PG_reset_ctrl(void __iomem *base)
{
	writel(DAC960_PG_IDB_CTRL_RESET, base + DAC960_PG_IDB_OFFSET);
}

static inline void DAC960_PG_mem_mbox_new_cmd(void __iomem *base)
{
	writel(DAC960_PG_IDB_MMBOX_NEW_CMD, base + DAC960_PG_IDB_OFFSET);
}

static inline bool DAC960_PG_hw_mbox_is_full(void __iomem *base)
{
	unsigned char idb = readl(base + DAC960_PG_IDB_OFFSET);

	return idb & DAC960_PG_IDB_HWMBOX_FULL;
}

static inline bool DAC960_PG_init_in_progress(void __iomem *base)
{
	unsigned char idb = readl(base + DAC960_PG_IDB_OFFSET);

	return idb & DAC960_PG_IDB_INIT_IN_PROGRESS;
}

static inline void DAC960_PG_ack_hw_mbox_intr(void __iomem *base)
{
	writel(DAC960_PG_ODB_HWMBOX_ACK_IRQ, base + DAC960_PG_ODB_OFFSET);
}

static inline void DAC960_PG_ack_mem_mbox_intr(void __iomem *base)
{
	writel(DAC960_PG_ODB_MMBOX_ACK_IRQ, base + DAC960_PG_ODB_OFFSET);
}

static inline void DAC960_PG_ack_intr(void __iomem *base)
{
	writel(DAC960_PG_ODB_HWMBOX_ACK_IRQ | DAC960_PG_ODB_MMBOX_ACK_IRQ,
	       base + DAC960_PG_ODB_OFFSET);
}

static inline bool DAC960_PG_hw_mbox_status_available(void __iomem *base)
{
	unsigned char odb = readl(base + DAC960_PG_ODB_OFFSET);

	return odb & DAC960_PG_ODB_HWMBOX_STS_AVAIL;
}

static inline bool DAC960_PG_mem_mbox_status_available(void __iomem *base)
{
	unsigned char odb = readl(base + DAC960_PG_ODB_OFFSET);

	return odb & DAC960_PG_ODB_MMBOX_STS_AVAIL;
}

static inline void DAC960_PG_enable_intr(void __iomem *base)
{
	unsigned int imask = (unsigned int)-1;

	imask &= ~DAC960_PG_IRQMASK_DISABLE_IRQ;
	writel(imask, base + DAC960_PG_IRQMASK_OFFSET);
}

static inline void DAC960_PG_disable_intr(void __iomem *base)
{
	unsigned int imask = (unsigned int)-1;

	writel(imask, base + DAC960_PG_IRQMASK_OFFSET);
}

static inline bool DAC960_PG_intr_enabled(void __iomem *base)
{
	unsigned int imask = readl(base + DAC960_PG_IRQMASK_OFFSET);

	return !(imask & DAC960_PG_IRQMASK_DISABLE_IRQ);
}

static inline void DAC960_PG_write_cmd_mbox(union myrb_cmd_mbox *mem_mbox,
		union myrb_cmd_mbox *mbox)
{
	mem_mbox->words[1] = mbox->words[1];
	mem_mbox->words[2] = mbox->words[2];
	mem_mbox->words[3] = mbox->words[3];
	/* Memory barrier to prevent reordering */
	wmb();
	mem_mbox->words[0] = mbox->words[0];
	/* Memory barrier to force PCI access */
	mb();
}

static inline void DAC960_PG_write_hw_mbox(void __iomem *base,
		union myrb_cmd_mbox *mbox)
{
	writel(mbox->words[0], base + DAC960_PG_CMDOP_OFFSET);
	writel(mbox->words[1], base + DAC960_PG_MBOX4_OFFSET);
	writel(mbox->words[2], base + DAC960_PG_MBOX8_OFFSET);
	writeb(mbox->bytes[12], base + DAC960_PG_MBOX12_OFFSET);
}

static inline unsigned char
DAC960_PG_read_status_cmd_ident(void __iomem *base)
{
	return readb(base + DAC960_PG_STSID_OFFSET);
}

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

static inline bool
DAC960_PG_read_error_status(void __iomem *base, unsigned char *error,
		unsigned char *param0, unsigned char *param1)
{
	unsigned char errsts = readb(base + DAC960_PG_ERRSTS_OFFSET);

	if (!(errsts & DAC960_PG_ERRSTS_PENDING))
		return false;
	errsts &= ~DAC960_PG_ERRSTS_PENDING;
	*error = errsts;
	*param0 = readb(base + DAC960_PG_CMDOP_OFFSET);
	*param1 = readb(base + DAC960_PG_CMDID_OFFSET);
	writeb(0, base + DAC960_PG_ERRSTS_OFFSET);
	return true;
}

static inline unsigned short
DAC960_PG_mbox_init(struct pci_dev *pdev, void __iomem *base,
		union myrb_cmd_mbox *mbox)
{
	unsigned short status;
	int timeout = 0;

	while (timeout < MYRB_MAILBOX_TIMEOUT) {
		if (!DAC960_PG_hw_mbox_is_full(base))
			break;
		udelay(10);
		timeout++;
	}
	if (DAC960_PG_hw_mbox_is_full(base)) {
		dev_err(&pdev->dev,
			"Timeout waiting for empty mailbox\n");
		return MYRB_STATUS_SUBSYS_TIMEOUT;
	}
	DAC960_PG_write_hw_mbox(base, mbox);
	DAC960_PG_hw_mbox_new_cmd(base);

	timeout = 0;
	while (timeout < MYRB_MAILBOX_TIMEOUT) {
		if (DAC960_PG_hw_mbox_status_available(base))
			break;
		udelay(10);
		timeout++;
	}
	if (!DAC960_PG_hw_mbox_status_available(base)) {
		dev_err(&pdev->dev,
			"Timeout waiting for mailbox status\n");
		return MYRB_STATUS_SUBSYS_TIMEOUT;
	}
	status = DAC960_PG_read_status(base);
	DAC960_PG_ack_hw_mbox_intr(base);
	DAC960_PG_ack_hw_mbox_status(base);

	return status;
}

static int DAC960_PG_hw_init(struct pci_dev *pdev,
		struct myrb_hba *cb, void __iomem *base)
{
	int timeout = 0;
	unsigned char error, parm0, parm1;

	DAC960_PG_disable_intr(base);
	DAC960_PG_ack_hw_mbox_status(base);
	udelay(1000);
	while (DAC960_PG_init_in_progress(base) &&
	       timeout < MYRB_MAILBOX_TIMEOUT) {
		if (DAC960_PG_read_error_status(base, &error,
						&parm0, &parm1) &&
		    myrb_err_status(cb, error, parm0, parm1))
			return -EIO;
		udelay(10);
		timeout++;
	}
	if (timeout == MYRB_MAILBOX_TIMEOUT) {
		dev_err(&pdev->dev,
			"Timeout waiting for Controller Initialisation\n");
		return -ETIMEDOUT;
	}
	if (!myrb_enable_mmio(cb, DAC960_PG_mbox_init)) {
		dev_err(&pdev->dev,
			"Unable to Enable Memory Mailbox Interface\n");
		DAC960_PG_reset_ctrl(base);
		return -ENODEV;
	}
	DAC960_PG_enable_intr(base);
	cb->qcmd = myrb_qcmd;
	cb->write_cmd_mbox = DAC960_PG_write_cmd_mbox;
	if (cb->dual_mode_interface)
		cb->get_cmd_mbox = DAC960_PG_mem_mbox_new_cmd;
	else
		cb->get_cmd_mbox = DAC960_PG_hw_mbox_new_cmd;
	cb->disable_intr = DAC960_PG_disable_intr;
	cb->reset = DAC960_PG_reset_ctrl;

	return 0;
}

static irqreturn_t DAC960_PG_intr_handler(int irq, void *arg)
{
	struct myrb_hba *cb = arg;
	void __iomem *base = cb->io_base;
	struct myrb_stat_mbox *next_stat_mbox;
	unsigned long flags;

	spin_lock_irqsave(&cb->queue_lock, flags);
	DAC960_PG_ack_intr(base);
	next_stat_mbox = cb->next_stat_mbox;
	while (next_stat_mbox->valid) {
		unsigned char id = next_stat_mbox->id;
		struct scsi_cmnd *scmd = NULL;
		struct myrb_cmdblk *cmd_blk = NULL;

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

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

		if (id < 3)
			myrb_handle_cmdblk(cb, cmd_blk);
		else
			myrb_handle_scsi(cb, cmd_blk, scmd);
	}
	cb->next_stat_mbox = next_stat_mbox;
	spin_unlock_irqrestore(&cb->queue_lock, flags);
	return IRQ_HANDLED;
}

struct myrb_privdata DAC960_PG_privdata = {
	.hw_init =	DAC960_PG_hw_init,
	.irq_handler =	DAC960_PG_intr_handler,
	.mmio_size =	DAC960_PG_mmio_size,
};


/*
 * DAC960 PD Series Controllers
 */

static inline void DAC960_PD_hw_mbox_new_cmd(void __iomem *base)
{
	writeb(DAC960_PD_IDB_HWMBOX_NEW_CMD, base + DAC960_PD_IDB_OFFSET);
}

static inline void DAC960_PD_ack_hw_mbox_status(void __iomem *base)
{
	writeb(DAC960_PD_IDB_HWMBOX_ACK_STS, base + DAC960_PD_IDB_OFFSET);
}

static inline void DAC960_PD_gen_intr(void __iomem *base)
{
	writeb(DAC960_PD_IDB_GEN_IRQ, base + DAC960_PD_IDB_OFFSET);
}

static inline void DAC960_PD_reset_ctrl(void __iomem *base)
{
	writeb(DAC960_PD_IDB_CTRL_RESET, base + DAC960_PD_IDB_OFFSET);
}

static inline bool DAC960_PD_hw_mbox_is_full(void __iomem *base)
{
	unsigned char idb = readb(base + DAC960_PD_IDB_OFFSET);

	return idb & DAC960_PD_IDB_HWMBOX_FULL;
}

static inline bool DAC960_PD_init_in_progress(void __iomem *base)
{
	unsigned char idb = readb(base + DAC960_PD_IDB_OFFSET);

	return idb & DAC960_PD_IDB_INIT_IN_PROGRESS;
}

static inline void DAC960_PD_ack_intr(void __iomem *base)
{
	writeb(DAC960_PD_ODB_HWMBOX_ACK_IRQ, base + DAC960_PD_ODB_OFFSET);
}

static inline bool DAC960_PD_hw_mbox_status_available(void __iomem *base)
{
	unsigned char odb = readb(base + DAC960_PD_ODB_OFFSET);

	return odb & DAC960_PD_ODB_HWMBOX_STS_AVAIL;
}

static inline void DAC960_PD_enable_intr(void __iomem *base)
{
	writeb(DAC960_PD_IRQMASK_ENABLE_IRQ, base + DAC960_PD_IRQEN_OFFSET);
}

static inline void DAC960_PD_disable_intr(void __iomem *base)
{
	writeb(0, base + DAC960_PD_IRQEN_OFFSET);
}

static inline bool DAC960_PD_intr_enabled(void __iomem *base)
{
	unsigned char imask = readb(base + DAC960_PD_IRQEN_OFFSET);

	return imask & DAC960_PD_IRQMASK_ENABLE_IRQ;
}

static inline void DAC960_PD_write_cmd_mbox(void __iomem *base,
		union myrb_cmd_mbox *mbox)
{
	writel(mbox->words[0], base + DAC960_PD_CMDOP_OFFSET);
	writel(mbox->words[1], base + DAC960_PD_MBOX4_OFFSET);
	writel(mbox->words[2], base + DAC960_PD_MBOX8_OFFSET);
	writeb(mbox->bytes[12], base + DAC960_PD_MBOX12_OFFSET);
}

static inline unsigned char
DAC960_PD_read_status_cmd_ident(void __iomem *base)
{
	return readb(base + DAC960_PD_STSID_OFFSET);
}

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

static inline bool
DAC960_PD_read_error_status(void __iomem *base, unsigned char *error,
		unsigned char *param0, unsigned char *param1)
{
	unsigned char errsts = readb(base + DAC960_PD_ERRSTS_OFFSET);

	if (!(errsts & DAC960_PD_ERRSTS_PENDING))
		return false;
	errsts &= ~DAC960_PD_ERRSTS_PENDING;
	*error = errsts;
	*param0 = readb(base + DAC960_PD_CMDOP_OFFSET);
	*param1 = readb(base + DAC960_PD_CMDID_OFFSET);
	writeb(0, base + DAC960_PD_ERRSTS_OFFSET);
	return true;
}

static void DAC960_PD_qcmd(struct myrb_hba *cb, struct myrb_cmdblk *cmd_blk)
{
	void __iomem *base = cb->io_base;
	union myrb_cmd_mbox *mbox = &cmd_blk->mbox;

	while (DAC960_PD_hw_mbox_is_full(base))
		udelay(1);
	DAC960_PD_write_cmd_mbox(base, mbox);
	DAC960_PD_hw_mbox_new_cmd(base);
}

static int DAC960_PD_hw_init(struct pci_dev *pdev,
		struct myrb_hba *cb, void __iomem *base)
{
	int timeout = 0;
	unsigned char error, parm0, parm1;

	if (!request_region(cb->io_addr, 0x80, "myrb")) {
		dev_err(&pdev->dev, "IO port 0x%lx busy\n",
			(unsigned long)cb->io_addr);
		return -EBUSY;
	}
	DAC960_PD_disable_intr(base);
	DAC960_PD_ack_hw_mbox_status(base);
	udelay(1000);
	while (DAC960_PD_init_in_progress(base) &&
	       timeout < MYRB_MAILBOX_TIMEOUT) {
		if (DAC960_PD_read_error_status(base, &error,
					      &parm0, &parm1) &&
		    myrb_err_status(cb, error, parm0, parm1))
			return -EIO;
		udelay(10);
		timeout++;
	}
	if (timeout == MYRB_MAILBOX_TIMEOUT) {
		dev_err(&pdev->dev,
			"Timeout waiting for Controller Initialisation\n");
		return -ETIMEDOUT;
	}
	if (!myrb_enable_mmio(cb, NULL)) {
		dev_err(&pdev->dev,
			"Unable to Enable Memory Mailbox Interface\n");
		DAC960_PD_reset_ctrl(base);
		return -ENODEV;
	}
	DAC960_PD_enable_intr(base);
	cb->qcmd = DAC960_PD_qcmd;
	cb->disable_intr = DAC960_PD_disable_intr;
	cb->reset = DAC960_PD_reset_ctrl;

	return 0;
}

static irqreturn_t DAC960_PD_intr_handler(int irq, void *arg)
{
	struct myrb_hba *cb = arg;
	void __iomem *base = cb->io_base;
	unsigned long flags;

	spin_lock_irqsave(&cb->queue_lock, flags);
	while (DAC960_PD_hw_mbox_status_available(base)) {
		unsigned char id = DAC960_PD_read_status_cmd_ident(base);
		struct scsi_cmnd *scmd = NULL;
		struct myrb_cmdblk *cmd_blk = NULL;

		if (id == MYRB_DCMD_TAG)
			cmd_blk = &cb->dcmd_blk;
		else if (id == MYRB_MCMD_TAG)
			cmd_blk = &cb->mcmd_blk;
		else {
			scmd = scsi_host_find_tag(cb->host, id - 3);
			if (scmd)
				cmd_blk = scsi_cmd_priv(scmd);
		}
		if (cmd_blk)
			cmd_blk->status = DAC960_PD_read_status(base);
		else
			dev_err(&cb->pdev->dev,
				"Unhandled command completion %d\n", id);

		DAC960_PD_ack_intr(base);
		DAC960_PD_ack_hw_mbox_status(base);

		if (id < 3)
			myrb_handle_cmdblk(cb, cmd_blk);
		else
			myrb_handle_scsi(cb, cmd_blk, scmd);
	}
	spin_unlock_irqrestore(&cb->queue_lock, flags);
	return IRQ_HANDLED;
}

struct myrb_privdata DAC960_PD_privdata = {
	.hw_init =	DAC960_PD_hw_init,
	.irq_handler =	DAC960_PD_intr_handler,
	.mmio_size =	DAC960_PD_mmio_size,
};


/*
 * DAC960 P Series Controllers
 *
 * Similar to the DAC960 PD Series Controllers, but some commands have
 * to be translated.
 */

static inline void myrb_translate_enquiry(void *enq)
{
	memcpy(enq + 132, enq + 36, 64);
	memset(enq + 36, 0, 96);
}

static inline void myrb_translate_devstate(void *state)
{
	memcpy(state + 2, state + 3, 1);
	memmove(state + 4, state + 5, 2);
	memmove(state + 6, state + 8, 4);
}

static inline void myrb_translate_to_rw_command(struct myrb_cmdblk *cmd_blk)
{
	union myrb_cmd_mbox *mbox = &cmd_blk->mbox;
	int ldev_num = mbox->type5.ld.ldev_num;

	mbox->bytes[3] &= 0x7;
	mbox->bytes[3] |= mbox->bytes[7] << 6;
	mbox->bytes[7] = ldev_num;
}

static inline void myrb_translate_from_rw_command(struct myrb_cmdblk *cmd_blk)
{
	union myrb_cmd_mbox *mbox = &cmd_blk->mbox;
	int ldev_num = mbox->bytes[7];

	mbox->bytes[7] = mbox->bytes[3] >> 6;
	mbox->bytes[3] &= 0x7;
	mbox->bytes[3] |= ldev_num << 3;
}

static void DAC960_P_qcmd(struct myrb_hba *cb, struct myrb_cmdblk *cmd_blk)
{
	void __iomem *base = cb->io_base;
	union myrb_cmd_mbox *mbox = &cmd_blk->mbox;

	switch (mbox->common.opcode) {
	case MYRB_CMD_ENQUIRY:
		mbox->common.opcode = MYRB_CMD_ENQUIRY_OLD;
		break;
	case MYRB_CMD_GET_DEVICE_STATE:
		mbox->common.opcode = MYRB_CMD_GET_DEVICE_STATE_OLD;
		break;
	case MYRB_CMD_READ:
		mbox->common.opcode = MYRB_CMD_READ_OLD;
		myrb_translate_to_rw_command(cmd_blk);
		break;
	case MYRB_CMD_WRITE:
		mbox->common.opcode = MYRB_CMD_WRITE_OLD;
		myrb_translate_to_rw_command(cmd_blk);
		break;
	case MYRB_CMD_READ_SG:
		mbox->common.opcode = MYRB_CMD_READ_SG_OLD;
		myrb_translate_to_rw_command(cmd_blk);
		break;
	case MYRB_CMD_WRITE_SG:
		mbox->common.opcode = MYRB_CMD_WRITE_SG_OLD;
		myrb_translate_to_rw_command(cmd_blk);
		break;
	default:
		break;
	}
	while (DAC960_PD_hw_mbox_is_full(base))
		udelay(1);
	DAC960_PD_write_cmd_mbox(base, mbox);
	DAC960_PD_hw_mbox_new_cmd(base);
}


static int DAC960_P_hw_init(struct pci_dev *pdev,
		struct myrb_hba *cb, void __iomem *base)
{
	int timeout = 0;
	unsigned char error, parm0, parm1;

	if (!request_region(cb->io_addr, 0x80, "myrb")) {
		dev_err(&pdev->dev, "IO port 0x%lx busy\n",
			(unsigned long)cb->io_addr);
		return -EBUSY;
	}
	DAC960_PD_disable_intr(base);
	DAC960_PD_ack_hw_mbox_status(base);
	udelay(1000);
	while (DAC960_PD_init_in_progress(base) &&
	       timeout < MYRB_MAILBOX_TIMEOUT) {
		if (DAC960_PD_read_error_status(base, &error,
						&parm0, &parm1) &&
		    myrb_err_status(cb, error, parm0, parm1))
			return -EAGAIN;
		udelay(10);
		timeout++;
	}
	if (timeout == MYRB_MAILBOX_TIMEOUT) {
		dev_err(&pdev->dev,
			"Timeout waiting for Controller Initialisation\n");
		return -ETIMEDOUT;
	}
	if (!myrb_enable_mmio(cb, NULL)) {
		dev_err(&pdev->dev,
			"Unable to allocate DMA mapped memory\n");
		DAC960_PD_reset_ctrl(base);
		return -ETIMEDOUT;
	}
	DAC960_PD_enable_intr(base);
	cb->qcmd = DAC960_P_qcmd;
	cb->disable_intr = DAC960_PD_disable_intr;
	cb->reset = DAC960_PD_reset_ctrl;

	return 0;
}

static irqreturn_t DAC960_P_intr_handler(int irq, void *arg)
{
	struct myrb_hba *cb = arg;
	void __iomem *base = cb->io_base;
	unsigned long flags;

	spin_lock_irqsave(&cb->queue_lock, flags);
	while (DAC960_PD_hw_mbox_status_available(base)) {
		unsigned char id = DAC960_PD_read_status_cmd_ident(base);
		struct scsi_cmnd *scmd = NULL;
		struct myrb_cmdblk *cmd_blk = NULL;
		union myrb_cmd_mbox *mbox;
		enum myrb_cmd_opcode op;


		if (id == MYRB_DCMD_TAG)
			cmd_blk = &cb->dcmd_blk;
		else if (id == MYRB_MCMD_TAG)
			cmd_blk = &cb->mcmd_blk;
		else {
			scmd = scsi_host_find_tag(cb->host, id - 3);
			if (scmd)
				cmd_blk = scsi_cmd_priv(scmd);
		}
		if (cmd_blk)
			cmd_blk->status = DAC960_PD_read_status(base);
		else
			dev_err(&cb->pdev->dev,
				"Unhandled command completion %d\n", id);

		DAC960_PD_ack_intr(base);
		DAC960_PD_ack_hw_mbox_status(base);

		if (!cmd_blk)
			continue;

		mbox = &cmd_blk->mbox;
		op = mbox->common.opcode;
		switch (op) {
		case MYRB_CMD_ENQUIRY_OLD:
			mbox->common.opcode = MYRB_CMD_ENQUIRY;
			myrb_translate_enquiry(cb->enquiry);
			break;
		case MYRB_CMD_READ_OLD:
			mbox->common.opcode = MYRB_CMD_READ;
			myrb_translate_from_rw_command(cmd_blk);
			break;
		case MYRB_CMD_WRITE_OLD:
			mbox->common.opcode = MYRB_CMD_WRITE;
			myrb_translate_from_rw_command(cmd_blk);
			break;
		case MYRB_CMD_READ_SG_OLD:
			mbox->common.opcode = MYRB_CMD_READ_SG;
			myrb_translate_from_rw_command(cmd_blk);
			break;
		case MYRB_CMD_WRITE_SG_OLD:
			mbox->common.opcode = MYRB_CMD_WRITE_SG;
			myrb_translate_from_rw_command(cmd_blk);
			break;
		default:
			break;
		}
		if (id < 3)
			myrb_handle_cmdblk(cb, cmd_blk);
		else
			myrb_handle_scsi(cb, cmd_blk, scmd);
	}
	spin_unlock_irqrestore(&cb->queue_lock, flags);
	return IRQ_HANDLED;
}

struct myrb_privdata DAC960_P_privdata = {
	.hw_init =	DAC960_P_hw_init,
	.irq_handler =	DAC960_P_intr_handler,
	.mmio_size =	DAC960_PD_mmio_size,
};

static struct myrb_hba *myrb_detect(struct pci_dev *pdev,
		const struct pci_device_id *entry)
{
	struct myrb_privdata *privdata =
		(struct myrb_privdata *)entry->driver_data;
	irq_handler_t irq_handler = privdata->irq_handler;
	unsigned int mmio_size = privdata->mmio_size;
	struct Scsi_Host *shost;
	struct myrb_hba *cb = NULL;

	shost = scsi_host_alloc(&myrb_template, sizeof(struct myrb_hba));
	if (!shost) {
		dev_err(&pdev->dev, "Unable to allocate Controller\n");
		return NULL;
	}
	shost->max_cmd_len = 12;
	shost->max_lun = 256;
	cb = shost_priv(shost);
	mutex_init(&cb->dcmd_mutex);
	mutex_init(&cb->dma_mutex);
	cb->pdev = pdev;

	if (pci_enable_device(pdev))
		goto failure;

	if (privdata->hw_init == DAC960_PD_hw_init ||
	    privdata->hw_init == DAC960_P_hw_init) {
		cb->io_addr = pci_resource_start(pdev, 0);
		cb->pci_addr = pci_resource_start(pdev, 1);
	} else
		cb->pci_addr = pci_resource_start(pdev, 0);

	pci_set_drvdata(pdev, cb);
	spin_lock_init(&cb->queue_lock);
	if (mmio_size < PAGE_SIZE)
		mmio_size = PAGE_SIZE;
	cb->mmio_base = ioremap(cb->pci_addr & PAGE_MASK, mmio_size);
	if (cb->mmio_base == NULL) {
		dev_err(&pdev->dev,
			"Unable to map Controller Register Window\n");
		goto failure;
	}

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

	if (request_irq(pdev->irq, irq_handler, IRQF_SHARED, "myrb", cb) < 0) {
		dev_err(&pdev->dev,
			"Unable to acquire IRQ Channel %d\n", pdev->irq);
		goto failure;
	}
	cb->irq = pdev->irq;
	return cb;

failure:
	dev_err(&pdev->dev,
		"Failed to initialize Controller\n");
	myrb_cleanup(cb);
	return NULL;
}

static int myrb_probe(struct pci_dev *dev, const struct pci_device_id *entry)
{
	struct myrb_hba *cb;
	int ret;

	cb = myrb_detect(dev, entry);
	if (!cb)
		return -ENODEV;

	ret = myrb_get_hba_config(cb);
	if (ret < 0) {
		myrb_cleanup(cb);
		return ret;
	}

	if (!myrb_create_mempools(dev, cb)) {
		ret = -ENOMEM;
		goto failed;
	}

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


static void myrb_remove(struct pci_dev *pdev)
{
	struct myrb_hba *cb = pci_get_drvdata(pdev);

	shost_printk(KERN_NOTICE, cb->host, "Flushing Cache...");
	myrb_exec_type3(cb, MYRB_CMD_FLUSH, 0);
	myrb_cleanup(cb);
	myrb_destroy_mempools(cb);
}


static const struct pci_device_id myrb_id_table[] = {
	{
		PCI_DEVICE_SUB(PCI_VENDOR_ID_DEC,
			       PCI_DEVICE_ID_DEC_21285,
			       PCI_VENDOR_ID_MYLEX,
			       PCI_DEVICE_ID_MYLEX_DAC960_LA),
		.driver_data	= (unsigned long) &DAC960_LA_privdata,
	},
	{
		PCI_DEVICE_DATA(MYLEX, DAC960_PG, &DAC960_PG_privdata),
	},
	{
		PCI_DEVICE_DATA(MYLEX, DAC960_PD, &DAC960_PD_privdata),
	},
	{
		PCI_DEVICE_DATA(MYLEX, DAC960_P, &DAC960_P_privdata),
	},
	{0, },
};

MODULE_DEVICE_TABLE(pci, myrb_id_table);

static struct pci_driver myrb_pci_driver = {
	.name		= "myrb",
	.id_table	= myrb_id_table,
	.probe		= myrb_probe,
	.remove		= myrb_remove,
};

static int __init myrb_init_module(void)
{
	int ret;

	myrb_raid_template = raid_class_attach(&myrb_raid_functions);
	if (!myrb_raid_template)
		return -ENODEV;

	ret = pci_register_driver(&myrb_pci_driver);
	if (ret)
		raid_class_release(myrb_raid_template);

	return ret;
}

static void __exit myrb_cleanup_module(void)
{
	pci_unregister_driver(&myrb_pci_driver);
	raid_class_release(myrb_raid_template);
}

module_init(myrb_init_module);
module_exit(myrb_cleanup_module);

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