/*
 * Driver for Western Digital WD7193, WD7197 and WD7296 SCSI cards
 * Copyright 2013 Ondrej Zary
 *
 * Original driver by
 * Aaron Dewell <dewell@woods.net>
 * Gaerti <Juergen.Gaertner@mbox.si.uni-hannover.de>
 *
 * HW documentation available in book:
 *
 * SPIDER Command Protocol
 * by Chandru M. Sippy
 * SCSI Storage Products (MCP)
 * Western Digital Corporation
 * 09-15-95
 *
 * http://web.archive.org/web/20070717175254/http://sun1.rrzn.uni-hannover.de/gaertner.juergen/wd719x/Linux/Docu/Spider/
 */

/*
 * Driver workflow:
 * 1. SCSI command is transformed to SCB (Spider Control Block) by the
 *    queuecommand function.
 * 2. The address of the SCB is stored in a list to be able to access it, if
 *    something goes wrong.
 * 3. The address of the SCB is written to the Controller, which loads the SCB
 *    via BM-DMA and processes it.
 * 4. After it has finished, it generates an interrupt, and sets registers.
 *
 * flaws:
 *  - abort/reset functions
 *
 * ToDo:
 *  - tagged queueing
 */

#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/pci.h>
#include <linux/firmware.h>
#include <linux/eeprom_93cx6.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_host.h>
#include "wd719x.h"

/* low-level register access */
static inline u8 wd719x_readb(struct wd719x *wd, u8 reg)
{
	return ioread8(wd->base + reg);
}

static inline u32 wd719x_readl(struct wd719x *wd, u8 reg)
{
	return ioread32(wd->base + reg);
}

static inline void wd719x_writeb(struct wd719x *wd, u8 reg, u8 val)
{
	iowrite8(val, wd->base + reg);
}

static inline void wd719x_writew(struct wd719x *wd, u8 reg, u16 val)
{
	iowrite16(val, wd->base + reg);
}

static inline void wd719x_writel(struct wd719x *wd, u8 reg, u32 val)
{
	iowrite32(val, wd->base + reg);
}

/* wait until the command register is ready */
static inline int wd719x_wait_ready(struct wd719x *wd)
{
	int i = 0;

	do {
		if (wd719x_readb(wd, WD719X_AMR_COMMAND) == WD719X_CMD_READY)
			return 0;
		udelay(1);
	} while (i++ < WD719X_WAIT_FOR_CMD_READY);

	dev_err(&wd->pdev->dev, "command register is not ready: 0x%02x\n",
		wd719x_readb(wd, WD719X_AMR_COMMAND));

	return -ETIMEDOUT;
}

/* poll interrupt status register until command finishes */
static inline int wd719x_wait_done(struct wd719x *wd, int timeout)
{
	u8 status;

	while (timeout > 0) {
		status = wd719x_readb(wd, WD719X_AMR_INT_STATUS);
		if (status)
			break;
		timeout--;
		udelay(1);
	}

	if (timeout <= 0) {
		dev_err(&wd->pdev->dev, "direct command timed out\n");
		return -ETIMEDOUT;
	}

	if (status != WD719X_INT_NOERRORS) {
		dev_err(&wd->pdev->dev, "direct command failed, status 0x%02x, SUE 0x%02x\n",
			status, wd719x_readb(wd, WD719X_AMR_SCB_ERROR));
		return -EIO;
	}

	return 0;
}

static int wd719x_direct_cmd(struct wd719x *wd, u8 opcode, u8 dev, u8 lun,
			     u8 tag, dma_addr_t data, int timeout)
{
	int ret = 0;

	/* clear interrupt status register (allow command register to clear) */
	wd719x_writeb(wd, WD719X_AMR_INT_STATUS, WD719X_INT_NONE);

	/* Wait for the Command register to become free */
	if (wd719x_wait_ready(wd))
		return -ETIMEDOUT;

	/* make sure we get NO interrupts */
	dev |= WD719X_DISABLE_INT;
	wd719x_writeb(wd, WD719X_AMR_CMD_PARAM, dev);
	wd719x_writeb(wd, WD719X_AMR_CMD_PARAM_2, lun);
	wd719x_writeb(wd, WD719X_AMR_CMD_PARAM_3, tag);
	if (data)
		wd719x_writel(wd, WD719X_AMR_SCB_IN, data);

	/* clear interrupt status register again */
	wd719x_writeb(wd, WD719X_AMR_INT_STATUS, WD719X_INT_NONE);

	/* Now, write the command */
	wd719x_writeb(wd, WD719X_AMR_COMMAND, opcode);

	if (timeout)	/* wait for the command to complete */
		ret = wd719x_wait_done(wd, timeout);

	/* clear interrupt status register (clean up) */
	if (opcode != WD719X_CMD_READ_FIRMVER)
		wd719x_writeb(wd, WD719X_AMR_INT_STATUS, WD719X_INT_NONE);

	return ret;
}

