#include <linux/types.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/blkdev.h>
#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/spinlock.h>
#include <linux/interrupt.h>

#include <asm/setup.h>
#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/amigaints.h>
#include <asm/amigahw.h>
#include <asm/irq.h>

#include "scsi.h"
#include <scsi/scsi_host.h>
#include "wd33c93.h"
#include "a3000.h"

#include<linux/stat.h>

#define DMA(ptr) ((a3000_scsiregs *)((ptr)->base))
#define HDATA(ptr) ((struct WD33C93_hostdata *)((ptr)->hostdata))

static struct Scsi_Host *a3000_host = NULL;

static int a3000_release(struct Scsi_Host *instance);

static irqreturn_t a3000_intr (int irq, void *dummy)
{
	unsigned long flags;
	unsigned int status = DMA(a3000_host)->ISTR;

	if (!(status & ISTR_INT_P))
		return IRQ_NONE;
	if (status & ISTR_INTS)
	{
		spin_lock_irqsave(a3000_host->host_lock, flags);
		wd33c93_intr (a3000_host);
		spin_unlock_irqrestore(a3000_host->host_lock, flags);
		return IRQ_HANDLED;
	}
	printk("Non-serviced A3000 SCSI-interrupt? ISTR = %02x\n", status);
	return IRQ_NONE;
}

static int dma_setup(struct scsi_cmnd *cmd, int dir_in)
{
    unsigned short cntr = CNTR_PDMD | CNTR_INTEN;
    unsigned long addr = virt_to_bus(cmd->SCp.ptr);

    /*
     * if the physical address has the wrong alignment, or if
     * physical address is bad, or if it is a write and at the
     * end of a physical memory chunk, then allocate a bounce
     * buffer
     */
    if (addr & A3000_XFER_MASK)
    {
	HDATA(a3000_host)->dma_bounce_len = (cmd->SCp.this_residual + 511)
	    & ~0x1ff;
	HDATA(a3000_host)->dma_bounce_buffer =
	    kmalloc (HDATA(a3000_host)->dma_bounce_len, GFP_KERNEL);
	
	/* can't allocate memory; use PIO */
	if (!HDATA(a3000_host)->dma_bounce_buffer) {
	    HDATA(a3000_host)->dma_bounce_len = 0;
	    return 1;
	}

	if (!dir_in) {
	    /* copy to bounce buffer for a write */
	    memcpy (HDATA(a3000_host)->dma_bounce_buffer,
		cmd->SCp.ptr, cmd->SCp.this_residual);
	}

	addr = virt_to_bus(HDATA(a3000_host)->dma_bounce_buffer);
    }

    /* setup dma direction */
    if (!dir_in)
	cntr |= CNTR_DDIR;

    /* remember direction */
    HDATA(a3000_host)->dma_dir = dir_in;

    DMA(a3000_host)->CNTR = cntr;

    /* setup DMA *physical* address */
    DMA(a3000_host)->ACR = addr;

    if (dir_in)
  	/* invalidate any cache */
	cache_clear (addr, cmd->SCp.this_residual);
    else
	/* push any dirty cache */
	cache_push (addr, cmd->SCp.this_residual);

    /* start DMA */
    mb();			/* make sure setup is completed */
    DMA(a3000_host)->ST_DMA = 1;
    mb();			/* make sure DMA has started before next IO */

    /* return success */
    return 0;
}

