// SPDX-License-Identifier: GPL-2.0-only
/*
 * 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");