static void wd719x_destroy(struct wd719x *wd)
{
	/* stop the RISC */
	if (wd719x_direct_cmd(wd, WD719X_CMD_SLEEP, 0, 0, 0, 0,
			      WD719X_WAIT_FOR_RISC))
		dev_warn(&wd->pdev->dev, "RISC sleep command failed\n");
	/* disable RISC */
	wd719x_writeb(wd, WD719X_PCI_MODE_SELECT, 0);

	WARN_ON_ONCE(!list_empty(&wd->active_scbs));

	/* free internal buffers */
	dma_free_coherent(&wd->pdev->dev, wd->fw_size, wd->fw_virt,
			  wd->fw_phys);
	wd->fw_virt = NULL;
	dma_free_coherent(&wd->pdev->dev, WD719X_HASH_TABLE_SIZE, wd->hash_virt,
			  wd->hash_phys);
	wd->hash_virt = NULL;
	dma_free_coherent(&wd->pdev->dev, sizeof(struct wd719x_host_param),
			  wd->params, wd->params_phys);
	wd->params = NULL;
	free_irq(wd->pdev->irq, wd);
}

/* finish a SCSI command, unmap buffers */
static void wd719x_finish_cmd(struct wd719x_scb *scb, int result)
{
	struct scsi_cmnd *cmd = scb->cmd;
	struct wd719x *wd = shost_priv(cmd->device->host);

	list_del(&scb->list);

	dma_unmap_single(&wd->pdev->dev, scb->phys,
			sizeof(struct wd719x_scb), DMA_BIDIRECTIONAL);
	scsi_dma_unmap(cmd);
	dma_unmap_single(&wd->pdev->dev, cmd->SCp.dma_handle,
			 SCSI_SENSE_BUFFERSIZE, DMA_FROM_DEVICE);

	cmd->result = result << 16;
	cmd->scsi_done(cmd);
}

/* Build a SCB and send it to the card */
static int wd719x_queuecommand(struct Scsi_Host *sh, struct scsi_cmnd *cmd)
{
	int i, count_sg;
	unsigned long flags;
	struct wd719x_scb *scb = scsi_cmd_priv(cmd);
	struct wd719x *wd = shost_priv(sh);

	scb->cmd = cmd;

	scb->CDB_tag = 0;	/* Tagged queueing not supported yet */
	scb->devid = cmd->device->id;
	scb->lun = cmd->device->lun;

	/* copy the command */
	memcpy(scb->CDB, cmd->cmnd, cmd->cmd_len);

	/* map SCB */
	scb->phys = dma_map_single(&wd->pdev->dev, scb, sizeof(*scb),
				   DMA_BIDIRECTIONAL);

	if (dma_mapping_error(&wd->pdev->dev, scb->phys))
		goto out_error;

	/* map sense buffer */
	scb->sense_buf_length = SCSI_SENSE_BUFFERSIZE;
	cmd->SCp.dma_handle = dma_map_single(&wd->pdev->dev, cmd->sense_buffer,
			SCSI_SENSE_BUFFERSIZE, DMA_FROM_DEVICE);
	if (dma_mapping_error(&wd->pdev->dev, cmd->SCp.dma_handle))
		goto out_unmap_scb;
	scb->sense_buf = cpu_to_le32(cmd->SCp.dma_handle);

	/* request autosense */
	scb->SCB_options |= WD719X_SCB_FLAGS_AUTO_REQUEST_SENSE;

	/* check direction */
	if (cmd->sc_data_direction == DMA_TO_DEVICE)
		scb->SCB_options |= WD719X_SCB_FLAGS_CHECK_DIRECTION
				 |  WD719X_SCB_FLAGS_PCI_TO_SCSI;
	else if (cmd->sc_data_direction == DMA_FROM_DEVICE)
		scb->SCB_options |= WD719X_SCB_FLAGS_CHECK_DIRECTION;

	/* Scather/gather */
	count_sg = scsi_dma_map(cmd);
	if (count_sg < 0)
		goto out_unmap_sense;
	BUG_ON(count_sg > WD719X_SG);

	if (count_sg) {
		struct scatterlist *sg;

		scb->data_length = cpu_to_le32(count_sg *
					       sizeof(struct wd719x_sglist));
		scb->data_p = cpu_to_le32(scb->phys +
					  offsetof(struct wd719x_scb, sg_list));

		scsi_for_each_sg(cmd, sg, count_sg, i) {
			scb->sg_list[i].ptr = cpu_to_le32(sg_dma_address(sg));
			scb->sg_list[i].length = cpu_to_le32(sg_dma_len(sg));
		}
		scb->SCB_options |= WD719X_SCB_FLAGS_DO_SCATTER_GATHER;
	} else { /* zero length */
		scb->data_length = 0;
		scb->data_p = 0;
	}

	spin_lock_irqsave(wd->sh->host_lock, flags);

	/* check if the Command register is free */
	if (wd719x_readb(wd, WD719X_AMR_COMMAND) != WD719X_CMD_READY) {
		spin_unlock_irqrestore(wd->sh->host_lock, flags);
		return SCSI_MLQUEUE_HOST_BUSY;
	}

	list_add(&scb->list, &wd->active_scbs);

	/* write pointer to the AMR */
	wd719x_writel(wd, WD719X_AMR_SCB_IN, scb->phys);
	/* send SCB opcode */
	wd719x_writeb(wd, WD719X_AMR_COMMAND, WD719X_CMD_PROCESS_SCB);

	spin_unlock_irqrestore(wd->sh->host_lock, flags);
	return 0;

out_unmap_sense:
	dma_unmap_single(&wd->pdev->dev, cmd->SCp.dma_handle,
			 SCSI_SENSE_BUFFERSIZE, DMA_FROM_DEVICE);
out_unmap_scb:
	dma_unmap_single(&wd->pdev->dev, scb->phys, sizeof(*scb),
			 DMA_BIDIRECTIONAL);
out_error:
	cmd->result = DID_ERROR << 16;
	cmd->scsi_done(cmd);
	return 0;
}

