/*
 * Oktagon_esp.c -- Driver for bsc Oktagon
 *
 * Written by Carsten Pluntke 1998
 *
 * Based on cyber_esp.c
 */


#if defined(CONFIG_AMIGA) || defined(CONFIG_APUS)
#define USE_BOTTOM_HALF
#endif

#include <linux/module.h>

#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/types.h>
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/blkdev.h>
#include <linux/proc_fs.h>
#include <linux/stat.h>
#include <linux/reboot.h>
#include <asm/system.h>
#include <asm/ptrace.h>
#include <asm/pgtable.h>


#include "scsi.h"
#include <scsi/scsi_host.h>
#include "NCR53C9x.h"

#include <linux/zorro.h>
#include <asm/irq.h>
#include <asm/amigaints.h>
#include <asm/amigahw.h>

#ifdef USE_BOTTOM_HALF
#include <linux/workqueue.h>
#include <linux/interrupt.h>
#endif

/* The controller registers can be found in the Z2 config area at these
 * offsets:
 */
#define OKTAGON_ESP_ADDR 0x03000
#define OKTAGON_DMA_ADDR 0x01000


static int  dma_bytes_sent(struct NCR_ESP *esp, int fifo_count);
static int  dma_can_transfer(struct NCR_ESP *esp, Scsi_Cmnd *sp);
static void dma_dump_state(struct NCR_ESP *esp);
static void dma_init_read(struct NCR_ESP *esp, __u32 vaddress, int length);
static void dma_init_write(struct NCR_ESP *esp, __u32 vaddress, int length);
static void dma_ints_off(struct NCR_ESP *esp);
static void dma_ints_on(struct NCR_ESP *esp);
static int  dma_irq_p(struct NCR_ESP *esp);
static void dma_led_off(struct NCR_ESP *esp);
static void dma_led_on(struct NCR_ESP *esp);
static int  dma_ports_p(struct NCR_ESP *esp);
static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write);

static void dma_irq_exit(struct NCR_ESP *esp);
static void dma_invalidate(struct NCR_ESP *esp);

static void dma_mmu_get_scsi_one(struct NCR_ESP *,Scsi_Cmnd *);
static void dma_mmu_get_scsi_sgl(struct NCR_ESP *,Scsi_Cmnd *);
static void dma_mmu_release_scsi_one(struct NCR_ESP *,Scsi_Cmnd *);
static void dma_mmu_release_scsi_sgl(struct NCR_ESP *,Scsi_Cmnd *);
static void dma_advance_sg(Scsi_Cmnd *);
static int  oktagon_notify_reboot(struct notifier_block *this, unsigned long code, void *x);

#ifdef USE_BOTTOM_HALF
static void dma_commit(struct work_struct *unused);

long oktag_to_io(long *paddr, long *addr, long len);
long oktag_from_io(long *addr, long *paddr, long len);

static DECLARE_WORK(tq_fake_dma, dma_commit);

#define DMA_MAXTRANSFER 0x8000

#else

/*
 * No bottom half. Use transfer directly from IRQ. Find a narrow path
 * between too much IRQ overhead and clogging the IRQ for too long.
 */

#define DMA_MAXTRANSFER 0x1000

#endif

static struct notifier_block oktagon_notifier = { 
	oktagon_notify_reboot,
	NULL,
	0
};

static long *paddress;
static long *address;
static long len;
static long dma_on;
static int direction;
static struct NCR_ESP *current_esp;


static volatile unsigned char cmd_buffer[16];
				/* This is where all commands are put
				 * before they are trasfered to the ESP chip
				 * via PIO.
				 */

