|
|
1.1 root 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_I386_FLOPPY_H
11: #define __ASM_I386_FLOPPY_H
12:
13:
14: #define SW fd_routine[use_virtual_dma&1]
15:
16:
17: #define fd_inb(port) inb_p(port)
18: #define fd_outb(port,value) outb_p(port,value)
19:
20: #define fd_enable_dma() SW._enable_dma(FLOPPY_DMA)
21: #define fd_disable_dma() SW._disable_dma(FLOPPY_DMA)
22: #define fd_request_dma() SW._request_dma(FLOPPY_DMA,"floppy")
23: #define fd_free_dma() SW._free_dma(FLOPPY_DMA)
24: #define fd_clear_dma_ff() SW._clear_dma_ff(FLOPPY_DMA)
25: #define fd_set_dma_mode(mode) SW._set_dma_mode(FLOPPY_DMA,mode)
26: #define fd_set_dma_addr(addr) SW._set_dma_addr(FLOPPY_DMA,addr)
27: #define fd_set_dma_count(count) SW._set_dma_count(FLOPPY_DMA,count)
28: #define fd_enable_irq() enable_irq(FLOPPY_IRQ)
29: #define fd_disable_irq() disable_irq(FLOPPY_IRQ)
30: #define fd_cacheflush(addr,size) /* nothing */
31: #define fd_request_irq() SW._request_irq(FLOPPY_IRQ, floppy_interrupt, \
32: SA_INTERRUPT|SA_SAMPLE_RANDOM, \
33: "floppy", NULL)
34: #define fd_free_irq() free_irq(FLOPPY_IRQ, NULL)
35: #define fd_get_dma_residue() SW._get_dma_residue(FLOPPY_DMA)
36: #define fd_dma_mem_alloc(size) SW._dma_mem_alloc(size)
37: #define fd_dma_mem_free(addr,size) SW._dma_mem_free(addr,size)
38:
39: static int virtual_dma_count=0;
40: static int virtual_dma_residue=0;
41: static unsigned long virtual_dma_addr=0;
42: static int virtual_dma_mode=0;
43: static int doing_pdma=0;
44:
45: static void floppy_hardint(int irq, void *dev_id, struct pt_regs * regs)
46: {
47: register unsigned char st;
48:
49: #undef TRACE_FLPY_INT
50: #undef NO_FLOPPY_ASSEMBLER
51:
52: #ifdef TRACE_FLPY_INT
53: static int calls=0;
54: static int bytes=0;
55: static int dma_wait=0;
56: #endif
57: if(!doing_pdma) {
58: floppy_interrupt(irq, dev_id, regs);
59: return;
60: }
61:
62: #ifdef TRACE_FLPY_INT
63: if(!calls)
64: bytes = virtual_dma_count;
65: #endif
66:
67: #ifndef NO_FLOPPY_ASSEMBLER
68: __asm__ (
69: "testl %1,%1
70: je 3f
71: 1: inb %w4,%b0
72: andb $160,%b0
73: cmpb $160,%b0
74: jne 2f
75: incw %w4
76: testl %3,%3
77: jne 4f
78: inb %w4,%b0
79: movb %0,(%2)
80: jmp 5f
81: 4: movb (%2),%0
82: outb %b0,%w4
83: 5: decw %w4
84: outb %0,$0x80
85: decl %1
86: incl %2
87: testl %1,%1
88: jne 1b
89: 3: inb %w4,%b0
90: 2: "
91: : "=a" ((char) st),
92: "=c" ((long) virtual_dma_count),
93: "=S" ((long) virtual_dma_addr)
94: : "b" ((long) virtual_dma_mode),
95: "d" ((short) virtual_dma_port+4),
96: "1" ((long) virtual_dma_count),
97: "2" ((long) virtual_dma_addr));
98: #else
99: {
100: register int lcount;
101: register char *lptr;
102:
103: st = 1;
104: for(lcount=virtual_dma_count, lptr=(char *)virtual_dma_addr;
105: lcount; lcount--, lptr++) {
106: st=inb(virtual_dma_port+4) & 0xa0 ;
107: if(st != 0xa0)
108: break;
109: if(virtual_dma_mode)
110: outb_p(*lptr, virtual_dma_port+5);
111: else
112: *lptr = inb_p(virtual_dma_port+5);
113: st = inb(virtual_dma_port+4);
114: }
115: virtual_dma_count = lcount;
116: virtual_dma_addr = (int) lptr;
117: }
118: #endif
119:
120: #ifdef TRACE_FLPY_INT
121: calls++;
122: #endif
123: if(st == 0x20)
124: return;
125: if(!(st & 0x20)) {
126: virtual_dma_residue += virtual_dma_count;
127: virtual_dma_count=0;
128: #ifdef TRACE_FLPY_INT
129: printk("count=%x, residue=%x calls=%d bytes=%d dma_wait=%d\n",
130: virtual_dma_count, virtual_dma_residue, calls, bytes,
131: dma_wait);
132: calls = 0;
133: dma_wait=0;
134: #endif
135: doing_pdma = 0;
136: floppy_interrupt(irq, dev_id, regs);
137: return;
138: }
139: #ifdef TRACE_FLPY_INT
140: if(!virtual_dma_count)
141: dma_wait++;
142: #endif
143: }
144:
145: static void vdma_enable_dma(unsigned int dummy)
146: {
147: doing_pdma = 1;
148: }
149:
150: static void vdma_disable_dma(unsigned int dummy)
151: {
152: doing_pdma = 0;
153: virtual_dma_residue += virtual_dma_count;
154: virtual_dma_count=0;
155: }
156:
157: static int vdma_request_dma(unsigned int dmanr, const char * device_id)
158: {
159: return 0;
160: }
161:
162: static void vdma_nop(unsigned int dummy)
163: {
164: }
165:
166: static void vdma_set_dma_mode(unsigned int dummy,char mode)
167: {
168: virtual_dma_mode = (mode == DMA_MODE_WRITE);
169: }
170:
171: static void vdma_set_dma_addr(unsigned int dummy,unsigned int addr)
172: {
173: virtual_dma_addr = addr;
174: }
175:
176: static void vdma_set_dma_count(unsigned int dummy,unsigned int count)
177: {
178: virtual_dma_count = count;
179: virtual_dma_residue = 0;
180: }
181:
182: static int vdma_get_dma_residue(unsigned int dummy)
183: {
184: return virtual_dma_count + virtual_dma_residue;
185: }
186:
187:
188: static int vdma_request_irq(unsigned int irq,
189: void (*handler)(int, void *, struct pt_regs *),
190: unsigned long flags,
191: const char *device,
192: void *dev_id)
193: {
194: return request_irq(irq, floppy_hardint,SA_INTERRUPT,device, dev_id);
195:
196: }
197:
198: static unsigned long dma_mem_alloc(unsigned long size)
199: {
200: return __get_dma_pages(GFP_KERNEL,__get_order(size));
201: }
202:
203: static void dma_mem_free(unsigned long addr, unsigned long size)
204: {
205: free_pages(addr, __get_order(size));
206: }
207:
208: static unsigned long vdma_mem_alloc(unsigned long size)
209: {
210: return (unsigned long) vmalloc(size);
211: }
212:
213: static void vdma_mem_free(unsigned long addr, unsigned long size)
214: {
215: return vfree((void *)addr);
216: }
217:
218: struct fd_routine_l {
219: void (*_enable_dma)(unsigned int dummy);
220: void (*_disable_dma)(unsigned int dummy);
221: int (*_request_dma)(unsigned int dmanr, const char * device_id);
222: void (*_free_dma)(unsigned int dmanr);
223: void (*_clear_dma_ff)(unsigned int dummy);
224: void (*_set_dma_mode)(unsigned int dummy, char mode);
225: void (*_set_dma_addr)(unsigned int dummy, unsigned int addr);
226: void (*_set_dma_count)(unsigned int dummy, unsigned int count);
227: int (*_get_dma_residue)(unsigned int dummy);
228: int (*_request_irq)(unsigned int irq,
229: void (*handler)(int, void *, struct pt_regs *),
230: unsigned long flags,
231: const char *device,
232: void *dev_id);
233: unsigned long (*_dma_mem_alloc) (unsigned long size);
234: void (*_dma_mem_free)(unsigned long addr, unsigned long size);
235: } fd_routine[] = {
236: {
237: enable_dma,
238: disable_dma,
239: request_dma,
240: free_dma,
241: clear_dma_ff,
242: set_dma_mode,
243: set_dma_addr,
244: set_dma_count,
245: get_dma_residue,
246: request_irq,
247: dma_mem_alloc,
248: dma_mem_free
249: },
250: {
251: vdma_enable_dma,
252: vdma_disable_dma,
253: vdma_request_dma,
254: vdma_nop,
255: vdma_nop,
256: vdma_set_dma_mode,
257: vdma_set_dma_addr,
258: vdma_set_dma_count,
259: vdma_get_dma_residue,
260: vdma_request_irq,
261: vdma_mem_alloc,
262: vdma_mem_free
263: }
264: };
265:
266: __inline__ void virtual_dma_init(void)
267: {
268: /* Nothing to do on an i386 */
269: }
270:
271: static int FDC1 = 0x3f0;
272: static int FDC2 = -1;
273:
274: #define FLOPPY0_TYPE ((CMOS_READ(0x10) >> 4) & 15)
275: #define FLOPPY1_TYPE (CMOS_READ(0x10) & 15)
276:
277: #define N_FDC 2
278: #define N_DRIVE 8
279:
280: /*
281: * The DMA channel used by the floppy controller cannot access data at
282: * addresses >= 16MB
283: *
284: * Went back to the 1MB limit, as some people had problems with the floppy
285: * driver otherwise. It doesn't matter much for performance anyway, as most
286: * floppy accesses go through the track buffer.
287: */
288: #define CROSS_64KB(a,s) (((unsigned long)(a)/K_64 != ((unsigned long)(a) + (s) - 1) / K_64) && ! (use_virtual_dma & 1))
289:
290: #endif /* __ASM_I386_FLOPPY_H */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.