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#include <linux/vmalloc.h> 14 15 16/* 17 * The DMA channel used by the floppy controller cannot access data at 18 * addresses >= 16MB 19 * 20 * Went back to the 1MB limit, as some people had problems with the floppy 21 * driver otherwise. It doesn't matter much for performance anyway, as most 22 * floppy accesses go through the track buffer. 23 */ 24#define _CROSS_64KB(a,s,vdma) \ 25(!(vdma) && ((unsigned long)(a)/K_64 != ((unsigned long)(a) + (s) - 1) / K_64)) 26 27#define CROSS_64KB(a,s) _CROSS_64KB(a,s,use_virtual_dma & 1) 28 29 30#define SW fd_routine[use_virtual_dma&1] 31#define CSW fd_routine[can_use_virtual_dma & 1] 32 33 34#define fd_inb(port) inb_p(port) 35#define fd_outb(value,port) outb_p(value,port) 36 37#define fd_request_dma() CSW._request_dma(FLOPPY_DMA,"floppy") 38#define fd_free_dma() CSW._free_dma(FLOPPY_DMA) 39#define fd_enable_irq() enable_irq(FLOPPY_IRQ) 40#define fd_disable_irq() disable_irq(FLOPPY_IRQ) 41#define fd_free_irq() free_irq(FLOPPY_IRQ, NULL) 42#define fd_get_dma_residue() SW._get_dma_residue(FLOPPY_DMA) 43#define fd_dma_mem_alloc(size) SW._dma_mem_alloc(size) 44#define fd_dma_setup(addr, size, mode, io) SW._dma_setup(addr, size, mode, io) 45 46#define FLOPPY_CAN_FALLBACK_ON_NODMA 47 48static int virtual_dma_count; 49static int virtual_dma_residue; 50static char *virtual_dma_addr; 51static int virtual_dma_mode; 52static int doing_pdma; 53 54static irqreturn_t floppy_hardint(int irq, void *dev_id) 55{ 56 register unsigned char st; 57 58#undef TRACE_FLPY_INT 59 60#ifdef TRACE_FLPY_INT 61 static int calls=0; 62 static int bytes=0; 63 static int dma_wait=0; 64#endif 65 if (!doing_pdma) 66 return floppy_interrupt(irq, dev_id); 67 68#ifdef TRACE_FLPY_INT 69 if(!calls) 70 bytes = virtual_dma_count; 71#endif 72 73 { 74 register int lcount; 75 register char *lptr; 76 77 st = 1; 78 for(lcount=virtual_dma_count, lptr=virtual_dma_addr; 79 lcount; lcount--, lptr++) { 80 st=inb(virtual_dma_port+4) & 0xa0 ; 81 if(st != 0xa0) 82 break; 83 if(virtual_dma_mode) 84 outb_p(*lptr, virtual_dma_port+5); 85 else 86 *lptr = inb_p(virtual_dma_port+5); 87 } 88 virtual_dma_count = lcount; 89 virtual_dma_addr = lptr; 90 st = inb(virtual_dma_port+4); 91 } 92 93#ifdef TRACE_FLPY_INT 94 calls++; 95#endif 96 if(st == 0x20) 97 return IRQ_HANDLED; 98 if(!(st & 0x20)) { 99 virtual_dma_residue += virtual_dma_count; 100 virtual_dma_count=0; 101#ifdef TRACE_FLPY_INT 102 printk("count=%x, residue=%x calls=%d bytes=%d dma_wait=%d\n", 103 virtual_dma_count, virtual_dma_residue, calls, bytes, 104 dma_wait); 105 calls = 0; 106 dma_wait=0; 107#endif 108 doing_pdma = 0; 109 floppy_interrupt(irq, dev_id); 110 return IRQ_HANDLED; 111 } 112#ifdef TRACE_FLPY_INT 113 if(!virtual_dma_count) 114 dma_wait++; 115#endif 116 return IRQ_HANDLED; 117} 118 119static void fd_disable_dma(void) 120{ 121 if(! (can_use_virtual_dma & 1)) 122 disable_dma(FLOPPY_DMA); 123 doing_pdma = 0; 124 virtual_dma_residue += virtual_dma_count; 125 virtual_dma_count=0; 126} 127 128static int vdma_request_dma(unsigned int dmanr, const char * device_id) 129{ 130 return 0; 131} 132 133static void vdma_nop(unsigned int dummy) 134{ 135} 136 137 138static int vdma_get_dma_residue(unsigned int dummy) 139{ 140 return virtual_dma_count + virtual_dma_residue; 141} 142 143 144static int fd_request_irq(void) 145{ 146 if(can_use_virtual_dma) 147 return request_irq(FLOPPY_IRQ, floppy_hardint, 148 IRQF_DISABLED, "floppy", NULL); 149 else 150 return request_irq(FLOPPY_IRQ, floppy_interrupt, 151 IRQF_DISABLED, "floppy", NULL); 152 153} 154 155static unsigned long dma_mem_alloc(unsigned long size) 156{ 157 return __get_dma_pages(GFP_KERNEL,get_order(size)); 158} 159 160 161static unsigned long vdma_mem_alloc(unsigned long size) 162{ 163 return (unsigned long) vmalloc(size); 164 165} 166 167#define nodma_mem_alloc(size) vdma_mem_alloc(size) 168 169static void _fd_dma_mem_free(unsigned long addr, unsigned long size) 170{ 171 if((unsigned int) addr >= (unsigned int) high_memory) 172 vfree((void *)addr); 173 else 174 free_pages(addr, get_order(size)); 175} 176 177#define fd_dma_mem_free(addr, size) _fd_dma_mem_free(addr, size) 178 179static void _fd_chose_dma_mode(char *addr, unsigned long size) 180{ 181 if(can_use_virtual_dma == 2) { 182 if((unsigned int) addr >= (unsigned int) high_memory || 183 isa_virt_to_bus(addr) >= 0x1000000 || 184 _CROSS_64KB(addr, size, 0)) 185 use_virtual_dma = 1; 186 else 187 use_virtual_dma = 0; 188 } else { 189 use_virtual_dma = can_use_virtual_dma & 1; 190 } 191} 192 193#define fd_chose_dma_mode(addr, size) _fd_chose_dma_mode(addr, size) 194 195 196static int vdma_dma_setup(char *addr, unsigned long size, int mode, int io) 197{ 198 doing_pdma = 1; 199 virtual_dma_port = io; 200 virtual_dma_mode = (mode == DMA_MODE_WRITE); 201 virtual_dma_addr = addr; 202 virtual_dma_count = size; 203 virtual_dma_residue = 0; 204 return 0; 205} 206 207static int hard_dma_setup(char *addr, unsigned long size, int mode, int io) 208{ 209#ifdef FLOPPY_SANITY_CHECK 210 if (CROSS_64KB(addr, size)) { 211 printk("DMA crossing 64-K boundary %p-%p\n", addr, addr+size); 212 return -1; 213 } 214#endif 215 /* actual, physical DMA */ 216 doing_pdma = 0; 217 clear_dma_ff(FLOPPY_DMA); 218 set_dma_mode(FLOPPY_DMA,mode); 219 set_dma_addr(FLOPPY_DMA,isa_virt_to_bus(addr)); 220 set_dma_count(FLOPPY_DMA,size); 221 enable_dma(FLOPPY_DMA); 222 return 0; 223} 224 225static struct fd_routine_l { 226 int (*_request_dma)(unsigned int dmanr, const char * device_id); 227 void (*_free_dma)(unsigned int dmanr); 228 int (*_get_dma_residue)(unsigned int dummy); 229 unsigned long (*_dma_mem_alloc) (unsigned long size); 230 int (*_dma_setup)(char *addr, unsigned long size, int mode, int io); 231} fd_routine[] = { 232 { 233 request_dma, 234 free_dma, 235 get_dma_residue, 236 dma_mem_alloc, 237 hard_dma_setup 238 }, 239 { 240 vdma_request_dma, 241 vdma_nop, 242 vdma_get_dma_residue, 243 vdma_mem_alloc, 244 vdma_dma_setup 245 } 246}; 247 248 249static int FDC1 = 0x3f0; 250static int FDC2 = -1; 251 252/* 253 * Floppy types are stored in the rtc's CMOS RAM and so rtc_lock 254 * is needed to prevent corrupted CMOS RAM in case "insmod floppy" 255 * coincides with another rtc CMOS user. Paul G. 256 */ 257#define FLOPPY0_TYPE ({ \ 258 unsigned long flags; \ 259 unsigned char val; \ 260 spin_lock_irqsave(&rtc_lock, flags); \ 261 val = (CMOS_READ(0x10) >> 4) & 15; \ 262 spin_unlock_irqrestore(&rtc_lock, flags); \ 263 val; \ 264}) 265 266#define FLOPPY1_TYPE ({ \ 267 unsigned long flags; \ 268 unsigned char val; \ 269 spin_lock_irqsave(&rtc_lock, flags); \ 270 val = CMOS_READ(0x10) & 15; \ 271 spin_unlock_irqrestore(&rtc_lock, flags); \ 272 val; \ 273}) 274 275#define N_FDC 2 276#define N_DRIVE 8 277 278#define FLOPPY_MOTOR_MASK 0xf0 279 280#define AUTO_DMA 281 282#define EXTRA_FLOPPY_PARAMS 283 284#endif /* __ASM_I386_FLOPPY_H */ 285