/***************************************************************** Detection */
int oktagon_esp_detect(struct scsi_host_template *tpnt)
{
	struct NCR_ESP *esp;
	struct zorro_dev *z = NULL;
	unsigned long address;
	struct ESP_regs *eregs;

	while ((z = zorro_find_device(ZORRO_PROD_BSC_OKTAGON_2008, z))) {
	    unsigned long board = z->resource.start;
	    if (request_mem_region(board+OKTAGON_ESP_ADDR,
				   sizeof(struct ESP_regs), "NCR53C9x")) {
		/*
		 * It is a SCSI controller.
		 * Hardwire Host adapter to SCSI ID 7
		 */
		
		address = (unsigned long)ZTWO_VADDR(board);
		eregs = (struct ESP_regs *)(address + OKTAGON_ESP_ADDR);

		/* This line was 5 lines lower */
		esp = esp_allocate(tpnt, (void *)board + OKTAGON_ESP_ADDR, 0);

		/* we have to shift the registers only one bit for oktagon */
		esp->shift = 1;

		esp_write(eregs->esp_cfg1, (ESP_CONFIG1_PENABLE | 7));
		udelay(5);
		if (esp_read(eregs->esp_cfg1) != (ESP_CONFIG1_PENABLE | 7))
			return 0; /* Bail out if address did not hold data */

		/* Do command transfer with programmed I/O */
		esp->do_pio_cmds = 1;

		/* Required functions */
		esp->dma_bytes_sent = &dma_bytes_sent;
		esp->dma_can_transfer = &dma_can_transfer;
		esp->dma_dump_state = &dma_dump_state;
		esp->dma_init_read = &dma_init_read;
		esp->dma_init_write = &dma_init_write;
		esp->dma_ints_off = &dma_ints_off;
		esp->dma_ints_on = &dma_ints_on;
		esp->dma_irq_p = &dma_irq_p;
		esp->dma_ports_p = &dma_ports_p;
		esp->dma_setup = &dma_setup;

		/* Optional functions */
		esp->dma_barrier = 0;
		esp->dma_drain = 0;
		esp->dma_invalidate = &dma_invalidate;
		esp->dma_irq_entry = 0;
		esp->dma_irq_exit = &dma_irq_exit;
		esp->dma_led_on = &dma_led_on;
		esp->dma_led_off = &dma_led_off;
		esp->dma_poll = 0;
		esp->dma_reset = 0;

		esp->dma_mmu_get_scsi_one = &dma_mmu_get_scsi_one;
		esp->dma_mmu_get_scsi_sgl = &dma_mmu_get_scsi_sgl;
		esp->dma_mmu_release_scsi_one = &dma_mmu_release_scsi_one;
		esp->dma_mmu_release_scsi_sgl = &dma_mmu_release_scsi_sgl;
		esp->dma_advance_sg = &dma_advance_sg;

		/* SCSI chip speed */
		/* Looking at the quartz of the SCSI board... */
		esp->cfreq = 25000000;

		/* The DMA registers on the CyberStorm are mapped
		 * relative to the device (i.e. in the same Zorro
		 * I/O block).
		 */
		esp->dregs = (void *)(address + OKTAGON_DMA_ADDR);

		paddress = (long *) esp->dregs;

		/* ESP register base */
		esp->eregs = eregs;
		
		/* Set the command buffer */
		esp->esp_command = (volatile unsigned char*) cmd_buffer;

		/* Yes, the virtual address. See below. */
		esp->esp_command_dvma = (__u32) cmd_buffer;

		esp->irq = IRQ_AMIGA_PORTS;
		request_irq(IRQ_AMIGA_PORTS, esp_intr, IRQF_SHARED,
			    "BSC Oktagon SCSI", esp->ehost);

		/* Figure out our scsi ID on the bus */
		esp->scsi_id = 7;
		
		/* We don't have a differential SCSI-bus. */
		esp->diff = 0;

		esp_initialize(esp);

		printk("ESP_Oktagon Driver 1.1"
#ifdef USE_BOTTOM_HALF
		       " [BOTTOM_HALF]"
#else
		       " [IRQ]"
#endif
		       " registered.\n");
		printk("ESP: Total of %d ESP hosts found, %d actually in use.\n", nesps,esps_in_use);
		esps_running = esps_in_use;
		current_esp = esp;
		register_reboot_notifier(&oktagon_notifier);
		return esps_in_use;
	    }
	}
	return 0;
}


/*
 * On certain configurations the SCSI equipment gets confused on reboot,
 * so we have to reset it then.
 */

static int
oktagon_notify_reboot(struct notifier_block *this, unsigned long code, void *x)
{
  struct NCR_ESP *esp;
  
  if((code == SYS_DOWN || code == SYS_HALT) && (esp = current_esp))
   {
    esp_bootup_reset(esp,esp->eregs);
    udelay(500); /* Settle time. Maybe unnecessary. */
   }
  return NOTIFY_DONE;
}
    

	
#ifdef USE_BOTTOM_HALF


/*
 * The bsc Oktagon controller has no real DMA, so we have to do the 'DMA
 * transfer' in the interrupt (Yikes!) or use a bottom half to not to clutter
 * IRQ's for longer-than-good.
 *
 * FIXME
 * BIG PROBLEM: 'len' is usually the buffer length, not the expected length
 * of the data. So DMA may finish prematurely, further reads lead to
 * 'machine check' on APUS systems (don't know about m68k systems, AmigaOS
 * deliberately ignores the bus faults) and a normal copy-loop can't
 * be exited prematurely just at the right moment by the dma_invalidate IRQ.
 * So do it the hard way, write an own copier in assembler and
 * catch the exception.
 *                                     -- Carsten
 */
 
 
