// SPDX-License-Identifier: GPL-2.0-only
/*
 * Marvell UMI driver
 *
 * Copyright 2011 Marvell. <jyli@marvell.com>
*/

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/pci.h>
#include <linux/list.h>
#include <linux/spinlock.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/ktime.h>
#include <linux/blkdev.h>
#include <linux/io.h>
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_transport.h>
#include <scsi/scsi_eh.h>
#include <linux/uaccess.h>
#include <linux/kthread.h>

#include "mvumi.h"

MODULE_LICENSE("GPL");
MODULE_AUTHOR("jyli@marvell.com");
MODULE_DESCRIPTION("Marvell UMI Driver");

static const struct pci_device_id mvumi_pci_table[] = {
	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, PCI_DEVICE_ID_MARVELL_MV9143) },
	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, PCI_DEVICE_ID_MARVELL_MV9580) },
	{ 0 }
};

MODULE_DEVICE_TABLE(pci, mvumi_pci_table);

static void tag_init(struct mvumi_tag *st, unsigned short size)
{
	unsigned short i;
	BUG_ON(size != st->size);
	st->top = size;
	for (i = 0; i < size; i++)
		st->stack[i] = size - 1 - i;
}

static unsigned short tag_get_one(struct mvumi_hba *mhba, struct mvumi_tag *st)
{
	BUG_ON(st->top <= 0);
	return st->stack[--st->top];
}

static void tag_release_one(struct mvumi_hba *mhba, struct mvumi_tag *st,
							unsigned short tag)
{
	BUG_ON(st->top >= st->size);
	st->stack[st->top++] = tag;
}

static bool tag_is_empty(struct mvumi_tag *st)
{
	if (st->top == 0)
		return true;
	else
		return false;
}

static void mvumi_unmap_pci_addr(struct pci_dev *dev, void **addr_array)
{
	int i;

	for (i = 0; i < MAX_BASE_ADDRESS; i++)
		if ((pci_resource_flags(dev, i) & IORESOURCE_MEM) &&
								addr_array[i])
			pci_iounmap(dev, addr_array[i]);
}

static int mvumi_map_pci_addr(struct pci_dev *dev, void **addr_array)
{
	int i;

	for (i = 0; i < MAX_BASE_ADDRESS; i++) {
		if (pci_resource_flags(dev, i) & IORESOURCE_MEM) {
			addr_array[i] = pci_iomap(dev, i, 0);
			if (!addr_array[i]) {
				dev_err(&dev->dev, "failed to map Bar[%d]\n",
									i);
				mvumi_unmap_pci_addr(dev, addr_array);
				return -ENOMEM;
			}
		} else
			addr_array[i] = NULL;

		dev_dbg(&dev->dev, "Bar %d : %p.\n", i, addr_array[i]);
	}

	return 0;
}

static struct mvumi_res *mvumi_alloc_mem_resource(struct mvumi_hba *mhba,
				enum resource_type type, unsigned int size)
{
	struct mvumi_res *res = kzalloc(sizeof(*res), GFP_ATOMIC);

	if (!res) {
		dev_err(&mhba->pdev->dev,
			"Failed to allocate memory for resource manager.\n");
		return NULL;
	}

	switch (type) {
	case RESOURCE_CACHED_MEMORY:
		res->virt_addr = kzalloc(size, GFP_ATOMIC);
		if (!res->virt_addr) {
			dev_err(&mhba->pdev->dev,
				"unable to allocate memory,size = %d.\n", size);
			kfree(res);
			return NULL;
		}
		break;

	case RESOURCE_UNCACHED_MEMORY:
		size = round_up(size, 8);
		res->virt_addr = dma_alloc_coherent(&mhba->pdev->dev, size,
						    &res->bus_addr,
						    GFP_KERNEL);
		if (!res->virt_addr) {
			dev_err(&mhba->pdev->dev,
					"unable to allocate consistent mem,"
							"size = %d.\n", size);
			kfree(res);
			return NULL;
		}
		break;

	default:
		dev_err(&mhba->pdev->dev, "unknown resource type %d.\n", type);
		kfree(res);
		return NULL;
	}

	res->type = type;
	res->size = size;
	INIT_LIST_HEAD(&res->entry);
	list_add_tail(&res->entry, &mhba->res_list);

	return res;
}

static void mvumi_release_mem_resource(struct mvumi_hba *mhba)
{
	struct mvumi_res *res, *tmp;

	list_for_each_entry_safe(res, tmp, &mhba->res_list, entry) {
		switch (res->type) {
		case RESOURCE_UNCACHED_MEMORY:
			dma_free_coherent(&mhba->pdev->dev, res->size,
						res->virt_addr, res->bus_addr);
			break;
		case RESOURCE_CACHED_MEMORY:
			kfree(res->virt_addr);
			break;
		default:
			dev_err(&mhba->pdev->dev,
				"unknown resource type %d\n", res->type);
			break;
		}
		list_del(&res->entry);
		kfree(res);
	}
	mhba->fw_flag &= ~MVUMI_FW_ALLOC;
}

/**
 * mvumi_make_sgl -	Prepares  SGL
 * @mhba:		Adapter soft state
 * @scmd:		SCSI command from the mid-layer
 * @sgl_p:		SGL to be filled in
 * @sg_count:		return the number of SG elements
 *
 * If successful, this function returns 0. otherwise, it returns -1.
 */
static int mvumi_make_sgl(struct mvumi_hba *mhba, struct scsi_cmnd *scmd,
					void *sgl_p, unsigned char *sg_count)
{
	struct scatterlist *sg;
	struct mvumi_sgl *m_sg = (struct mvumi_sgl *) sgl_p;
	unsigned int i;
	unsigned int sgnum = scsi_sg_count(scmd);
	dma_addr_t busaddr;

	*sg_count = dma_map_sg(&mhba->pdev->dev, scsi_sglist(scmd), sgnum,
			       scmd->sc_data_direction);
	if (*sg_count > mhba->max_sge) {
		dev_err(&mhba->pdev->dev,
			"sg count[0x%x] is bigger than max sg[0x%x].\n",
			*sg_count, mhba->max_sge);
		dma_unmap_sg(&mhba->pdev->dev, scsi_sglist(scmd), sgnum,
			     scmd->sc_data_direction);
		return -1;
	}
	scsi_for_each_sg(scmd, sg, *sg_count, i) {
		busaddr = sg_dma_address(sg);
		m_sg->baseaddr_l = cpu_to_le32(lower_32_bits(busaddr));
		m_sg->baseaddr_h = cpu_to_le32(upper_32_bits(busaddr));
		m_sg->flags = 0;
		sgd_setsz(mhba, m_sg, cpu_to_le32(sg_dma_len(sg)));
		if ((i + 1) == *sg_count)
			m_sg->flags |= 1U << mhba->eot_flag;

		sgd_inc(mhba, m_sg);
	}

	return 0;
}

static int mvumi_internal_cmd_sgl(struct mvumi_hba *mhba, struct mvumi_cmd *cmd,
							unsigned int size)
{
	struct mvumi_sgl *m_sg;
	void *virt_addr;
	dma_addr_t phy_addr;

	if (size == 0)
		return 0;

	virt_addr = dma_alloc_coherent(&mhba->pdev->dev, size, &phy_addr,
				       GFP_KERNEL);
	if (!virt_addr)
		return -1;

	m_sg = (struct mvumi_sgl *) &cmd->frame->payload[0];
	cmd->frame->sg_counts = 1;
	cmd->data_buf = virt_addr;

	m_sg->baseaddr_l = cpu_to_le32(lower_32_bits(phy_addr));
	m_sg->baseaddr_h = cpu_to_le32(upper_32_bits(phy_addr));
	m_sg->flags = 1U << mhba->eot_flag;
	sgd_setsz(mhba, m_sg, cpu_to_le32(size));

	return 0;
}

static struct mvumi_cmd *mvumi_create_internal_cmd(struct mvumi_hba *mhba,
				unsigned int buf_size)
{
	struct mvumi_cmd *cmd;

	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
	if (!cmd) {
		dev_err(&mhba->pdev->dev, "failed to create a internal cmd\n");
		return NULL;
	}
	INIT_LIST_HEAD(&cmd->queue_pointer);

	cmd->frame = dma_alloc_coherent(&mhba->pdev->dev, mhba->ib_max_size,
			&cmd->frame_phys, GFP_KERNEL);
	if (!cmd->frame) {
		dev_err(&mhba->pdev->dev, "failed to allocate memory for FW"
			" frame,size = %d.\n", mhba->ib_max_size);
		kfree(cmd);
		return NULL;
	}

	if (buf_size) {
		if (mvumi_internal_cmd_sgl(mhba, cmd, buf_size)) {
			dev_err(&mhba->pdev->dev, "failed to allocate memory"
						" for internal frame\n");
			dma_free_coherent(&mhba->pdev->dev, mhba->ib_max_size,
					cmd->frame, cmd->frame_phys);
			kfree(cmd);
			return NULL;
		}
	} else
		cmd->frame->sg_counts = 0;

	return cmd;
}

static void mvumi_delete_internal_cmd(struct mvumi_hba *mhba,
						struct mvumi_cmd *cmd)
{
	struct mvumi_sgl *m_sg;
	unsigned int size;
	dma_addr_t phy_addr;

	if (cmd && cmd->frame) {
		if (cmd->frame->sg_counts) {
			m_sg = (struct mvumi_sgl *) &cmd->frame->payload[0];
			sgd_getsz(mhba, m_sg, size);

			phy_addr = (dma_addr_t) m_sg->baseaddr_l |
				(dma_addr_t) ((m_sg->baseaddr_h << 16) << 16);

			dma_free_coherent(&mhba->pdev->dev, size, cmd->data_buf,
								phy_addr);
		}
		dma_free_coherent(&mhba->pdev->dev, mhba->ib_max_size,
				cmd->frame, cmd->frame_phys);
		kfree(cmd);
	}
}

/**
 * mvumi_get_cmd -	Get a command from the free pool
 * @mhba:		Adapter soft state
 *
 * Returns a free command from the pool
 */
static struct mvumi_cmd *mvumi_get_cmd(struct mvumi_hba *mhba)
{
	struct mvumi_cmd *cmd = NULL;

	if (likely(!list_empty(&mhba->cmd_pool))) {
		cmd = list_entry((&mhba->cmd_pool)->next,
				struct mvumi_cmd, queue_pointer);
		list_del_init(&cmd->queue_pointer);
	} else
		dev_warn(&mhba->pdev->dev, "command pool is empty!\n");

	return cmd;
}

/**
 * mvumi_return_cmd -	Return a cmd to free command pool
 * @mhba:		Adapter soft state
 * @cmd:		Command packet to be returned to free command pool
 */
static inline void mvumi_return_cmd(struct mvumi_hba *mhba,
						struct mvumi_cmd *cmd)
{
	cmd->scmd = NULL;
	list_add_tail(&cmd->queue_pointer, &mhba->cmd_pool);
}

/**
 * mvumi_free_cmds -	Free all the cmds in the free cmd pool
 * @mhba:		Adapter soft state
 */
static void mvumi_free_cmds(struct mvumi_hba *mhba)
{
	struct mvumi_cmd *cmd;

	while (!list_empty(&mhba->cmd_pool)) {
		cmd = list_first_entry(&mhba->cmd_pool, struct mvumi_cmd,
							queue_pointer);
		list_del(&cmd->queue_pointer);
		if (!(mhba->hba_capability & HS_CAPABILITY_SUPPORT_DYN_SRC))
			kfree(cmd->frame);
		kfree(cmd);
	}
}

/**
 * mvumi_alloc_cmds -	Allocates the command packets
 * @mhba:		Adapter soft state
 *
 */
