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