static void dma_commit(struct work_struct *unused)
{
    long wait,len2,pos;
    struct NCR_ESP *esp;

    ESPDATA(("Transfer: %ld bytes, Address 0x%08lX, Direction: %d\n",
         len,(long) address,direction));
    dma_ints_off(current_esp);

    pos = 0;
    wait = 1;
    if(direction) /* write? (memory to device) */
     {
      while(len > 0)
       {
        len2 = oktag_to_io(paddress, address+pos, len);
	if(!len2)
	 {
	  if(wait > 1000)
	   {
	    printk("Expedited DMA exit (writing) %ld\n",len);
	    break;
	   }
	  mdelay(wait);
	  wait *= 2;
	 }
	pos += len2;
	len -= len2*sizeof(long);
       }
     } else {
      while(len > 0)
       {
        len2 = oktag_from_io(address+pos, paddress, len);
	if(!len2)
	 {
	  if(wait > 1000)
	   {
	    printk("Expedited DMA exit (reading) %ld\n",len);
	    break;
	   }
	  mdelay(wait);
	  wait *= 2;
	 }
	pos += len2;
	len -= len2*sizeof(long);
       }
     }

    /* to make esp->shift work */
    esp=current_esp;

#if 0
    len2 = (esp_read(current_esp->eregs->esp_tclow) & 0xff) |
           ((esp_read(current_esp->eregs->esp_tcmed) & 0xff) << 8);

    /*
     * Uh uh. If you see this, len and transfer count registers were out of
     * sync. That means really serious trouble.
     */

    if(len2)
      printk("Eeeek!! Transfer count still %ld!\n",len2);
#endif

    /*
     * Normally we just need to exit and wait for the interrupt to come.
     * But at least one device (my Microtek ScanMaker 630) regularly mis-
     * calculates the bytes it should send which is really ugly because
     * it locks up the SCSI bus if not accounted for.
     */

    if(!(esp_read(current_esp->eregs->esp_status) & ESP_STAT_INTR))
     {
      long len = 100;
      long trash[10];

      /*
       * Interrupt bit was not set. Either the device is just plain lazy
       * so we give it a 10 ms chance or...
       */
      while(len-- && (!(esp_read(current_esp->eregs->esp_status) & ESP_STAT_INTR)))
        udelay(100);


      if(!(esp_read(current_esp->eregs->esp_status) & ESP_STAT_INTR))
       {
        /*
	 * So we think that the transfer count is out of sync. Since we
	 * have all we want we are happy and can ditch the trash.
	 */
	 
        len = DMA_MAXTRANSFER;

        while(len-- && (!(esp_read(current_esp->eregs->esp_status) & ESP_STAT_INTR)))
          oktag_from_io(trash,paddress,2);

        if(!(esp_read(current_esp->eregs->esp_status) & ESP_STAT_INTR))
         {
          /*
           * Things really have gone wrong. If we leave the system in that
           * state, the SCSI bus is locked forever. I hope that this will
           * turn the system in a more or less running state.
           */
          printk("Device is bolixed, trying bus reset...\n");
	  esp_bootup_reset(current_esp,current_esp->eregs);
         }
       }
     }

    ESPDATA(("Transfer_finale: do_data_finale should come\n"));

    len = 0;
    dma_on = 0;
    dma_ints_on(current_esp);
}

#endif

/************************************************************* DMA Functions */
static int dma_bytes_sent(struct NCR_ESP *esp, int fifo_count)
{
	/* Since the CyberStorm DMA is fully dedicated to the ESP chip,
	 * the number of bytes sent (to the ESP chip) equals the number
	 * of bytes in the FIFO - there is no buffering in the DMA controller.
	 * XXXX Do I read this right? It is from host to ESP, right?
	 */
	return fifo_count;
}

static int dma_can_transfer(struct NCR_ESP *esp, Scsi_Cmnd *sp)
{
	unsigned long sz = sp->SCp.this_residual;
	if(sz > DMA_MAXTRANSFER)
		sz = DMA_MAXTRANSFER;
	return sz;
}

static void dma_dump_state(struct NCR_ESP *esp)
{
}

/*
 * What the f$@& is this?
 *
 * Some SCSI devices (like my Microtek ScanMaker 630 scanner) want to transfer
 * more data than requested. How much? Dunno. So ditch the bogus data into
 * the sink, hoping the device will advance to the next phase sooner or later.
 *
 *                         -- Carsten
 */

static long oktag_eva_buffer[16]; /* The data sink */

static void oktag_check_dma(void)
{
  struct NCR_ESP *esp;

  esp=current_esp;
  if(!len)
   {
    address = oktag_eva_buffer;
    len = 2;
    /* esp_do_data sets them to zero like len */
    esp_write(current_esp->eregs->esp_tclow,2);
    esp_write(current_esp->eregs->esp_tcmed,0);
   }
}

