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)
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>
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
);
33 init_one_dvma(struct Linux_SBus_DMA
*dma
, int num_dma
))
35 printk("dma%d: ", num_dma
);
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
) {
42 dma
->revision
=dvmarev0
;
43 printk("Revision 0 ");
46 dma
->revision
=dvmaesc1
;
47 printk("ESC Revision 1 ");
50 dma
->revision
=dvmarev1
;
51 printk("Revision 1 ");
54 dma
->revision
=dvmarev2
;
55 printk("Revision 2 ");
58 dma
->revision
=dvmahme
;
59 printk("HME DVMA gate array ");
62 dma
->revision
=dvmarevplus
;
63 printk("Revision 1 PLUS ");
66 printk("unknown dma version %x",
67 (dma
->regs
->cond_reg
)&DMA_DEVICE_ID
);
72 #if 0 /* Clutters up the screen */
73 dump_dma_regs(dma
->regs
);
77 /* Probe this SBus DMA module(s) */
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
;
86 for_each_sbusdev(this_dev
, sbus
) {
89 if(!strcmp(this_dev
->prom_name
, "SUNW,fas"))
91 else if(strcmp(this_dev
->prom_name
, "dma") &&
92 strcmp(this_dev
->prom_name
, "ledma") &&
93 strcmp(this_dev
->prom_name
, "espdma"))
97 dma
= kmalloc(sizeof(struct Linux_SBus_DMA
), GFP_ATOMIC
);
99 dma
->SBus_dev
= this_dev
;
101 /* Put at end of dma chain */
104 while(dchain
->next
) dchain
=dchain
->next
;
107 /* We're the first in line */
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
,
117 else /* All others have only 1 reg set. */
118 prom_apply_sbus_ranges(sbus
, dma
->SBus_dev
->reg_addrs
,
120 dma
->regs
= (struct sparc_dma_registers
*)
121 sparc_alloc_io (dma
->SBus_dev
->reg_addrs
[0].phys_addr
, 0,
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) */
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
);
147 /* Only one DMA device */
150 dma
->regs
= (struct sparc_dma_registers
*)
151 sparc_alloc_io (sun4_dma_physaddr
, 0,
152 PAGE_SIZE
, "dma", 0x0, 0x0);
157 init_one_dvma(dma
, 0);