static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt,
		     int status)
{
    /* disable SCSI interrupts */
    unsigned short cntr = CNTR_PDMD;

    if (!HDATA(instance)->dma_dir)
	cntr |= CNTR_DDIR;

    DMA(instance)->CNTR = cntr;
    mb();			/* make sure CNTR is updated before next IO */

    /* flush if we were reading */
    if (HDATA(instance)->dma_dir) {
	DMA(instance)->FLUSH = 1;
	mb();			/* don't allow prefetch */
	while (!(DMA(instance)->ISTR & ISTR_FE_FLG))
	    barrier();
	mb();			/* no IO until FLUSH is done */
    }

    /* clear a possible interrupt */
    /* I think that this CINT is only necessary if you are
     * using the terminal count features.   HM 7 Mar 1994
     */
    DMA(instance)->CINT = 1;

    /* stop DMA */
    DMA(instance)->SP_DMA = 1;
    mb();			/* make sure DMA is stopped before next IO */

    /* restore the CONTROL bits (minus the direction flag) */
    DMA(instance)->CNTR = CNTR_PDMD | CNTR_INTEN;
    mb();			/* make sure CNTR is updated before next IO */

    /* copy from a bounce buffer, if necessary */
    if (status && HDATA(instance)->dma_bounce_buffer) {
	if (SCpnt) {
	    if (HDATA(instance)->dma_dir && SCpnt)
		memcpy (SCpnt->SCp.ptr,
			HDATA(instance)->dma_bounce_buffer,
			SCpnt->SCp.this_residual);
	    kfree (HDATA(instance)->dma_bounce_buffer);
	    HDATA(instance)->dma_bounce_buffer = NULL;
	    HDATA(instance)->dma_bounce_len = 0;
	} else {
	    kfree (HDATA(instance)->dma_bounce_buffer);
	    HDATA(instance)->dma_bounce_buffer = NULL;
	    HDATA(instance)->dma_bounce_len = 0;
	}
    }
}

static int __init a3000_detect(struct scsi_host_template *tpnt)
{
    wd33c93_regs regs;

    if  (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(A3000_SCSI))
	return 0;
    if (!request_mem_region(0xDD0000, 256, "wd33c93"))
	return 0;

    tpnt->proc_name = "A3000";
    tpnt->proc_info = &wd33c93_proc_info;

    a3000_host = scsi_register (tpnt, sizeof(struct WD33C93_hostdata));
    if (a3000_host == NULL)
	goto fail_register;

    a3000_host->base = ZTWO_VADDR(0xDD0000);
    a3000_host->irq = IRQ_AMIGA_PORTS;
    DMA(a3000_host)->DAWR = DAWR_A3000;
    regs.SASR = &(DMA(a3000_host)->SASR);
    regs.SCMD = &(DMA(a3000_host)->SCMD);
    HDATA(a3000_host)->no_sync = 0xff;
    HDATA(a3000_host)->fast = 0;
    HDATA(a3000_host)->dma_mode = CTRL_DMA;
    wd33c93_init(a3000_host, regs, dma_setup, dma_stop, WD33C93_FS_12_15);
    if (request_irq(IRQ_AMIGA_PORTS, a3000_intr, IRQF_SHARED, "A3000 SCSI",
		    a3000_intr))
        goto fail_irq;
    DMA(a3000_host)->CNTR = CNTR_PDMD | CNTR_INTEN;

    return 1;

fail_irq:
    scsi_unregister(a3000_host);
fail_register:
    release_mem_region(0xDD0000, 256);
    return 0;
}

static int a3000_bus_reset(struct scsi_cmnd *cmd)
{
	/* FIXME perform bus-specific reset */
	
	/* FIXME 2: kill this entire function, which should
	   cause mid-layer to call wd33c93_host_reset anyway? */

	spin_lock_irq(cmd->device->host->host_lock);
	wd33c93_host_reset(cmd);
	spin_unlock_irq(cmd->device->host->host_lock);

	return SUCCESS;
}

#define HOSTS_C

static struct scsi_host_template driver_template = {
	.proc_name		= "A3000",
	.name			= "Amiga 3000 built-in SCSI",
	.detect			= a3000_detect,
	.release		= a3000_release,
	.queuecommand		= wd33c93_queuecommand,
	.eh_abort_handler	= wd33c93_abort,
	.eh_bus_reset_handler	= a3000_bus_reset,
	.eh_host_reset_handler	= wd33c93_host_reset,
	.can_queue		= CAN_QUEUE,
	.this_id		= 7,
	.sg_tablesize		= SG_ALL,
	.cmd_per_lun		= CMD_PER_LUN,
	.use_clustering		= ENABLE_CLUSTERING
};


#include "scsi_module.c"

static int a3000_release(struct Scsi_Host *instance)
{
    DMA(instance)->CNTR = 0;
    release_mem_region(0xDD0000, 256);
    free_irq(IRQ_AMIGA_PORTS, a3000_intr);
    return 1;
}

MODULE_LICENSE("GPL");
