Path: blob/master/arch/parisc/include/asm/floppy.h
10818 views
/* Architecture specific parts of the Floppy driver1*2* Linux/PA-RISC Project (http://www.parisc-linux.org/)3* Copyright (C) 2000 Matthew Wilcox (willy a debian . org)4* Copyright (C) 2000 Dave Kennedy5*6* This program is free software; you can redistribute it and/or modify7* it under the terms of the GNU General Public License as published by8* the Free Software Foundation; either version 2 of the License, or9* (at your option) any later version.10*11* This program is distributed in the hope that it will be useful,12* but WITHOUT ANY WARRANTY; without even the implied warranty of13* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the14* GNU General Public License for more details.15*16* You should have received a copy of the GNU General Public License17* along with this program; if not, write to the Free Software18* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA19*/20#ifndef __ASM_PARISC_FLOPPY_H21#define __ASM_PARISC_FLOPPY_H2223#include <linux/vmalloc.h>242526/*27* The DMA channel used by the floppy controller cannot access data at28* addresses >= 16MB29*30* Went back to the 1MB limit, as some people had problems with the floppy31* driver otherwise. It doesn't matter much for performance anyway, as most32* floppy accesses go through the track buffer.33*/34#define _CROSS_64KB(a,s,vdma) \35(!vdma && ((unsigned long)(a)/K_64 != ((unsigned long)(a) + (s) - 1) / K_64))3637#define CROSS_64KB(a,s) _CROSS_64KB(a,s,use_virtual_dma & 1)383940#define SW fd_routine[use_virtual_dma&1]41#define CSW fd_routine[can_use_virtual_dma & 1]424344#define fd_inb(port) readb(port)45#define fd_outb(value, port) writeb(value, port)4647#define fd_request_dma() CSW._request_dma(FLOPPY_DMA,"floppy")48#define fd_free_dma() CSW._free_dma(FLOPPY_DMA)49#define fd_enable_irq() enable_irq(FLOPPY_IRQ)50#define fd_disable_irq() disable_irq(FLOPPY_IRQ)51#define fd_free_irq() free_irq(FLOPPY_IRQ, NULL)52#define fd_get_dma_residue() SW._get_dma_residue(FLOPPY_DMA)53#define fd_dma_mem_alloc(size) SW._dma_mem_alloc(size)54#define fd_dma_setup(addr, size, mode, io) SW._dma_setup(addr, size, mode, io)5556#define FLOPPY_CAN_FALLBACK_ON_NODMA5758static int virtual_dma_count=0;59static int virtual_dma_residue=0;60static char *virtual_dma_addr=0;61static int virtual_dma_mode=0;62static int doing_pdma=0;6364static void floppy_hardint(int irq, void *dev_id, struct pt_regs * regs)65{66register unsigned char st;6768#undef TRACE_FLPY_INT6970#ifdef TRACE_FLPY_INT71static int calls=0;72static int bytes=0;73static int dma_wait=0;74#endif75if (!doing_pdma) {76floppy_interrupt(irq, dev_id, regs);77return;78}7980#ifdef TRACE_FLPY_INT81if(!calls)82bytes = virtual_dma_count;83#endif8485{86register int lcount;87register char *lptr = virtual_dma_addr;8889for (lcount = virtual_dma_count; lcount; lcount--) {90st = fd_inb(virtual_dma_port+4) & 0xa0 ;91if (st != 0xa0)92break;93if (virtual_dma_mode) {94fd_outb(*lptr, virtual_dma_port+5);95} else {96*lptr = fd_inb(virtual_dma_port+5);97}98lptr++;99}100virtual_dma_count = lcount;101virtual_dma_addr = lptr;102st = fd_inb(virtual_dma_port+4);103}104105#ifdef TRACE_FLPY_INT106calls++;107#endif108if (st == 0x20)109return;110if (!(st & 0x20)) {111virtual_dma_residue += virtual_dma_count;112virtual_dma_count = 0;113#ifdef TRACE_FLPY_INT114printk("count=%x, residue=%x calls=%d bytes=%d dma_wait=%d\n",115virtual_dma_count, virtual_dma_residue, calls, bytes,116dma_wait);117calls = 0;118dma_wait=0;119#endif120doing_pdma = 0;121floppy_interrupt(irq, dev_id, regs);122return;123}124#ifdef TRACE_FLPY_INT125if (!virtual_dma_count)126dma_wait++;127#endif128}129130static void fd_disable_dma(void)131{132if(! (can_use_virtual_dma & 1))133disable_dma(FLOPPY_DMA);134doing_pdma = 0;135virtual_dma_residue += virtual_dma_count;136virtual_dma_count=0;137}138139static int vdma_request_dma(unsigned int dmanr, const char * device_id)140{141return 0;142}143144static void vdma_nop(unsigned int dummy)145{146}147148149static int vdma_get_dma_residue(unsigned int dummy)150{151return virtual_dma_count + virtual_dma_residue;152}153154155static int fd_request_irq(void)156{157if(can_use_virtual_dma)158return request_irq(FLOPPY_IRQ, floppy_hardint,159IRQF_DISABLED, "floppy", NULL);160else161return request_irq(FLOPPY_IRQ, floppy_interrupt,162IRQF_DISABLED, "floppy", NULL);163}164165static unsigned long dma_mem_alloc(unsigned long size)166{167return __get_dma_pages(GFP_KERNEL, get_order(size));168}169170171static unsigned long vdma_mem_alloc(unsigned long size)172{173return (unsigned long) vmalloc(size);174175}176177#define nodma_mem_alloc(size) vdma_mem_alloc(size)178179static void _fd_dma_mem_free(unsigned long addr, unsigned long size)180{181if((unsigned int) addr >= (unsigned int) high_memory)182return vfree((void *)addr);183else184free_pages(addr, get_order(size));185}186187#define fd_dma_mem_free(addr, size) _fd_dma_mem_free(addr, size)188189static void _fd_chose_dma_mode(char *addr, unsigned long size)190{191if(can_use_virtual_dma == 2) {192if((unsigned int) addr >= (unsigned int) high_memory ||193virt_to_bus(addr) >= 0x1000000 ||194_CROSS_64KB(addr, size, 0))195use_virtual_dma = 1;196else197use_virtual_dma = 0;198} else {199use_virtual_dma = can_use_virtual_dma & 1;200}201}202203#define fd_chose_dma_mode(addr, size) _fd_chose_dma_mode(addr, size)204205206static int vdma_dma_setup(char *addr, unsigned long size, int mode, int io)207{208doing_pdma = 1;209virtual_dma_port = io;210virtual_dma_mode = (mode == DMA_MODE_WRITE);211virtual_dma_addr = addr;212virtual_dma_count = size;213virtual_dma_residue = 0;214return 0;215}216217static int hard_dma_setup(char *addr, unsigned long size, int mode, int io)218{219#ifdef FLOPPY_SANITY_CHECK220if (CROSS_64KB(addr, size)) {221printk("DMA crossing 64-K boundary %p-%p\n", addr, addr+size);222return -1;223}224#endif225/* actual, physical DMA */226doing_pdma = 0;227clear_dma_ff(FLOPPY_DMA);228set_dma_mode(FLOPPY_DMA,mode);229set_dma_addr(FLOPPY_DMA,virt_to_bus(addr));230set_dma_count(FLOPPY_DMA,size);231enable_dma(FLOPPY_DMA);232return 0;233}234235static struct fd_routine_l {236int (*_request_dma)(unsigned int dmanr, const char * device_id);237void (*_free_dma)(unsigned int dmanr);238int (*_get_dma_residue)(unsigned int dummy);239unsigned long (*_dma_mem_alloc) (unsigned long size);240int (*_dma_setup)(char *addr, unsigned long size, int mode, int io);241} fd_routine[] = {242{243request_dma,244free_dma,245get_dma_residue,246dma_mem_alloc,247hard_dma_setup248},249{250vdma_request_dma,251vdma_nop,252vdma_get_dma_residue,253vdma_mem_alloc,254vdma_dma_setup255}256};257258259static int FDC1 = 0x3f0; /* Lies. Floppy controller is memory mapped, not io mapped */260static int FDC2 = -1;261262#define FLOPPY0_TYPE 0263#define FLOPPY1_TYPE 0264265#define N_FDC 1266#define N_DRIVE 8267268#define EXTRA_FLOPPY_PARAMS269270#endif /* __ASM_PARISC_FLOPPY_H */271272273