static int mvumi_alloc_cmds(struct mvumi_hba *mhba)
{
	int i;
	struct mvumi_cmd *cmd;

	for (i = 0; i < mhba->max_io; i++) {
		cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
		if (!cmd)
			goto err_exit;

		INIT_LIST_HEAD(&cmd->queue_pointer);
		list_add_tail(&cmd->queue_pointer, &mhba->cmd_pool);
		if (mhba->hba_capability & HS_CAPABILITY_SUPPORT_DYN_SRC) {
			cmd->frame = mhba->ib_frame + i * mhba->ib_max_size;
			cmd->frame_phys = mhba->ib_frame_phys
						+ i * mhba->ib_max_size;
		} else
			cmd->frame = kzalloc(mhba->ib_max_size, GFP_KERNEL);
		if (!cmd->frame)
			goto err_exit;
	}
	return 0;

err_exit:
	dev_err(&mhba->pdev->dev,
			"failed to allocate memory for cmd[0x%x].\n", i);
	while (!list_empty(&mhba->cmd_pool)) {
		cmd = list_first_entry(&mhba->cmd_pool, struct mvumi_cmd,
						queue_pointer);
		list_del(&cmd->queue_pointer);
		if (!(mhba->hba_capability & HS_CAPABILITY_SUPPORT_DYN_SRC))
			kfree(cmd->frame);
		kfree(cmd);
	}
	return -ENOMEM;
}

static unsigned int mvumi_check_ib_list_9143(struct mvumi_hba *mhba)
{
	unsigned int ib_rp_reg;
	struct mvumi_hw_regs *regs = mhba->regs;

	ib_rp_reg = ioread32(mhba->regs->inb_read_pointer);

	if (unlikely(((ib_rp_reg & regs->cl_slot_num_mask) ==
			(mhba->ib_cur_slot & regs->cl_slot_num_mask)) &&
			((ib_rp_reg & regs->cl_pointer_toggle)
			 != (mhba->ib_cur_slot & regs->cl_pointer_toggle)))) {
		dev_warn(&mhba->pdev->dev, "no free slot to use.\n");
		return 0;
	}
	if (atomic_read(&mhba->fw_outstanding) >= mhba->max_io) {
		dev_warn(&mhba->pdev->dev, "firmware io overflow.\n");
		return 0;
	} else {
		return mhba->max_io - atomic_read(&mhba->fw_outstanding);
	}
}

static unsigned int mvumi_check_ib_list_9580(struct mvumi_hba *mhba)
{
	unsigned int count;
	if (atomic_read(&mhba->fw_outstanding) >= (mhba->max_io - 1))
		return 0;
	count = ioread32(mhba->ib_shadow);
	if (count == 0xffff)
		return 0;
	return count;
}

static void mvumi_get_ib_list_entry(struct mvumi_hba *mhba, void **ib_entry)
{
	unsigned int cur_ib_entry;

	cur_ib_entry = mhba->ib_cur_slot & mhba->regs->cl_slot_num_mask;
	cur_ib_entry++;
	if (cur_ib_entry >= mhba->list_num_io) {
		cur_ib_entry -= mhba->list_num_io;
		mhba->ib_cur_slot ^= mhba->regs->cl_pointer_toggle;
	}
	mhba->ib_cur_slot &= ~mhba->regs->cl_slot_num_mask;
	mhba->ib_cur_slot |= (cur_ib_entry & mhba->regs->cl_slot_num_mask);
	if (mhba->hba_capability & HS_CAPABILITY_SUPPORT_DYN_SRC) {
		*ib_entry = mhba->ib_list + cur_ib_entry *
				sizeof(struct mvumi_dyn_list_entry);
	} else {
		*ib_entry = mhba->ib_list + cur_ib_entry * mhba->ib_max_size;
	}
	atomic_inc(&mhba->fw_outstanding);
}

static void mvumi_send_ib_list_entry(struct mvumi_hba *mhba)
{
	iowrite32(0xffff, mhba->ib_shadow);
	iowrite32(mhba->ib_cur_slot, mhba->regs->inb_write_pointer);
}

static char mvumi_check_ob_frame(struct mvumi_hba *mhba,
		unsigned int cur_obf, struct mvumi_rsp_frame *p_outb_frame)
{
	unsigned short tag, request_id;

	udelay(1);
	p_outb_frame = mhba->ob_list + cur_obf * mhba->ob_max_size;
	request_id = p_outb_frame->request_id;
	tag = p_outb_frame->tag;
	if (tag > mhba->tag_pool.size) {
		dev_err(&mhba->pdev->dev, "ob frame data error\n");
		return -1;
	}
	if (mhba->tag_cmd[tag] == NULL) {
		dev_err(&mhba->pdev->dev, "tag[0x%x] with NO command\n", tag);
		return -1;
	} else if (mhba->tag_cmd[tag]->request_id != request_id &&
						mhba->request_id_enabled) {
			dev_err(&mhba->pdev->dev, "request ID from FW:0x%x,"
					"cmd request ID:0x%x\n", request_id,
					mhba->tag_cmd[tag]->request_id);
			return -1;
	}

	return 0;
}

static int mvumi_check_ob_list_9143(struct mvumi_hba *mhba,
			unsigned int *cur_obf, unsigned int *assign_obf_end)
{
	unsigned int ob_write, ob_write_shadow;
	struct mvumi_hw_regs *regs = mhba->regs;

	do {
		ob_write = ioread32(regs->outb_copy_pointer);
		ob_write_shadow = ioread32(mhba->ob_shadow);
	} while ((ob_write & regs->cl_slot_num_mask) != ob_write_shadow);

	*cur_obf = mhba->ob_cur_slot & mhba->regs->cl_slot_num_mask;
	*assign_obf_end = ob_write & mhba->regs->cl_slot_num_mask;

	if ((ob_write & regs->cl_pointer_toggle) !=
			(mhba->ob_cur_slot & regs->cl_pointer_toggle)) {
		*assign_obf_end += mhba->list_num_io;
	}
	return 0;
}

static int mvumi_check_ob_list_9580(struct mvumi_hba *mhba,
			unsigned int *cur_obf, unsigned int *assign_obf_end)
{
	unsigned int ob_write;
	struct mvumi_hw_regs *regs = mhba->regs;

	ob_write = ioread32(regs->outb_read_pointer);
	ob_write = ioread32(regs->outb_copy_pointer);
	*cur_obf = mhba->ob_cur_slot & mhba->regs->cl_slot_num_mask;
	*assign_obf_end = ob_write & mhba->regs->cl_slot_num_mask;
	if (*assign_obf_end < *cur_obf)
		*assign_obf_end += mhba->list_num_io;
	else if (*assign_obf_end == *cur_obf)
		return -1;
	return 0;
}

static void mvumi_receive_ob_list_entry(struct mvumi_hba *mhba)
{
	unsigned int cur_obf, assign_obf_end, i;
	struct mvumi_ob_data *ob_data;
	struct mvumi_rsp_frame *p_outb_frame;
	struct mvumi_hw_regs *regs = mhba->regs;

	if (mhba->instancet->check_ob_list(mhba, &cur_obf, &assign_obf_end))
		return;

	for (i = (assign_obf_end - cur_obf); i != 0; i--) {
		cur_obf++;
		if (cur_obf >= mhba->list_num_io) {
			cur_obf -= mhba->list_num_io;
			mhba->ob_cur_slot ^= regs->cl_pointer_toggle;
		}

		p_outb_frame = mhba->ob_list + cur_obf * mhba->ob_max_size;

		/* Copy pointer may point to entry in outbound list
		*  before entry has valid data
		*/
		if (unlikely(p_outb_frame->tag > mhba->tag_pool.size ||
			mhba->tag_cmd[p_outb_frame->tag] == NULL ||
			p_outb_frame->request_id !=
				mhba->tag_cmd[p_outb_frame->tag]->request_id))
			if (mvumi_check_ob_frame(mhba, cur_obf, p_outb_frame))
				continue;

		if (!list_empty(&mhba->ob_data_list)) {
			ob_data = (struct mvumi_ob_data *)
				list_first_entry(&mhba->ob_data_list,
					struct mvumi_ob_data, list);
			list_del_init(&ob_data->list);
		} else {
			ob_data = NULL;
			if (cur_obf == 0) {
				cur_obf = mhba->list_num_io - 1;
				mhba->ob_cur_slot ^= regs->cl_pointer_toggle;
			} else
				cur_obf -= 1;
			break;
		}

		memcpy(ob_data->data, p_outb_frame, mhba->ob_max_size);
		p_outb_frame->tag = 0xff;

		list_add_tail(&ob_data->list, &mhba->free_ob_list);
	}
	mhba->ob_cur_slot &= ~regs->cl_slot_num_mask;
	mhba->ob_cur_slot |= (cur_obf & regs->cl_slot_num_mask);
	iowrite32(mhba->ob_cur_slot, regs->outb_read_pointer);
}

static void mvumi_reset(struct mvumi_hba *mhba)
{
	struct mvumi_hw_regs *regs = mhba->regs;

	iowrite32(0, regs->enpointa_mask_reg);
	if (ioread32(regs->arm_to_pciea_msg1) != HANDSHAKE_DONESTATE)
		return;

	iowrite32(DRBL_SOFT_RESET, regs->pciea_to_arm_drbl_reg);
}

static unsigned char mvumi_start(struct mvumi_hba *mhba);

static int mvumi_wait_for_outstanding(struct mvumi_hba *mhba)
{
	mhba->fw_state = FW_STATE_ABORT;
	mvumi_reset(mhba);

	if (mvumi_start(mhba))
		return FAILED;
	else
		return SUCCESS;
}

static int mvumi_wait_for_fw(struct mvumi_hba *mhba)
{
	struct mvumi_hw_regs *regs = mhba->regs;
	u32 tmp;
	unsigned long before;
	before = jiffies;

	iowrite32(0, regs->enpointa_mask_reg);
	tmp = ioread32(regs->arm_to_pciea_msg1);
	while (tmp != HANDSHAKE_READYSTATE) {
		iowrite32(DRBL_MU_RESET, regs->pciea_to_arm_drbl_reg);
		if (time_after(jiffies, before + FW_MAX_DELAY * HZ)) {
			dev_err(&mhba->pdev->dev,
				"FW reset failed [0x%x].\n", tmp);
			return FAILED;
		}

		msleep(500);
		rmb();
		tmp = ioread32(regs->arm_to_pciea_msg1);
	}

	return SUCCESS;
}

static void mvumi_backup_bar_addr(struct mvumi_hba *mhba)
{
	unsigned char i;

	for (i = 0; i < MAX_BASE_ADDRESS; i++) {
		pci_read_config_dword(mhba->pdev, 0x10 + i * 4,
						&mhba->pci_base[i]);
	}
}

static void mvumi_restore_bar_addr(struct mvumi_hba *mhba)
{
	unsigned char i;

	for (i = 0; i < MAX_BASE_ADDRESS; i++) {
		if (mhba->pci_base[i])
			pci_write_config_dword(mhba->pdev, 0x10 + i * 4,
						mhba->pci_base[i]);
	}
}

static int mvumi_pci_set_master(struct pci_dev *pdev)
{
	int ret = 0;

	pci_set_master(pdev);

	if (IS_DMA64) {
		if (dma_set_mask(&pdev->dev, DMA_BIT_MASK(64)))
			ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
	} else
		ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));

	return ret;
}

static int mvumi_reset_host_9580(struct mvumi_hba *mhba)
{
	mhba->fw_state = FW_STATE_ABORT;

	iowrite32(0, mhba->regs->reset_enable);
	iowrite32(0xf, mhba->regs->reset_request);

	iowrite32(0x10, mhba->regs->reset_enable);
	iowrite32(0x10, mhba->regs->reset_request);
	msleep(100);
	pci_disable_device(mhba->pdev);

	if (pci_enable_device(mhba->pdev)) {
		dev_err(&mhba->pdev->dev, "enable device failed\n");
		return FAILED;
	}
	if (mvumi_pci_set_master(mhba->pdev)) {
		dev_err(&mhba->pdev->dev, "set master failed\n");
		return FAILED;
	}
	mvumi_restore_bar_addr(mhba);
	if (mvumi_wait_for_fw(mhba) == FAILED)
		return FAILED;

	return mvumi_wait_for_outstanding(mhba);
}

static int mvumi_reset_host_9143(struct mvumi_hba *mhba)
{
	return mvumi_wait_for_outstanding(mhba);
}

static int mvumi_host_reset(struct scsi_cmnd *scmd)
{
	struct mvumi_hba *mhba;

	mhba = (struct mvumi_hba *) scmd->device->host->hostdata;

	scmd_printk(KERN_NOTICE, scmd, "RESET -%u cmd=%x retries=%x\n",
			scsi_cmd_to_rq(scmd)->tag, scmd->cmnd[0], scmd->retries);

	return mhba->instancet->reset_host(mhba);
}

