/*
 * Implementation independent bits of the Floppy driver.
 *
 * much of this file is derived from what was originally the Q40 floppy driver.
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 *
 * Copyright (C) 1999, 2000, 2001
 *
 * Sun3x support added 2/4/2000 Sam Creasey (sammy@sammy.net)
 *
 */

#include <asm/io.h>

#include <linux/vmalloc.h>

asmlinkage irqreturn_t floppy_hardint(int irq, void *dev_id);

/* constants... */

#undef MAX_DMA_ADDRESS
#define MAX_DMA_ADDRESS   0x00  /* nothing like that */


/*
 * Again, the CMOS information doesn't work on m68k..
 */
#define FLOPPY0_TYPE (MACH_IS_Q40 ? 6 : 4)
#define FLOPPY1_TYPE 0

/* basically PC init + set use_virtual_dma */
#define  FDC1 m68k_floppy_init()

#define N_FDC 1
#define N_DRIVE 8


/* vdma globals adapted from asm-i386/floppy.h */

static int virtual_dma_count=0;
static int virtual_dma_residue=0;
static char *virtual_dma_addr=NULL;
static int virtual_dma_mode=0;
static int doing_pdma=0;

#include <asm/sun3xflop.h>

extern spinlock_t  dma_spin_lock;

static __inline__ unsigned long claim_dma_lock(void)
{
	unsigned long flags;
	spin_lock_irqsave(&dma_spin_lock, flags);
	return flags;
}

static __inline__ void release_dma_lock(unsigned long flags)
{
	spin_unlock_irqrestore(&dma_spin_lock, flags);
}


static __inline__ unsigned char fd_inb(int port)
{
	if(MACH_IS_Q40)
		return inb_p(port);
	else if(MACH_IS_SUN3X)
		return sun3x_82072_fd_inb(port);
	return 0;
}

static __inline__ void fd_outb(unsigned char value, int port)
{
	if(MACH_IS_Q40)
		outb_p(value, port);
	else if(MACH_IS_SUN3X)
		sun3x_82072_fd_outb(value, port);
}


static int fd_request_irq(void)
{
	if(MACH_IS_Q40)
		return request_irq(FLOPPY_IRQ, floppy_hardint,
				   IRQF_DISABLED, "floppy", floppy_hardint);
	else if(MACH_IS_SUN3X)
		return sun3xflop_request_irq();
	return -ENXIO;
}

static void fd_free_irq(void)
{
	if(MACH_IS_Q40)
		free_irq(FLOPPY_IRQ, floppy_hardint);
}

#define fd_request_dma()        vdma_request_dma(FLOPPY_DMA,"floppy")
#define fd_get_dma_residue()    vdma_get_dma_residue(FLOPPY_DMA)
#define fd_dma_mem_alloc(size)	vdma_mem_alloc(size)
#define fd_dma_setup(addr, size, mode, io) vdma_dma_setup(addr, size, mode, io)

#define fd_enable_irq()           /* nothing... */
#define fd_disable_irq()          /* nothing... */

#define fd_free_dma()             /* nothing */

/* No 64k boundary crossing problems on Q40 - no DMA at all */
#define CROSS_64KB(a,s) (0)

#define DMA_MODE_READ  0x44    /* i386 look-alike */
#define DMA_MODE_WRITE 0x48


static int m68k_floppy_init(void)
{
  use_virtual_dma =1;
  can_use_virtual_dma = 1;


  if (MACH_IS_Q40)
	  return 0x3f0;
  else if(MACH_IS_SUN3X)
	  return sun3xflop_init();
  else
    return -1;
}


static int vdma_request_dma(unsigned int dmanr, const char * device_id)
{
	return 0;
}


static int vdma_get_dma_residue(unsigned int dummy)
{
	return virtual_dma_count + virtual_dma_residue;
}


static unsigned long vdma_mem_alloc(unsigned long size)
{
	return (unsigned long) vmalloc(size);

}

static void _fd_dma_mem_free(unsigned long addr, unsigned long size)
{
        vfree((void *)addr);
}
#define fd_dma_mem_free(addr,size) _fd_dma_mem_free(addr, size)


/* choose_dma_mode ???*/

static int vdma_dma_setup(char *addr, unsigned long size, int mode, int io)
{
	doing_pdma = 1;
	virtual_dma_port = (MACH_IS_Q40 ? io : 0);
	virtual_dma_mode = (mode  == DMA_MODE_WRITE);
	virtual_dma_addr = addr;
	virtual_dma_count = size;
	virtual_dma_residue = 0;
	return 0;
}



static void fd_disable_dma(void)
{
	doing_pdma = 0;
	virtual_dma_residue += virtual_dma_count;
	virtual_dma_count=0;
}



/* this is the only truly Q40 specific function */

asmlinkage irqreturn_t floppy_hardint(int irq, void *dev_id)
{
	register unsigned char st;

#undef TRACE_FLPY_INT
#define NO_FLOPPY_ASSEMBLER

#ifdef TRACE_FLPY_INT
	static int calls=0;
	static int bytes=0;
	static int dma_wait=0;
#endif
	if(!doing_pdma) {
		floppy_interrupt(irq, dev_id);
		return IRQ_HANDLED;
	}

#ifdef TRACE_FLPY_INT
	if(!calls)
		bytes = virtual_dma_count;
#endif

	{
		register int lcount;
		register char *lptr;

		/* serve 1st byte fast: */

		st=1;
		for(lcount=virtual_dma_count, lptr=virtual_dma_addr;
		    lcount; lcount--, lptr++) {
			st=inb(virtual_dma_port+4) & 0xa0 ;
			if(st != 0xa0)
				break;
			if(virtual_dma_mode)
				outb_p(*lptr, virtual_dma_port+5);
			else
				*lptr = inb_p(virtual_dma_port+5);
		}

		virtual_dma_count = lcount;
		virtual_dma_addr = lptr;
		st = inb(virtual_dma_port+4);
	}

#ifdef TRACE_FLPY_INT
	calls++;
#endif
	if(st == 0x20)
		return IRQ_HANDLED;
	if(!(st & 0x20)) {
		virtual_dma_residue += virtual_dma_count;
		virtual_dma_count=0;
#ifdef TRACE_FLPY_INT
		printk("count=%x, residue=%x calls=%d bytes=%d dma_wait=%d\n",
		       virtual_dma_count, virtual_dma_residue, calls, bytes,
		       dma_wait);
		calls = 0;
		dma_wait=0;
#endif
		doing_pdma = 0;
		floppy_interrupt(irq, dev_id);
		return IRQ_HANDLED;
	}
#ifdef TRACE_FLPY_INT
	if(!virtual_dma_count)
		dma_wait++;
#endif
	return IRQ_HANDLED;
}

#define EXTRA_FLOPPY_PARAMS
