Import 2.3.5
[davej-history.git] / drivers / sbus / dvma.c
blobcf60be7981fa82fcc8352fb5427eae94ab4be543
1 /* dvma.c: Routines that are used to access DMA on the Sparc SBus.
3 * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
4 */
6 #include <linux/config.h>
7 #include <linux/string.h>
8 #include <linux/kernel.h>
9 #include <linux/malloc.h>
10 #include <linux/init.h>
12 #include <asm/oplib.h>
13 #include <asm/delay.h>
14 #include <asm/io.h>
15 #include <asm/dma.h>
16 #include <asm/sbus.h>
18 struct Linux_SBus_DMA *dma_chain;
20 /* Print out the current values in the DMA control registers */
21 extern __inline__ void
22 dump_dma_regs(struct sparc_dma_registers *dregs)
24 printk("DMA CONTROL<%08lx> ADDR<%08lx> CNT<%08lx> TEST<%08lx>\n",
25 (unsigned long) dregs->cond_reg,
26 (unsigned long) dregs->st_addr,
27 (unsigned long) dregs->cnt,
28 (unsigned long) dregs->dma_test);
29 return;
32 __initfunc(void
33 init_one_dvma(struct Linux_SBus_DMA *dma, int num_dma))
35 printk("dma%d: ", num_dma);
37 dma->next = 0;
38 dma->running=0; /* No transfers going on as of yet */
39 dma->allocated=0; /* No one has allocated us yet */
40 switch((dma->regs->cond_reg)&DMA_DEVICE_ID) {
41 case DMA_VERS0:
42 dma->revision=dvmarev0;
43 printk("Revision 0 ");
44 break;
45 case DMA_ESCV1:
46 dma->revision=dvmaesc1;
47 printk("ESC Revision 1 ");
48 break;
49 case DMA_VERS1:
50 dma->revision=dvmarev1;
51 printk("Revision 1 ");
52 break;
53 case DMA_VERS2:
54 dma->revision=dvmarev2;
55 printk("Revision 2 ");
56 break;
57 case DMA_VERHME:
58 dma->revision=dvmahme;
59 printk("HME DVMA gate array ");
60 break;
61 case DMA_VERSPLUS:
62 dma->revision=dvmarevplus;
63 printk("Revision 1 PLUS ");
64 break;
65 default:
66 printk("unknown dma version %x",
67 (dma->regs->cond_reg)&DMA_DEVICE_ID);
68 dma->allocated = 1;
69 break;
71 printk("\n");
72 #if 0 /* Clutters up the screen */
73 dump_dma_regs(dma->regs);
74 #endif
77 /* Probe this SBus DMA module(s) */
78 __initfunc(void
79 dvma_init(struct linux_sbus *sbus))
81 struct linux_sbus_device *this_dev;
82 struct Linux_SBus_DMA *dma;
83 struct Linux_SBus_DMA *dchain;
84 static int num_dma=0;
86 for_each_sbusdev(this_dev, sbus) {
87 int hme = 0;
89 if(!strcmp(this_dev->prom_name, "SUNW,fas"))
90 hme = 1;
91 else if(strcmp(this_dev->prom_name, "dma") &&
92 strcmp(this_dev->prom_name, "ledma") &&
93 strcmp(this_dev->prom_name, "espdma"))
94 continue;
96 /* Found one... */
97 dma = kmalloc(sizeof(struct Linux_SBus_DMA), GFP_ATOMIC);
99 dma->SBus_dev = this_dev;
101 /* Put at end of dma chain */
102 dchain = dma_chain;
103 if(dchain) {
104 while(dchain->next) dchain=dchain->next;
105 dchain->next=dma;
106 } else {
107 /* We're the first in line */
108 dma_chain=dma;
111 /* The constant PAGE_SIZE that is passed to sparc_alloc_io makes the
112 * routine only alloc 1 page, that was what the original code did
114 if(hme) /* On HME cards, dvma lives with esp, 2 reg sets. */
115 prom_apply_sbus_ranges(sbus, dma->SBus_dev->reg_addrs,
116 0x2, dma->SBus_dev);
117 else /* All others have only 1 reg set. */
118 prom_apply_sbus_ranges(sbus, dma->SBus_dev->reg_addrs,
119 0x1, dma->SBus_dev);
120 dma->regs = (struct sparc_dma_registers *)
121 sparc_alloc_io (dma->SBus_dev->reg_addrs[0].phys_addr, 0,
122 PAGE_SIZE, "dma",
123 dma->SBus_dev->reg_addrs[0].which_io, 0x0);
125 dma->node = dma->SBus_dev->prom_node;
127 init_one_dvma(dma, num_dma++);
129 }; /* while(this_dev) */
132 #ifdef CONFIG_SUN4
134 #include <asm/sun4paddr.h>
136 __initfunc(void sun4_dvma_init(void))
138 struct Linux_SBus_DMA *dma;
139 struct Linux_SBus_DMA *dchain;
141 if(sun4_dma_physaddr) {
142 dma = kmalloc(sizeof(struct Linux_SBus_DMA), GFP_ATOMIC);
144 /* No SBUS */
145 dma->SBus_dev = 0x0;
147 /* Only one DMA device */
148 dma_chain=dma;
150 dma->regs = (struct sparc_dma_registers *)
151 sparc_alloc_io (sun4_dma_physaddr, 0,
152 PAGE_SIZE, "dma", 0x0, 0x0);
154 /* No prom node */
155 dma->node = 0x0;
157 init_one_dvma(dma, 0);
158 } else {
159 dma_chain=0x0;
163 #endif