/*
 * Support for IDE interfaces on Celleb platform
 *
 * (C) Copyright 2006 TOSHIBA CORPORATION
 *
 * This code is based on drivers/ata/ata_piix.c:
 *  Copyright 2003-2005 Red Hat Inc
 *  Copyright 2003-2005 Jeff Garzik
 *  Copyright (C) 1998-1999 Andrzej Krzysztofowicz, Author and Maintainer
 *  Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org>
 *  Copyright (C) 2003 Red Hat Inc <alan@redhat.com>
 *
 * and drivers/ata/ahci.c:
 *  Copyright 2004-2005 Red Hat, Inc.
 *
 * and drivers/ata/libata-core.c:
 *  Copyright 2003-2004 Red Hat, Inc.  All rights reserved.
 *  Copyright 2003-2004 Jeff Garzik
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/blkdev.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <scsi/scsi_host.h>
#include <linux/libata.h>

#define DRV_NAME		"pata_scc"
#define DRV_VERSION		"0.2"

#define PCI_DEVICE_ID_TOSHIBA_SCC_ATA		0x01b4

/* PCI BARs */
#define SCC_CTRL_BAR		0
#define SCC_BMID_BAR		1

/* offset of CTRL registers */
#define SCC_CTL_PIOSHT		0x000
#define SCC_CTL_PIOCT		0x004
#define SCC_CTL_MDMACT		0x008
#define SCC_CTL_MCRCST		0x00C
#define SCC_CTL_SDMACT		0x010
#define SCC_CTL_SCRCST		0x014
#define SCC_CTL_UDENVT		0x018
#define SCC_CTL_TDVHSEL 	0x020
#define SCC_CTL_MODEREG 	0x024
#define SCC_CTL_ECMODE		0xF00
#define SCC_CTL_MAEA0		0xF50
#define SCC_CTL_MAEC0		0xF54
#define SCC_CTL_CCKCTRL 	0xFF0

/* offset of BMID registers */
#define SCC_DMA_CMD		0x000
#define SCC_DMA_STATUS		0x004
#define SCC_DMA_TABLE_OFS	0x008
#define SCC_DMA_INTMASK 	0x010
#define SCC_DMA_INTST		0x014
#define SCC_DMA_PTERADD 	0x018
#define SCC_REG_CMD_ADDR	0x020
#define SCC_REG_DATA		0x000
#define SCC_REG_ERR		0x004
#define SCC_REG_FEATURE 	0x004
#define SCC_REG_NSECT		0x008
#define SCC_REG_LBAL		0x00C
#define SCC_REG_LBAM		0x010
#define SCC_REG_LBAH		0x014
#define SCC_REG_DEVICE		0x018
#define SCC_REG_STATUS		0x01C
#define SCC_REG_CMD		0x01C
#define SCC_REG_ALTSTATUS	0x020

/* register value */
#define TDVHSEL_MASTER		0x00000001
#define TDVHSEL_SLAVE		0x00000004

#define MODE_JCUSFEN		0x00000080

#define ECMODE_VALUE		0x01

#define CCKCTRL_ATARESET	0x00040000
#define CCKCTRL_BUFCNT		0x00020000
#define CCKCTRL_CRST		0x00010000
#define CCKCTRL_OCLKEN		0x00000100
#define CCKCTRL_ATACLKOEN	0x00000002
#define CCKCTRL_LCLKEN		0x00000001

#define QCHCD_IOS_SS		0x00000001

#define QCHSD_STPDIAG		0x00020000

#define INTMASK_MSK		0xD1000012
#define INTSTS_SERROR		0x80000000
#define INTSTS_PRERR		0x40000000
#define INTSTS_RERR		0x10000000
#define INTSTS_ICERR		0x01000000
#define INTSTS_BMSINT		0x00000010
#define INTSTS_BMHE		0x00000008
#define INTSTS_IOIRQS		0x00000004
#define INTSTS_INTRQ		0x00000002
#define INTSTS_ACTEINT		0x00000001


/* PIO transfer mode table */
/* JCHST */
static const unsigned long JCHSTtbl[2][7] = {
	{0x0E, 0x05, 0x02, 0x03, 0x02, 0x00, 0x00},	/* 100MHz */
	{0x13, 0x07, 0x04, 0x04, 0x03, 0x00, 0x00}	/* 133MHz */
};

/* JCHHT */
static const unsigned long JCHHTtbl[2][7] = {
	{0x0E, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00},	/* 100MHz */
	{0x13, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00}	/* 133MHz */
};

/* JCHCT */
static const unsigned long JCHCTtbl[2][7] = {
	{0x1D, 0x1D, 0x1C, 0x0B, 0x06, 0x00, 0x00},	/* 100MHz */
	{0x27, 0x26, 0x26, 0x0E, 0x09, 0x00, 0x00}	/* 133MHz */
};

/* DMA transfer mode  table */
/* JCHDCTM/JCHDCTS */
static const unsigned long JCHDCTxtbl[2][7] = {
	{0x0A, 0x06, 0x04, 0x03, 0x01, 0x00, 0x00},	/* 100MHz */
	{0x0E, 0x09, 0x06, 0x04, 0x02, 0x01, 0x00}	/* 133MHz */
};

/* JCSTWTM/JCSTWTS  */
static const unsigned long JCSTWTxtbl[2][7] = {
	{0x06, 0x04, 0x03, 0x02, 0x02, 0x02, 0x00},	/* 100MHz */
	{0x09, 0x06, 0x04, 0x02, 0x02, 0x02, 0x02}	/* 133MHz */
};

