1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
/*
* arch/arm/kernel/dma-a5k.c
*
* Copyright (C) 1998 Russell King
*
* DMA functions specific to A5000 architecture
*/
#include <linux/sched.h>
#include <linux/init.h>
#include <asm/dma.h>
#include <asm/fiq.h>
#include <asm/io.h>
#include <asm/hardware.h>
#include "dma.h"
static struct fiq_handler fh = { NULL, "floppydma", NULL, NULL };
int arch_request_dma(dmach_t channel, dma_t *dma, const char *dev_id)
{
if (channel == DMA_VIRTUAL_FLOPPY)
return 0;
else
return -EINVAL;
}
void arch_free_dma(dmach_t channel, dma_t *dma)
{
if (channel != DMA_VIRTUAL_FLOPPY)
printk("arch_free_dma: invalid channel %d\n", channel);
}
int arch_get_dma_residue(dmach_t channel, dma_t *dma)
{
if (channel != DMA_VIRTUAL_FLOPPY)
printk("arch_dma_count: invalid channel %d\n", channel);
else {
struct pt_regs regs;
get_fiq_regs(®s);
return regs.ARM_r9;
}
return 0;
}
void arch_enable_dma(dmach_t channel, dma_t *dma)
{
if (channel != DMA_VIRTUAL_FLOPPY)
printk("arch_enable_dma: invalid channel %d\n", channel);
else {
struct pt_regs regs;
void *fiqhandler_start;
unsigned int fiqhandler_length;
extern void floppy_fiqsetup(unsigned long len, unsigned long addr,
unsigned long port);
if (dma->dma_mode == DMA_MODE_READ) {
extern unsigned char floppy_fiqin_start, floppy_fiqin_end;
fiqhandler_start = &floppy_fiqin_start;
fiqhandler_length = &floppy_fiqin_end - &floppy_fiqin_start;
} else {
extern unsigned char floppy_fiqout_start, floppy_fiqout_end;
fiqhandler_start = &floppy_fiqout_start;
fiqhandler_length = &floppy_fiqout_end - &floppy_fiqout_start;
}
if (claim_fiq(&fh)) {
printk("floppydma: couldn't claim FIQ.\n");
return;
}
memcpy((void *)0x1c, fiqhandler_start, fiqhandler_length);
regs.ARM_r9 = dma->buf.length;
regs.ARM_r10 = __bus_to_virt(dma->buf.address);
regs.ARM_fp = (int)PCIO_FLOPPYDMABASE;
set_fiq_regs(®s);
enable_irq(dma->dma_irq);
}
}
void arch_disable_dma(dmach_t channel, dma_t *dma)
{
if (channel != DMA_VIRTUAL_FLOPPY)
printk("arch_disable_dma: invalid channel %d\n", channel);
else {
disable_irq(dma->dma_irq);
release_fiq(&fh);
}
}
int arch_set_dma_speed(dmach_t channel, dma_t *dma, int cycle_ns)
{
return 0;
}
__initfunc(void arch_dma_init(dma_t *dma))
{
dma[DMA_VIRTUAL_FLOPPY].dma_irq = 64;
}
|