static int wd719x_chip_init(struct wd719x *wd)
{
	int i, ret;
	u32 risc_init[3];
	const struct firmware *fw_wcs, *fw_risc;
	const char fwname_wcs[] = "wd719x-wcs.bin";
	const char fwname_risc[] = "wd719x-risc.bin";

	memset(wd->hash_virt, 0, WD719X_HASH_TABLE_SIZE);

	/* WCS (sequencer) firmware */
	ret = request_firmware(&fw_wcs, fwname_wcs, &wd->pdev->dev);
	if (ret) {
		dev_err(&wd->pdev->dev, "Unable to load firmware %s: %d\n",
			fwname_wcs, ret);
		return ret;
	}
	/* RISC firmware */
	ret = request_firmware(&fw_risc, fwname_risc, &wd->pdev->dev);
	if (ret) {
		dev_err(&wd->pdev->dev, "Unable to load firmware %s: %d\n",
			fwname_risc, ret);
		release_firmware(fw_wcs);
		return ret;
	}
	wd->fw_size = ALIGN(fw_wcs->size, 4) + fw_risc->size;

	if (!wd->fw_virt)
		wd->fw_virt = dma_alloc_coherent(&wd->pdev->dev, wd->fw_size,
						 &wd->fw_phys, GFP_KERNEL);
	if (!wd->fw_virt) {
		ret = -ENOMEM;
		goto wd719x_init_end;
	}

	/* make a fresh copy of WCS and RISC code */
	memcpy(wd->fw_virt, fw_wcs->data, fw_wcs->size);
	memcpy(wd->fw_virt + ALIGN(fw_wcs->size, 4), fw_risc->data,
		fw_risc->size);

	/* Reset the Spider Chip and adapter itself */
	wd719x_writeb(wd, WD719X_PCI_PORT_RESET, WD719X_PCI_RESET);
	udelay(WD719X_WAIT_FOR_RISC);
	/* Clear PIO mode bits set by BIOS */
	wd719x_writeb(wd, WD719X_AMR_CMD_PARAM, 0);
	/* ensure RISC is not running */
	wd719x_writeb(wd, WD719X_PCI_MODE_SELECT, 0);
	/* ensure command port is ready */
	wd719x_writeb(wd, WD719X_AMR_COMMAND, 0);
	if (wd719x_wait_ready(wd)) {
		ret = -ETIMEDOUT;
		goto wd719x_init_end;
	}

	/* Transfer the first 2K words of RISC code to kick start the uP */
	risc_init[0] = wd->fw_phys;				/* WCS FW */
	risc_init[1] = wd->fw_phys + ALIGN(fw_wcs->size, 4);	/* RISC FW */
	risc_init[2] = wd->hash_phys;				/* hash table */

	/* clear DMA status */
	wd719x_writeb(wd, WD719X_PCI_CHANNEL2_3STATUS, 0);

	/* address to read firmware from */
	wd719x_writel(wd, WD719X_PCI_EXTERNAL_ADDR, risc_init[1]);
	/* base address to write firmware to (on card) */
	wd719x_writew(wd, WD719X_PCI_INTERNAL_ADDR, WD719X_PRAM_BASE_ADDR);
	/* size: first 2K words */
	wd719x_writew(wd, WD719X_PCI_DMA_TRANSFER_SIZE, 2048 * 2);
	/* start DMA */
	wd719x_writeb(wd, WD719X_PCI_CHANNEL2_3CMD, WD719X_START_CHANNEL2_3DMA);

	/* wait for DMA to complete */
	i = WD719X_WAIT_FOR_RISC;
	while (i-- > 0) {
		u8 status = wd719x_readb(wd, WD719X_PCI_CHANNEL2_3STATUS);
		if (status == WD719X_START_CHANNEL2_3DONE)
			break;
		if (status == WD719X_START_CHANNEL2_3ABORT) {
			dev_warn(&wd->pdev->dev, "RISC bootstrap failed: DMA aborted\n");
			ret = -EIO;
			goto wd719x_init_end;
		}
		udelay(1);
	}
	if (i < 1) {
		dev_warn(&wd->pdev->dev, "RISC bootstrap failed: DMA timeout\n");
		ret = -ETIMEDOUT;
		goto wd719x_init_end;
	}

	/* firmware is loaded, now initialize and wake up the RISC */
	/* write RISC initialization long words to Spider */
	wd719x_writel(wd, WD719X_AMR_SCB_IN, risc_init[0]);
	wd719x_writel(wd, WD719X_AMR_SCB_IN + 4, risc_init[1]);
	wd719x_writel(wd, WD719X_AMR_SCB_IN + 8, risc_init[2]);

	/* disable interrupts during initialization of RISC */
	wd719x_writeb(wd, WD719X_AMR_CMD_PARAM, WD719X_DISABLE_INT);

	/* issue INITIALIZE RISC comand */
	wd719x_writeb(wd, WD719X_AMR_COMMAND, WD719X_CMD_INIT_RISC);
	/* enable advanced mode (wake up RISC) */
	wd719x_writeb(wd, WD719X_PCI_MODE_SELECT, WD719X_ENABLE_ADVANCE_MODE);
	udelay(WD719X_WAIT_FOR_RISC);

	ret = wd719x_wait_done(wd, WD719X_WAIT_FOR_RISC);
	/* clear interrupt status register */
	wd719x_writeb(wd, WD719X_AMR_INT_STATUS, WD719X_INT_NONE);
	if (ret) {
		dev_warn(&wd->pdev->dev, "Unable to initialize RISC\n");
		goto wd719x_init_end;
	}
	/* RISC is up and running */

	/* Read FW version from RISC */
	ret = wd719x_direct_cmd(wd, WD719X_CMD_READ_FIRMVER, 0, 0, 0, 0,
				WD719X_WAIT_FOR_RISC);
	if (ret) {
		dev_warn(&wd->pdev->dev, "Unable to read firmware version\n");
		goto wd719x_init_end;
	}
	dev_info(&wd->pdev->dev, "RISC initialized with firmware version %.2x.%.2x\n",
			wd719x_readb(wd, WD719X_AMR_SCB_OUT + 1),
			wd719x_readb(wd, WD719X_AMR_SCB_OUT));

	/* RESET SCSI bus */
	ret = wd719x_direct_cmd(wd, WD719X_CMD_BUSRESET, 0, 0, 0, 0,
				WD719X_WAIT_FOR_SCSI_RESET);
	if (ret) {
		dev_warn(&wd->pdev->dev, "SCSI bus reset failed\n");
		goto wd719x_init_end;
	}

	/* use HostParameter structure to set Spider's Host Parameter Block */
	ret = wd719x_direct_cmd(wd, WD719X_CMD_SET_PARAM, 0,
				sizeof(struct wd719x_host_param), 0,
				wd->params_phys, WD719X_WAIT_FOR_RISC);
	if (ret) {
		dev_warn(&wd->pdev->dev, "Failed to set HOST PARAMETERS\n");
		goto wd719x_init_end;
	}

	/* initiate SCAM (does nothing if disabled in BIOS) */
	/* bug?: we should pass a mask of static IDs which we don't have */
	ret = wd719x_direct_cmd(wd, WD719X_CMD_INIT_SCAM, 0, 0, 0, 0,
				WD719X_WAIT_FOR_SCSI_RESET);
	if (ret) {
		dev_warn(&wd->pdev->dev, "SCAM initialization failed\n");
		goto wd719x_init_end;
	}

	/* clear AMR_BIOS_SHARE_INT register */
	wd719x_writeb(wd, WD719X_AMR_BIOS_SHARE_INT, 0);

wd719x_init_end:
	release_firmware(fw_wcs);
	release_firmware(fw_risc);

	return ret;
}

