~ubuntu-branches/ubuntu/precise/linux-lowlatency/precise

« back to all changes in this revision

Viewing changes to arch/parisc/include/asm/floppy.h

  • Committer: Package Import Robot
  • Author(s): Alessio Igor Bogani
  • Date: 2011-10-26 11:13:05 UTC
  • Revision ID: package-import@ubuntu.com-20111026111305-tz023xykf0i6eosh
Tags: upstream-3.2.0
ImportĀ upstreamĀ versionĀ 3.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*    Architecture specific parts of the Floppy driver
 
2
 *
 
3
 *    Linux/PA-RISC Project (http://www.parisc-linux.org/)
 
4
 *    Copyright (C) 2000 Matthew Wilcox (willy a debian . org)
 
5
 *    Copyright (C) 2000 Dave Kennedy
 
6
 *
 
7
 *    This program is free software; you can redistribute it and/or modify
 
8
 *    it under the terms of the GNU General Public License as published by
 
9
 *    the Free Software Foundation; either version 2 of the License, or
 
10
 *    (at your option) any later version.
 
11
 *
 
12
 *    This program is distributed in the hope that it will be useful,
 
13
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
 *    GNU General Public License for more details.
 
16
 *
 
17
 *    You should have received a copy of the GNU General Public License
 
18
 *    along with this program; if not, write to the Free Software
 
19
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
20
 */
 
21
#ifndef __ASM_PARISC_FLOPPY_H
 
22
#define __ASM_PARISC_FLOPPY_H
 
23
 
 
24
#include <linux/vmalloc.h>
 
25
 
 
26
 
 
27
/*
 
28
 * The DMA channel used by the floppy controller cannot access data at
 
29
 * addresses >= 16MB
 
30
 *
 
31
 * Went back to the 1MB limit, as some people had problems with the floppy
 
32
 * driver otherwise. It doesn't matter much for performance anyway, as most
 
33
 * floppy accesses go through the track buffer.
 
34
 */
 
35
#define _CROSS_64KB(a,s,vdma) \
 
36
(!vdma && ((unsigned long)(a)/K_64 != ((unsigned long)(a) + (s) - 1) / K_64))
 
37
 
 
38
#define CROSS_64KB(a,s) _CROSS_64KB(a,s,use_virtual_dma & 1)
 
39
 
 
40
 
 
41
#define SW fd_routine[use_virtual_dma&1]
 
42
#define CSW fd_routine[can_use_virtual_dma & 1]
 
43
 
 
44
 
 
45
#define fd_inb(port)                    readb(port)
 
46
#define fd_outb(value, port)            writeb(value, port)
 
47
 
 
48
#define fd_request_dma()        CSW._request_dma(FLOPPY_DMA,"floppy")
 
49
#define fd_free_dma()           CSW._free_dma(FLOPPY_DMA)
 
50
#define fd_enable_irq()         enable_irq(FLOPPY_IRQ)
 
51
#define fd_disable_irq()        disable_irq(FLOPPY_IRQ)
 
52
#define fd_free_irq()           free_irq(FLOPPY_IRQ, NULL)
 
53
#define fd_get_dma_residue()    SW._get_dma_residue(FLOPPY_DMA)
 
54
#define fd_dma_mem_alloc(size)  SW._dma_mem_alloc(size)
 
55
#define fd_dma_setup(addr, size, mode, io) SW._dma_setup(addr, size, mode, io)
 
56
 
 
57
#define FLOPPY_CAN_FALLBACK_ON_NODMA
 
58
 
 
59
static int virtual_dma_count=0;
 
60
static int virtual_dma_residue=0;
 
61
static char *virtual_dma_addr=0;
 
62
static int virtual_dma_mode=0;
 
63
static int doing_pdma=0;
 
64
 
 
65
static void floppy_hardint(int irq, void *dev_id, struct pt_regs * regs)
 
66
{
 
67
        register unsigned char st;
 
68
 
 
69
#undef TRACE_FLPY_INT
 
70
 
 
71
#ifdef TRACE_FLPY_INT
 
72
        static int calls=0;
 
73
        static int bytes=0;
 
74
        static int dma_wait=0;
 
75
#endif
 
76
        if (!doing_pdma) {
 
77
                floppy_interrupt(irq, dev_id, regs);
 
78
                return;
 
79
        }
 
80
 
 
81
#ifdef TRACE_FLPY_INT
 
82
        if(!calls)
 
83
                bytes = virtual_dma_count;
 
84
#endif
 
85
 
 
86
        {
 
87
                register int lcount;
 
88
                register char *lptr = virtual_dma_addr;
 
89
 
 
90
                for (lcount = virtual_dma_count; lcount; lcount--) {
 
91
                        st = fd_inb(virtual_dma_port+4) & 0xa0 ;
 
92
                        if (st != 0xa0) 
 
93
                                break;
 
94
                        if (virtual_dma_mode) {
 
95
                                fd_outb(*lptr, virtual_dma_port+5);
 
96
                        } else {
 
97
                                *lptr = fd_inb(virtual_dma_port+5);
 
98
                        }
 
99
                        lptr++;
 
100
                }
 
101
                virtual_dma_count = lcount;
 
102
                virtual_dma_addr = lptr;
 
103
                st = fd_inb(virtual_dma_port+4);
 
104
        }
 
105
 
 
106
#ifdef TRACE_FLPY_INT
 
107
        calls++;
 
108
#endif
 
109
        if (st == 0x20)
 
110
                return;
 
111
        if (!(st & 0x20)) {
 
112
                virtual_dma_residue += virtual_dma_count;
 
113
                virtual_dma_count = 0;
 
114
#ifdef TRACE_FLPY_INT
 
115
                printk("count=%x, residue=%x calls=%d bytes=%d dma_wait=%d\n", 
 
116
                       virtual_dma_count, virtual_dma_residue, calls, bytes,
 
117
                       dma_wait);
 
118
                calls = 0;
 
119
                dma_wait=0;
 
120
#endif
 
121
                doing_pdma = 0;
 
122
                floppy_interrupt(irq, dev_id, regs);
 
123
                return;
 
124
        }
 
125
#ifdef TRACE_FLPY_INT
 
126
        if (!virtual_dma_count)
 
127
                dma_wait++;
 
128
#endif
 
129
}
 
130
 
 
131
static void fd_disable_dma(void)
 
132
{
 
133
        if(! (can_use_virtual_dma & 1))
 
134
                disable_dma(FLOPPY_DMA);
 
135
        doing_pdma = 0;
 
136
        virtual_dma_residue += virtual_dma_count;
 
137
        virtual_dma_count=0;
 
138
}
 
139
 
 
140
static int vdma_request_dma(unsigned int dmanr, const char * device_id)
 
141
{
 
142
        return 0;
 
143
}
 
144
 
 
145
static void vdma_nop(unsigned int dummy)
 
146
{
 
147
}
 
148
 
 
149
 
 
150
static int vdma_get_dma_residue(unsigned int dummy)
 
151
{
 
152
        return virtual_dma_count + virtual_dma_residue;
 
153
}
 
154
 
 
155
 
 
156
static int fd_request_irq(void)
 
157
{
 
158
        if(can_use_virtual_dma)
 
159
                return request_irq(FLOPPY_IRQ, floppy_hardint,
 
160
                                   IRQF_DISABLED, "floppy", NULL);
 
161
        else
 
162
                return request_irq(FLOPPY_IRQ, floppy_interrupt,
 
163
                                   IRQF_DISABLED, "floppy", NULL);
 
164
}
 
165
 
 
166
static unsigned long dma_mem_alloc(unsigned long size)
 
167
{
 
168
        return __get_dma_pages(GFP_KERNEL, get_order(size));
 
169
}
 
170
 
 
171
 
 
172
static unsigned long vdma_mem_alloc(unsigned long size)
 
173
{
 
174
        return (unsigned long) vmalloc(size);
 
175
 
 
176
}
 
177
 
 
178
#define nodma_mem_alloc(size) vdma_mem_alloc(size)
 
179
 
 
180
static void _fd_dma_mem_free(unsigned long addr, unsigned long size)
 
181
{
 
182
        if((unsigned int) addr >= (unsigned int) high_memory)
 
183
                return vfree((void *)addr);
 
184
        else
 
185
                free_pages(addr, get_order(size));              
 
186
}
 
187
 
 
188
#define fd_dma_mem_free(addr, size)  _fd_dma_mem_free(addr, size) 
 
189
 
 
190
static void _fd_chose_dma_mode(char *addr, unsigned long size)
 
191
{
 
192
        if(can_use_virtual_dma == 2) {
 
193
                if((unsigned int) addr >= (unsigned int) high_memory ||
 
194
                   virt_to_bus(addr) >= 0x1000000 ||
 
195
                   _CROSS_64KB(addr, size, 0))
 
196
                        use_virtual_dma = 1;
 
197
                else
 
198
                        use_virtual_dma = 0;
 
199
        } else {
 
200
                use_virtual_dma = can_use_virtual_dma & 1;
 
201
        }
 
202
}
 
203
 
 
204
#define fd_chose_dma_mode(addr, size) _fd_chose_dma_mode(addr, size)
 
205
 
 
206
 
 
207
static int vdma_dma_setup(char *addr, unsigned long size, int mode, int io)
 
208
{
 
209
        doing_pdma = 1;
 
210
        virtual_dma_port = io;
 
211
        virtual_dma_mode = (mode  == DMA_MODE_WRITE);
 
212
        virtual_dma_addr = addr;
 
213
        virtual_dma_count = size;
 
214
        virtual_dma_residue = 0;
 
215
        return 0;
 
216
}
 
217
 
 
218
static int hard_dma_setup(char *addr, unsigned long size, int mode, int io)
 
219
{
 
220
#ifdef FLOPPY_SANITY_CHECK
 
221
        if (CROSS_64KB(addr, size)) {
 
222
                printk("DMA crossing 64-K boundary %p-%p\n", addr, addr+size);
 
223
                return -1;
 
224
        }
 
225
#endif
 
226
        /* actual, physical DMA */
 
227
        doing_pdma = 0;
 
228
        clear_dma_ff(FLOPPY_DMA);
 
229
        set_dma_mode(FLOPPY_DMA,mode);
 
230
        set_dma_addr(FLOPPY_DMA,virt_to_bus(addr));
 
231
        set_dma_count(FLOPPY_DMA,size);
 
232
        enable_dma(FLOPPY_DMA);
 
233
        return 0;
 
234
}
 
235
 
 
236
static struct fd_routine_l {
 
237
        int (*_request_dma)(unsigned int dmanr, const char * device_id);
 
238
        void (*_free_dma)(unsigned int dmanr);
 
239
        int (*_get_dma_residue)(unsigned int dummy);
 
240
        unsigned long (*_dma_mem_alloc) (unsigned long size);
 
241
        int (*_dma_setup)(char *addr, unsigned long size, int mode, int io);
 
242
} fd_routine[] = {
 
243
        {
 
244
                request_dma,
 
245
                free_dma,
 
246
                get_dma_residue,
 
247
                dma_mem_alloc,
 
248
                hard_dma_setup
 
249
        },
 
250
        {
 
251
                vdma_request_dma,
 
252
                vdma_nop,
 
253
                vdma_get_dma_residue,
 
254
                vdma_mem_alloc,
 
255
                vdma_dma_setup
 
256
        }
 
257
};
 
258
 
 
259
 
 
260
static int FDC1 = 0x3f0; /* Lies.  Floppy controller is memory mapped, not io mapped */
 
261
static int FDC2 = -1;
 
262
 
 
263
#define FLOPPY0_TYPE    0
 
264
#define FLOPPY1_TYPE    0
 
265
 
 
266
#define N_FDC 1
 
267
#define N_DRIVE 8
 
268
 
 
269
#define EXTRA_FLOPPY_PARAMS
 
270
 
 
271
#endif /* __ASM_PARISC_FLOPPY_H */