static void dma_init_read(struct NCR_ESP *esp, __u32 vaddress, int length)
{
	/* Zorro is noncached, everything else done using processor. */
	/* cache_clear(addr, length); */
	
	if(dma_on)
	  panic("dma_init_read while dma process is initialized/running!\n");
	direction = 0;
	address = (long *) vaddress;
	current_esp = esp;
	len = length;
	oktag_check_dma();
        dma_on = 1;
}

static void dma_init_write(struct NCR_ESP *esp, __u32 vaddress, int length)
{
	/* cache_push(addr, length); */

	if(dma_on)
	  panic("dma_init_write while dma process is initialized/running!\n");
	direction = 1;
	address = (long *) vaddress;
	current_esp = esp;
	len = length;
	oktag_check_dma();
	dma_on = 1;
}

static void dma_ints_off(struct NCR_ESP *esp)
{
	disable_irq(esp->irq);
}

static void dma_ints_on(struct NCR_ESP *esp)
{
	enable_irq(esp->irq);
}

static int dma_irq_p(struct NCR_ESP *esp)
{
	/* It's important to check the DMA IRQ bit in the correct way! */
	return (esp_read(esp->eregs->esp_status) & ESP_STAT_INTR);
}

static void dma_led_off(struct NCR_ESP *esp)
{
}

static void dma_led_on(struct NCR_ESP *esp)
{
}

static int dma_ports_p(struct NCR_ESP *esp)
{
	return ((amiga_custom.intenar) & IF_PORTS);
}

static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write)
{
	/* On the Sparc, DMA_ST_WRITE means "move data from device to memory"
	 * so when (write) is true, it actually means READ!
	 */
	if(write){
		dma_init_read(esp, addr, count);
	} else {
		dma_init_write(esp, addr, count);
	}
}

/*
 * IRQ entry when DMA transfer is ready to be started
 */

static void dma_irq_exit(struct NCR_ESP *esp)
{
#ifdef USE_BOTTOM_HALF
	if(dma_on)
	 {
	  schedule_work(&tq_fake_dma);
	 }
#else
	while(len && !dma_irq_p(esp))
	 {
	  if(direction)
	    *paddress = *address++;
	   else
	    *address++ = *paddress;
	  len -= (sizeof(long));
	 }
	len = 0;
        dma_on = 0;
#endif
}

/*
 * IRQ entry when DMA has just finished
 */

static void dma_invalidate(struct NCR_ESP *esp)
{
}

/*
 * Since the processor does the data transfer we have to use the custom
 * mmu interface to pass the virtual address, not the physical.
 */

void dma_mmu_get_scsi_one(struct NCR_ESP *esp, Scsi_Cmnd *sp)
{
        sp->SCp.ptr =
                sp->request_buffer;
}

void dma_mmu_get_scsi_sgl(struct NCR_ESP *esp, Scsi_Cmnd *sp)
{
        sp->SCp.ptr = page_address(sp->SCp.buffer->page)+
		      sp->SCp.buffer->offset;
}

void dma_mmu_release_scsi_one(struct NCR_ESP *esp, Scsi_Cmnd *sp)
{
}

void dma_mmu_release_scsi_sgl(struct NCR_ESP *esp, Scsi_Cmnd *sp)
{
}

void dma_advance_sg(Scsi_Cmnd *sp)
{
	sp->SCp.ptr = page_address(sp->SCp.buffer->page)+
		      sp->SCp.buffer->offset;
}


#define HOSTS_C

int oktagon_esp_release(struct Scsi_Host *instance)
{
#ifdef MODULE
	unsigned long address = (unsigned long)((struct NCR_ESP *)instance->hostdata)->edev;
	esp_release();
	release_mem_region(address, sizeof(struct ESP_regs));
	free_irq(IRQ_AMIGA_PORTS, esp_intr);
	unregister_reboot_notifier(&oktagon_notifier);
#endif
	return 1;
}


static struct scsi_host_template driver_template = {
	.proc_name		= "esp-oktagon",
	.proc_info		= &esp_proc_info,
	.name			= "BSC Oktagon SCSI",
	.detect			= oktagon_esp_detect,
	.slave_alloc		= esp_slave_alloc,
	.slave_destroy		= esp_slave_destroy,
	.release		= oktagon_esp_release,
	.queuecommand		= esp_queue,
	.eh_abort_handler	= esp_abort,
	.eh_bus_reset_handler	= esp_reset,
	.can_queue		= 7,
	.this_id		= 7,
	.sg_tablesize		= SG_ALL,
	.cmd_per_lun		= 1,
	.use_clustering		= ENABLE_CLUSTERING
};


#include "scsi_module.c"

MODULE_LICENSE("GPL");
