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