/* JCTSS */
static const unsigned long JCTSStbl[2][7] = {
	{0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x00},	/* 100MHz */
	{0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05}	/* 133MHz */
};

/* JCENVT */
static const unsigned long JCENVTtbl[2][7] = {
	{0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00},	/* 100MHz */
	{0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02}	/* 133MHz */
};

/* JCACTSELS/JCACTSELM */
static const unsigned long JCACTSELtbl[2][7] = {
	{0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00},	/* 100MHz */
	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}	/* 133MHz */
};

static const struct pci_device_id scc_pci_tbl[] = {
	{PCI_VENDOR_ID_TOSHIBA_2, PCI_DEVICE_ID_TOSHIBA_SCC_ATA,
	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
	{ }	/* terminate list */
};

/**
 *	scc_set_piomode - Initialize host controller PATA PIO timings
 *	@ap: Port whose timings we are configuring
 *	@adev: um
 *
 *	Set PIO mode for device.
 *
 *	LOCKING:
 *	None (inherited from caller).
 */

static void scc_set_piomode (struct ata_port *ap, struct ata_device *adev)
{
	unsigned int pio = adev->pio_mode - XFER_PIO_0;
	void __iomem *ctrl_base = ap->host->iomap[SCC_CTRL_BAR];
	void __iomem *cckctrl_port = ctrl_base + SCC_CTL_CCKCTRL;
	void __iomem *piosht_port = ctrl_base + SCC_CTL_PIOSHT;
	void __iomem *pioct_port = ctrl_base + SCC_CTL_PIOCT;
	unsigned long reg;
	int offset;

	reg = in_be32(cckctrl_port);
	if (reg & CCKCTRL_ATACLKOEN)
		offset = 1;	/* 133MHz */
	else
		offset = 0;	/* 100MHz */

	reg = JCHSTtbl[offset][pio] << 16 | JCHHTtbl[offset][pio];
	out_be32(piosht_port, reg);
	reg = JCHCTtbl[offset][pio];
	out_be32(pioct_port, reg);
}

/**
 *	scc_set_dmamode - Initialize host controller PATA DMA timings
 *	@ap: Port whose timings we are configuring
 *	@adev: um
 *	@udma: udma mode, 0 - 6
 *
 *	Set UDMA mode for device.
 *
 *	LOCKING:
 *	None (inherited from caller).
 */

static void scc_set_dmamode (struct ata_port *ap, struct ata_device *adev)
{
	unsigned int udma = adev->dma_mode;
	unsigned int is_slave = (adev->devno != 0);
	u8 speed = udma;
	void __iomem *ctrl_base = ap->host->iomap[SCC_CTRL_BAR];
	void __iomem *cckctrl_port = ctrl_base + SCC_CTL_CCKCTRL;
	void __iomem *mdmact_port = ctrl_base + SCC_CTL_MDMACT;
	void __iomem *mcrcst_port = ctrl_base + SCC_CTL_MCRCST;
	void __iomem *sdmact_port = ctrl_base + SCC_CTL_SDMACT;
	void __iomem *scrcst_port = ctrl_base + SCC_CTL_SCRCST;
	void __iomem *udenvt_port = ctrl_base + SCC_CTL_UDENVT;
	void __iomem *tdvhsel_port = ctrl_base + SCC_CTL_TDVHSEL;
	int offset, idx;

	if (in_be32(cckctrl_port) & CCKCTRL_ATACLKOEN)
		offset = 1;	/* 133MHz */
	else
		offset = 0;	/* 100MHz */

	if (speed >= XFER_UDMA_0)
		idx = speed - XFER_UDMA_0;
	else
		return;

	if (is_slave) {
		out_be32(sdmact_port, JCHDCTxtbl[offset][idx]);
		out_be32(scrcst_port, JCSTWTxtbl[offset][idx]);
		out_be32(tdvhsel_port,
			 (in_be32(tdvhsel_port) & ~TDVHSEL_SLAVE) | (JCACTSELtbl[offset][idx] << 2));
	} else {
		out_be32(mdmact_port, JCHDCTxtbl[offset][idx]);
		out_be32(mcrcst_port, JCSTWTxtbl[offset][idx]);
		out_be32(tdvhsel_port,
			 (in_be32(tdvhsel_port) & ~TDVHSEL_MASTER) | JCACTSELtbl[offset][idx]);
	}
	out_be32(udenvt_port,
		 JCTSStbl[offset][idx] << 16 | JCENVTtbl[offset][idx]);
}

/**
 *	scc_tf_load - send taskfile registers to host controller
 *	@ap: Port to which output is sent
 *	@tf: ATA taskfile register set
 *
 *	Note: Original code is ata_tf_load().
 */

static void scc_tf_load (struct ata_port *ap, const struct ata_taskfile *tf)
{
	struct ata_ioports *ioaddr = &ap->ioaddr;
	unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR;

	if (tf->ctl != ap->last_ctl) {
		out_be32(ioaddr->ctl_addr, tf->ctl);
		ap->last_ctl = tf->ctl;
		ata_wait_idle(ap);
	}

	if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) {
		out_be32(ioaddr->feature_addr, tf->hob_feature);
		out_be32(ioaddr->nsect_addr, tf->hob_nsect);
		out_be32(ioaddr->lbal_addr, tf->hob_lbal);
		out_be32(ioaddr->lbam_addr, tf->hob_lbam);
		out_be32(ioaddr->lbah_addr, tf->hob_lbah);
		VPRINTK("hob: feat 0x%X nsect 0x%X, lba 0x%X 0x%X 0x%X\n",
			tf->hob_feature,
			tf->hob_nsect,
			tf->hob_lbal,
			tf->hob_lbam,
			tf->hob_lbah);
	}

	if (is_addr) {
		out_be32(ioaddr->feature_addr, tf->feature);
		out_be32(ioaddr->nsect_addr, tf->nsect);
		out_be32(ioaddr->lbal_addr, tf->lbal);
		out_be32(ioaddr->lbam_addr, tf->lbam);
		out_be32(ioaddr->lbah_addr, tf->lbah);
		VPRINTK("feat 0x%X nsect 0x%X lba 0x%X 0x%X 0x%X\n",
			tf->feature,
			tf->nsect,
			tf->lbal,
			tf->lbam,
			tf->lbah);
	}

	if (tf->flags & ATA_TFLAG_DEVICE) {
		out_be32(ioaddr->device_addr, tf->device);
		VPRINTK("device 0x%X\n", tf->device);
	}

	ata_wait_idle(ap);
}

/**
 *	scc_check_status - Read device status reg & clear interrupt
 *	@ap: port where the device is
 *
 *	Note: Original code is ata_check_status().
 */

static u8 scc_check_status (struct ata_port *ap)
{
	return in_be32(ap->ioaddr.status_addr);
}

/**
 *	scc_tf_read - input device's ATA taskfile shadow registers
 *	@ap: Port from which input is read
 *	@tf: ATA taskfile register set for storing input
 *
 *	Note: Original code is ata_tf_read().
 */

static void scc_tf_read (struct ata_port *ap, struct ata_taskfile *tf)
{
	struct ata_ioports *ioaddr = &ap->ioaddr;

	tf->command = scc_check_status(ap);
	tf->feature = in_be32(ioaddr->error_addr);
	tf->nsect = in_be32(ioaddr->nsect_addr);
	tf->lbal = in_be32(ioaddr->lbal_addr);
	tf->lbam = in_be32(ioaddr->lbam_addr);
	tf->lbah = in_be32(ioaddr->lbah_addr);
	tf->device = in_be32(ioaddr->device_addr);

	if (tf->flags & ATA_TFLAG_LBA48) {
		out_be32(ioaddr->ctl_addr, tf->ctl | ATA_HOB);
		tf->hob_feature = in_be32(ioaddr->error_addr);
		tf->hob_nsect = in_be32(ioaddr->nsect_addr);
		tf->hob_lbal = in_be32(ioaddr->lbal_addr);
		tf->hob_lbam = in_be32(ioaddr->lbam_addr);
		tf->hob_lbah = in_be32(ioaddr->lbah_addr);
	}
}

/**
 *	scc_exec_command - issue ATA command to host controller
 *	@ap: port to which command is being issued
 *	@tf: ATA taskfile register set
 *
 *	Note: Original code is ata_exec_command().
 */

static void scc_exec_command (struct ata_port *ap,
			      const struct ata_taskfile *tf)
{
	DPRINTK("ata%u: cmd 0x%X\n", ap->print_id, tf->command);

	out_be32(ap->ioaddr.command_addr, tf->command);
	ata_pause(ap);
}

/**
 *	scc_check_altstatus - Read device alternate status reg
 *	@ap: port where the device is
 */

static u8 scc_check_altstatus (struct ata_port *ap)
{
	return in_be32(ap->ioaddr.altstatus_addr);
}

/**
 *	scc_std_dev_select - Select device 0/1 on ATA bus
 *	@ap: ATA channel to manipulate
 *	@device: ATA device (numbered from zero) to select
 *
 *	Note: Original code is ata_std_dev_select().
 */

static void scc_std_dev_select (struct ata_port *ap, unsigned int device)
{
	u8 tmp;

	if (device == 0)
		tmp = ATA_DEVICE_OBS;
	else
		tmp = ATA_DEVICE_OBS | ATA_DEV1;

	out_be32(ap->ioaddr.device_addr, tmp);
	ata_pause(ap);
}

/**
 *	scc_bmdma_setup - Set up PCI IDE BMDMA transaction
 *	@qc: Info associated with this ATA transaction.
 *
 *	Note: Original code is ata_bmdma_setup().
 */

static void scc_bmdma_setup (struct ata_queued_cmd *qc)
{
	struct ata_port *ap = qc->ap;
	unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE);
	u8 dmactl;
	void __iomem *mmio = ap->ioaddr.bmdma_addr;

	/* load PRD table addr */
	out_be32(mmio + SCC_DMA_TABLE_OFS, ap->prd_dma);

	/* specify data direction, triple-check start bit is clear */
	dmactl = in_be32(mmio + SCC_DMA_CMD);
	dmactl &= ~(ATA_DMA_WR | ATA_DMA_START);
	if (!rw)
		dmactl |= ATA_DMA_WR;
	out_be32(mmio + SCC_DMA_CMD, dmactl);

	/* issue r/w command */
	ap->ops->exec_command(ap, &qc->tf);
}

/**
 *	scc_bmdma_start - Start a PCI IDE BMDMA transaction
 *	@qc: Info associated with this ATA transaction.
 *
 *	Note: Original code is ata_bmdma_start().
 */