static int mvumi_issue_blocked_cmd(struct mvumi_hba *mhba,
						struct mvumi_cmd *cmd)
{
	unsigned long flags;

	cmd->cmd_status = REQ_STATUS_PENDING;

	if (atomic_read(&cmd->sync_cmd)) {
		dev_err(&mhba->pdev->dev,
			"last blocked cmd not finished, sync_cmd = %d\n",
						atomic_read(&cmd->sync_cmd));
		BUG_ON(1);
		return -1;
	}
	atomic_inc(&cmd->sync_cmd);
	spin_lock_irqsave(mhba->shost->host_lock, flags);
	mhba->instancet->fire_cmd(mhba, cmd);
	spin_unlock_irqrestore(mhba->shost->host_lock, flags);

	wait_event_timeout(mhba->int_cmd_wait_q,
		(cmd->cmd_status != REQ_STATUS_PENDING),
		MVUMI_INTERNAL_CMD_WAIT_TIME * HZ);

	/* command timeout */
	if (atomic_read(&cmd->sync_cmd)) {
		spin_lock_irqsave(mhba->shost->host_lock, flags);
		atomic_dec(&cmd->sync_cmd);
		if (mhba->tag_cmd[cmd->frame->tag]) {
			mhba->tag_cmd[cmd->frame->tag] = NULL;
			dev_warn(&mhba->pdev->dev, "TIMEOUT:release tag [%d]\n",
							cmd->frame->tag);
			tag_release_one(mhba, &mhba->tag_pool, cmd->frame->tag);
		}
		if (!list_empty(&cmd->queue_pointer)) {
			dev_warn(&mhba->pdev->dev,
				"TIMEOUT:A internal command doesn't send!\n");
			list_del_init(&cmd->queue_pointer);
		} else
			atomic_dec(&mhba->fw_outstanding);

		spin_unlock_irqrestore(mhba->shost->host_lock, flags);
	}
	return 0;
}

static void mvumi_release_fw(struct mvumi_hba *mhba)
{
	mvumi_free_cmds(mhba);
	mvumi_release_mem_resource(mhba);
	mvumi_unmap_pci_addr(mhba->pdev, mhba->base_addr);
	dma_free_coherent(&mhba->pdev->dev, HSP_MAX_SIZE,
		mhba->handshake_page, mhba->handshake_page_phys);
	kfree(mhba->regs);
	pci_release_regions(mhba->pdev);
}

static unsigned char mvumi_flush_cache(struct mvumi_hba *mhba)
{
	struct mvumi_cmd *cmd;
	struct mvumi_msg_frame *frame;
	unsigned char device_id, retry = 0;
	unsigned char bitcount = sizeof(unsigned char) * 8;

	for (device_id = 0; device_id < mhba->max_target_id; device_id++) {
		if (!(mhba->target_map[device_id / bitcount] &
				(1 << (device_id % bitcount))))
			continue;
get_cmd:	cmd = mvumi_create_internal_cmd(mhba, 0);
		if (!cmd) {
			if (retry++ >= 5) {
				dev_err(&mhba->pdev->dev, "failed to get memory"
					" for internal flush cache cmd for "
					"device %d", device_id);
				retry = 0;
				continue;
			} else
				goto get_cmd;
		}
		cmd->scmd = NULL;
		cmd->cmd_status = REQ_STATUS_PENDING;
		atomic_set(&cmd->sync_cmd, 0);
		frame = cmd->frame;
		frame->req_function = CL_FUN_SCSI_CMD;
		frame->device_id = device_id;
		frame->cmd_flag = CMD_FLAG_NON_DATA;
		frame->data_transfer_length = 0;
		frame->cdb_length = MAX_COMMAND_SIZE;
		memset(frame->cdb, 0, MAX_COMMAND_SIZE);
		frame->cdb[0] = SCSI_CMD_MARVELL_SPECIFIC;
		frame->cdb[1] = CDB_CORE_MODULE;
		frame->cdb[2] = CDB_CORE_SHUTDOWN;

		mvumi_issue_blocked_cmd(mhba, cmd);
		if (cmd->cmd_status != SAM_STAT_GOOD) {
			dev_err(&mhba->pdev->dev,
				"device %d flush cache failed, status=0x%x.\n",
				device_id, cmd->cmd_status);
		}

		mvumi_delete_internal_cmd(mhba, cmd);
	}
	return 0;
}

static unsigned char
mvumi_calculate_checksum(struct mvumi_hs_header *p_header,
							unsigned short len)
{
	unsigned char *ptr;
	unsigned char ret = 0, i;

	ptr = (unsigned char *) p_header->frame_content;
	for (i = 0; i < len; i++) {
		ret ^= *ptr;
		ptr++;
	}

	return ret;
}

static void mvumi_hs_build_page(struct mvumi_hba *mhba,
				struct mvumi_hs_header *hs_header)
{
	struct mvumi_hs_page2 *hs_page2;
	struct mvumi_hs_page4 *hs_page4;
	struct mvumi_hs_page3 *hs_page3;
	u64 time;
	u64 local_time;

	switch (hs_header->page_code) {
	case HS_PAGE_HOST_INFO:
		hs_page2 = (struct mvumi_hs_page2 *) hs_header;
		hs_header->frame_length = sizeof(*hs_page2) - 4;
		memset(hs_header->frame_content, 0, hs_header->frame_length);
		hs_page2->host_type = 3; /* 3 mean linux*/
		if (mhba->hba_capability & HS_CAPABILITY_SUPPORT_DYN_SRC)
			hs_page2->host_cap = 0x08;/* host dynamic source mode */
		hs_page2->host_ver.ver_major = VER_MAJOR;
		hs_page2->host_ver.ver_minor = VER_MINOR;
		hs_page2->host_ver.ver_oem = VER_OEM;
		hs_page2->host_ver.ver_build = VER_BUILD;
		hs_page2->system_io_bus = 0;
		hs_page2->slot_number = 0;
		hs_page2->intr_level = 0;
		hs_page2->intr_vector = 0;
		time = ktime_get_real_seconds();
		local_time = (time - (sys_tz.tz_minuteswest * 60));
		hs_page2->seconds_since1970 = local_time;
		hs_header->checksum = mvumi_calculate_checksum(hs_header,
						hs_header->frame_length);
		break;

	case HS_PAGE_FIRM_CTL:
		hs_page3 = (struct mvumi_hs_page3 *) hs_header;
		hs_header->frame_length = sizeof(*hs_page3) - 4;
		memset(hs_header->frame_content, 0, hs_header->frame_length);
		hs_header->checksum = mvumi_calculate_checksum(hs_header,
						hs_header->frame_length);
		break;

	case HS_PAGE_CL_INFO:
		hs_page4 = (struct mvumi_hs_page4 *) hs_header;
		hs_header->frame_length = sizeof(*hs_page4) - 4;
		memset(hs_header->frame_content, 0, hs_header->frame_length);
		hs_page4->ib_baseaddr_l = lower_32_bits(mhba->ib_list_phys);
		hs_page4->ib_baseaddr_h = upper_32_bits(mhba->ib_list_phys);

		hs_page4->ob_baseaddr_l = lower_32_bits(mhba->ob_list_phys);
		hs_page4->ob_baseaddr_h = upper_32_bits(mhba->ob_list_phys);
		hs_page4->ib_entry_size = mhba->ib_max_size_setting;
		hs_page4->ob_entry_size = mhba->ob_max_size_setting;
		if (mhba->hba_capability
			& HS_CAPABILITY_NEW_PAGE_IO_DEPTH_DEF) {
			hs_page4->ob_depth = find_first_bit((unsigned long *)
							    &mhba->list_num_io,
							    BITS_PER_LONG);
			hs_page4->ib_depth = find_first_bit((unsigned long *)
							    &mhba->list_num_io,
							    BITS_PER_LONG);
		} else {
			hs_page4->ob_depth = (u8) mhba->list_num_io;
			hs_page4->ib_depth = (u8) mhba->list_num_io;
		}
		hs_header->checksum = mvumi_calculate_checksum(hs_header,
						hs_header->frame_length);
		break;

	default:
		dev_err(&mhba->pdev->dev, "cannot build page, code[0x%x]\n",
			hs_header->page_code);
		break;
	}
}

/**
 * mvumi_init_data -	Initialize requested date for FW
 * @mhba:			Adapter soft state
 */
static int mvumi_init_data(struct mvumi_hba *mhba)
{
	struct mvumi_ob_data *ob_pool;
	struct mvumi_res *res_mgnt;
	unsigned int tmp_size, offset, i;
	void *virmem, *v;
	dma_addr_t p;

	if (mhba->fw_flag & MVUMI_FW_ALLOC)
		return 0;

	tmp_size = mhba->ib_max_size * mhba->max_io;
	if (mhba->hba_capability & HS_CAPABILITY_SUPPORT_DYN_SRC)
		tmp_size += sizeof(struct mvumi_dyn_list_entry) * mhba->max_io;

	tmp_size += 128 + mhba->ob_max_size * mhba->max_io;
	tmp_size += 8 + sizeof(u32)*2 + 16;

	res_mgnt = mvumi_alloc_mem_resource(mhba,
					RESOURCE_UNCACHED_MEMORY, tmp_size);
	if (!res_mgnt) {
		dev_err(&mhba->pdev->dev,
			"failed to allocate memory for inbound list\n");
		goto fail_alloc_dma_buf;
	}

	p = res_mgnt->bus_addr;
	v = res_mgnt->virt_addr;
	/* ib_list */
	offset = round_up(p, 128) - p;
	p += offset;
	v += offset;
	mhba->ib_list = v;
	mhba->ib_list_phys = p;
	if (mhba->hba_capability & HS_CAPABILITY_SUPPORT_DYN_SRC) {
		v += sizeof(struct mvumi_dyn_list_entry) * mhba->max_io;
		p += sizeof(struct mvumi_dyn_list_entry) * mhba->max_io;
		mhba->ib_frame = v;
		mhba->ib_frame_phys = p;
	}
	v += mhba->ib_max_size * mhba->max_io;
	p += mhba->ib_max_size * mhba->max_io;

	/* ib shadow */
	offset = round_up(p, 8) - p;
	p += offset;
	v += offset;
	mhba->ib_shadow = v;
	mhba->ib_shadow_phys = p;
	p += sizeof(u32)*2;
	v += sizeof(u32)*2;
	/* ob shadow */
	if (mhba->pdev->device == PCI_DEVICE_ID_MARVELL_MV9580) {
		offset = round_up(p, 8) - p;
		p += offset;
		v += offset;
		mhba->ob_shadow = v;
		mhba->ob_shadow_phys = p;
		p += 8;
		v += 8;
	} else {
		offset = round_up(p, 4) - p;
		p += offset;
		v += offset;
		mhba->ob_shadow = v;
		mhba->ob_shadow_phys = p;
		p += 4;
		v += 4;
	}

	/* ob list */
	offset = round_up(p, 128) - p;
	p += offset;
	v += offset;

	mhba->ob_list = v;
	mhba->ob_list_phys = p;

	/* ob data pool */
	tmp_size = mhba->max_io * (mhba->ob_max_size + sizeof(*ob_pool));
	tmp_size = round_up(tmp_size, 8);

	res_mgnt = mvumi_alloc_mem_resource(mhba,
				RESOURCE_CACHED_MEMORY, tmp_size);
	if (!res_mgnt) {
		dev_err(&mhba->pdev->dev,
			"failed to allocate memory for outbound data buffer\n");
		goto fail_alloc_dma_buf;
	}
	virmem = res_mgnt->virt_addr;

	for (i = mhba->max_io; i != 0; i--) {
		ob_pool = (struct mvumi_ob_data *) virmem;
		list_add_tail(&ob_pool->list, &mhba->ob_data_list);
		virmem += mhba->ob_max_size + sizeof(*ob_pool);
	}

	tmp_size = sizeof(unsigned short) * mhba->max_io +
				sizeof(struct mvumi_cmd *) * mhba->max_io;
	tmp_size += round_up(mhba->max_target_id, sizeof(unsigned char) * 8) /
						(sizeof(unsigned char) * 8);

	res_mgnt = mvumi_alloc_mem_resource(mhba,
				RESOURCE_CACHED_MEMORY, tmp_size);
	if (!res_mgnt) {
		dev_err(&mhba->pdev->dev,
			"failed to allocate memory for tag and target map\n");
		goto fail_alloc_dma_buf;
	}

	virmem = res_mgnt->virt_addr;
	mhba->tag_pool.stack = virmem;
	mhba->tag_pool.size = mhba->max_io;
	tag_init(&mhba->tag_pool, mhba->max_io);
	virmem += sizeof(unsigned short) * mhba->max_io;

	mhba->tag_cmd = virmem;
	virmem += sizeof(struct mvumi_cmd *) * mhba->max_io;

	mhba->target_map = virmem;

	mhba->fw_flag |= MVUMI_FW_ALLOC;
	return 0;

fail_alloc_dma_buf:
	mvumi_release_mem_resource(mhba);
	return -1;
}