static int wd719x_abort(struct scsi_cmnd *cmd)
{
	int action, result;
	unsigned long flags;
	struct wd719x_scb *scb = scsi_cmd_priv(cmd);
	struct wd719x *wd = shost_priv(cmd->device->host);

	dev_info(&wd->pdev->dev, "abort command, tag: %x\n", cmd->tag);

	action = /*cmd->tag ? WD719X_CMD_ABORT_TAG : */WD719X_CMD_ABORT;

	spin_lock_irqsave(wd->sh->host_lock, flags);
	result = wd719x_direct_cmd(wd, action, cmd->device->id,
				   cmd->device->lun, cmd->tag, scb->phys, 0);
	spin_unlock_irqrestore(wd->sh->host_lock, flags);
	if (result)
		return FAILED;

	return SUCCESS;
}

static int wd719x_reset(struct scsi_cmnd *cmd, u8 opcode, u8 device)
{
	int result;
	unsigned long flags;
	struct wd719x *wd = shost_priv(cmd->device->host);

	dev_info(&wd->pdev->dev, "%s reset requested\n",
		 (opcode == WD719X_CMD_BUSRESET) ? "bus" : "device");

	spin_lock_irqsave(wd->sh->host_lock, flags);
	result = wd719x_direct_cmd(wd, opcode, device, 0, 0, 0,
				   WD719X_WAIT_FOR_SCSI_RESET);
	spin_unlock_irqrestore(wd->sh->host_lock, flags);
	if (result)
		return FAILED;

	return SUCCESS;
}

