xref: /linux/arch/x86/include/asm/floppy.h (revision 07fdad3a93756b872da7b53647715c48d0f4a2d0)
1 /*
2  * Architecture specific parts of the Floppy driver
3  *
4  * This file is subject to the terms and conditions of the GNU General Public
5  * License.  See the file "COPYING" in the main directory of this archive
6  * for more details.
7  *
8  * Copyright (C) 1995
9  */
10 #ifndef _ASM_X86_FLOPPY_H
11 #define _ASM_X86_FLOPPY_H
12 
13 #include <linux/sizes.h>
14 #include <linux/vmalloc.h>
15 
16 /*
17  * The DMA channel used by the floppy controller cannot access data at
18  * addresses >= 16MB
19  *
20  * Went back to the 1MB limit, as some people had problems with the floppy
21  * driver otherwise. It doesn't matter much for performance anyway, as most
22  * floppy accesses go through the track buffer.
23  */
24 #define _CROSS_64KB(a, s, vdma)						\
25 	(!(vdma) &&							\
26 	 ((unsigned long)(a) / SZ_64K != ((unsigned long)(a) + (s) - 1) / SZ_64K))
27 
28 #define SW fd_routine[use_virtual_dma & 1]
29 #define CSW fd_routine[can_use_virtual_dma & 1]
30 
31 
32 #define fd_inb(base, reg)		inb_p((base) + (reg))
33 #define fd_outb(value, base, reg)	outb_p(value, (base) + (reg))
34 
35 #define fd_request_dma()	CSW._request_dma(FLOPPY_DMA, "floppy")
36 #define fd_free_dma()		CSW._free_dma(FLOPPY_DMA)
37 #define fd_enable_irq()		enable_irq(FLOPPY_IRQ)
38 #define fd_disable_irq()	disable_irq(FLOPPY_IRQ)
39 #define fd_free_irq()		free_irq(FLOPPY_IRQ, NULL)
40 #define fd_get_dma_residue()	SW._get_dma_residue(FLOPPY_DMA)
41 #define fd_dma_mem_alloc(size)	SW._dma_mem_alloc(size)
42 #define fd_dma_setup(addr, size, mode, io) SW._dma_setup(addr, size, mode, io)
43 
44 #define FLOPPY_CAN_FALLBACK_ON_NODMA
45 
46 static int virtual_dma_count;
47 static int virtual_dma_residue;
48 static char *virtual_dma_addr;
49 static int virtual_dma_mode;
50 static int doing_pdma;
51 
52 static irqreturn_t floppy_hardint(int irq, void *dev_id)
53 {
54 	unsigned char st;
55 
56 #undef TRACE_FLPY_INT
57 
58 #ifdef TRACE_FLPY_INT
59 	static int calls;
60 	static int bytes;
61 	static int dma_wait;
62 #endif
63 	if (!doing_pdma)
64 		return floppy_interrupt(irq, dev_id);
65 
66 #ifdef TRACE_FLPY_INT
67 	if (!calls)
68 		bytes = virtual_dma_count;
69 #endif
70 
71 	{
72 		int lcount;
73 		char *lptr;
74 
75 		for (lcount = virtual_dma_count, lptr = virtual_dma_addr;
76 		     lcount; lcount--, lptr++) {
77 			st = inb(virtual_dma_port + FD_STATUS);
78 			st &= STATUS_DMA | STATUS_READY;
79 			if (st != (STATUS_DMA | STATUS_READY))
80 				break;
81 			if (virtual_dma_mode)
82 				outb_p(*lptr, virtual_dma_port + FD_DATA);
83 			else
84 				*lptr = inb_p(virtual_dma_port + FD_DATA);
85 		}
86 		virtual_dma_count = lcount;
87 		virtual_dma_addr = lptr;
88 		st = inb(virtual_dma_port + FD_STATUS);
89 	}
90 
91 #ifdef TRACE_FLPY_INT
92 	calls++;
93 #endif
94 	if (st == STATUS_DMA)
95 		return IRQ_HANDLED;
96 	if (!(st & STATUS_DMA)) {
97 		virtual_dma_residue += virtual_dma_count;
98 		virtual_dma_count = 0;
99 #ifdef TRACE_FLPY_INT
100 		printk(KERN_DEBUG "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);
108 		return IRQ_HANDLED;
109 	}
110 #ifdef TRACE_FLPY_INT
111 	if (!virtual_dma_count)
112 		dma_wait++;
113 #endif
114 	return IRQ_HANDLED;
115 }
116 
117 static void fd_disable_dma(void)
118 {
119 	if (!(can_use_virtual_dma & 1))
120 		disable_dma(FLOPPY_DMA);
121 	doing_pdma = 0;
122 	virtual_dma_residue += virtual_dma_count;
123 	virtual_dma_count = 0;
124 }
125 
126 static int vdma_request_dma(unsigned int dmanr, const char *device_id)
127 {
128 	return 0;
129 }
130 
131 static void vdma_nop(unsigned int dummy)
132 {
133 }
134 
135 
136 static int vdma_get_dma_residue(unsigned int dummy)
137 {
138 	return virtual_dma_count + virtual_dma_residue;
139 }
140 
141 
142 static int fd_request_irq(void)
143 {
144 	if (can_use_virtual_dma)
145 		return request_irq(FLOPPY_IRQ, floppy_hardint,
146 				   0, "floppy", NULL);
147 	else
148 		return request_irq(FLOPPY_IRQ, floppy_interrupt,
149 				   0, "floppy", NULL);
150 }
151 
152 static unsigned long dma_mem_alloc(unsigned long size)
153 {
154 	return __get_dma_pages(GFP_KERNEL|__GFP_NORETRY, get_order(size));
155 }
156 
157 
158 static unsigned long vdma_mem_alloc(unsigned long size)
159 {
160 	return (unsigned long)vmalloc(size);
161 
162 }
163 
164 #define nodma_mem_alloc(size) vdma_mem_alloc(size)
165 
166 static void _fd_dma_mem_free(unsigned long addr, unsigned long size)
167 {
168 	if ((unsigned long)addr >= (unsigned long)high_memory)
169 		vfree((void *)addr);
170 	else
171 		free_pages(addr, get_order(size));
172 }
173 
174 #define fd_dma_mem_free(addr, size)  _fd_dma_mem_free(addr, size)
175 
176 static void _fd_chose_dma_mode(char *addr, unsigned long size)
177 {
178 	if (can_use_virtual_dma == 2) {
179 		if ((unsigned long)addr >= (unsigned long)high_memory ||
180 		    isa_virt_to_bus(addr) >= 0x1000000 ||
181 		    _CROSS_64KB(addr, size, 0))
182 			use_virtual_dma = 1;
183 		else
184 			use_virtual_dma = 0;
185 	} else {
186 		use_virtual_dma = can_use_virtual_dma & 1;
187 	}
188 }
189 
190 #define fd_chose_dma_mode(addr, size) _fd_chose_dma_mode(addr, size)
191 
192 
193 static int vdma_dma_setup(char *addr, unsigned long size, int mode, int io)
194 {
195 	doing_pdma = 1;
196 	virtual_dma_port = io;
197 	virtual_dma_mode = (mode == DMA_MODE_WRITE);
198 	virtual_dma_addr = addr;
199 	virtual_dma_count = size;
200 	virtual_dma_residue = 0;
201 	return 0;
202 }
203 
204 static int hard_dma_setup(char *addr, unsigned long size, int mode, int io)
205 {
206 #ifdef FLOPPY_SANITY_CHECK
207 	if (_CROSS_64KB(addr, size, use_virtual_dma & 1)) {
208 		printk("DMA crossing 64-K boundary %p-%p\n", addr, addr+size);
209 		return -1;
210 	}
211 #endif
212 	/* actual, physical DMA */
213 	doing_pdma = 0;
214 	clear_dma_ff(FLOPPY_DMA);
215 	set_dma_mode(FLOPPY_DMA, mode);
216 	set_dma_addr(FLOPPY_DMA, isa_virt_to_bus(addr));
217 	set_dma_count(FLOPPY_DMA, size);
218 	enable_dma(FLOPPY_DMA);
219 	return 0;
220 }
221 
222 static struct fd_routine_l {
223 	int (*_request_dma)(unsigned int dmanr, const char *device_id);
224 	void (*_free_dma)(unsigned int dmanr);
225 	int (*_get_dma_residue)(unsigned int dummy);
226 	unsigned long (*_dma_mem_alloc)(unsigned long size);
227 	int (*_dma_setup)(char *addr, unsigned long size, int mode, int io);
228 } fd_routine[] = {
229 	{
230 		._request_dma		= request_dma,
231 		._free_dma		= free_dma,
232 		._get_dma_residue	= get_dma_residue,
233 		._dma_mem_alloc		= dma_mem_alloc,
234 		._dma_setup		= hard_dma_setup
235 	},
236 	{
237 		._request_dma		= vdma_request_dma,
238 		._free_dma		= vdma_nop,
239 		._get_dma_residue	= vdma_get_dma_residue,
240 		._dma_mem_alloc		= vdma_mem_alloc,
241 		._dma_setup		= vdma_dma_setup
242 	}
243 };
244 
245 
246 static int FDC1 = 0x3f0;
247 static int FDC2 = -1;
248 
249 /*
250  * Floppy types are stored in the rtc's CMOS RAM and so rtc_lock
251  * is needed to prevent corrupted CMOS RAM in case "insmod floppy"
252  * coincides with another rtc CMOS user.		Paul G.
253  */
254 #define FLOPPY0_TYPE					\
255 ({							\
256 	unsigned long flags;				\
257 	unsigned char val;				\
258 	spin_lock_irqsave(&rtc_lock, flags);		\
259 	val = (CMOS_READ(0x10) >> 4) & 15;		\
260 	spin_unlock_irqrestore(&rtc_lock, flags);	\
261 	val;						\
262 })
263 
264 #define FLOPPY1_TYPE					\
265 ({							\
266 	unsigned long flags;				\
267 	unsigned char val;				\
268 	spin_lock_irqsave(&rtc_lock, flags);		\
269 	val = CMOS_READ(0x10) & 15;			\
270 	spin_unlock_irqrestore(&rtc_lock, flags);	\
271 	val;						\
272 })
273 
274 #define N_FDC 2
275 #define N_DRIVE 8
276 
277 #define EXTRA_FLOPPY_PARAMS
278 
279 #endif /* _ASM_X86_FLOPPY_H */
280