static int mvumi_hs_process_page(struct mvumi_hba *mhba,
				struct mvumi_hs_header *hs_header)
{
	struct mvumi_hs_page1 *hs_page1;
	unsigned char page_checksum;

	page_checksum = mvumi_calculate_checksum(hs_header,
						hs_header->frame_length);
	if (page_checksum != hs_header->checksum) {
		dev_err(&mhba->pdev->dev, "checksum error\n");
		return -1;
	}

	switch (hs_header->page_code) {
	case HS_PAGE_FIRM_CAP:
		hs_page1 = (struct mvumi_hs_page1 *) hs_header;

		mhba->max_io = hs_page1->max_io_support;
		mhba->list_num_io = hs_page1->cl_inout_list_depth;
		mhba->max_transfer_size = hs_page1->max_transfer_size;
		mhba->max_target_id = hs_page1->max_devices_support;
		mhba->hba_capability = hs_page1->capability;
		mhba->ib_max_size_setting = hs_page1->cl_in_max_entry_size;
		mhba->ib_max_size = (1 << hs_page1->cl_in_max_entry_size) << 2;

		mhba->ob_max_size_setting = hs_page1->cl_out_max_entry_size;
		mhba->ob_max_size = (1 << hs_page1->cl_out_max_entry_size) << 2;

		dev_dbg(&mhba->pdev->dev, "FW version:%d\n",
						hs_page1->fw_ver.ver_build);

		if (mhba->hba_capability & HS_CAPABILITY_SUPPORT_COMPACT_SG)
			mhba->eot_flag = 22;
		else
			mhba->eot_flag = 27;
		if (mhba->hba_capability & HS_CAPABILITY_NEW_PAGE_IO_DEPTH_DEF)
			mhba->list_num_io = 1 << hs_page1->cl_inout_list_depth;
		break;
	default:
		dev_err(&mhba->pdev->dev, "handshake: page code error\n");
		return -1;
	}
	return 0;
}

/**
 * mvumi_handshake -	Move the FW to READY state
 * @mhba:				Adapter soft state
 *
 * During the initialization, FW passes can potentially be in any one of
 * several possible states. If the FW in operational, waiting-for-handshake
 * states, driver must take steps to bring it to ready state. Otherwise, it
 * has to wait for the ready state.
 */
static int mvumi_handshake(struct mvumi_hba *mhba)
{
	unsigned int hs_state, tmp, hs_fun;
	struct mvumi_hs_header *hs_header;
	struct mvumi_hw_regs *regs = mhba->regs;

	if (mhba->fw_state == FW_STATE_STARTING)
		hs_state = HS_S_START;
	else {
		tmp = ioread32(regs->arm_to_pciea_msg0);
		hs_state = HS_GET_STATE(tmp);
		dev_dbg(&mhba->pdev->dev, "handshake state[0x%x].\n", hs_state);
		if (HS_GET_STATUS(tmp) != HS_STATUS_OK) {
			mhba->fw_state = FW_STATE_STARTING;
			return -1;
		}
	}

	hs_fun = 0;
	switch (hs_state) {
	case HS_S_START:
		mhba->fw_state = FW_STATE_HANDSHAKING;
		HS_SET_STATUS(hs_fun, HS_STATUS_OK);
		HS_SET_STATE(hs_fun, HS_S_RESET);
		iowrite32(HANDSHAKE_SIGNATURE, regs->pciea_to_arm_msg1);
		iowrite32(hs_fun, regs->pciea_to_arm_msg0);
		iowrite32(DRBL_HANDSHAKE, regs->pciea_to_arm_drbl_reg);
		break;

	case HS_S_RESET:
		iowrite32(lower_32_bits(mhba->handshake_page_phys),
					regs->pciea_to_arm_msg1);
		iowrite32(upper_32_bits(mhba->handshake_page_phys),
					regs->arm_to_pciea_msg1);
		HS_SET_STATUS(hs_fun, HS_STATUS_OK);
		HS_SET_STATE(hs_fun, HS_S_PAGE_ADDR);
		iowrite32(hs_fun, regs->pciea_to_arm_msg0);
		iowrite32(DRBL_HANDSHAKE, regs->pciea_to_arm_drbl_reg);
		break;

	case HS_S_PAGE_ADDR:
	case HS_S_QUERY_PAGE:
	case HS_S_SEND_PAGE:
		hs_header = (struct mvumi_hs_header *) mhba->handshake_page;
		if (hs_header->page_code == HS_PAGE_FIRM_CAP) {
			mhba->hba_total_pages =
			((struct mvumi_hs_page1 *) hs_header)->total_pages;

			if (mhba->hba_total_pages == 0)
				mhba->hba_total_pages = HS_PAGE_TOTAL-1;
		}

		if (hs_state == HS_S_QUERY_PAGE) {
			if (mvumi_hs_process_page(mhba, hs_header)) {
				HS_SET_STATE(hs_fun, HS_S_ABORT);
				return -1;
			}
			if (mvumi_init_data(mhba)) {
				HS_SET_STATE(hs_fun, HS_S_ABORT);
				return -1;
			}
		} else if (hs_state == HS_S_PAGE_ADDR) {
			hs_header->page_code = 0;
			mhba->hba_total_pages = HS_PAGE_TOTAL-1;
		}

		if ((hs_header->page_code + 1) <= mhba->hba_total_pages) {
			hs_header->page_code++;
			if (hs_header->page_code != HS_PAGE_FIRM_CAP) {
				mvumi_hs_build_page(mhba, hs_header);
				HS_SET_STATE(hs_fun, HS_S_SEND_PAGE);
			} else
				HS_SET_STATE(hs_fun, HS_S_QUERY_PAGE);
		} else
			HS_SET_STATE(hs_fun, HS_S_END);

		HS_SET_STATUS(hs_fun, HS_STATUS_OK);
		iowrite32(hs_fun, regs->pciea_to_arm_msg0);
		iowrite32(DRBL_HANDSHAKE, regs->pciea_to_arm_drbl_reg);
		break;

	case HS_S_END:
		/* Set communication list ISR */
		tmp = ioread32(regs->enpointa_mask_reg);
		tmp |= regs->int_comaout | regs->int_comaerr;
		iowrite32(tmp, regs->enpointa_mask_reg);
		iowrite32(mhba->list_num_io, mhba->ib_shadow);
		/* Set InBound List Available count shadow */
		iowrite32(lower_32_bits(mhba->ib_shadow_phys),
					regs->inb_aval_count_basel);
		iowrite32(upper_32_bits(mhba->ib_shadow_phys),
					regs->inb_aval_count_baseh);

		if (mhba->pdev->device == PCI_DEVICE_ID_MARVELL_MV9143) {
			/* Set OutBound List Available count shadow */
			iowrite32((mhba->list_num_io-1) |
							regs->cl_pointer_toggle,
							mhba->ob_shadow);
			iowrite32(lower_32_bits(mhba->ob_shadow_phys),
							regs->outb_copy_basel);
			iowrite32(upper_32_bits(mhba->ob_shadow_phys),
							regs->outb_copy_baseh);
		}

		mhba->ib_cur_slot = (mhba->list_num_io - 1) |
							regs->cl_pointer_toggle;
		mhba->ob_cur_slot = (mhba->list_num_io - 1) |
							regs->cl_pointer_toggle;
		mhba->fw_state = FW_STATE_STARTED;

		break;
	default:
		dev_err(&mhba->pdev->dev, "unknown handshake state [0x%x].\n",
								hs_state);
		return -1;
	}
	return 0;
}

static unsigned char mvumi_handshake_event(struct mvumi_hba *mhba)
{
	unsigned int isr_status;
	unsigned long before;

	before = jiffies;
	mvumi_handshake(mhba);
	do {
		isr_status = mhba->instancet->read_fw_status_reg(mhba);

		if (mhba->fw_state == FW_STATE_STARTED)
			return 0;
		if (time_after(jiffies, before + FW_MAX_DELAY * HZ)) {
			dev_err(&mhba->pdev->dev,
				"no handshake response at state 0x%x.\n",
				  mhba->fw_state);
			dev_err(&mhba->pdev->dev,
				"isr : global=0x%x,status=0x%x.\n",
					mhba->global_isr, isr_status);
			return -1;
		}
		rmb();
		usleep_range(1000, 2000);
	} while (!(isr_status & DRBL_HANDSHAKE_ISR));

	return 0;
}

static unsigned char mvumi_check_handshake(struct mvumi_hba *mhba)
{
	unsigned int tmp;
	unsigned long before;

	before = jiffies;
	tmp = ioread32(mhba->regs->arm_to_pciea_msg1);
	while ((tmp != HANDSHAKE_READYSTATE) && (tmp != HANDSHAKE_DONESTATE)) {
		if (tmp != HANDSHAKE_READYSTATE)
			iowrite32(DRBL_MU_RESET,
					mhba->regs->pciea_to_arm_drbl_reg);
		if (time_after(jiffies, before + FW_MAX_DELAY * HZ)) {
			dev_err(&mhba->pdev->dev,
				"invalid signature [0x%x].\n", tmp);
			return -1;
		}
		usleep_range(1000, 2000);
		rmb();
		tmp = ioread32(mhba->regs->arm_to_pciea_msg1);
	}

	mhba->fw_state = FW_STATE_STARTING;
	dev_dbg(&mhba->pdev->dev, "start firmware handshake...\n");
	do {
		if (mvumi_handshake_event(mhba)) {
			dev_err(&mhba->pdev->dev,
					"handshake failed at state 0x%x.\n",
						mhba->fw_state);
			return -1;
		}
	} while (mhba->fw_state != FW_STATE_STARTED);

	dev_dbg(&mhba->pdev->dev, "firmware handshake done\n");

	return 0;
}

static unsigned char mvumi_start(struct mvumi_hba *mhba)
{
	unsigned int tmp;
	struct mvumi_hw_regs *regs = mhba->regs;

	/* clear Door bell */
	tmp = ioread32(regs->arm_to_pciea_drbl_reg);
	iowrite32(tmp, regs->arm_to_pciea_drbl_reg);

	iowrite32(regs->int_drbl_int_mask, regs->arm_to_pciea_mask_reg);
	tmp = ioread32(regs->enpointa_mask_reg) | regs->int_dl_cpu2pciea;
	iowrite32(tmp, regs->enpointa_mask_reg);
	msleep(100);
	if (mvumi_check_handshake(mhba))
		return -1;

	return 0;
}

/**
 * mvumi_complete_cmd -	Completes a command
 * @mhba:			Adapter soft state
 * @cmd:			Command to be completed
 * @ob_frame:			Command response
 */
static void mvumi_complete_cmd(struct mvumi_hba *mhba, struct mvumi_cmd *cmd,
					struct mvumi_rsp_frame *ob_frame)
{
	struct scsi_cmnd *scmd = cmd->scmd;

	mvumi_priv(cmd->scmd)->cmd_priv = NULL;
	scmd->result = ob_frame->req_status;