static void scc_bmdma_start (struct ata_queued_cmd *qc)
{
	struct ata_port *ap = qc->ap;
	u8 dmactl;
	void __iomem *mmio = ap->ioaddr.bmdma_addr;

	/* start host DMA transaction */
	dmactl = in_be32(mmio + SCC_DMA_CMD);
	out_be32(mmio + SCC_DMA_CMD, dmactl | ATA_DMA_START);
}

/**
 *	scc_devchk - PATA device presence detection
 *	@ap: ATA channel to examine
 *	@device: Device to examine (starting at zero)
 *
 *	Note: Original code is ata_devchk().
 */

static unsigned int scc_devchk (struct ata_port *ap,
				unsigned int device)
{
	struct ata_ioports *ioaddr = &ap->ioaddr;
	u8 nsect, lbal;

	ap->ops->dev_select(ap, device);

	out_be32(ioaddr->nsect_addr, 0x55);
	out_be32(ioaddr->lbal_addr, 0xaa);

	out_be32(ioaddr->nsect_addr, 0xaa);
	out_be32(ioaddr->lbal_addr, 0x55);

	out_be32(ioaddr->nsect_addr, 0x55);
	out_be32(ioaddr->lbal_addr, 0xaa);

	nsect = in_be32(ioaddr->nsect_addr);
	lbal = in_be32(ioaddr->lbal_addr);

	if ((nsect == 0x55) && (lbal == 0xaa))
		return 1;	/* we found a device */

	return 0;		/* nothing found */
}

/**
 *	scc_bus_post_reset - PATA device post reset
 *
 *	Note: Original code is ata_bus_post_reset().
 */

static int scc_bus_post_reset(struct ata_port *ap, unsigned int devmask,
                              unsigned long deadline)
{
	struct ata_ioports *ioaddr = &ap->ioaddr;
	unsigned int dev0 = devmask & (1 << 0);
	unsigned int dev1 = devmask & (1 << 1);
	int rc;

	/* if device 0 was found in ata_devchk, wait for its
	 * BSY bit to clear
	 */
	if (dev0) {
		rc = ata_wait_ready(ap, deadline);
		if (rc && rc != -ENODEV)
			return rc;
	}

	/* if device 1 was found in ata_devchk, wait for
	 * register access, then wait for BSY to clear
	 */
	while (dev1) {
		u8 nsect, lbal;

		ap->ops->dev_select(ap, 1);
		nsect = in_be32(ioaddr->nsect_addr);
		lbal = in_be32(ioaddr->lbal_addr);
		if ((nsect == 1) && (lbal == 1))
			break;
		if (time_after(jiffies, deadline))
			return -EBUSY;
		msleep(50);	/* give drive a breather */
	}
	if (dev1) {
		rc = ata_wait_ready(ap, deadline);
		if (rc && rc != -ENODEV)
			return rc;
	}

	/* is all this really necessary? */
	ap->ops->dev_select(ap, 0);
	if (dev1)
		ap->ops->dev_select(ap, 1);
	if (dev0)
		ap->ops->dev_select(ap, 0);

	return 0;
}

/**
 *	scc_bus_softreset - PATA device software reset
 *
 *	Note: Original code is ata_bus_softreset().
 */

static unsigned int scc_bus_softreset(struct ata_port *ap, unsigned int devmask,
                                      unsigned long deadline)
{
	struct ata_ioports *ioaddr = &ap->ioaddr;

	DPRINTK("ata%u: bus reset via SRST\n", ap->print_id);

	/* software reset.  causes dev0 to be selected */
	out_be32(ioaddr->ctl_addr, ap->ctl);
	udelay(20);
	out_be32(ioaddr->ctl_addr, ap->ctl | ATA_SRST);
	udelay(20);
	out_be32(ioaddr->ctl_addr, ap->ctl);

	/* spec mandates ">= 2ms" before checking status.
	 * We wait 150ms, because that was the magic delay used for
	 * ATAPI devices in Hale Landis's ATADRVR, for the period of time
	 * between when the ATA command register is written, and then
	 * status is checked.  Because waiting for "a while" before
	 * checking status is fine, post SRST, we perform this magic
	 * delay here as well.
	 *
	 * Old drivers/ide uses the 2mS rule and then waits for ready
	 */
	msleep(150);

	/* Before we perform post reset processing we want to see if
	 * the bus shows 0xFF because the odd clown forgets the D7
	 * pulldown resistor.
	 */
	if (scc_check_status(ap) == 0xFF)
		return 0;

	scc_bus_post_reset(ap, devmask, deadline);

	return 0;
}

/**
 *	scc_std_softreset - reset host port via ATA SRST
 *	@ap: port to reset
 *	@classes: resulting classes of attached devices
 *	@deadline: deadline jiffies for the operation
 *
 *	Note: Original code is ata_std_softreset().
 */

static int scc_std_softreset (struct ata_port *ap, unsigned int *classes,
                              unsigned long deadline)
{
	unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS;
	unsigned int devmask = 0, err_mask;
	u8 err;

	DPRINTK("ENTER\n");

	if (ata_port_offline(ap)) {
		classes[0] = ATA_DEV_NONE;
		goto out;
	}

	/* determine if device 0/1 are present */
	if (scc_devchk(ap, 0))
		devmask |= (1 << 0);
	if (slave_possible && scc_devchk(ap, 1))
		devmask |= (1 << 1);

	/* select device 0 again */
	ap->ops->dev_select(ap, 0);

	/* issue bus reset */
	DPRINTK("about to softreset, devmask=%x\n", devmask);
	err_mask = scc_bus_softreset(ap, devmask, deadline);
	if (err_mask) {
		ata_port_printk(ap, KERN_ERR, "SRST failed (err_mask=0x%x)\n",
				err_mask);
		return -EIO;
	}

	/* determine by signature whether we have ATA or ATAPI devices */
	classes[0] = ata_dev_try_classify(ap, 0, &err);
	if (slave_possible && err != 0x81)
		classes[1] = ata_dev_try_classify(ap, 1, &err);

 out:
	DPRINTK("EXIT, classes[0]=%u [1]=%u\n", classes[0], classes[1]);
	return 0;
}

/**
 *	scc_bmdma_stop - Stop PCI IDE BMDMA transfer
 *	@qc: Command we are ending DMA for
 */

static void scc_bmdma_stop (struct ata_queued_cmd *qc)
{
	struct ata_port *ap = qc->ap;
	void __iomem *ctrl_base = ap->host->iomap[SCC_CTRL_BAR];
	void __iomem *bmid_base = ap->host->iomap[SCC_BMID_BAR];
	u32 reg;

	while (1) {
		reg = in_be32(bmid_base + SCC_DMA_INTST);

		if (reg & INTSTS_SERROR) {
			printk(KERN_WARNING "%s: SERROR\n", DRV_NAME);
			out_be32(bmid_base + SCC_DMA_INTST, INTSTS_SERROR|INTSTS_BMSINT);
			out_be32(bmid_base + SCC_DMA_CMD,
				 in_be32(bmid_base + SCC_DMA_CMD) & ~ATA_DMA_START);
			continue;
		}

		if (reg & INTSTS_PRERR) {
			u32 maea0, maec0;
			maea0 = in_be32(ctrl_base + SCC_CTL_MAEA0);
			maec0 = in_be32(ctrl_base + SCC_CTL_MAEC0);
			printk(KERN_WARNING "%s: PRERR [addr:%x cmd:%x]\n", DRV_NAME, maea0, maec0);
			out_be32(bmid_base + SCC_DMA_INTST, INTSTS_PRERR|INTSTS_BMSINT);
			out_be32(bmid_base + SCC_DMA_CMD,
				 in_be32(bmid_base + SCC_DMA_CMD) & ~ATA_DMA_START);
			continue;
		}

		if (reg & INTSTS_RERR) {
			printk(KERN_WARNING "%s: Response Error\n", DRV_NAME);
			out_be32(bmid_base + SCC_DMA_INTST, INTSTS_RERR|INTSTS_BMSINT);
			out_be32(bmid_base + SCC_DMA_CMD,
				 in_be32(bmid_base + SCC_DMA_CMD) & ~ATA_DMA_START);
			continue;
		}

		if (reg & INTSTS_ICERR) {
			out_be32(bmid_base + SCC_DMA_CMD,
				 in_be32(bmid_base + SCC_DMA_CMD) & ~ATA_DMA_START);
			printk(KERN_WARNING "%s: Illegal Configuration\n", DRV_NAME);
			out_be32(bmid_base + SCC_DMA_INTST, INTSTS_ICERR|INTSTS_BMSINT);
			continue;
		}

		if (reg & INTSTS_BMSINT) {
			unsigned int classes;
			unsigned long deadline = jiffies + ATA_TMOUT_BOOT;
			printk(KERN_WARNING "%s: Internal Bus Error\n", DRV_NAME);
			out_be32(bmid_base + SCC_DMA_INTST, INTSTS_BMSINT);
			/* TBD: SW reset */
			scc_std_softreset(ap, &classes, deadline);
			continue;
		}

		if (reg & INTSTS_BMHE) {
			out_be32(bmid_base + SCC_DMA_INTST, INTSTS_BMHE);
			continue;
		}

		if (reg & INTSTS_ACTEINT) {
			out_be32(bmid_base + SCC_DMA_INTST, INTSTS_ACTEINT);
			continue;
		}

		if (reg & INTSTS_IOIRQS) {
			out_be32(bmid_base + SCC_DMA_INTST, INTSTS_IOIRQS);
			continue;
		}
		break;
	}

	/* clear start/stop bit */
	out_be32(bmid_base + SCC_DMA_CMD,
		 in_be32(bmid_base + SCC_DMA_CMD) & ~ATA_DMA_START);

	/* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */
	ata_altstatus(ap);	/* dummy read */
}

/**
 *	scc_bmdma_status - Read PCI IDE BMDMA status
 *	@ap: Port associated with this ATA transaction.
 */

static u8 scc_bmdma_status (struct ata_port *ap)
{
	u8 host_stat;
	void __iomem *mmio = ap->ioaddr.bmdma_addr;

	host_stat = in_be32(mmio + SCC_DMA_STATUS);

	/* Workaround for PTERADD: emulate DMA_INTR when
	 * - IDE_STATUS[ERR] = 1
	 * - INT_STATUS[INTRQ] = 1
	 * - DMA_STATUS[IORACTA] = 1
	 */
	if (!(host_stat & ATA_DMA_INTR)) {
		u32 int_status = in_be32(mmio + SCC_DMA_INTST);
		if (ata_altstatus(ap) & ATA_ERR &&
		    int_status & INTSTS_INTRQ &&
		    host_stat & ATA_DMA_ACTIVE)
			host_stat |= ATA_DMA_INTR;
	}

	return host_stat;
}