static int wd719x_dev_reset(struct scsi_cmnd *cmd)
{
	return wd719x_reset(cmd, WD719X_CMD_RESET, cmd->device->id);
}

static int wd719x_bus_reset(struct scsi_cmnd *cmd)
{
	return wd719x_reset(cmd, WD719X_CMD_BUSRESET, 0);
}

static int wd719x_host_reset(struct scsi_cmnd *cmd)
{
	struct wd719x *wd = shost_priv(cmd->device->host);
	struct wd719x_scb *scb, *tmp;
	unsigned long flags;
	int result;

	dev_info(&wd->pdev->dev, "host reset requested\n");
	spin_lock_irqsave(wd->sh->host_lock, flags);
	/* Try to reinit the RISC */
	if (wd719x_chip_init(wd) == 0)
		result = SUCCESS;
	else
		result = FAILED;

	/* flush all SCBs */
	list_for_each_entry_safe(scb, tmp, &wd->active_scbs, list)
		wd719x_finish_cmd(scb, result);
	spin_unlock_irqrestore(wd->sh->host_lock, flags);

	return result;
}

static int wd719x_biosparam(struct scsi_device *sdev, struct block_device *bdev,
			    sector_t capacity, int geom[])
{
	if (capacity >= 0x200000) {
		geom[0] = 255;	/* heads */
		geom[1] = 63;	/* sectors */
	} else {
		geom[0] = 64;	/* heads */
		geom[1] = 32;	/* sectors */
	}
	geom[2] = sector_div(capacity, geom[0] * geom[1]);	/* cylinders */

	return 0;
}

/* process a SCB-completion interrupt */
static inline void wd719x_interrupt_SCB(struct wd719x *wd,
					union wd719x_regs regs,
					struct wd719x_scb *scb)
{
	int result;

	/* now have to find result from card */
	switch (regs.bytes.SUE) {
	case WD719X_SUE_NOERRORS:
		result = DID_OK;
		break;
	case WD719X_SUE_REJECTED:
		dev_err(&wd->pdev->dev, "command rejected\n");
		result = DID_ERROR;
		break;
	case WD719X_SUE_SCBQFULL:
		dev_err(&wd->pdev->dev, "SCB queue is full\n");
		result = DID_ERROR;
		break;
	case WD719X_SUE_TERM:
		dev_dbg(&wd->pdev->dev, "SCB terminated by direct command\n");
		result = DID_ABORT;	/* or DID_RESET? */
		break;
	case WD719X_SUE_CHAN1ABORT:
	case WD719X_SUE_CHAN23ABORT:
		result = DID_ABORT;
		dev_err(&wd->pdev->dev, "DMA abort\n");
		break;
	case WD719X_SUE_CHAN1PAR:
	case WD719X_SUE_CHAN23PAR:
		result = DID_PARITY;
		dev_err(&wd->pdev->dev, "DMA parity error\n");
		break;
	case WD719X_SUE_TIMEOUT:
		result = DID_TIME_OUT;
		dev_dbg(&wd->pdev->dev, "selection timeout\n");
		break;
	case WD719X_SUE_RESET:
		dev_dbg(&wd->pdev->dev, "bus reset occurred\n");
		result = DID_RESET;
		break;
	case WD719X_SUE_BUSERROR:
		dev_dbg(&wd->pdev->dev, "SCSI bus error\n");
		result = DID_ERROR;
		break;
	case WD719X_SUE_WRONGWAY:
		dev_err(&wd->pdev->dev, "wrong data transfer direction\n");
		result = DID_ERROR;
		break;
	case WD719X_SUE_BADPHASE:
		dev_err(&wd->pdev->dev, "invalid SCSI phase\n");
		result = DID_ERROR;
		break;
	case WD719X_SUE_TOOLONG:
		dev_err(&wd->pdev->dev, "record too long\n");
		result = DID_ERROR;
		break;
	case WD719X_SUE_BUSFREE:
		dev_err(&wd->pdev->dev, "unexpected bus free\n");
		result = DID_NO_CONNECT; /* or DID_ERROR ???*/
		break;
	case WD719X_SUE_ARSDONE:
		dev_dbg(&wd->pdev->dev, "auto request sense\n");
		if (regs.bytes.SCSI == 0)
			result = DID_OK;
		else
			result = DID_PARITY;
		break;
	case WD719X_SUE_IGNORED:
		dev_err(&wd->pdev->dev, "target id %d ignored command\n",
			scb->cmd->device->id);
		result = DID_NO_CONNECT;
		break;
	case WD719X_SUE_WRONGTAGS:
		dev_err(&wd->pdev->dev, "reversed tags\n");
		result = DID_ERROR;
		break;
	case WD719X_SUE_BADTAGS:
		dev_err(&wd->pdev->dev, "tag type not supported by target\n");
		result = DID_ERROR;
		break;
	case WD719X_SUE_NOSCAMID:
		dev_err(&wd->pdev->dev, "no SCAM soft ID available\n");
		result = DID_ERROR;
		break;
	default:
		dev_warn(&wd->pdev->dev, "unknown SUE error code: 0x%x\n",
			 regs.bytes.SUE);
		result = DID_ERROR;
		break;
	}