	switch (ob_frame->req_status) {
	case SAM_STAT_GOOD:
		scmd->result |= DID_OK << 16;
		break;
	case SAM_STAT_BUSY:
		scmd->result |= DID_BUS_BUSY << 16;
		break;
	case SAM_STAT_CHECK_CONDITION:
		scmd->result |= (DID_OK << 16);
		if (ob_frame->rsp_flag & CL_RSP_FLAG_SENSEDATA) {
			memcpy(cmd->scmd->sense_buffer, ob_frame->payload,
				sizeof(struct mvumi_sense_data));
		}
		break;
	default:
		scmd->result |= (DID_ABORT << 16);
		break;
	}

	if (scsi_bufflen(scmd))
		dma_unmap_sg(&mhba->pdev->dev, scsi_sglist(scmd),
			     scsi_sg_count(scmd),
			     scmd->sc_data_direction);
	scsi_done(scmd);
	mvumi_return_cmd(mhba, cmd);
}

static void mvumi_complete_internal_cmd(struct mvumi_hba *mhba,
						struct mvumi_cmd *cmd,
					struct mvumi_rsp_frame *ob_frame)
{
	if (atomic_read(&cmd->sync_cmd)) {
		cmd->cmd_status = ob_frame->req_status;

		if ((ob_frame->req_status == SAM_STAT_CHECK_CONDITION) &&
				(ob_frame->rsp_flag & CL_RSP_FLAG_SENSEDATA) &&
				cmd->data_buf) {
			memcpy(cmd->data_buf, ob_frame->payload,
					sizeof(struct mvumi_sense_data));
		}
		atomic_dec(&cmd->sync_cmd);
		wake_up(&mhba->int_cmd_wait_q);
	}
}

static void mvumi_show_event(struct mvumi_hba *mhba,
			struct mvumi_driver_event *ptr)
{
	unsigned int i;

	dev_warn(&mhba->pdev->dev,
		"Event[0x%x] id[0x%x] severity[0x%x] device id[0x%x]\n",
		ptr->sequence_no, ptr->event_id, ptr->severity, ptr->device_id);
	if (ptr->param_count) {
		printk(KERN_WARNING "Event param(len 0x%x): ",
						ptr->param_count);
		for (i = 0; i < ptr->param_count; i++)
			printk(KERN_WARNING "0x%x ", ptr->params[i]);

		printk(KERN_WARNING "\n");
	}

	if (ptr->sense_data_length) {
		printk(KERN_WARNING "Event sense data(len 0x%x): ",
						ptr->sense_data_length);
		for (i = 0; i < ptr->sense_data_length; i++)
			printk(KERN_WARNING "0x%x ", ptr->sense_data[i]);
		printk(KERN_WARNING "\n");
	}
}

static int mvumi_handle_hotplug(struct mvumi_hba *mhba, u16 devid, int status)
{
	struct scsi_device *sdev;
	int ret = -1;

	if (status == DEVICE_OFFLINE) {
		sdev = scsi_device_lookup(mhba->shost, 0, devid, 0);
		if (sdev) {
			dev_dbg(&mhba->pdev->dev, "remove disk %d-%d-%d.\n", 0,
								sdev->id, 0);
			scsi_remove_device(sdev);
			scsi_device_put(sdev);
			ret = 0;
		} else
			dev_err(&mhba->pdev->dev, " no disk[%d] to remove\n",
									devid);
	} else if (status == DEVICE_ONLINE) {
		sdev = scsi_device_lookup(mhba->shost, 0, devid, 0);
		if (!sdev) {
			scsi_add_device(mhba->shost, 0, devid, 0);
			dev_dbg(&mhba->pdev->dev, " add disk %d-%d-%d.\n", 0,
								devid, 0);
			ret = 0;
		} else {
			dev_err(&mhba->pdev->dev, " don't add disk %d-%d-%d.\n",
								0, devid, 0);
			scsi_device_put(sdev);
		}
	}
	return ret;
}

static u64 mvumi_inquiry(struct mvumi_hba *mhba,
	unsigned int id, struct mvumi_cmd *cmd)
{
	struct mvumi_msg_frame *frame;
	u64 wwid = 0;
	int cmd_alloc = 0;
	int data_buf_len = 64;

	if (!cmd) {
		cmd = mvumi_create_internal_cmd(mhba, data_buf_len);
		if (cmd)
			cmd_alloc = 1;
		else
			return 0;
	} else {
		memset(cmd->data_buf, 0, data_buf_len);
	}
	cmd->scmd = NULL;
	cmd->cmd_status = REQ_STATUS_PENDING;
	atomic_set(&cmd->sync_cmd, 0);
	frame = cmd->frame;
	frame->device_id = (u16) id;
	frame->cmd_flag = CMD_FLAG_DATA_IN;
	frame->req_function = CL_FUN_SCSI_CMD;
	frame->cdb_length = 6;
	frame->data_transfer_length = MVUMI_INQUIRY_LENGTH;
	memset(frame->cdb, 0, frame->cdb_length);
	frame->cdb[0] = INQUIRY;
	frame->cdb[4] = frame->data_transfer_length;

	mvumi_issue_blocked_cmd(mhba, cmd);

	if (cmd->cmd_status == SAM_STAT_GOOD) {
		if (mhba->pdev->device == PCI_DEVICE_ID_MARVELL_MV9143)
			wwid = id + 1;
		else
			memcpy((void *)&wwid,
			       (cmd->data_buf + MVUMI_INQUIRY_UUID_OFF),
			       MVUMI_INQUIRY_UUID_LEN);
		dev_dbg(&mhba->pdev->dev,
			"inquiry device(0:%d:0) wwid(%llx)\n", id, wwid);
	} else {
		wwid = 0;
	}
	if (cmd_alloc)
		mvumi_delete_internal_cmd(mhba, cmd);

	return wwid;
}

static void mvumi_detach_devices(struct mvumi_hba *mhba)
{
	struct mvumi_device *mv_dev = NULL , *dev_next;
	struct scsi_device *sdev = NULL;

	mutex_lock(&mhba->device_lock);

	/* detach Hard Disk */
	list_for_each_entry_safe(mv_dev, dev_next,
		&mhba->shost_dev_list, list) {
		mvumi_handle_hotplug(mhba, mv_dev->id, DEVICE_OFFLINE);
		list_del_init(&mv_dev->list);
		dev_dbg(&mhba->pdev->dev, "release device(0:%d:0) wwid(%llx)\n",
			mv_dev->id, mv_dev->wwid);
		kfree(mv_dev);
	}
	list_for_each_entry_safe(mv_dev, dev_next, &mhba->mhba_dev_list, list) {
		list_del_init(&mv_dev->list);
		dev_dbg(&mhba->pdev->dev, "release device(0:%d:0) wwid(%llx)\n",
			mv_dev->id, mv_dev->wwid);
		kfree(mv_dev);
	}

	/* detach virtual device */
	if (mhba->pdev->device == PCI_DEVICE_ID_MARVELL_MV9580)
		sdev = scsi_device_lookup(mhba->shost, 0,
						mhba->max_target_id - 1, 0);

	if (sdev) {
		scsi_remove_device(sdev);
		scsi_device_put(sdev);
	}

	mutex_unlock(&mhba->device_lock);
}

static void mvumi_rescan_devices(struct mvumi_hba *mhba, int id)
{
	struct scsi_device *sdev;

	sdev = scsi_device_lookup(mhba->shost, 0, id, 0);
	if (sdev) {
		scsi_rescan_device(sdev);
		scsi_device_put(sdev);
	}
}

static int mvumi_match_devices(struct mvumi_hba *mhba, int id, u64 wwid)
{
	struct mvumi_device *mv_dev = NULL;

	list_for_each_entry(mv_dev, &mhba->shost_dev_list, list) {
		if (mv_dev->wwid == wwid) {
			if (mv_dev->id != id) {
				dev_err(&mhba->pdev->dev,
					"%s has same wwid[%llx] ,"
					" but different id[%d %d]\n",
					__func__, mv_dev->wwid, mv_dev->id, id);
				return -1;
			} else {
				if (mhba->pdev->device ==
						PCI_DEVICE_ID_MARVELL_MV9143)
					mvumi_rescan_devices(mhba, id);
				return 1;
			}
		}
	}
	return 0;
}

static void mvumi_remove_devices(struct mvumi_hba *mhba, int id)
{
	struct mvumi_device *mv_dev = NULL, *dev_next;

	list_for_each_entry_safe(mv_dev, dev_next,
				&mhba->shost_dev_list, list) {
		if (mv_dev->id == id) {
			dev_dbg(&mhba->pdev->dev,
				"detach device(0:%d:0) wwid(%llx) from HOST\n",
				mv_dev->id, mv_dev->wwid);
			mvumi_handle_hotplug(mhba, mv_dev->id, DEVICE_OFFLINE);
			list_del_init(&mv_dev->list);
			kfree(mv_dev);
		}
	}
}

static int mvumi_probe_devices(struct mvumi_hba *mhba)
{
	int id, maxid;
	u64 wwid = 0;
	struct mvumi_device *mv_dev = NULL;
	struct mvumi_cmd *cmd = NULL;
	int found = 0;

	cmd = mvumi_create_internal_cmd(mhba, 64);
	if (!cmd)
		return -1;

	if (mhba->pdev->device == PCI_DEVICE_ID_MARVELL_MV9143)
		maxid = mhba->max_target_id;
	else
		maxid = mhba->max_target_id - 1;

	for (id = 0; id < maxid; id++) {
		wwid = mvumi_inquiry(mhba, id, cmd);
		if (!wwid) {
			/* device no response, remove it */
			mvumi_remove_devices(mhba, id);
		} else {
			/* device response, add it */
			found = mvumi_match_devices(mhba, id, wwid);
			if (!found) {
				mvumi_remove_devices(mhba, id);
				mv_dev = kzalloc(sizeof(struct mvumi_device),
								GFP_KERNEL);
				if (!mv_dev) {
					dev_err(&mhba->pdev->dev,
						"%s alloc mv_dev failed\n",
						__func__);
					continue;
				}
				mv_dev->id = id;
				mv_dev->wwid = wwid;
				mv_dev->sdev = NULL;
				INIT_LIST_HEAD(&mv_dev->list);
				list_add_tail(&mv_dev->list,
					      &mhba->mhba_dev_list);
				dev_dbg(&mhba->pdev->dev,
					"probe a new device(0:%d:0)"
					" wwid(%llx)\n", id, mv_dev->wwid);
			} else if (found == -1)
				return -1;
			else
				continue;
		}
	}

	if (cmd)
		mvumi_delete_internal_cmd(mhba, cmd);

	return 0;
}

static int mvumi_rescan_bus(void *data)
{
	int ret = 0;
	struct mvumi_hba *mhba = (struct mvumi_hba *) data;
	struct mvumi_device *mv_dev = NULL , *dev_next;

	while (!kthread_should_stop()) {

		set_current_state(TASK_INTERRUPTIBLE);
		if (!atomic_read(&mhba->pnp_count))
			schedule();
		msleep(1000);
		atomic_set(&mhba->pnp_count, 0);
		__set_current_state(TASK_RUNNING);

		mutex_lock(&mhba->device_lock);
		ret = mvumi_probe_devices(mhba);
		if (!ret) {
			list_for_each_entry_safe(mv_dev, dev_next,
						 &mhba->mhba_dev_list, list) {
				if (mvumi_handle_hotplug(mhba, mv_dev->id,
							 DEVICE_ONLINE)) {
					dev_err(&mhba->pdev->dev,
						"%s add device(0:%d:0) failed"
						"wwid(%llx) has exist\n",
						__func__,
						mv_dev->id, mv_dev->wwid);
					list_del_init(&mv_dev->list);
					kfree(mv_dev);
				} else {
					list_move_tail(&mv_dev->list,
						       &mhba->shost_dev_list);
				}
			}
		}
		mutex_unlock(&mhba->device_lock);
	}
	return 0;
}

static void mvumi_proc_msg(struct mvumi_hba *mhba,
					struct mvumi_hotplug_event *param)
{
	u16 size = param->size;
	const unsigned long *ar_bitmap;
	const unsigned long *re_bitmap;
	int index;