/**
 *	scc_data_xfer - Transfer data by PIO
 *	@adev: device for this I/O
 *	@buf: data buffer
 *	@buflen: buffer length
 *	@write_data: read/write
 *
 *	Note: Original code is ata_data_xfer().
 */

static void scc_data_xfer (struct ata_device *adev, unsigned char *buf,
			   unsigned int buflen, int write_data)
{
	struct ata_port *ap = adev->ap;
	unsigned int words = buflen >> 1;
	unsigned int i;
	u16 *buf16 = (u16 *) buf;
	void __iomem *mmio = ap->ioaddr.data_addr;

	/* Transfer multiple of 2 bytes */
	if (write_data) {
		for (i = 0; i < words; i++)
			out_be32(mmio, cpu_to_le16(buf16[i]));
	} else {
		for (i = 0; i < words; i++)
			buf16[i] = le16_to_cpu(in_be32(mmio));
	}

	/* Transfer trailing 1 byte, if any. */
	if (unlikely(buflen & 0x01)) {
		u16 align_buf[1] = { 0 };
		unsigned char *trailing_buf = buf + buflen - 1;

		if (write_data) {
			memcpy(align_buf, trailing_buf, 1);
			out_be32(mmio, cpu_to_le16(align_buf[0]));
		} else {
			align_buf[0] = le16_to_cpu(in_be32(mmio));
			memcpy(trailing_buf, align_buf, 1);
		}
	}
}

/**
 *	scc_irq_on - Enable interrupts on a port.
 *	@ap: Port on which interrupts are enabled.
 *
 *	Note: Original code is ata_irq_on().
 */

static u8 scc_irq_on (struct ata_port *ap)
{
	struct ata_ioports *ioaddr = &ap->ioaddr;
	u8 tmp;

	ap->ctl &= ~ATA_NIEN;
	ap->last_ctl = ap->ctl;

	out_be32(ioaddr->ctl_addr, ap->ctl);
	tmp = ata_wait_idle(ap);

	ap->ops->irq_clear(ap);

	return tmp;
}

/**
 *	scc_irq_ack - Acknowledge a device interrupt.
 *	@ap: Port on which interrupts are enabled.
 *
 *	Note: Original code is ata_irq_ack().
 */

static u8 scc_irq_ack (struct ata_port *ap, unsigned int chk_drq)
{
	unsigned int bits = chk_drq ? ATA_BUSY | ATA_DRQ : ATA_BUSY;
	u8 host_stat, post_stat, status;

	status = ata_busy_wait(ap, bits, 1000);
	if (status & bits)
		if (ata_msg_err(ap))
			printk(KERN_ERR "abnormal status 0x%X\n", status);

	/* get controller status; clear intr, err bits */
	host_stat = in_be32(ap->ioaddr.bmdma_addr + SCC_DMA_STATUS);
	out_be32(ap->ioaddr.bmdma_addr + SCC_DMA_STATUS,
		 host_stat | ATA_DMA_INTR | ATA_DMA_ERR);

	post_stat = in_be32(ap->ioaddr.bmdma_addr + SCC_DMA_STATUS);

	if (ata_msg_intr(ap))
		printk(KERN_INFO "%s: irq ack: host_stat 0x%X, new host_stat 0x%X, drv_stat 0x%X\n",
		       __FUNCTION__,
		       host_stat, post_stat, status);

	return status;
}

/**
 *	scc_bmdma_freeze - Freeze BMDMA controller port
 *	@ap: port to freeze
 *
 *	Note: Original code is ata_bmdma_freeze().
 */

static void scc_bmdma_freeze (struct ata_port *ap)
{
	struct ata_ioports *ioaddr = &ap->ioaddr;

	ap->ctl |= ATA_NIEN;
	ap->last_ctl = ap->ctl;

	out_be32(ioaddr->ctl_addr, ap->ctl);

	/* Under certain circumstances, some controllers raise IRQ on
	 * ATA_NIEN manipulation.  Also, many controllers fail to mask
	 * previously pending IRQ on ATA_NIEN assertion.  Clear it.
	 */
	ata_chk_status(ap);

	ap->ops->irq_clear(ap);
}

/**
 *	scc_pata_prereset - prepare for reset
 *	@ap: ATA port to be reset
 *	@deadline: deadline jiffies for the operation
 */

static int scc_pata_prereset(struct ata_port *ap, unsigned long deadline)
{
	ap->cbl = ATA_CBL_PATA80;
	return ata_std_prereset(ap, deadline);
}

/**
 *	scc_std_postreset - standard postreset callback
 *	@ap: the target ata_port
 *	@classes: classes of attached devices
 *
 *	Note: Original code is ata_std_postreset().
 */

static void scc_std_postreset (struct ata_port *ap, unsigned int *classes)
{
	DPRINTK("ENTER\n");

	/* re-enable interrupts */
	if (!ap->ops->error_handler)
		ap->ops->irq_on(ap);

	/* is double-select really necessary? */
	if (classes[0] != ATA_DEV_NONE)
		ap->ops->dev_select(ap, 1);
	if (classes[1] != ATA_DEV_NONE)
		ap->ops->dev_select(ap, 0);

	/* bail out if no device is present */
	if (classes[0] == ATA_DEV_NONE && classes[1] == ATA_DEV_NONE) {
		DPRINTK("EXIT, no device\n");
		return;
	}

	/* set up device control */
	if (ap->ioaddr.ctl_addr)
		out_be32(ap->ioaddr.ctl_addr, ap->ctl);

	DPRINTK("EXIT\n");
}