	wd719x_finish_cmd(scb, result);
}

static irqreturn_t wd719x_interrupt(int irq, void *dev_id)
{
	struct wd719x *wd = dev_id;
	union wd719x_regs regs;
	unsigned long flags;
	u32 SCB_out;

	spin_lock_irqsave(wd->sh->host_lock, flags);
	/* read SCB pointer back from card */
	SCB_out = wd719x_readl(wd, WD719X_AMR_SCB_OUT);
	/* read all status info at once */
	regs.all = cpu_to_le32(wd719x_readl(wd, WD719X_AMR_OP_CODE));

	switch (regs.bytes.INT) {
	case WD719X_INT_NONE:
		spin_unlock_irqrestore(wd->sh->host_lock, flags);
		return IRQ_NONE;
	case WD719X_INT_LINKNOSTATUS:
		dev_err(&wd->pdev->dev, "linked command completed with no status\n");
		break;
	case WD719X_INT_BADINT:
		dev_err(&wd->pdev->dev, "unsolicited interrupt\n");
		break;
	case WD719X_INT_NOERRORS:
	case WD719X_INT_LINKNOERRORS:
	case WD719X_INT_ERRORSLOGGED:
	case WD719X_INT_SPIDERFAILED:
		/* was the cmd completed a direct or SCB command? */
		if (regs.bytes.OPC == WD719X_CMD_PROCESS_SCB) {
			struct wd719x_scb *scb;
			list_for_each_entry(scb, &wd->active_scbs, list)
				if (SCB_out == scb->phys)
					break;
			if (SCB_out == scb->phys)
				wd719x_interrupt_SCB(wd, regs, scb);
			else
				dev_err(&wd->pdev->dev, "card returned invalid SCB pointer\n");
		} else
			dev_warn(&wd->pdev->dev, "direct command 0x%x completed\n",
				 regs.bytes.OPC);
		break;
	case WD719X_INT_PIOREADY:
		dev_err(&wd->pdev->dev, "card indicates PIO data ready but we never use PIO\n");
		/* interrupt will not be cleared until all data is read */
		break;
	default:
		dev_err(&wd->pdev->dev, "unknown interrupt reason: %d\n",
			regs.bytes.INT);

	}
	/* clear interrupt so another can happen */
	wd719x_writeb(wd, WD719X_AMR_INT_STATUS, WD719X_INT_NONE);
	spin_unlock_irqrestore(wd->sh->host_lock, flags);

	return IRQ_HANDLED;
}

static void wd719x_eeprom_reg_read(struct eeprom_93cx6 *eeprom)
{
	struct wd719x *wd = eeprom->data;
	u8 reg = wd719x_readb(wd, WD719X_PCI_GPIO_DATA);

	eeprom->reg_data_out = reg & WD719X_EE_DO;
}

static void wd719x_eeprom_reg_write(struct eeprom_93cx6 *eeprom)
{
	struct wd719x *wd = eeprom->data;
	u8 reg = 0;

	if (eeprom->reg_data_in)
		reg |= WD719X_EE_DI;
	if (eeprom->reg_data_clock)
		reg |= WD719X_EE_CLK;
	if (eeprom->reg_chip_select)
		reg |= WD719X_EE_CS;

	wd719x_writeb(wd, WD719X_PCI_GPIO_DATA, reg);
}