	if (mhba->fw_flag & MVUMI_FW_ATTACH) {
		index = -1;
		ar_bitmap = (const unsigned long *) param->bitmap;
		re_bitmap = (const unsigned long *) &param->bitmap[size >> 3];

		mutex_lock(&mhba->sas_discovery_mutex);
		do {
			index = find_next_zero_bit(ar_bitmap, size, index + 1);
			if (index >= size)
				break;
			mvumi_handle_hotplug(mhba, index, DEVICE_ONLINE);
		} while (1);

		index = -1;
		do {
			index = find_next_zero_bit(re_bitmap, size, index + 1);
			if (index >= size)
				break;
			mvumi_handle_hotplug(mhba, index, DEVICE_OFFLINE);
		} while (1);
		mutex_unlock(&mhba->sas_discovery_mutex);
	}
}

static void mvumi_notification(struct mvumi_hba *mhba, u8 msg, void *buffer)
{
	if (msg == APICDB1_EVENT_GETEVENT) {
		int i, count;
		struct mvumi_driver_event *param = NULL;
		struct mvumi_event_req *er = buffer;
		count = er->count;
		if (count > MAX_EVENTS_RETURNED) {
			dev_err(&mhba->pdev->dev, "event count[0x%x] is bigger"
					" than max event count[0x%x].\n",
					count, MAX_EVENTS_RETURNED);
			return;
		}
		for (i = 0; i < count; i++) {
			param = &er->events[i];
			mvumi_show_event(mhba, param);
		}
	} else if (msg == APICDB1_HOST_GETEVENT) {
		mvumi_proc_msg(mhba, buffer);
	}
}

static int mvumi_get_event(struct mvumi_hba *mhba, unsigned char msg)
{
	struct mvumi_cmd *cmd;
	struct mvumi_msg_frame *frame;

	cmd = mvumi_create_internal_cmd(mhba, 512);
	if (!cmd)
		return -1;
	cmd->scmd = NULL;
	cmd->cmd_status = REQ_STATUS_PENDING;
	atomic_set(&cmd->sync_cmd, 0);
	frame = cmd->frame;
	frame->device_id = 0;
	frame->cmd_flag = CMD_FLAG_DATA_IN;
	frame->req_function = CL_FUN_SCSI_CMD;
	frame->cdb_length = MAX_COMMAND_SIZE;
	frame->data_transfer_length = sizeof(struct mvumi_event_req);
	memset(frame->cdb, 0, MAX_COMMAND_SIZE);
	frame->cdb[0] = APICDB0_EVENT;
	frame->cdb[1] = msg;
	mvumi_issue_blocked_cmd(mhba, cmd);

	if (cmd->cmd_status != SAM_STAT_GOOD)
		dev_err(&mhba->pdev->dev, "get event failed, status=0x%x.\n",
							cmd->cmd_status);
	else
		mvumi_notification(mhba, cmd->frame->cdb[1], cmd->data_buf);

	mvumi_delete_internal_cmd(mhba, cmd);
	return 0;
}

static void mvumi_scan_events(struct work_struct *work)
{
	struct mvumi_events_wq *mu_ev =
		container_of(work, struct mvumi_events_wq, work_q);

	mvumi_get_event(mu_ev->mhba, mu_ev->event);
	kfree(mu_ev);
}

static void mvumi_launch_events(struct mvumi_hba *mhba, u32 isr_status)
{
	struct mvumi_events_wq *mu_ev;

	while (isr_status & (DRBL_BUS_CHANGE | DRBL_EVENT_NOTIFY)) {
		if (isr_status & DRBL_BUS_CHANGE) {
			atomic_inc(&mhba->pnp_count);
			wake_up_process(mhba->dm_thread);
			isr_status &= ~(DRBL_BUS_CHANGE);
			continue;
		}

		mu_ev = kzalloc(sizeof(*mu_ev), GFP_ATOMIC);
		if (mu_ev) {
			INIT_WORK(&mu_ev->work_q, mvumi_scan_events);
			mu_ev->mhba = mhba;
			mu_ev->event = APICDB1_EVENT_GETEVENT;
			isr_status &= ~(DRBL_EVENT_NOTIFY);
			mu_ev->param = NULL;
			schedule_work(&mu_ev->work_q);
		}
	}
}

static void mvumi_handle_clob(struct mvumi_hba *mhba)
{
	struct mvumi_rsp_frame *ob_frame;
	struct mvumi_cmd *cmd;
	struct mvumi_ob_data *pool;

	while (!list_empty(&mhba->free_ob_list)) {
		pool = list_first_entry(&mhba->free_ob_list,
						struct mvumi_ob_data, list);
		list_del_init(&pool->list);
		list_add_tail(&pool->list, &mhba->ob_data_list);

		ob_frame = (struct mvumi_rsp_frame *) &pool->data[0];
		cmd = mhba->tag_cmd[ob_frame->tag];

		atomic_dec(&mhba->fw_outstanding);
		mhba->tag_cmd[ob_frame->tag] = NULL;
		tag_release_one(mhba, &mhba->tag_pool, ob_frame->tag);
		if (cmd->scmd)
			mvumi_complete_cmd(mhba, cmd, ob_frame);
		else
			mvumi_complete_internal_cmd(mhba, cmd, ob_frame);
	}
	mhba->instancet->fire_cmd(mhba, NULL);
}

static irqreturn_t mvumi_isr_handler(int irq, void *devp)
{
	struct mvumi_hba *mhba = (struct mvumi_hba *) devp;
	unsigned long flags;

	spin_lock_irqsave(mhba->shost->host_lock, flags);
	if (unlikely(mhba->instancet->clear_intr(mhba) || !mhba->global_isr)) {
		spin_unlock_irqrestore(mhba->shost->host_lock, flags);
		return IRQ_NONE;
	}

	if (mhba->global_isr & mhba->regs->int_dl_cpu2pciea) {
		if (mhba->isr_status & (DRBL_BUS_CHANGE | DRBL_EVENT_NOTIFY))
			mvumi_launch_events(mhba, mhba->isr_status);
		if (mhba->isr_status & DRBL_HANDSHAKE_ISR) {
			dev_warn(&mhba->pdev->dev, "enter handshake again!\n");
			mvumi_handshake(mhba);
		}

	}

	if (mhba->global_isr & mhba->regs->int_comaout)
		mvumi_receive_ob_list_entry(mhba);

	mhba->global_isr = 0;
	mhba->isr_status = 0;
	if (mhba->fw_state == FW_STATE_STARTED)
		mvumi_handle_clob(mhba);
	spin_unlock_irqrestore(mhba->shost->host_lock, flags);
	return IRQ_HANDLED;
}

static enum mvumi_qc_result mvumi_send_command(struct mvumi_hba *mhba,
						struct mvumi_cmd *cmd)
{
	void *ib_entry;
	struct mvumi_msg_frame *ib_frame;
	unsigned int frame_len;

	ib_frame = cmd->frame;
	if (unlikely(mhba->fw_state != FW_STATE_STARTED)) {
		dev_dbg(&mhba->pdev->dev, "firmware not ready.\n");
		return MV_QUEUE_COMMAND_RESULT_NO_RESOURCE;
	}
	if (tag_is_empty(&mhba->tag_pool)) {
		dev_dbg(&mhba->pdev->dev, "no free tag.\n");
		return MV_QUEUE_COMMAND_RESULT_NO_RESOURCE;
	}
	mvumi_get_ib_list_entry(mhba, &ib_entry);

	cmd->frame->tag = tag_get_one(mhba, &mhba->tag_pool);
	cmd->frame->request_id = mhba->io_seq++;
	cmd->request_id = cmd->frame->request_id;
	mhba->tag_cmd[cmd->frame->tag] = cmd;
	frame_len = sizeof(*ib_frame) +
				ib_frame->sg_counts * sizeof(struct mvumi_sgl);
	if (mhba->hba_capability & HS_CAPABILITY_SUPPORT_DYN_SRC) {
		struct mvumi_dyn_list_entry *dle;
		dle = ib_entry;
		dle->src_low_addr =
			cpu_to_le32(lower_32_bits(cmd->frame_phys));
		dle->src_high_addr =
			cpu_to_le32(upper_32_bits(cmd->frame_phys));
		dle->if_length = (frame_len >> 2) & 0xFFF;
	} else {
		memcpy(ib_entry, ib_frame, frame_len);
	}
	return MV_QUEUE_COMMAND_RESULT_SENT;
}

static void mvumi_fire_cmd(struct mvumi_hba *mhba, struct mvumi_cmd *cmd)
{
	unsigned short num_of_cl_sent = 0;
	unsigned int count;
	enum mvumi_qc_result result;

	if (cmd)
		list_add_tail(&cmd->queue_pointer, &mhba->waiting_req_list);
	count = mhba->instancet->check_ib_list(mhba);
	if (list_empty(&mhba->waiting_req_list) || !count)
		return;

	do {
		cmd = list_first_entry(&mhba->waiting_req_list,
				       struct mvumi_cmd, queue_pointer);
		list_del_init(&cmd->queue_pointer);
		result = mvumi_send_command(mhba, cmd);
		switch (result) {
		case MV_QUEUE_COMMAND_RESULT_SENT:
			num_of_cl_sent++;
			break;
		case MV_QUEUE_COMMAND_RESULT_NO_RESOURCE:
			list_add(&cmd->queue_pointer, &mhba->waiting_req_list);
			if (num_of_cl_sent > 0)
				mvumi_send_ib_list_entry(mhba);

			return;
		}
	} while (!list_empty(&mhba->waiting_req_list) && count--);

	if (num_of_cl_sent > 0)
		mvumi_send_ib_list_entry(mhba);
}

/**
 * mvumi_enable_intr -	Enables interrupts
 * @mhba:		Adapter soft state
 */
static void mvumi_enable_intr(struct mvumi_hba *mhba)
{
	unsigned int mask;
	struct mvumi_hw_regs *regs = mhba->regs;

	iowrite32(regs->int_drbl_int_mask, regs->arm_to_pciea_mask_reg);
	mask = ioread32(regs->enpointa_mask_reg);
	mask |= regs->int_dl_cpu2pciea | regs->int_comaout | regs->int_comaerr;
	iowrite32(mask, regs->enpointa_mask_reg);
}

/**
 * mvumi_disable_intr -Disables interrupt
 * @mhba:		Adapter soft state
 */
static void mvumi_disable_intr(struct mvumi_hba *mhba)
{
	unsigned int mask;
	struct mvumi_hw_regs *regs = mhba->regs;

	iowrite32(0, regs->arm_to_pciea_mask_reg);
	mask = ioread32(regs->enpointa_mask_reg);
	mask &= ~(regs->int_dl_cpu2pciea | regs->int_comaout |
							regs->int_comaerr);
	iowrite32(mask, regs->enpointa_mask_reg);
}

static int mvumi_clear_intr(void *extend)
{
	struct mvumi_hba *mhba = (struct mvumi_hba *) extend;
	unsigned int status, isr_status = 0, tmp = 0;
	struct mvumi_hw_regs *regs = mhba->regs;

	status = ioread32(regs->main_int_cause_reg);
	if (!(status & regs->int_mu) || status == 0xFFFFFFFF)
		return 1;
	if (unlikely(status & regs->int_comaerr)) {
		tmp = ioread32(regs->outb_isr_cause);
		if (mhba->pdev->device == PCI_DEVICE_ID_MARVELL_MV9580) {
			if (tmp & regs->clic_out_err) {
				iowrite32(tmp & regs->clic_out_err,
							regs->outb_isr_cause);
			}
		} else {
			if (tmp & (regs->clic_in_err | regs->clic_out_err))
				iowrite32(tmp & (regs->clic_in_err |
						regs->clic_out_err),
						regs->outb_isr_cause);
		}
		status ^= mhba->regs->int_comaerr;
		/* inbound or outbound parity error, command will timeout */
	}
	if (status & regs->int_comaout) {
		tmp = ioread32(regs->outb_isr_cause);
		if (tmp & regs->clic_irq)
			iowrite32(tmp & regs->clic_irq, regs->outb_isr_cause);
	}
	if (status & regs->int_dl_cpu2pciea) {
		isr_status = ioread32(regs->arm_to_pciea_drbl_reg);
		if (isr_status)
			iowrite32(isr_status, regs->arm_to_pciea_drbl_reg);
	}

	mhba->global_isr = status;
	mhba->isr_status = isr_status;

	return 0;
}

/**
 * mvumi_read_fw_status_reg - returns the current FW status value
 * @mhba:		Adapter soft state
 */
