|
|
1.1 ! root 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: ! 14: #define SW fd_routine[use_virtual_dma&1] ! 15: ! 16: ! 17: #define fd_inb(port) inb_p(port) ! 18: #define fd_outb(port,value) outb_p(port,value) ! 19: ! 20: #define fd_enable_dma() SW._enable_dma(FLOPPY_DMA) ! 21: #define fd_disable_dma() SW._disable_dma(FLOPPY_DMA) ! 22: #define fd_request_dma() SW._request_dma(FLOPPY_DMA,"floppy") ! 23: #define fd_free_dma() SW._free_dma(FLOPPY_DMA) ! 24: #define fd_clear_dma_ff() SW._clear_dma_ff(FLOPPY_DMA) ! 25: #define fd_set_dma_mode(mode) SW._set_dma_mode(FLOPPY_DMA,mode) ! 26: #define fd_set_dma_addr(addr) SW._set_dma_addr(FLOPPY_DMA,addr) ! 27: #define fd_set_dma_count(count) SW._set_dma_count(FLOPPY_DMA,count) ! 28: #define fd_enable_irq() enable_irq(FLOPPY_IRQ) ! 29: #define fd_disable_irq() disable_irq(FLOPPY_IRQ) ! 30: #define fd_cacheflush(addr,size) /* nothing */ ! 31: #define fd_request_irq() SW._request_irq(FLOPPY_IRQ, floppy_interrupt, \ ! 32: SA_INTERRUPT|SA_SAMPLE_RANDOM, \ ! 33: "floppy", NULL) ! 34: #define fd_free_irq() free_irq(FLOPPY_IRQ, NULL) ! 35: #define fd_get_dma_residue() SW._get_dma_residue(FLOPPY_DMA) ! 36: #define fd_dma_mem_alloc(size) SW._dma_mem_alloc(size) ! 37: #define fd_dma_mem_free(addr,size) SW._dma_mem_free(addr,size) ! 38: ! 39: static int virtual_dma_count=0; ! 40: static int virtual_dma_residue=0; ! 41: static unsigned long virtual_dma_addr=0; ! 42: static int virtual_dma_mode=0; ! 43: static int doing_pdma=0; ! 44: ! 45: static void floppy_hardint(int irq, void *dev_id, struct pt_regs * regs) ! 46: { ! 47: register unsigned char st; ! 48: ! 49: #undef TRACE_FLPY_INT ! 50: #undef NO_FLOPPY_ASSEMBLER ! 51: ! 52: #ifdef TRACE_FLPY_INT ! 53: static int calls=0; ! 54: static int bytes=0; ! 55: static int dma_wait=0; ! 56: #endif ! 57: if(!doing_pdma) { ! 58: floppy_interrupt(irq, dev_id, regs); ! 59: return; ! 60: } ! 61: ! 62: #ifdef TRACE_FLPY_INT ! 63: if(!calls) ! 64: bytes = virtual_dma_count; ! 65: #endif ! 66: ! 67: #ifndef NO_FLOPPY_ASSEMBLER ! 68: __asm__ ( ! 69: "testl %1,%1 ! 70: je 3f ! 71: 1: inb %w4,%b0 ! 72: andb $160,%b0 ! 73: cmpb $160,%b0 ! 74: jne 2f ! 75: incw %w4 ! 76: testl %3,%3 ! 77: jne 4f ! 78: inb %w4,%b0 ! 79: movb %0,(%2) ! 80: jmp 5f ! 81: 4: movb (%2),%0 ! 82: outb %b0,%w4 ! 83: 5: decw %w4 ! 84: outb %0,$0x80 ! 85: decl %1 ! 86: incl %2 ! 87: testl %1,%1 ! 88: jne 1b ! 89: 3: inb %w4,%b0 ! 90: 2: " ! 91: : "=a" ((char) st), ! 92: "=c" ((long) virtual_dma_count), ! 93: "=S" ((long) virtual_dma_addr) ! 94: : "b" ((long) virtual_dma_mode), ! 95: "d" ((short) virtual_dma_port+4), ! 96: "1" ((long) virtual_dma_count), ! 97: "2" ((long) virtual_dma_addr)); ! 98: #else ! 99: { ! 100: register int lcount; ! 101: register char *lptr; ! 102: ! 103: st = 1; ! 104: for(lcount=virtual_dma_count, lptr=(char *)virtual_dma_addr; ! 105: lcount; lcount--, lptr++) { ! 106: st=inb(virtual_dma_port+4) & 0xa0 ; ! 107: if(st != 0xa0) ! 108: break; ! 109: if(virtual_dma_mode) ! 110: outb_p(*lptr, virtual_dma_port+5); ! 111: else ! 112: *lptr = inb_p(virtual_dma_port+5); ! 113: st = inb(virtual_dma_port+4); ! 114: } ! 115: virtual_dma_count = lcount; ! 116: virtual_dma_addr = (int) lptr; ! 117: } ! 118: #endif ! 119: ! 120: #ifdef TRACE_FLPY_INT ! 121: calls++; ! 122: #endif ! 123: if(st == 0x20) ! 124: return; ! 125: if(!(st & 0x20)) { ! 126: virtual_dma_residue += virtual_dma_count; ! 127: virtual_dma_count=0; ! 128: #ifdef TRACE_FLPY_INT ! 129: printk("count=%x, residue=%x calls=%d bytes=%d dma_wait=%d\n", ! 130: virtual_dma_count, virtual_dma_residue, calls, bytes, ! 131: dma_wait); ! 132: calls = 0; ! 133: dma_wait=0; ! 134: #endif ! 135: doing_pdma = 0; ! 136: floppy_interrupt(irq, dev_id, regs); ! 137: return; ! 138: } ! 139: #ifdef TRACE_FLPY_INT ! 140: if(!virtual_dma_count) ! 141: dma_wait++; ! 142: #endif ! 143: } ! 144: ! 145: static void vdma_enable_dma(unsigned int dummy) ! 146: { ! 147: doing_pdma = 1; ! 148: } ! 149: ! 150: static void vdma_disable_dma(unsigned int dummy) ! 151: { ! 152: doing_pdma = 0; ! 153: virtual_dma_residue += virtual_dma_count; ! 154: virtual_dma_count=0; ! 155: } ! 156: ! 157: static int vdma_request_dma(unsigned int dmanr, const char * device_id) ! 158: { ! 159: return 0; ! 160: } ! 161: ! 162: static void vdma_nop(unsigned int dummy) ! 163: { ! 164: } ! 165: ! 166: static void vdma_set_dma_mode(unsigned int dummy,char mode) ! 167: { ! 168: virtual_dma_mode = (mode == DMA_MODE_WRITE); ! 169: } ! 170: ! 171: static void vdma_set_dma_addr(unsigned int dummy,unsigned int addr) ! 172: { ! 173: virtual_dma_addr = addr; ! 174: } ! 175: ! 176: static void vdma_set_dma_count(unsigned int dummy,unsigned int count) ! 177: { ! 178: virtual_dma_count = count; ! 179: virtual_dma_residue = 0; ! 180: } ! 181: ! 182: static int vdma_get_dma_residue(unsigned int dummy) ! 183: { ! 184: return virtual_dma_count + virtual_dma_residue; ! 185: } ! 186: ! 187: ! 188: static int vdma_request_irq(unsigned int irq, ! 189: void (*handler)(int, void *, struct pt_regs *), ! 190: unsigned long flags, ! 191: const char *device, ! 192: void *dev_id) ! 193: { ! 194: return request_irq(irq, floppy_hardint,SA_INTERRUPT,device, dev_id); ! 195: ! 196: } ! 197: ! 198: static unsigned long dma_mem_alloc(unsigned long size) ! 199: { ! 200: return __get_dma_pages(GFP_KERNEL,__get_order(size)); ! 201: } ! 202: ! 203: static void dma_mem_free(unsigned long addr, unsigned long size) ! 204: { ! 205: free_pages(addr, __get_order(size)); ! 206: } ! 207: ! 208: static unsigned long vdma_mem_alloc(unsigned long size) ! 209: { ! 210: return (unsigned long) vmalloc(size); ! 211: } ! 212: ! 213: static void vdma_mem_free(unsigned long addr, unsigned long size) ! 214: { ! 215: return vfree((void *)addr); ! 216: } ! 217: ! 218: struct fd_routine_l { ! 219: void (*_enable_dma)(unsigned int dummy); ! 220: void (*_disable_dma)(unsigned int dummy); ! 221: int (*_request_dma)(unsigned int dmanr, const char * device_id); ! 222: void (*_free_dma)(unsigned int dmanr); ! 223: void (*_clear_dma_ff)(unsigned int dummy); ! 224: void (*_set_dma_mode)(unsigned int dummy, char mode); ! 225: void (*_set_dma_addr)(unsigned int dummy, unsigned int addr); ! 226: void (*_set_dma_count)(unsigned int dummy, unsigned int count); ! 227: int (*_get_dma_residue)(unsigned int dummy); ! 228: int (*_request_irq)(unsigned int irq, ! 229: void (*handler)(int, void *, struct pt_regs *), ! 230: unsigned long flags, ! 231: const char *device, ! 232: void *dev_id); ! 233: unsigned long (*_dma_mem_alloc) (unsigned long size); ! 234: void (*_dma_mem_free)(unsigned long addr, unsigned long size); ! 235: } fd_routine[] = { ! 236: { ! 237: enable_dma, ! 238: disable_dma, ! 239: request_dma, ! 240: free_dma, ! 241: clear_dma_ff, ! 242: set_dma_mode, ! 243: set_dma_addr, ! 244: set_dma_count, ! 245: get_dma_residue, ! 246: request_irq, ! 247: dma_mem_alloc, ! 248: dma_mem_free ! 249: }, ! 250: { ! 251: vdma_enable_dma, ! 252: vdma_disable_dma, ! 253: vdma_request_dma, ! 254: vdma_nop, ! 255: vdma_nop, ! 256: vdma_set_dma_mode, ! 257: vdma_set_dma_addr, ! 258: vdma_set_dma_count, ! 259: vdma_get_dma_residue, ! 260: vdma_request_irq, ! 261: vdma_mem_alloc, ! 262: vdma_mem_free ! 263: } ! 264: }; ! 265: ! 266: __inline__ void virtual_dma_init(void) ! 267: { ! 268: /* Nothing to do on an i386 */ ! 269: } ! 270: ! 271: static int FDC1 = 0x3f0; ! 272: static int FDC2 = -1; ! 273: ! 274: #define FLOPPY0_TYPE ((CMOS_READ(0x10) >> 4) & 15) ! 275: #define FLOPPY1_TYPE (CMOS_READ(0x10) & 15) ! 276: ! 277: #define N_FDC 2 ! 278: #define N_DRIVE 8 ! 279: ! 280: /* ! 281: * The DMA channel used by the floppy controller cannot access data at ! 282: * addresses >= 16MB ! 283: * ! 284: * Went back to the 1MB limit, as some people had problems with the floppy ! 285: * driver otherwise. It doesn't matter much for performance anyway, as most ! 286: * floppy accesses go through the track buffer. ! 287: */ ! 288: #define CROSS_64KB(a,s) (((unsigned long)(a)/K_64 != ((unsigned long)(a) + (s) - 1) / K_64) && ! (use_virtual_dma & 1)) ! 289: ! 290: #endif /* __ASM_I386_FLOPPY_H */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.