Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/parisc/include/asm/floppy.h
29271 views
1
/* SPDX-License-Identifier: GPL-2.0-or-later */
2
/* Architecture specific parts of the Floppy driver
3
*
4
* Linux/PA-RISC Project (http://www.parisc-linux.org/)
5
* Copyright (C) 2000 Matthew Wilcox (willy a debian . org)
6
* Copyright (C) 2000 Dave Kennedy
7
*/
8
#ifndef __ASM_PARISC_FLOPPY_H
9
#define __ASM_PARISC_FLOPPY_H
10
11
#include <linux/sizes.h>
12
#include <linux/vmalloc.h>
13
14
/*
15
* The DMA channel used by the floppy controller cannot access data at
16
* addresses >= 16MB
17
*
18
* Went back to the 1MB limit, as some people had problems with the floppy
19
* driver otherwise. It doesn't matter much for performance anyway, as most
20
* floppy accesses go through the track buffer.
21
*/
22
#define _CROSS_64KB(a,s,vdma) \
23
(!(vdma) && \
24
((unsigned long)(a) / SZ_64K != ((unsigned long)(a) + (s) - 1) / SZ_64K))
25
26
#define SW fd_routine[use_virtual_dma&1]
27
#define CSW fd_routine[can_use_virtual_dma & 1]
28
29
#define fd_inb(base, reg) readb((base) + (reg))
30
#define fd_outb(value, base, reg) writeb(value, (base) + (reg))
31
32
#define fd_request_dma() CSW._request_dma(FLOPPY_DMA,"floppy")
33
#define fd_free_dma() CSW._free_dma(FLOPPY_DMA)
34
#define fd_enable_irq() enable_irq(FLOPPY_IRQ)
35
#define fd_disable_irq() disable_irq(FLOPPY_IRQ)
36
#define fd_free_irq() free_irq(FLOPPY_IRQ, NULL)
37
#define fd_get_dma_residue() SW._get_dma_residue(FLOPPY_DMA)
38
#define fd_dma_mem_alloc(size) SW._dma_mem_alloc(size)
39
#define fd_dma_setup(addr, size, mode, io) SW._dma_setup(addr, size, mode, io)
40
41
#define FLOPPY_CAN_FALLBACK_ON_NODMA
42
43
static int virtual_dma_count=0;
44
static int virtual_dma_residue=0;
45
static char *virtual_dma_addr=0;
46
static int virtual_dma_mode=0;
47
static int doing_pdma=0;
48
49
static void floppy_hardint(int irq, void *dev_id, struct pt_regs * regs)
50
{
51
register unsigned char st;
52
53
#undef TRACE_FLPY_INT
54
55
#ifdef TRACE_FLPY_INT
56
static int calls=0;
57
static int bytes=0;
58
static int dma_wait=0;
59
#endif
60
if (!doing_pdma) {
61
floppy_interrupt(irq, dev_id, regs);
62
return;
63
}
64
65
#ifdef TRACE_FLPY_INT
66
if(!calls)
67
bytes = virtual_dma_count;
68
#endif
69
70
{
71
register int lcount;
72
register char *lptr = virtual_dma_addr;
73
74
for (lcount = virtual_dma_count; lcount; lcount--) {
75
st = fd_inb(virtual_dma_port, FD_STATUS);
76
st &= STATUS_DMA | STATUS_READY;
77
if (st != (STATUS_DMA | STATUS_READY))
78
break;
79
if (virtual_dma_mode) {
80
fd_outb(*lptr, virtual_dma_port, FD_DATA);
81
} else {
82
*lptr = fd_inb(virtual_dma_port, FD_DATA);
83
}
84
lptr++;
85
}
86
virtual_dma_count = lcount;
87
virtual_dma_addr = lptr;
88
st = fd_inb(virtual_dma_port, FD_STATUS);
89
}
90
91
#ifdef TRACE_FLPY_INT
92
calls++;
93
#endif
94
if (st == STATUS_DMA)
95
return;
96
if (!(st & STATUS_DMA)) {
97
virtual_dma_residue += virtual_dma_count;
98
virtual_dma_count = 0;
99
#ifdef TRACE_FLPY_INT
100
printk("count=%x, residue=%x calls=%d bytes=%d dma_wait=%d\n",
101
virtual_dma_count, virtual_dma_residue, calls, bytes,
102
dma_wait);
103
calls = 0;
104
dma_wait=0;
105
#endif
106
doing_pdma = 0;
107
floppy_interrupt(irq, dev_id, regs);
108
return;
109
}
110
#ifdef TRACE_FLPY_INT
111
if (!virtual_dma_count)
112
dma_wait++;
113
#endif
114
}
115
116
static void fd_disable_dma(void)
117
{
118
if(! (can_use_virtual_dma & 1))
119
disable_dma(FLOPPY_DMA);
120
doing_pdma = 0;
121
virtual_dma_residue += virtual_dma_count;
122
virtual_dma_count=0;
123
}
124
125
static int vdma_request_dma(unsigned int dmanr, const char * device_id)
126
{
127
return 0;
128
}
129
130
static void vdma_nop(unsigned int dummy)
131
{
132
}
133
134
135
static int vdma_get_dma_residue(unsigned int dummy)
136
{
137
return virtual_dma_count + virtual_dma_residue;
138
}
139
140
141
static int fd_request_irq(void)
142
{
143
if(can_use_virtual_dma)
144
return request_irq(FLOPPY_IRQ, floppy_hardint,
145
0, "floppy", NULL);
146
else
147
return request_irq(FLOPPY_IRQ, floppy_interrupt,
148
0, "floppy", NULL);
149
}
150
151
static unsigned long dma_mem_alloc(unsigned long size)
152
{
153
return __get_dma_pages(GFP_KERNEL, get_order(size));
154
}
155
156
157
static unsigned long vdma_mem_alloc(unsigned long size)
158
{
159
return (unsigned long) vmalloc(size);
160
161
}
162
163
#define nodma_mem_alloc(size) vdma_mem_alloc(size)
164
165
static void _fd_dma_mem_free(unsigned long addr, unsigned long size)
166
{
167
if((unsigned int) addr >= (unsigned int) high_memory)
168
return vfree((void *)addr);
169
else
170
free_pages(addr, get_order(size));
171
}
172
173
#define fd_dma_mem_free(addr, size) _fd_dma_mem_free(addr, size)
174
175
static void _fd_chose_dma_mode(char *addr, unsigned long size)
176
{
177
if(can_use_virtual_dma == 2) {
178
if((unsigned int) addr >= (unsigned int) high_memory ||
179
virt_to_phys(addr) >= 0x1000000 ||
180
_CROSS_64KB(addr, size, 0))
181
use_virtual_dma = 1;
182
else
183
use_virtual_dma = 0;
184
} else {
185
use_virtual_dma = can_use_virtual_dma & 1;
186
}
187
}
188
189
#define fd_chose_dma_mode(addr, size) _fd_chose_dma_mode(addr, size)
190
191
192
static int vdma_dma_setup(char *addr, unsigned long size, int mode, int io)
193
{
194
doing_pdma = 1;
195
virtual_dma_port = io;
196
virtual_dma_mode = (mode == DMA_MODE_WRITE);
197
virtual_dma_addr = addr;
198
virtual_dma_count = size;
199
virtual_dma_residue = 0;
200
return 0;
201
}
202
203
static int hard_dma_setup(char *addr, unsigned long size, int mode, int io)
204
{
205
#ifdef FLOPPY_SANITY_CHECK
206
if (_CROSS_64KB(addr, size, use_virtual_dma & 1)) {
207
printk("DMA crossing 64-K boundary %p-%p\n", addr, addr+size);
208
return -1;
209
}
210
#endif
211
/* actual, physical DMA */
212
doing_pdma = 0;
213
clear_dma_ff(FLOPPY_DMA);
214
set_dma_mode(FLOPPY_DMA,mode);
215
set_dma_addr(FLOPPY_DMA,virt_to_phys(addr));
216
set_dma_count(FLOPPY_DMA,size);
217
enable_dma(FLOPPY_DMA);
218
return 0;
219
}
220
221
static struct fd_routine_l {
222
int (*_request_dma)(unsigned int dmanr, const char * device_id);
223
void (*_free_dma)(unsigned int dmanr);
224
int (*_get_dma_residue)(unsigned int dummy);
225
unsigned long (*_dma_mem_alloc) (unsigned long size);
226
int (*_dma_setup)(char *addr, unsigned long size, int mode, int io);
227
} fd_routine[] = {
228
{
229
request_dma,
230
free_dma,
231
get_dma_residue,
232
dma_mem_alloc,
233
hard_dma_setup
234
},
235
{
236
vdma_request_dma,
237
vdma_nop,
238
vdma_get_dma_residue,
239
vdma_mem_alloc,
240
vdma_dma_setup
241
}
242
};
243
244
245
static int FDC1 = 0x3f0; /* Lies. Floppy controller is memory mapped, not io mapped */
246
static int FDC2 = -1;
247
248
#define FLOPPY0_TYPE 0
249
#define FLOPPY1_TYPE 0
250
251
#define N_FDC 1
252
#define N_DRIVE 8
253
254
#define EXTRA_FLOPPY_PARAMS
255
256
#endif /* __ASM_PARISC_FLOPPY_H */
257
258