ia64/xen-unstable

view linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/floppy.h @ 4223:1a1a16726bd2

bitkeeper revision 1.1159.273.3 (423d44f5mg2mqgtSGUZfZFYsYmHuMA)

Primary floppy controller is at port 0x3f0, not 0x340.
Signed-off-by: Keir Fraser <keir@Xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Sun Mar 20 09:40:05 2005 +0000 (2005-03-20)
parents cff0d3baf599
children d580210d4a53 dbdf796cd98c 0bf276cd53cb
line source
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 * Modifications for Xen are Copyright (c) 2004, Keir Fraser.
11 */
12 #ifndef __ASM_XEN_I386_FLOPPY_H
13 #define __ASM_XEN_I386_FLOPPY_H
15 #include <linux/vmalloc.h>
17 /* XEN: Hit DMA paths on the head. This trick from asm-m68k/floppy.h. */
18 #include <asm/dma.h>
19 #undef MAX_DMA_ADDRESS
20 #define MAX_DMA_ADDRESS 0
21 #define CROSS_64KB(a,s) (0)
23 #define fd_inb(port) inb_p(port)
24 #define fd_outb(value,port) outb_p(value,port)
26 #define fd_request_dma() (0)
27 #define fd_free_dma() ((void)0)
28 #define fd_enable_irq() enable_irq(FLOPPY_IRQ)
29 #define fd_disable_irq() disable_irq(FLOPPY_IRQ)
30 #define fd_free_irq() free_irq(FLOPPY_IRQ, NULL)
31 #define fd_get_dma_residue() vdma_get_dma_residue(FLOPPY_DMA)
32 #define fd_dma_mem_alloc(size) vdma_mem_alloc(size)
33 #define fd_dma_mem_free(addr, size) vdma_mem_free(addr, size)
34 #define fd_dma_setup(addr, size, mode, io) vdma_dma_setup(addr, size, mode, io)
36 static int virtual_dma_count;
37 static int virtual_dma_residue;
38 static char *virtual_dma_addr;
39 static int virtual_dma_mode;
40 static int doing_pdma;
42 static irqreturn_t floppy_hardint(int irq, void *dev_id, struct pt_regs * regs)
43 {
44 register unsigned char st;
46 #undef TRACE_FLPY_INT
47 #define NO_FLOPPY_ASSEMBLER
49 #ifdef TRACE_FLPY_INT
50 static int calls=0;
51 static int bytes=0;
52 static int dma_wait=0;
53 #endif
54 if (!doing_pdma)
55 return floppy_interrupt(irq, dev_id, regs);
57 #ifdef TRACE_FLPY_INT
58 if(!calls)
59 bytes = virtual_dma_count;
60 #endif
62 #ifndef NO_FLOPPY_ASSEMBLER
63 __asm__ (
64 "testl %1,%1"
65 "je 3f"
66 "1: inb %w4,%b0"
67 "andb $160,%b0"
68 "cmpb $160,%b0"
69 "jne 2f"
70 "incw %w4"
71 "testl %3,%3"
72 "jne 4f"
73 "inb %w4,%b0"
74 "movb %0,(%2)"
75 "jmp 5f"
76 "4: movb (%2),%0"
77 "outb %b0,%w4"
78 "5: decw %w4"
79 "outb %0,$0x80"
80 "decl %1"
81 "incl %2"
82 "testl %1,%1"
83 "jne 1b"
84 "3: inb %w4,%b0"
85 "2: "
86 : "=a" ((char) st),
87 "=c" ((long) virtual_dma_count),
88 "=S" ((long) virtual_dma_addr)
89 : "b" ((long) virtual_dma_mode),
90 "d" ((short) virtual_dma_port+4),
91 "1" ((long) virtual_dma_count),
92 "2" ((long) virtual_dma_addr));
93 #else
94 {
95 register int lcount;
96 register char *lptr;
98 st = 1;
99 for(lcount=virtual_dma_count, lptr=virtual_dma_addr;
100 lcount; lcount--, lptr++) {
101 st=inb(virtual_dma_port+4) & 0xa0 ;
102 if(st != 0xa0)
103 break;
104 if(virtual_dma_mode)
105 outb_p(*lptr, virtual_dma_port+5);
106 else
107 *lptr = inb_p(virtual_dma_port+5);
108 }
109 virtual_dma_count = lcount;
110 virtual_dma_addr = lptr;
111 st = inb(virtual_dma_port+4);
112 }
113 #endif
115 #ifdef TRACE_FLPY_INT
116 calls++;
117 #endif
118 if(st == 0x20)
119 return IRQ_HANDLED;
120 if(!(st & 0x20)) {
121 virtual_dma_residue += virtual_dma_count;
122 virtual_dma_count=0;
123 #ifdef TRACE_FLPY_INT
124 printk("count=%x, residue=%x calls=%d bytes=%d dma_wait=%d\n",
125 virtual_dma_count, virtual_dma_residue, calls, bytes,
126 dma_wait);
127 calls = 0;
128 dma_wait=0;
129 #endif
130 doing_pdma = 0;
131 floppy_interrupt(irq, dev_id, regs);
132 return IRQ_HANDLED;
133 }
134 #ifdef TRACE_FLPY_INT
135 if(!virtual_dma_count)
136 dma_wait++;
137 #endif
138 return IRQ_HANDLED;
139 }
141 static void fd_disable_dma(void)
142 {
143 doing_pdma = 0;
144 virtual_dma_residue += virtual_dma_count;
145 virtual_dma_count=0;
146 }
148 static int vdma_get_dma_residue(unsigned int dummy)
149 {
150 return virtual_dma_count + virtual_dma_residue;
151 }
153 static int fd_request_irq(void)
154 {
155 return request_irq(FLOPPY_IRQ, floppy_hardint,SA_INTERRUPT,
156 "floppy", NULL);
157 }
159 static unsigned long vdma_mem_alloc(unsigned long size)
160 {
161 return (unsigned long) vmalloc(size);
163 }
165 static void vdma_mem_free(unsigned long addr, unsigned long size)
166 {
167 vfree((void *)addr);
168 }
170 static int vdma_dma_setup(char *addr, unsigned long size, int mode, int io)
171 {
172 doing_pdma = 1;
173 virtual_dma_port = io;
174 virtual_dma_mode = (mode == DMA_MODE_WRITE);
175 virtual_dma_addr = addr;
176 virtual_dma_count = size;
177 virtual_dma_residue = 0;
178 return 0;
179 }
181 /* XEN: This trick to force 'virtual DMA' is from include/asm-m68k/floppy.h. */
182 #define FDC1 xen_floppy_init()
183 static int FDC2 = -1;
185 static int xen_floppy_init(void)
186 {
187 use_virtual_dma = 1;
188 can_use_virtual_dma = 1;
189 return 0x3f0;
190 }
192 /*
193 * Floppy types are stored in the rtc's CMOS RAM and so rtc_lock
194 * is needed to prevent corrupted CMOS RAM in case "insmod floppy"
195 * coincides with another rtc CMOS user. Paul G.
196 */
197 #define FLOPPY0_TYPE ({ \
198 unsigned long flags; \
199 unsigned char val; \
200 spin_lock_irqsave(&rtc_lock, flags); \
201 val = (CMOS_READ(0x10) >> 4) & 15; \
202 spin_unlock_irqrestore(&rtc_lock, flags); \
203 val; \
204 })
206 #define FLOPPY1_TYPE ({ \
207 unsigned long flags; \
208 unsigned char val; \
209 spin_lock_irqsave(&rtc_lock, flags); \
210 val = CMOS_READ(0x10) & 15; \
211 spin_unlock_irqrestore(&rtc_lock, flags); \
212 val; \
213 })
215 #define N_FDC 2
216 #define N_DRIVE 8
218 #define FLOPPY_MOTOR_MASK 0xf0
220 #define EXTRA_FLOPPY_PARAMS
222 #endif /* __ASM_XEN_I386_FLOPPY_H */