/*
 * 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);

		/* 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");
