Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
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
43static int virtual_dma_count=0;
44static int virtual_dma_residue=0;
45static char *virtual_dma_addr=0;
46static int virtual_dma_mode=0;
47static int doing_pdma=0;
48
49static 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
116static 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
125static int vdma_request_dma(unsigned int dmanr, const char * device_id)
126{
127 return 0;
128}
129
130static void vdma_nop(unsigned int dummy)
131{
132}
133
134
135static int vdma_get_dma_residue(unsigned int dummy)
136{
137 return virtual_dma_count + virtual_dma_residue;
138}
139
140
141static 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
151static unsigned long dma_mem_alloc(unsigned long size)
152{
153 return __get_dma_pages(GFP_KERNEL, get_order(size));
154}
155
156
157static 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
165static 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
175static 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
192static 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
203static 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
221static 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
245static int FDC1 = 0x3f0; /* Lies. Floppy controller is memory mapped, not io mapped */
246static 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 */