static unsigned int mvumi_read_fw_status_reg(struct mvumi_hba *mhba)
{
	unsigned int status;

	status = ioread32(mhba->regs->arm_to_pciea_drbl_reg);
	if (status)
		iowrite32(status, mhba->regs->arm_to_pciea_drbl_reg);
	return status;
}

static struct mvumi_instance_template mvumi_instance_9143 = {
	.fire_cmd = mvumi_fire_cmd,
	.enable_intr = mvumi_enable_intr,
	.disable_intr = mvumi_disable_intr,
	.clear_intr = mvumi_clear_intr,
	.read_fw_status_reg = mvumi_read_fw_status_reg,
	.check_ib_list = mvumi_check_ib_list_9143,
	.check_ob_list = mvumi_check_ob_list_9143,
	.reset_host = mvumi_reset_host_9143,
};

static struct mvumi_instance_template mvumi_instance_9580 = {
	.fire_cmd = mvumi_fire_cmd,
	.enable_intr = mvumi_enable_intr,
	.disable_intr = mvumi_disable_intr,
	.clear_intr = mvumi_clear_intr,
	.read_fw_status_reg = mvumi_read_fw_status_reg,
	.check_ib_list = mvumi_check_ib_list_9580,
	.check_ob_list = mvumi_check_ob_list_9580,
	.reset_host = mvumi_reset_host_9580,
};

static int mvumi_slave_configure(struct scsi_device *sdev)
{
	struct mvumi_hba *mhba;
	unsigned char bitcount = sizeof(unsigned char) * 8;

	mhba = (struct mvumi_hba *) sdev->host->hostdata;
	if (sdev->id >= mhba->max_target_id)
		return -EINVAL;

	mhba->target_map[sdev->id / bitcount] |= (1 << (sdev->id % bitcount));
	return 0;
}

/**
 * mvumi_build_frame -	Prepares a direct cdb (DCDB) command
 * @mhba:		Adapter soft state
 * @scmd:		SCSI command
 * @cmd:		Command to be prepared in
 *
 * This function prepares CDB commands. These are typcially pass-through
 * commands to the devices.
 */
static unsigned char mvumi_build_frame(struct mvumi_hba *mhba,
				struct scsi_cmnd *scmd, struct mvumi_cmd *cmd)
{
	struct mvumi_msg_frame *pframe;

	cmd->scmd = scmd;
	cmd->cmd_status = REQ_STATUS_PENDING;
	pframe = cmd->frame;
	pframe->device_id = ((unsigned short) scmd->device->id) |
				(((unsigned short) scmd->device->lun) << 8);
	pframe->cmd_flag = 0;

	switch (scmd->sc_data_direction) {
	case DMA_NONE:
		pframe->cmd_flag |= CMD_FLAG_NON_DATA;
		break;
	case DMA_FROM_DEVICE:
		pframe->cmd_flag |= CMD_FLAG_DATA_IN;
		break;
	case DMA_TO_DEVICE:
		pframe->cmd_flag |= CMD_FLAG_DATA_OUT;
		break;
	case DMA_BIDIRECTIONAL:
	default:
		dev_warn(&mhba->pdev->dev, "unexpected data direction[%d] "
			"cmd[0x%x]\n", scmd->sc_data_direction, scmd->cmnd[0]);
		goto error;
	}

	pframe->cdb_length = scmd->cmd_len;
	memcpy(pframe->cdb, scmd->cmnd, pframe->cdb_length);
	pframe->req_function = CL_FUN_SCSI_CMD;
	if (scsi_bufflen(scmd)) {
		if (mvumi_make_sgl(mhba, scmd, &pframe->payload[0],
			&pframe->sg_counts))
			goto error;

		pframe->data_transfer_length = scsi_bufflen(scmd);
	} else {
		pframe->sg_counts = 0;
		pframe->data_transfer_length = 0;
	}
	return 0;

error:
	scsi_build_sense(scmd, 0, ILLEGAL_REQUEST, 0x24, 0);
	return -1;
}

/**
 * mvumi_queue_command -	Queue entry point
 * @shost:			Scsi host to queue command on
 * @scmd:			SCSI command to be queued
 */
static int mvumi_queue_command(struct Scsi_Host *shost,
					struct scsi_cmnd *scmd)
{
	struct mvumi_cmd *cmd;
	struct mvumi_hba *mhba;
	unsigned long irq_flags;

	spin_lock_irqsave(shost->host_lock, irq_flags);

	mhba = (struct mvumi_hba *) shost->hostdata;
	scmd->result = 0;
	cmd = mvumi_get_cmd(mhba);
	if (unlikely(!cmd)) {
		spin_unlock_irqrestore(shost->host_lock, irq_flags);
		return SCSI_MLQUEUE_HOST_BUSY;
	}

	if (unlikely(mvumi_build_frame(mhba, scmd, cmd)))
		goto out_return_cmd;

	cmd->scmd = scmd;
	mvumi_priv(scmd)->cmd_priv = cmd;
	mhba->instancet->fire_cmd(mhba, cmd);
	spin_unlock_irqrestore(shost->host_lock, irq_flags);
	return 0;

out_return_cmd:
	mvumi_return_cmd(mhba, cmd);
	scsi_done(scmd);
	spin_unlock_irqrestore(shost->host_lock, irq_flags);
	return 0;
}

static enum scsi_timeout_action mvumi_timed_out(struct scsi_cmnd *scmd)
{
	struct mvumi_cmd *cmd = mvumi_priv(scmd)->cmd_priv;
	struct Scsi_Host *host = scmd->device->host;
	struct mvumi_hba *mhba = shost_priv(host);
	unsigned long flags;

	spin_lock_irqsave(mhba->shost->host_lock, flags);

	if (mhba->tag_cmd[cmd->frame->tag]) {
		mhba->tag_cmd[cmd->frame->tag] = NULL;
		tag_release_one(mhba, &mhba->tag_pool, cmd->frame->tag);
	}
	if (!list_empty(&cmd->queue_pointer))
		list_del_init(&cmd->queue_pointer);
	else
		atomic_dec(&mhba->fw_outstanding);

	scmd->result = (DID_ABORT << 16);
	mvumi_priv(scmd)->cmd_priv = NULL;
	if (scsi_bufflen(scmd)) {
		dma_unmap_sg(&mhba->pdev->dev, scsi_sglist(scmd),
			     scsi_sg_count(scmd),
			     scmd->sc_data_direction);
	}
	mvumi_return_cmd(mhba, cmd);
	spin_unlock_irqrestore(mhba->shost->host_lock, flags);

	return SCSI_EH_NOT_HANDLED;
}

static int
mvumi_bios_param(struct scsi_device *sdev, struct block_device *bdev,
			sector_t capacity, int geom[])
{
	int heads, sectors;
	sector_t cylinders;
	unsigned long tmp;

	heads = 64;
	sectors = 32;
	tmp = heads * sectors;
	cylinders = capacity;
	sector_div(cylinders, tmp);

	if (capacity >= 0x200000) {
		heads = 255;
		sectors = 63;
		tmp = heads * sectors;
		cylinders = capacity;
		sector_div(cylinders, tmp);
	}
	geom[0] = heads;
	geom[1] = sectors;
	geom[2] = cylinders;

	return 0;
}

static const struct scsi_host_template mvumi_template = {

	.module = THIS_MODULE,
	.name = "Marvell Storage Controller",
	.slave_configure = mvumi_slave_configure,
	.queuecommand = mvumi_queue_command,
	.eh_timed_out = mvumi_timed_out,
	.eh_host_reset_handler = mvumi_host_reset,
	.bios_param = mvumi_bios_param,
	.dma_boundary = PAGE_SIZE - 1,
	.this_id = -1,
	.cmd_size = sizeof(struct mvumi_cmd_priv),
};

static int mvumi_cfg_hw_reg(struct mvumi_hba *mhba)
{
	void *base = NULL;
	struct mvumi_hw_regs *regs;

	switch (mhba->pdev->device) {
	case PCI_DEVICE_ID_MARVELL_MV9143:
		mhba->mmio = mhba->base_addr[0];
		base = mhba->mmio;
		if (!mhba->regs) {
			mhba->regs = kzalloc(sizeof(*regs), GFP_KERNEL);
			if (mhba->regs == NULL)
				return -ENOMEM;
		}
		regs = mhba->regs;

		/* For Arm */
		regs->ctrl_sts_reg          = base + 0x20104;
		regs->rstoutn_mask_reg      = base + 0x20108;
		regs->sys_soft_rst_reg      = base + 0x2010C;
		regs->main_int_cause_reg    = base + 0x20200;
		regs->enpointa_mask_reg     = base + 0x2020C;
		regs->rstoutn_en_reg        = base + 0xF1400;
		/* For Doorbell */
		regs->pciea_to_arm_drbl_reg = base + 0x20400;
		regs->arm_to_pciea_drbl_reg = base + 0x20408;
		regs->arm_to_pciea_mask_reg = base + 0x2040C;
		regs->pciea_to_arm_msg0     = base + 0x20430;
		regs->pciea_to_arm_msg1     = base + 0x20434;
		regs->arm_to_pciea_msg0     = base + 0x20438;
		regs->arm_to_pciea_msg1     = base + 0x2043C;

		/* For Message Unit */

		regs->inb_aval_count_basel  = base + 0x508;
		regs->inb_aval_count_baseh  = base + 0x50C;
		regs->inb_write_pointer     = base + 0x518;
		regs->inb_read_pointer      = base + 0x51C;
		regs->outb_coal_cfg         = base + 0x568;
		regs->outb_copy_basel       = base + 0x5B0;
		regs->outb_copy_baseh       = base + 0x5B4;
		regs->outb_copy_pointer     = base + 0x544;
		regs->outb_read_pointer     = base + 0x548;
		regs->outb_isr_cause        = base + 0x560;
		regs->outb_coal_cfg         = base + 0x568;
		/* Bit setting for HW */
		regs->int_comaout           = 1 << 8;
		regs->int_comaerr           = 1 << 6;
		regs->int_dl_cpu2pciea      = 1 << 1;
		regs->cl_pointer_toggle     = 1 << 12;
		regs->clic_irq              = 1 << 1;
		regs->clic_in_err           = 1 << 8;
		regs->clic_out_err          = 1 << 12;
		regs->cl_slot_num_mask      = 0xFFF;
		regs->int_drbl_int_mask     = 0x3FFFFFFF;
		regs->int_mu = regs->int_dl_cpu2pciea | regs->int_comaout |
							regs->int_comaerr;
		break;
	case PCI_DEVICE_ID_MARVELL_MV9580:
		mhba->mmio = mhba->base_addr[2];
		base = mhba->mmio;
		if (!mhba->regs) {
			mhba->regs = kzalloc(sizeof(*regs), GFP_KERNEL);
			if (mhba->regs == NULL)
				return -ENOMEM;
		}
		regs = mhba->regs;
		/* For Arm */
		regs->ctrl_sts_reg          = base + 0x20104;
		regs->rstoutn_mask_reg      = base + 0x1010C;
		regs->sys_soft_rst_reg      = base + 0x10108;
		regs->main_int_cause_reg    = base + 0x10200;
		regs->enpointa_mask_reg     = base + 0x1020C;
		regs->rstoutn_en_reg        = base + 0xF1400;

		/* For Doorbell */
		regs->pciea_to_arm_drbl_reg = base + 0x10460;
		regs->arm_to_pciea_drbl_reg = base + 0x10480;
		regs->arm_to_pciea_mask_reg = base + 0x10484;
		regs->pciea_to_arm_msg0     = base + 0x10400;
		regs->pciea_to_arm_msg1     = base + 0x10404;
		regs->arm_to_pciea_msg0     = base + 0x10420;
		regs->arm_to_pciea_msg1     = base + 0x10424;

		/* For reset*/
		regs->reset_request         = base + 0x10108;
		regs->reset_enable          = base + 0x1010c;

		/* For Message Unit */
		regs->inb_aval_count_basel  = base + 0x4008;
		regs->inb_aval_count_baseh  = base + 0x400C;
		regs->inb_write_pointer     = base + 0x4018;
		regs->inb_read_pointer      = base + 0x401C;
		regs->outb_copy_basel       = base + 0x4058;
		regs->outb_copy_baseh       = base + 0x405C;
		regs->outb_copy_pointer     = base + 0x406C;
		regs->outb_read_pointer     = base + 0x4070;
		regs->outb_coal_cfg         = base + 0x4080;
		regs->outb_isr_cause        = base + 0x4088;
		/* Bit setting for HW */
		regs->int_comaout           = 1 << 4;
		regs->int_dl_cpu2pciea      = 1 << 12;
		regs->int_comaerr           = 1 << 29;
		regs->cl_pointer_toggle     = 1 << 14;
		regs->cl_slot_num_mask      = 0x3FFF;
		regs->clic_irq              = 1 << 0;
		regs->clic_out_err          = 1 << 1;
		regs->int_drbl_int_mask     = 0x3FFFFFFF;
		regs->int_mu = regs->int_dl_cpu2pciea | regs->int_comaout;
		break;
	default:
		return -1;
	}

	return 0;
}

