patch-2.1.80 linux/arch/arm/kernel/dma.c
Next file: linux/arch/arm/kernel/ecard.c
Previous file: linux/arch/arm/kernel/calls.S
Back to the patch index
Back to the overall index
- Lines: 200
- Date:
Tue Jan 20 16:39:41 1998
- Orig file:
v2.1.79/linux/arch/arm/kernel/dma.c
- Orig date:
Wed Dec 31 16:00:00 1969
diff -u --recursive --new-file v2.1.79/linux/arch/arm/kernel/dma.c linux/arch/arm/kernel/dma.c
@@ -0,0 +1,199 @@
+/*
+ * linux/arch/arm/kernel/dma.c
+ *
+ * Copyright (C) 1995, 1996 Russell King
+ */
+
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <linux/malloc.h>
+#include <linux/mman.h>
+
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/irq.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+#define KERNEL_ARCH_DMA
+#include <asm/dma.h>
+
+static unsigned long dma_address[8];
+static unsigned long dma_count[8];
+static char dma_direction[8] = { -1, -1, -1, -1, -1, -1, -1};
+
+#if defined(CONFIG_ARCH_A5K) || defined(CONFIG_ARCH_RPC)
+#define DMA_PCIO
+#endif
+#if defined(CONFIG_ARCH_ARC) && defined(CONFIG_BLK_DEV_FD)
+#define DMA_OLD
+#endif
+
+void enable_dma (unsigned int dmanr)
+{
+ switch (dmanr) {
+#ifdef DMA_PCIO
+ case 2: {
+ void *fiqhandler_start;
+ unsigned int fiqhandler_length;
+ extern void floppy_fiqsetup (unsigned long len, unsigned long addr,
+ unsigned long port);
+ switch (dma_direction[dmanr]) {
+ case 1: {
+ extern unsigned char floppy_fiqin_start, floppy_fiqin_end;
+ fiqhandler_start = &floppy_fiqin_start;
+ fiqhandler_length = &floppy_fiqin_end - &floppy_fiqin_start;
+ break;
+ }
+ case 0: {
+ extern unsigned char floppy_fiqout_start, floppy_fiqout_end;
+ fiqhandler_start = &floppy_fiqout_start;
+ fiqhandler_length = &floppy_fiqout_end - &floppy_fiqout_start;
+ break;
+ }
+ default:
+ printk ("enable_dma: dma%d not initialised\n", dmanr);
+ return;
+ }
+ memcpy ((void *)0x1c, fiqhandler_start, fiqhandler_length);
+ flush_page_to_ram(0);
+ floppy_fiqsetup (dma_count[dmanr], dma_address[dmanr], (int)PCIO_FLOPPYDMABASE);
+ enable_irq (64);
+ return;
+ }
+#endif
+#ifdef DMA_OLD
+ case 0: { /* Data DMA */
+ switch (dma_direction[dmanr]) {
+ case 1: /* read */
+ {
+ extern unsigned char fdc1772_dma_read, fdc1772_dma_read_end;
+ extern void fdc1772_setupdma(unsigned int count,unsigned int addr);
+ unsigned long flags;
+#ifdef DEBUG
+ printk("enable_dma fdc1772 data read\n");
+#endif
+ save_flags(flags);
+ cliIF();
+
+ memcpy ((void *)0x1c, (void *)&fdc1772_dma_read,
+ &fdc1772_dma_read_end - &fdc1772_dma_read);
+ fdc1772_setupdma(dma_count[dmanr],dma_address[dmanr]); /* Sets data pointer up */
+ enable_irq (64);
+ restore_flags(flags);
+ }
+ break;
+
+ case 0: /* write */
+ {
+ extern unsigned char fdc1772_dma_write, fdc1772_dma_write_end;
+ extern void fdc1772_setupdma(unsigned int count,unsigned int addr);
+ unsigned long flags;
+
+#ifdef DEBUG
+ printk("enable_dma fdc1772 data write\n");
+#endif
+ save_flags(flags);
+ cliIF();
+ memcpy ((void *)0x1c, (void *)&fdc1772_dma_write,
+ &fdc1772_dma_write_end - &fdc1772_dma_write);
+ fdc1772_setupdma(dma_count[dmanr],dma_address[dmanr]); /* Sets data pointer up */
+ enable_irq (64);
+
+ restore_flags(flags);
+ }
+ break;
+ default:
+ printk ("enable_dma: dma%d not initialised\n", dmanr);
+ return;
+ }
+ }
+ break;
+
+ case 1: { /* Command end FIQ - actually just sets a flag */
+ /* Need to build a branch at the FIQ address */
+ extern void fdc1772_comendhandler(void);
+ unsigned long flags;
+
+ /*printk("enable_dma fdc1772 command end FIQ\n");*/
+ save_flags(flags);
+ cliIF();
+
+ *((unsigned int *)0x1c)=0xea000000 | (((unsigned int)fdc1772_comendhandler-(0x1c+8))/4); /* B fdc1772_comendhandler */
+
+ restore_flags(flags);
+ }
+ break;
+#endif
+ case DMA_0:
+ case DMA_1:
+ case DMA_2:
+ case DMA_3:
+ case DMA_S0:
+ case DMA_S1:
+ arch_enable_dma (dmanr - DMA_0);
+ break;
+
+ default:
+ printk ("enable_dma: dma %d not supported\n", dmanr);
+ }
+}
+
+void set_dma_mode (unsigned int dmanr, char mode)
+{
+ if (dmanr < 8) {
+ if (mode == DMA_MODE_READ)
+ dma_direction[dmanr] = 1;
+ else if (mode == DMA_MODE_WRITE)
+ dma_direction[dmanr] = 0;
+ else
+ printk ("set_dma_mode: dma%d: invalid mode %02X not supported\n",
+ dmanr, mode);
+ } else if (dmanr < MAX_DMA_CHANNELS)
+ arch_set_dma_mode (dmanr - DMA_0, mode);
+ else
+ printk ("set_dma_mode: dma %d not supported\n", dmanr);
+}
+
+void set_dma_addr (unsigned int dmanr, unsigned int addr)
+{
+ if (dmanr < 8)
+ dma_address[dmanr] = (unsigned long)addr;
+ else if (dmanr < MAX_DMA_CHANNELS)
+ arch_set_dma_addr (dmanr - DMA_0, addr);
+ else
+ printk ("set_dma_addr: dma %d not supported\n", dmanr);
+}
+
+void set_dma_count (unsigned int dmanr, unsigned int count)
+{
+ if (dmanr < 8)
+ dma_count[dmanr] = (unsigned long)count;
+ else if (dmanr < MAX_DMA_CHANNELS)
+ arch_set_dma_count (dmanr - DMA_0, count);
+ else
+ printk ("set_dma_count: dma %d not supported\n", dmanr);
+}
+
+int get_dma_residue (unsigned int dmanr)
+{
+ if (dmanr < 8) {
+ switch (dmanr) {
+#if defined(CONFIG_ARCH_A5K) || defined(CONFIG_ARCH_RPC)
+ case 2: {
+ extern int floppy_fiqresidual (void);
+ return floppy_fiqresidual ();
+ }
+#endif
+#if defined(CONFIG_ARCH_ARC) && defined(CONFIG_BLK_DEV_FD)
+ case 0: {
+ extern unsigned int fdc1772_bytestogo;
+ return fdc1772_bytestogo;
+ }
+#endif
+ default:
+ return -1;
+ }
+ } else if (dmanr < MAX_DMA_CHANNELS)
+ return arch_dma_count (dmanr - DMA_0);
+ return -1;
+}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov