Merge to Fedora kernel-2.6.18-1.2224_FC5 patched with stable patch-2.6.18.1-vs2.0...
[linux-2.6.git] / include / asm-i386 / mach-xen / asm / floppy.h
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
14
15 #include <linux/vmalloc.h>
16
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)
22
23 #define fd_inb(port)                    inb_p(port)
24 #define fd_outb(value,port)             outb_p(value,port)
25
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()    (virtual_dma_count + virtual_dma_residue)
32 #define fd_dma_setup(addr, size, mode, io) vdma_dma_setup(addr, size, mode, io)
33 /*
34  * Do not use vmalloc/vfree: floppy_release_irq_and_dma() gets called from
35  * softirq context via motor_off_callback. A generic bug we happen to trigger.
36  */
37 #define fd_dma_mem_alloc(size)  __get_free_pages(GFP_KERNEL, get_order(size))
38 #define fd_dma_mem_free(addr, size) free_pages(addr, get_order(size))
39
40 static int virtual_dma_count;
41 static int virtual_dma_residue;
42 static char *virtual_dma_addr;
43 static int virtual_dma_mode;
44 static int doing_pdma;
45
46 static irqreturn_t floppy_hardint(int irq, void *dev_id, struct pt_regs * regs)
47 {
48         register unsigned char st;
49         register int lcount;
50         register char *lptr;
51
52         if (!doing_pdma)
53                 return floppy_interrupt(irq, dev_id, regs);
54
55         st = 1;
56         for(lcount=virtual_dma_count, lptr=virtual_dma_addr; 
57             lcount; lcount--, lptr++) {
58                 st=inb(virtual_dma_port+4) & 0xa0 ;
59                 if(st != 0xa0) 
60                         break;
61                 if(virtual_dma_mode)
62                         outb_p(*lptr, virtual_dma_port+5);
63                 else
64                         *lptr = inb_p(virtual_dma_port+5);
65         }
66         virtual_dma_count = lcount;
67         virtual_dma_addr = lptr;
68         st = inb(virtual_dma_port+4);
69
70         if(st == 0x20)
71                 return IRQ_HANDLED;
72         if(!(st & 0x20)) {
73                 virtual_dma_residue += virtual_dma_count;
74                 virtual_dma_count=0;
75                 doing_pdma = 0;
76                 floppy_interrupt(irq, dev_id, regs);
77                 return IRQ_HANDLED;
78         }
79         return IRQ_HANDLED;
80 }
81
82 static void fd_disable_dma(void)
83 {
84         doing_pdma = 0;
85         virtual_dma_residue += virtual_dma_count;
86         virtual_dma_count=0;
87 }
88
89 static int fd_request_irq(void)
90 {
91         return request_irq(FLOPPY_IRQ, floppy_hardint,
92                            IRQF_DISABLED, "floppy", NULL);
93 }
94
95 static int vdma_dma_setup(char *addr, unsigned long size, int mode, int io)
96 {
97         doing_pdma = 1;
98         virtual_dma_port = io;
99         virtual_dma_mode = (mode  == DMA_MODE_WRITE);
100         virtual_dma_addr = addr;
101         virtual_dma_count = size;
102         virtual_dma_residue = 0;
103         return 0;
104 }
105
106 /* XEN: This trick to force 'virtual DMA' is from include/asm-m68k/floppy.h. */
107 #define FDC1 xen_floppy_init()
108 static int FDC2 = -1;
109
110 static int xen_floppy_init(void)
111 {
112         use_virtual_dma = 1;
113         can_use_virtual_dma = 1;
114         return 0x3f0;
115 }
116
117 /*
118  * Floppy types are stored in the rtc's CMOS RAM and so rtc_lock
119  * is needed to prevent corrupted CMOS RAM in case "insmod floppy"
120  * coincides with another rtc CMOS user.                Paul G.
121  */
122 #define FLOPPY0_TYPE    ({                              \
123         unsigned long flags;                            \
124         unsigned char val;                              \
125         spin_lock_irqsave(&rtc_lock, flags);            \
126         val = (CMOS_READ(0x10) >> 4) & 15;              \
127         spin_unlock_irqrestore(&rtc_lock, flags);       \
128         val;                                            \
129 })
130
131 #define FLOPPY1_TYPE    ({                              \
132         unsigned long flags;                            \
133         unsigned char val;                              \
134         spin_lock_irqsave(&rtc_lock, flags);            \
135         val = CMOS_READ(0x10) & 15;                     \
136         spin_unlock_irqrestore(&rtc_lock, flags);       \
137         val;                                            \
138 })
139
140 #define N_FDC 2
141 #define N_DRIVE 8
142
143 #define FLOPPY_MOTOR_MASK 0xf0
144
145 #define EXTRA_FLOPPY_PARAMS
146
147 #endif /* __ASM_XEN_I386_FLOPPY_H */