/* read config from EEPROM so it can be downloaded by the RISC on (re-)init */
static void wd719x_read_eeprom(struct wd719x *wd)
{
	struct eeprom_93cx6 eeprom;
	u8 gpio;
	struct wd719x_eeprom_header header;

	eeprom.data = wd;
	eeprom.register_read = wd719x_eeprom_reg_read;
	eeprom.register_write = wd719x_eeprom_reg_write;
	eeprom.width = PCI_EEPROM_WIDTH_93C46;

	/* set all outputs to low */
	wd719x_writeb(wd, WD719X_PCI_GPIO_DATA, 0);
	/* configure GPIO pins */
	gpio = wd719x_readb(wd, WD719X_PCI_GPIO_CONTROL);
	/* GPIO outputs */
	gpio &= (~(WD719X_EE_CLK | WD719X_EE_DI | WD719X_EE_CS));
	/* GPIO input */
	gpio |= WD719X_EE_DO;
	wd719x_writeb(wd, WD719X_PCI_GPIO_CONTROL, gpio);

	/* read EEPROM header */
	eeprom_93cx6_multireadb(&eeprom, 0, (u8 *)&header, sizeof(header));

	if (header.sig1 == 'W' && header.sig2 == 'D')
		eeprom_93cx6_multireadb(&eeprom, header.cfg_offset,
					(u8 *)wd->params,
					sizeof(struct wd719x_host_param));
	else { /* default EEPROM values */
		dev_warn(&wd->pdev->dev, "EEPROM signature is invalid (0x%02x 0x%02x), using default values\n",
			 header.sig1, header.sig2);
		wd->params->ch_1_th	= 0x10;	/* 16 DWs = 64 B */
		wd->params->scsi_conf	= 0x4c;	/* 48ma, spue, parity check */
		wd->params->own_scsi_id	= 0x07;	/* ID 7, SCAM disabled */
		wd->params->sel_timeout = 0x4d;	/* 250 ms */
		wd->params->sleep_timer	= 0x01;
		wd->params->cdb_size	= cpu_to_le16(0x5555);	/* all 6 B */
		wd->params->scsi_pad	= 0x1b;
		if (wd->type == WD719X_TYPE_7193) /* narrow card - disable */
			wd->params->wide = cpu_to_le32(0x00000000);
		else	/* initiate & respond to WIDE messages */
			wd->params->wide = cpu_to_le32(0xffffffff);
		wd->params->sync	= cpu_to_le32(0xffffffff);
		wd->params->soft_mask	= 0x00;	/* all disabled */
		wd->params->unsol_mask	= 0x00;	/* all disabled */
	}
	/* disable TAGGED messages */
	wd->params->tag_en = cpu_to_le16(0x0000);
}

/* Read card type from GPIO bits 1 and 3 */
static enum wd719x_card_type wd719x_detect_type(struct wd719x *wd)
{
	u8 card = wd719x_readb(wd, WD719X_PCI_GPIO_CONTROL);

	card |= WD719X_GPIO_ID_BITS;
	wd719x_writeb(wd, WD719X_PCI_GPIO_CONTROL, card);
	card = wd719x_readb(wd, WD719X_PCI_GPIO_DATA) & WD719X_GPIO_ID_BITS;
	switch (card) {
	case 0x08:
		return WD719X_TYPE_7193;
	case 0x02:
		return WD719X_TYPE_7197;
	case 0x00:
		return WD719X_TYPE_7296;
	default:
		dev_warn(&wd->pdev->dev, "unknown card type 0x%x\n", card);
		return WD719X_TYPE_UNKNOWN;
	}
}

static int wd719x_board_found(struct Scsi_Host *sh)
{
	struct wd719x *wd = shost_priv(sh);
	static const char * const card_types[] = {
		"Unknown card", "WD7193", "WD7197", "WD7296"
	};
	int ret;

	INIT_LIST_HEAD(&wd->active_scbs);

	sh->base = pci_resource_start(wd->pdev, 0);

	wd->type = wd719x_detect_type(wd);

	wd->sh = sh;
	sh->irq = wd->pdev->irq;
	wd->fw_virt = NULL;

	/* memory area for host (EEPROM) parameters */
	wd->params = dma_alloc_coherent(&wd->pdev->dev,
					sizeof(struct wd719x_host_param),
					&wd->params_phys, GFP_KERNEL);
	if (!wd->params) {
		dev_warn(&wd->pdev->dev, "unable to allocate parameter buffer\n");
		return -ENOMEM;
	}

	/* memory area for the RISC for hash table of outstanding requests */
	wd->hash_virt = dma_alloc_coherent(&wd->pdev->dev,
					   WD719X_HASH_TABLE_SIZE,
					   &wd->hash_phys, GFP_KERNEL);
	if (!wd->hash_virt) {
		dev_warn(&wd->pdev->dev, "unable to allocate hash buffer\n");
		ret = -ENOMEM;
		goto fail_free_params;
	}

	ret = request_irq(wd->pdev->irq, wd719x_interrupt, IRQF_SHARED,
			  "wd719x", wd);
	if (ret) {
		dev_warn(&wd->pdev->dev, "unable to assign IRQ %d\n",
			 wd->pdev->irq);
		goto fail_free_hash;
	}

	/* read parameters from EEPROM */
	wd719x_read_eeprom(wd);

	ret = wd719x_chip_init(wd);
	if (ret)
		goto fail_free_irq;

	sh->this_id = wd->params->own_scsi_id & WD719X_EE_SCSI_ID_MASK;

	dev_info(&wd->pdev->dev, "%s at I/O 0x%lx, IRQ %u, SCSI ID %d\n",
		 card_types[wd->type], sh->base, sh->irq, sh->this_id);

	return 0;

fail_free_irq:
	free_irq(wd->pdev->irq, wd);
fail_free_hash:
	dma_free_coherent(&wd->pdev->dev, WD719X_HASH_TABLE_SIZE, wd->hash_virt,
			    wd->hash_phys);
fail_free_params:
	dma_free_coherent(&wd->pdev->dev, sizeof(struct wd719x_host_param),
			    wd->params, wd->params_phys);

	return ret;
}