/**
 * mvumi_init_fw -	Initializes the FW
 * @mhba:		Adapter soft state
 *
 * This is the main function for initializing firmware.
 */
static int mvumi_init_fw(struct mvumi_hba *mhba)
{
	int ret = 0;

	if (pci_request_regions(mhba->pdev, MV_DRIVER_NAME)) {
		dev_err(&mhba->pdev->dev, "IO memory region busy!\n");
		return -EBUSY;
	}
	ret = mvumi_map_pci_addr(mhba->pdev, mhba->base_addr);
	if (ret)
		goto fail_ioremap;

	switch (mhba->pdev->device) {
	case PCI_DEVICE_ID_MARVELL_MV9143:
		mhba->instancet = &mvumi_instance_9143;
		mhba->io_seq = 0;
		mhba->max_sge = MVUMI_MAX_SG_ENTRY;
		mhba->request_id_enabled = 1;
		break;
	case PCI_DEVICE_ID_MARVELL_MV9580:
		mhba->instancet = &mvumi_instance_9580;
		mhba->io_seq = 0;
		mhba->max_sge = MVUMI_MAX_SG_ENTRY;
		break;
	default:
		dev_err(&mhba->pdev->dev, "device 0x%x not supported!\n",
							mhba->pdev->device);
		mhba->instancet = NULL;
		ret = -EINVAL;
		goto fail_alloc_mem;
	}
	dev_dbg(&mhba->pdev->dev, "device id : %04X is found.\n",
							mhba->pdev->device);
	ret = mvumi_cfg_hw_reg(mhba);
	if (ret) {
		dev_err(&mhba->pdev->dev,
			"failed to allocate memory for reg\n");
		ret = -ENOMEM;
		goto fail_alloc_mem;
	}
	mhba->handshake_page = dma_alloc_coherent(&mhba->pdev->dev,
			HSP_MAX_SIZE, &mhba->handshake_page_phys, GFP_KERNEL);
	if (!mhba->handshake_page) {
		dev_err(&mhba->pdev->dev,
			"failed to allocate memory for handshake\n");
		ret = -ENOMEM;
		goto fail_alloc_page;
	}

	if (mvumi_start(mhba)) {
		ret = -EINVAL;
		goto fail_ready_state;
	}
	ret = mvumi_alloc_cmds(mhba);
	if (ret)
		goto fail_ready_state;

	return 0;

fail_ready_state:
	mvumi_release_mem_resource(mhba);
	dma_free_coherent(&mhba->pdev->dev, HSP_MAX_SIZE,
		mhba->handshake_page, mhba->handshake_page_phys);
fail_alloc_page:
	kfree(mhba->regs);
fail_alloc_mem:
	mvumi_unmap_pci_addr(mhba->pdev, mhba->base_addr);
fail_ioremap:
	pci_release_regions(mhba->pdev);

	return ret;
}

/**
 * mvumi_io_attach -	Attaches this driver to SCSI mid-layer
 * @mhba:		Adapter soft state
 */
static int mvumi_io_attach(struct mvumi_hba *mhba)
{
	struct Scsi_Host *host = mhba->shost;
	struct scsi_device *sdev = NULL;
	int ret;
	unsigned int max_sg = (mhba->ib_max_size -
		sizeof(struct mvumi_msg_frame)) / sizeof(struct mvumi_sgl);

	host->irq = mhba->pdev->irq;
	host->unique_id = mhba->unique_id;
	host->can_queue = (mhba->max_io - 1) ? (mhba->max_io - 1) : 1;
	host->sg_tablesize = mhba->max_sge > max_sg ? max_sg : mhba->max_sge;
	host->max_sectors = mhba->max_transfer_size / 512;
	host->cmd_per_lun = (mhba->max_io - 1) ? (mhba->max_io - 1) : 1;
	host->max_id = mhba->max_target_id;
	host->max_cmd_len = MAX_COMMAND_SIZE;

	ret = scsi_add_host(host, &mhba->pdev->dev);
	if (ret) {
		dev_err(&mhba->pdev->dev, "scsi_add_host failed\n");
		return ret;
	}
	mhba->fw_flag |= MVUMI_FW_ATTACH;

	mutex_lock(&mhba->sas_discovery_mutex);
	if (mhba->pdev->device == PCI_DEVICE_ID_MARVELL_MV9580)
		ret = scsi_add_device(host, 0, mhba->max_target_id - 1, 0);
	else
		ret = 0;
	if (ret) {
		dev_err(&mhba->pdev->dev, "add virtual device failed\n");
		mutex_unlock(&mhba->sas_discovery_mutex);
		goto fail_add_device;
	}

	mhba->dm_thread = kthread_create(mvumi_rescan_bus,
						mhba, "mvumi_scanthread");
	if (IS_ERR(mhba->dm_thread)) {
		dev_err(&mhba->pdev->dev,
			"failed to create device scan thread\n");
		ret = PTR_ERR(mhba->dm_thread);
		mutex_unlock(&mhba->sas_discovery_mutex);
		goto fail_create_thread;
	}
	atomic_set(&mhba->pnp_count, 1);
	wake_up_process(mhba->dm_thread);

	mutex_unlock(&mhba->sas_discovery_mutex);
	return 0;

fail_create_thread:
	if (mhba->pdev->device == PCI_DEVICE_ID_MARVELL_MV9580)
		sdev = scsi_device_lookup(mhba->shost, 0,
						mhba->max_target_id - 1, 0);
	if (sdev) {
		scsi_remove_device(sdev);
		scsi_device_put(sdev);
	}
fail_add_device:
	scsi_remove_host(mhba->shost);
	return ret;
}

/**
 * mvumi_probe_one -	PCI hotplug entry point
 * @pdev:		PCI device structure
 * @id:			PCI ids of supported hotplugged adapter
 */
static int mvumi_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
{
	struct Scsi_Host *host;
	struct mvumi_hba *mhba;
	int ret;

	dev_dbg(&pdev->dev, " %#4.04x:%#4.04x:%#4.04x:%#4.04x: ",
			pdev->vendor, pdev->device, pdev->subsystem_vendor,
			pdev->subsystem_device);

	ret = pci_enable_device(pdev);
	if (ret)
		return ret;

	ret = mvumi_pci_set_master(pdev);
	if (ret)
		goto fail_set_dma_mask;

	host = scsi_host_alloc(&mvumi_template, sizeof(*mhba));
	if (!host) {
		dev_err(&pdev->dev, "scsi_host_alloc failed\n");
		ret = -ENOMEM;
		goto fail_alloc_instance;
	}
	mhba = shost_priv(host);

	INIT_LIST_HEAD(&mhba->cmd_pool);
	INIT_LIST_HEAD(&mhba->ob_data_list);
	INIT_LIST_HEAD(&mhba->free_ob_list);
	INIT_LIST_HEAD(&mhba->res_list);
	INIT_LIST_HEAD(&mhba->waiting_req_list);
	mutex_init(&mhba->device_lock);
	INIT_LIST_HEAD(&mhba->mhba_dev_list);
	INIT_LIST_HEAD(&mhba->shost_dev_list);
	atomic_set(&mhba->fw_outstanding, 0);
	init_waitqueue_head(&mhba->int_cmd_wait_q);
	mutex_init(&mhba->sas_discovery_mutex);

	mhba->pdev = pdev;
	mhba->shost = host;
	mhba->unique_id = pci_dev_id(pdev);

	ret = mvumi_init_fw(mhba);
	if (ret)
		goto fail_init_fw;

	ret = request_irq(mhba->pdev->irq, mvumi_isr_handler, IRQF_SHARED,
				"mvumi", mhba);
	if (ret) {
		dev_err(&pdev->dev, "failed to register IRQ\n");
		goto fail_init_irq;
	}

	mhba->instancet->enable_intr(mhba);
	pci_set_drvdata(pdev, mhba);

	ret = mvumi_io_attach(mhba);
	if (ret)
		goto fail_io_attach;

	mvumi_backup_bar_addr(mhba);
	dev_dbg(&pdev->dev, "probe mvumi driver successfully.\n");

	return 0;

fail_io_attach:
	mhba->instancet->disable_intr(mhba);
	free_irq(mhba->pdev->irq, mhba);
fail_init_irq:
	mvumi_release_fw(mhba);
fail_init_fw:
	scsi_host_put(host);

fail_alloc_instance:
fail_set_dma_mask:
	pci_disable_device(pdev);

	return ret;
}

static void mvumi_detach_one(struct pci_dev *pdev)
{
	struct Scsi_Host *host;
	struct mvumi_hba *mhba;

	mhba = pci_get_drvdata(pdev);
	if (mhba->dm_thread) {
		kthread_stop(mhba->dm_thread);
		mhba->dm_thread = NULL;
	}

	mvumi_detach_devices(mhba);
	host = mhba->shost;
	scsi_remove_host(mhba->shost);
	mvumi_flush_cache(mhba);

	mhba->instancet->disable_intr(mhba);
	free_irq(mhba->pdev->irq, mhba);
	mvumi_release_fw(mhba);
	scsi_host_put(host);
	pci_disable_device(pdev);
	dev_dbg(&pdev->dev, "driver is removed!\n");
}

/**
 * mvumi_shutdown -	Shutdown entry point
 * @pdev:		PCI device structure
 */
static void mvumi_shutdown(struct pci_dev *pdev)
{
	struct mvumi_hba *mhba = pci_get_drvdata(pdev);

	mvumi_flush_cache(mhba);
}

static int __maybe_unused mvumi_suspend(struct device *dev)
{
	struct pci_dev *pdev = to_pci_dev(dev);
	struct mvumi_hba *mhba = pci_get_drvdata(pdev);

	mvumi_flush_cache(mhba);

	mhba->instancet->disable_intr(mhba);
	mvumi_unmap_pci_addr(pdev, mhba->base_addr);

	return 0;
}

static int __maybe_unused mvumi_resume(struct device *dev)
{
	int ret;
	struct pci_dev *pdev = to_pci_dev(dev);
	struct mvumi_hba *mhba = pci_get_drvdata(pdev);

	ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
	if (ret)
		goto fail;
	ret = mvumi_map_pci_addr(mhba->pdev, mhba->base_addr);
	if (ret)
		goto release_regions;

	if (mvumi_cfg_hw_reg(mhba)) {
		ret = -EINVAL;
		goto unmap_pci_addr;
	}

	mhba->mmio = mhba->base_addr[0];
	mvumi_reset(mhba);

	if (mvumi_start(mhba)) {
		ret = -EINVAL;
		goto unmap_pci_addr;
	}

	mhba->instancet->enable_intr(mhba);

	return 0;

unmap_pci_addr:
	mvumi_unmap_pci_addr(pdev, mhba->base_addr);
release_regions:
	pci_release_regions(pdev);
fail:

	return ret;
}

static SIMPLE_DEV_PM_OPS(mvumi_pm_ops, mvumi_suspend, mvumi_resume);

static struct pci_driver mvumi_pci_driver = {

	.name = MV_DRIVER_NAME,
	.id_table = mvumi_pci_table,
	.probe = mvumi_probe_one,
	.remove = mvumi_detach_one,
	.shutdown = mvumi_shutdown,
	.driver.pm = &mvumi_pm_ops,
};

module_pci_driver(mvumi_pci_driver);
