floppy.h 4.03 KB
Newer Older
Linus Torvalds's avatar
Linus Torvalds committed
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
/*
 * Architecture specific parts of the 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) 1995
 */
#ifdef __KERNEL__
#ifndef __ASM_PPC_FLOPPY_H
#define __ASM_PPC_FLOPPY_H

#define fd_inb(port)		inb_p(port)
#define fd_outb(value,port)	outb_p(value,port)

#define fd_disable_dma()	fd_ops->_disable_dma(FLOPPY_DMA)
#define fd_free_dma()           fd_ops->_free_dma(FLOPPY_DMA)
#define fd_get_dma_residue()    fd_ops->_get_dma_residue(FLOPPY_DMA)
#define fd_dma_setup(addr, size, mode, io) fd_ops->_dma_setup(addr, size, mode, io)
#define fd_enable_irq()         enable_irq(FLOPPY_IRQ)
#define fd_disable_irq()        disable_irq(FLOPPY_IRQ)
#define fd_free_irq()           free_irq(FLOPPY_IRQ, NULL);

static int fd_request_dma(void);

struct fd_dma_ops {
	void (*_disable_dma)(unsigned int dmanr);
	void (*_free_dma)(unsigned int dmanr);
	int (*_get_dma_residue)(unsigned int dummy);
	int (*_dma_setup)(char *addr, unsigned long size, int mode, int io);
};

static int virtual_dma_count;
static int virtual_dma_residue;
static char *virtual_dma_addr;
static int virtual_dma_mode;
static int doing_vdma;
static struct fd_dma_ops *fd_ops;

41
static irqreturn_t floppy_hardint(int irq, void *dev_id)
Linus Torvalds's avatar
Linus Torvalds committed
42
43
44
45
46
47
{
	unsigned char st;
	int lcount;
	char *lptr;

	if (!doing_vdma)
48
		return floppy_interrupt(irq, dev_id);
Linus Torvalds's avatar
Linus Torvalds committed
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71


	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);

	if (st == 0x20)
		return IRQ_HANDLED;
	if (!(st & 0x20)) {
		virtual_dma_residue += virtual_dma_count;
		virtual_dma_count=0;
		doing_vdma = 0;
72
		floppy_interrupt(irq, dev_id);
Linus Torvalds's avatar
Linus Torvalds committed
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
98
		return IRQ_HANDLED;
	}
	return IRQ_HANDLED;
}

static void vdma_disable_dma(unsigned int dummy)
{
	doing_vdma = 0;
	virtual_dma_residue += virtual_dma_count;
	virtual_dma_count=0;
}

static void vdma_nop(unsigned int dummy)
{
}


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


static int fd_request_irq(void)
{
	if (can_use_virtual_dma)
99
100
		return request_irq(FLOPPY_IRQ, floppy_hardint,
				   IRQF_DISABLED, "floppy", NULL);
Linus Torvalds's avatar
Linus Torvalds committed
101
	else
102
103
		return request_irq(FLOPPY_IRQ, floppy_interrupt,
				   IRQF_DISABLED, "floppy", NULL);
Linus Torvalds's avatar
Linus Torvalds committed
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
}

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

static int hard_dma_setup(char *addr, unsigned long size, int mode, int io)
{
	/* actual, physical DMA */
	doing_vdma = 0;
	clear_dma_ff(FLOPPY_DMA);
	set_dma_mode(FLOPPY_DMA,mode);
	set_dma_addr(FLOPPY_DMA,(unsigned int)virt_to_bus(addr));
	set_dma_count(FLOPPY_DMA,size);
	enable_dma(FLOPPY_DMA);
	return 0;
}

static struct fd_dma_ops real_dma_ops =
{
	._disable_dma = disable_dma,
	._free_dma = free_dma,
	._get_dma_residue = get_dma_residue,
	._dma_setup = hard_dma_setup
};

static struct fd_dma_ops virt_dma_ops =
{
	._disable_dma = vdma_disable_dma,
	._free_dma = vdma_nop,
	._get_dma_residue = vdma_get_dma_residue,
	._dma_setup = vdma_dma_setup
};

static int fd_request_dma()
{
	if (can_use_virtual_dma & 1) {
		fd_ops = &virt_dma_ops;
		return 0;
	}
	else {
		fd_ops = &real_dma_ops;
		return request_dma(FLOPPY_DMA, "floppy");
	}
}

static int FDC1 = 0x3f0;
static int FDC2 = -1;

/*
 * Again, the CMOS information not available
 */
#define FLOPPY0_TYPE 6
#define FLOPPY1_TYPE 0

#define N_FDC 2			/* Don't change this! */
#define N_DRIVE 8

#define FLOPPY_MOTOR_MASK 0xf0

/*
 * The PowerPC has no problems with floppy DMA crossing 64k borders.
 */
#define CROSS_64KB(a,s)	(0)

#endif /* __ASM_PPC_FLOPPY_H */

#define EXTRA_FLOPPY_PARAMS

#endif /* __KERNEL__ */