/**
 *	scc_error_handler - Stock error handler for BMDMA controller
 *	@ap: port to handle error for
 */

static void scc_error_handler (struct ata_port *ap)
{
	ata_bmdma_drive_eh(ap, scc_pata_prereset, scc_std_softreset, NULL,
			   scc_std_postreset);
}

/**
 *	scc_bmdma_irq_clear - Clear PCI IDE BMDMA interrupt.
 *	@ap: Port associated with this ATA transaction.
 *
 *	Note: Original code is ata_bmdma_irq_clear().
 */

static void scc_bmdma_irq_clear (struct ata_port *ap)
{
	void __iomem *mmio = ap->ioaddr.bmdma_addr;

	if (!mmio)
		return;

	out_be32(mmio + SCC_DMA_STATUS, in_be32(mmio + SCC_DMA_STATUS));
}

/**
 *	scc_port_start - Set port up for dma.
 *	@ap: Port to initialize
 *
 *	Allocate space for PRD table using ata_port_start().
 *	Set PRD table address for PTERADD. (PRD Transfer End Read)
 */

static int scc_port_start (struct ata_port *ap)
{
	void __iomem *mmio = ap->ioaddr.bmdma_addr;
	int rc;

	rc = ata_port_start(ap);
	if (rc)
		return rc;

	out_be32(mmio + SCC_DMA_PTERADD, ap->prd_dma);
	return 0;
}

/**
 *	scc_port_stop - Undo scc_port_start()
 *	@ap: Port to shut down
 *
 *	Reset PTERADD.
 */

static void scc_port_stop (struct ata_port *ap)
{
	void __iomem *mmio = ap->ioaddr.bmdma_addr;

	out_be32(mmio + SCC_DMA_PTERADD, 0);
}

static struct scsi_host_template scc_sht = {
	.module			= THIS_MODULE,
	.name			= DRV_NAME,
	.ioctl			= ata_scsi_ioctl,
	.queuecommand		= ata_scsi_queuecmd,
	.can_queue		= ATA_DEF_QUEUE,
	.this_id		= ATA_SHT_THIS_ID,
	.sg_tablesize		= LIBATA_MAX_PRD,
	.cmd_per_lun		= ATA_SHT_CMD_PER_LUN,
	.emulated		= ATA_SHT_EMULATED,
	.use_clustering		= ATA_SHT_USE_CLUSTERING,
	.proc_name		= DRV_NAME,
	.dma_boundary		= ATA_DMA_BOUNDARY,
	.slave_configure	= ata_scsi_slave_config,
	.slave_destroy		= ata_scsi_slave_destroy,
	.bios_param		= ata_std_bios_param,
};

static const struct ata_port_operations scc_pata_ops = {
	.port_disable		= ata_port_disable,
	.set_piomode		= scc_set_piomode,
	.set_dmamode		= scc_set_dmamode,
	.mode_filter		= ata_pci_default_filter,

	.tf_load		= scc_tf_load,
	.tf_read		= scc_tf_read,
	.exec_command		= scc_exec_command,
	.check_status		= scc_check_status,
	.check_altstatus	= scc_check_altstatus,
	.dev_select		= scc_std_dev_select,

	.bmdma_setup		= scc_bmdma_setup,
	.bmdma_start		= scc_bmdma_start,
	.bmdma_stop		= scc_bmdma_stop,
	.bmdma_status		= scc_bmdma_status,
	.data_xfer		= scc_data_xfer,

	.qc_prep		= ata_qc_prep,
	.qc_issue		= ata_qc_issue_prot,

	.freeze			= scc_bmdma_freeze,
	.error_handler		= scc_error_handler,
	.post_internal_cmd	= scc_bmdma_stop,

	.irq_clear		= scc_bmdma_irq_clear,
	.irq_on			= scc_irq_on,
	.irq_ack		= scc_irq_ack,

	.port_start		= scc_port_start,
	.port_stop		= scc_port_stop,
};

static struct ata_port_info scc_port_info[] = {
	{
		.flags		= ATA_FLAG_SLAVE_POSS | ATA_FLAG_MMIO | ATA_FLAG_NO_LEGACY,
		.pio_mask	= 0x1f,	/* pio0-4 */
		.mwdma_mask	= 0x00,
		.udma_mask	= ATA_UDMA6,
		.port_ops	= &scc_pata_ops,
	},
};

/**
 *	scc_reset_controller - initialize SCC PATA controller.
 */

static int scc_reset_controller(struct ata_host *host)
{
	void __iomem *ctrl_base = host->iomap[SCC_CTRL_BAR];
	void __iomem *bmid_base = host->iomap[SCC_BMID_BAR];
	void __iomem *cckctrl_port = ctrl_base + SCC_CTL_CCKCTRL;
	void __iomem *mode_port = ctrl_base + SCC_CTL_MODEREG;
	void __iomem *ecmode_port = ctrl_base + SCC_CTL_ECMODE;
	void __iomem *intmask_port = bmid_base + SCC_DMA_INTMASK;
	void __iomem *dmastatus_port = bmid_base + SCC_DMA_STATUS;
	u32 reg = 0;

	out_be32(cckctrl_port, reg);
	reg |= CCKCTRL_ATACLKOEN;
	out_be32(cckctrl_port, reg);
	reg |= CCKCTRL_LCLKEN | CCKCTRL_OCLKEN;
	out_be32(cckctrl_port, reg);
	reg |= CCKCTRL_CRST;
	out_be32(cckctrl_port, reg);

	for (;;) {
		reg = in_be32(cckctrl_port);
		if (reg & CCKCTRL_CRST)
			break;
		udelay(5000);
	}

	reg |= CCKCTRL_ATARESET;
	out_be32(cckctrl_port, reg);
	out_be32(ecmode_port, ECMODE_VALUE);
	out_be32(mode_port, MODE_JCUSFEN);
	out_be32(intmask_port, INTMASK_MSK);

	if (in_be32(dmastatus_port) & QCHSD_STPDIAG) {
		printk(KERN_WARNING "%s: failed to detect 80c cable. (PDIAG# is high)\n", DRV_NAME);
		return -EIO;
	}

	return 0;
}

