1 /*
2 * Q40 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) 1999
9 */
10
11 #include <asm/io.h>
12
13 #include <linux/vmalloc.h>
14
15
16 asmlinkage void floppy_hardint(int irq, void *dev_id, struct pt_regs * regs);
17
18 #undef MAX_DMA_ADDRESS
19 #define MAX_DMA_ADDRESS 0x00 /* nothing like that */
20
21 extern spinlock_t dma_spin_lock;
22
23 static __inline__ unsigned long claim_dma_lock(void)
24 {
25 unsigned long flags;
26 spin_lock_irqsave(&dma_spin_lock, flags);
27 return flags;
28 }
29
30 static __inline__ void release_dma_lock(unsigned long flags)
31 {
32 spin_unlock_irqrestore(&dma_spin_lock, flags);
33 }
34
35
36
37 #define fd_inb(port) inb_p(port)
38 #define fd_outb(port,value) outb_p(port,value)
39
40
41 #define fd_request_dma() vdma_request_dma(FLOPPY_DMA,"floppy")
42 /*#define fd_free_dma() */
43
44
45 #define fd_get_dma_residue() vdma_get_dma_residue(FLOPPY_DMA)
46 #define fd_dma_mem_alloc(size) vdma_mem_alloc(size)
47 #define fd_dma_setup(addr, size, mode, io) vdma_dma_setup(addr, size, mode, io)
48
49
50 #define fd_enable_irq() /* nothing... */
51 #define fd_disable_irq() /* nothing... */
52 #define fd_free_irq() free_irq(FLOPPY_IRQ, NULL)
53
54 #define fd_free_dma() /* nothing */
55
56 /* No 64k boundary crossing problems on Q40 - no DMA at all */
57 #define CROSS_64KB(a,s) (0)
58
59 #define DMA_MODE_READ 0x44 /* i386 look-alike */
60 #define DMA_MODE_WRITE 0x48
61
62
63 static int q40_floppy_init(void)
64 {
65 use_virtual_dma =1;
66 /* FLOPPY_IRQ=6; */
67
68 if (MACH_IS_Q40)
69 return 0x3f0;
70 else
71 return -1;
72 }
73
74
75
76
77 /*
78 * Again, the CMOS information doesn't work on the Q40..
79 */
80 #define FLOPPY0_TYPE 6
81 #define FLOPPY1_TYPE 0
82
83
84
85
86 #define FLOPPY_MOTOR_MASK 0xf0
87
88
89
90
91 /* basically PC init + set use_virtual_dma */
92 #define FDC1 q40_floppy_init()
93 static int FDC2 = -1;
94
95
96 #define N_FDC 1
97 #define N_DRIVE 8
98
99
100
101 /* vdma stuff adapted from asm-i386/floppy.h */
102
103 static int virtual_dma_count=0;
104 static int virtual_dma_residue=0;
105 static char *virtual_dma_addr=0;
106 static int virtual_dma_mode=0;
107 static int doing_pdma=0;
108
109
110
111 static int fd_request_irq(void)
112 {
113 return request_irq(FLOPPY_IRQ, floppy_hardint,SA_INTERRUPT,
114 "floppy", NULL);
115 }
116
117 /*#define SLOW_DOWN do{outb(0,0x80);}while(0)*/
118 #define SLOW_DOWN do{int count=1;do{if(!jiffies)break;}while(count-->0);}while(0)
119
120 asmlinkage void floppy_hardint(int irq, void *dev_id, struct pt_regs * regs)
121 {
122 register unsigned char st;
123
124 #undef TRACE_FLPY_INT
125 #define NO_FLOPPY_ASSEMBLER
126
127 #ifdef TRACE_FLPY_INT
128 static int calls=0;
129 static int bytes=0;
130 static int dma_wait=0;
131 #endif
132 if(!doing_pdma) {
133 floppy_interrupt(irq, dev_id, regs);
134 return;
135 }
136
137 #ifdef TRACE_FLPY_INT
138 if(!calls)
139 bytes = virtual_dma_count;
140 #endif
141
142 {
143 register int lcount;
144 register char *lptr;
145
146 /* serve 1st byte fast: */
147
148 st=1;
149 for(lcount=virtual_dma_count, lptr=virtual_dma_addr;
150 lcount; lcount--, lptr++) {
151 st=inb(virtual_dma_port+4) & 0xa0 ;
152 if(st != 0xa0)
153 break;
154 if(virtual_dma_mode)
155 outb_p(*lptr, virtual_dma_port+5);
156 else
157 *lptr = inb_p(virtual_dma_port+5);
158 }
159
160 virtual_dma_count = lcount;
161 virtual_dma_addr = lptr;
162 st = inb(virtual_dma_port+4);
163 }
164
165 #ifdef TRACE_FLPY_INT
166 calls++;
167 #endif
168 if(st == 0x20)
169 return;
170 if(!(st & 0x20)) {
171 virtual_dma_residue += virtual_dma_count;
172 virtual_dma_count=0;
173 #ifdef TRACE_FLPY_INT
174 printk("count=%x, residue=%x calls=%d bytes=%d dma_wait=%d\n",
175 virtual_dma_count, virtual_dma_residue, calls, bytes,
176 dma_wait);
177 calls = 0;
178 dma_wait=0;
179 #endif
180 doing_pdma = 0;
181 floppy_interrupt(irq, dev_id, regs);
182 return;
183 }
184 #ifdef TRACE_FLPY_INT
185 if(!virtual_dma_count)
186 dma_wait++;
187 #endif
188 }
189
190
191
192 static int vdma_request_dma(unsigned int dmanr, const char * device_id)
193 {
194 return 0;
195 }
196
197
198 static int vdma_get_dma_residue(unsigned int dummy)
199 {
200 return virtual_dma_count + virtual_dma_residue;
201 }
202
203
204 static unsigned long vdma_mem_alloc(unsigned long size)
205 {
206 return (unsigned long) vmalloc(size);
207
208 }
209
210 static void _fd_dma_mem_free(unsigned long addr, unsigned long size)
211 {
212 vfree((void *)addr);
213 }
214 #define fd_dma_mem_free(addr,size) _fd_dma_mem_free(addr, size)
215
216
217 /* choose_dma_mode ???*/
218
219 static int vdma_dma_setup(char *addr, unsigned long size, int mode, int io)
220 {
221 doing_pdma = 1;
222 virtual_dma_port = io;
223 virtual_dma_mode = (mode == DMA_MODE_WRITE);
224 virtual_dma_addr = addr;
225 virtual_dma_count = size;
226 virtual_dma_residue = 0;
227 return 0;
228 }
229
230
231
232 static void fd_disable_dma(void)
233 {
234 doing_pdma = 0;
235 virtual_dma_residue += virtual_dma_count;
236 virtual_dma_count=0;
237 }
238
239
240
241
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.