static struct scsi_host_template wd719x_template = {
	.module				= THIS_MODULE,
	.name				= "Western Digital 719x",
	.cmd_size			= sizeof(struct wd719x_scb),
	.queuecommand			= wd719x_queuecommand,
	.eh_abort_handler		= wd719x_abort,
	.eh_device_reset_handler	= wd719x_dev_reset,
	.eh_bus_reset_handler		= wd719x_bus_reset,
	.eh_host_reset_handler		= wd719x_host_reset,
	.bios_param			= wd719x_biosparam,
	.proc_name			= "wd719x",
	.can_queue			= 255,
	.this_id			= 7,
	.sg_tablesize			= WD719X_SG,
};

static int wd719x_pci_probe(struct pci_dev *pdev, const struct pci_device_id *d)
{
	int err;
	struct Scsi_Host *sh;
	struct wd719x *wd;

	err = pci_enable_device(pdev);
	if (err)
		goto fail;

	if (dma_set_mask(&pdev->dev, DMA_BIT_MASK(32))) {
		dev_warn(&pdev->dev, "Unable to set 32-bit DMA mask\n");
		goto disable_device;
	}

	err = pci_request_regions(pdev, "wd719x");
	if (err)
		goto disable_device;
	pci_set_master(pdev);

	err = -ENODEV;
	if (pci_resource_len(pdev, 0) == 0)
		goto release_region;

	err = -ENOMEM;
	sh = scsi_host_alloc(&wd719x_template, sizeof(struct wd719x));
	if (!sh)
		goto release_region;

	wd = shost_priv(sh);
	wd->base = pci_iomap(pdev, 0, 0);
	if (!wd->base)
		goto free_host;
	wd->pdev = pdev;

	err = wd719x_board_found(sh);
	if (err)
		goto unmap;

	err = scsi_add_host(sh, &wd->pdev->dev);
	if (err)
		goto destroy;

	scsi_scan_host(sh);

	pci_set_drvdata(pdev, sh);
	return 0;

destroy:
	wd719x_destroy(wd);
unmap:
	pci_iounmap(pdev, wd->base);
free_host:
	scsi_host_put(sh);
release_region:
	pci_release_regions(pdev);
disable_device:
	pci_disable_device(pdev);
fail:
	return err;
}


static void wd719x_pci_remove(struct pci_dev *pdev)
{
	struct Scsi_Host *sh = pci_get_drvdata(pdev);
	struct wd719x *wd = shost_priv(sh);

	scsi_remove_host(sh);
	wd719x_destroy(wd);
	pci_iounmap(pdev, wd->base);
	pci_release_regions(pdev);
	pci_disable_device(pdev);

	scsi_host_put(sh);
}

static const struct pci_device_id wd719x_pci_table[] = {
	{ PCI_DEVICE(PCI_VENDOR_ID_WD, 0x3296) },
	{}
};

MODULE_DEVICE_TABLE(pci, wd719x_pci_table);

static struct pci_driver wd719x_pci_driver = {
	.name =		"wd719x",
	.id_table =	wd719x_pci_table,
	.probe =	wd719x_pci_probe,
	.remove =	wd719x_pci_remove,
};

module_pci_driver(wd719x_pci_driver);

MODULE_DESCRIPTION("Western Digital WD7193/7197/7296 SCSI driver");
MODULE_AUTHOR("Ondrej Zary, Aaron Dewell, Juergen Gaertner");
MODULE_LICENSE("GPL");
MODULE_FIRMWARE("wd719x-wcs.bin");
MODULE_FIRMWARE("wd719x-risc.bin");