/**
 *	scc_setup_ports - initialize ioaddr with SCC PATA port offsets.
 *	@ioaddr: IO address structure to be initialized
 *	@base: base address of BMID region
 */

static void scc_setup_ports (struct ata_ioports *ioaddr, void __iomem *base)
{
	ioaddr->cmd_addr = base + SCC_REG_CMD_ADDR;
	ioaddr->altstatus_addr = ioaddr->cmd_addr + SCC_REG_ALTSTATUS;
	ioaddr->ctl_addr = ioaddr->cmd_addr + SCC_REG_ALTSTATUS;
	ioaddr->bmdma_addr = base;
	ioaddr->data_addr = ioaddr->cmd_addr + SCC_REG_DATA;
	ioaddr->error_addr = ioaddr->cmd_addr + SCC_REG_ERR;
	ioaddr->feature_addr = ioaddr->cmd_addr + SCC_REG_FEATURE;
	ioaddr->nsect_addr = ioaddr->cmd_addr + SCC_REG_NSECT;
	ioaddr->lbal_addr = ioaddr->cmd_addr + SCC_REG_LBAL;
	ioaddr->lbam_addr = ioaddr->cmd_addr + SCC_REG_LBAM;
	ioaddr->lbah_addr = ioaddr->cmd_addr + SCC_REG_LBAH;
	ioaddr->device_addr = ioaddr->cmd_addr + SCC_REG_DEVICE;
	ioaddr->status_addr = ioaddr->cmd_addr + SCC_REG_STATUS;
	ioaddr->command_addr = ioaddr->cmd_addr + SCC_REG_CMD;
}

static int scc_host_init(struct ata_host *host)
{
	struct pci_dev *pdev = to_pci_dev(host->dev);
	int rc;

	rc = scc_reset_controller(host);
	if (rc)
		return rc;

	rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
	if (rc)
		return rc;
	rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
	if (rc)
		return rc;

	scc_setup_ports(&host->ports[0]->ioaddr, host->iomap[SCC_BMID_BAR]);

	pci_set_master(pdev);

	return 0;
}

/**
 *	scc_init_one - Register SCC PATA device with kernel services
 *	@pdev: PCI device to register
 *	@ent: Entry in scc_pci_tbl matching with @pdev
 *
 *	LOCKING:
 *	Inherited from PCI layer (may sleep).
 *
 *	RETURNS:
 *	Zero on success, or -ERRNO value.
 */

static int scc_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
{
	static int printed_version;
	unsigned int board_idx = (unsigned int) ent->driver_data;
	const struct ata_port_info *ppi[] = { &scc_port_info[board_idx], NULL };
	struct ata_host *host;
	int rc;

	if (!printed_version++)
		dev_printk(KERN_DEBUG, &pdev->dev,
			   "version " DRV_VERSION "\n");

	host = ata_host_alloc_pinfo(&pdev->dev, ppi, 1);
	if (!host)
		return -ENOMEM;

	rc = pcim_enable_device(pdev);
	if (rc)
		return rc;

	rc = pcim_iomap_regions(pdev, (1 << SCC_CTRL_BAR) | (1 << SCC_BMID_BAR), DRV_NAME);
	if (rc == -EBUSY)
		pcim_pin_device(pdev);
	if (rc)
		return rc;
	host->iomap = pcim_iomap_table(pdev);

	rc = scc_host_init(host);
	if (rc)
		return rc;

	return ata_host_activate(host, pdev->irq, ata_interrupt, IRQF_SHARED,
				 &scc_sht);
}

static struct pci_driver scc_pci_driver = {
	.name			= DRV_NAME,
	.id_table		= scc_pci_tbl,
	.probe			= scc_init_one,
	.remove			= ata_pci_remove_one,
#ifdef CONFIG_PM
	.suspend		= ata_pci_device_suspend,
	.resume			= ata_pci_device_resume,
#endif
};

static int __init scc_init (void)
{
	int rc;

	DPRINTK("pci_register_driver\n");
	rc = pci_register_driver(&scc_pci_driver);
	if (rc)
		return rc;

	DPRINTK("done\n");
	return 0;
}

static void __exit scc_exit (void)
{
	pci_unregister_driver(&scc_pci_driver);
}

module_init(scc_init);
module_exit(scc_exit);

MODULE_AUTHOR("Toshiba corp");
MODULE_DESCRIPTION("SCSI low-level driver for Toshiba SCC PATA controller");
MODULE_LICENSE("GPL");
MODULE_DEVICE_TABLE(pci, scc_pci_tbl);
MODULE_VERSION(DRV_VERSION);
