Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Architecture specific parts of the Floppy driver
0003  *
0004  * This file is subject to the terms and conditions of the GNU General Public
0005  * License.  See the file "COPYING" in the main directory of this archive
0006  * for more details.
0007  *
0008  * Copyright (C) 1995
0009  */
0010 #ifndef __ASM_POWERPC_FLOPPY_H
0011 #define __ASM_POWERPC_FLOPPY_H
0012 #ifdef __KERNEL__
0013 
0014 #include <asm/machdep.h>
0015 
0016 #define fd_inb(base, reg)       inb_p((base) + (reg))
0017 #define fd_outb(value, base, reg)   outb_p(value, (base) + (reg))
0018 
0019 #define fd_enable_dma()         enable_dma(FLOPPY_DMA)
0020 #define fd_disable_dma()     fd_ops->_disable_dma(FLOPPY_DMA)
0021 #define fd_free_dma()           fd_ops->_free_dma(FLOPPY_DMA)
0022 #define fd_clear_dma_ff()       clear_dma_ff(FLOPPY_DMA)
0023 #define fd_set_dma_mode(mode)   set_dma_mode(FLOPPY_DMA, mode)
0024 #define fd_set_dma_count(count) set_dma_count(FLOPPY_DMA, count)
0025 #define fd_get_dma_residue()    fd_ops->_get_dma_residue(FLOPPY_DMA)
0026 #define fd_enable_irq()         enable_irq(FLOPPY_IRQ)
0027 #define fd_disable_irq()        disable_irq(FLOPPY_IRQ)
0028 #define fd_free_irq()           free_irq(FLOPPY_IRQ, NULL);
0029 
0030 #include <linux/pci.h>
0031 #include <asm/ppc-pci.h>    /* for isa_bridge_pcidev */
0032 
0033 #define fd_dma_setup(addr,size,mode,io) fd_ops->_dma_setup(addr,size,mode,io)
0034 
0035 static int fd_request_dma(void);
0036 
0037 struct fd_dma_ops {
0038     void (*_disable_dma)(unsigned int dmanr);
0039     void (*_free_dma)(unsigned int dmanr);
0040     int (*_get_dma_residue)(unsigned int dummy);
0041     int (*_dma_setup)(char *addr, unsigned long size, int mode, int io);
0042 };
0043 
0044 static int virtual_dma_count;
0045 static int virtual_dma_residue;
0046 static char *virtual_dma_addr;
0047 static int virtual_dma_mode;
0048 static int doing_vdma;
0049 static struct fd_dma_ops *fd_ops;
0050 
0051 static irqreturn_t floppy_hardint(int irq, void *dev_id)
0052 {
0053     unsigned char st;
0054     int lcount;
0055     char *lptr;
0056 
0057     if (!doing_vdma)
0058         return floppy_interrupt(irq, dev_id);
0059 
0060 
0061     st = 1;
0062     for (lcount=virtual_dma_count, lptr=virtual_dma_addr;
0063          lcount; lcount--, lptr++) {
0064         st = inb(virtual_dma_port + FD_STATUS);
0065         st &= STATUS_DMA | STATUS_READY;
0066         if (st != (STATUS_DMA | STATUS_READY))
0067             break;
0068         if (virtual_dma_mode)
0069             outb_p(*lptr, virtual_dma_port + FD_DATA);
0070         else
0071             *lptr = inb_p(virtual_dma_port + FD_DATA);
0072     }
0073     virtual_dma_count = lcount;
0074     virtual_dma_addr = lptr;
0075     st = inb(virtual_dma_port + FD_STATUS);
0076 
0077     if (st == STATUS_DMA)
0078         return IRQ_HANDLED;
0079     if (!(st & STATUS_DMA)) {
0080         virtual_dma_residue += virtual_dma_count;
0081         virtual_dma_count=0;
0082         doing_vdma = 0;
0083         floppy_interrupt(irq, dev_id);
0084         return IRQ_HANDLED;
0085     }
0086     return IRQ_HANDLED;
0087 }
0088 
0089 static void vdma_disable_dma(unsigned int dummy)
0090 {
0091     doing_vdma = 0;
0092     virtual_dma_residue += virtual_dma_count;
0093     virtual_dma_count=0;
0094 }
0095 
0096 static void vdma_nop(unsigned int dummy)
0097 {
0098 }
0099 
0100 
0101 static int vdma_get_dma_residue(unsigned int dummy)
0102 {
0103     return virtual_dma_count + virtual_dma_residue;
0104 }
0105 
0106 
0107 static int fd_request_irq(void)
0108 {
0109     if (can_use_virtual_dma)
0110         return request_irq(FLOPPY_IRQ, floppy_hardint,
0111                    0, "floppy", NULL);
0112     else
0113         return request_irq(FLOPPY_IRQ, floppy_interrupt,
0114                    0, "floppy", NULL);
0115 }
0116 
0117 static int vdma_dma_setup(char *addr, unsigned long size, int mode, int io)
0118 {
0119     doing_vdma = 1;
0120     virtual_dma_port = io;
0121     virtual_dma_mode = (mode  == DMA_MODE_WRITE);
0122     virtual_dma_addr = addr;
0123     virtual_dma_count = size;
0124     virtual_dma_residue = 0;
0125     return 0;
0126 }
0127 
0128 static int hard_dma_setup(char *addr, unsigned long size, int mode, int io)
0129 {
0130     static unsigned long prev_size;
0131     static dma_addr_t bus_addr = 0;
0132     static char *prev_addr;
0133     static int prev_dir;
0134     int dir;
0135 
0136     doing_vdma = 0;
0137     dir = (mode == DMA_MODE_READ) ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
0138 
0139     if (bus_addr 
0140         && (addr != prev_addr || size != prev_size || dir != prev_dir)) {
0141         /* different from last time -- unmap prev */
0142         dma_unmap_single(&isa_bridge_pcidev->dev, bus_addr, prev_size,
0143                  prev_dir);
0144         bus_addr = 0;
0145     }
0146 
0147     if (!bus_addr)  /* need to map it */
0148         bus_addr = dma_map_single(&isa_bridge_pcidev->dev, addr, size,
0149                       dir);
0150 
0151     /* remember this one as prev */
0152     prev_addr = addr;
0153     prev_size = size;
0154     prev_dir = dir;
0155 
0156     fd_clear_dma_ff();
0157     fd_set_dma_mode(mode);
0158     set_dma_addr(FLOPPY_DMA, bus_addr);
0159     fd_set_dma_count(size);
0160     virtual_dma_port = io;
0161     fd_enable_dma();
0162 
0163     return 0;
0164 }
0165 
0166 static struct fd_dma_ops real_dma_ops =
0167 {
0168     ._disable_dma = disable_dma,
0169     ._free_dma = free_dma,
0170     ._get_dma_residue = get_dma_residue,
0171     ._dma_setup = hard_dma_setup
0172 };
0173 
0174 static struct fd_dma_ops virt_dma_ops =
0175 {
0176     ._disable_dma = vdma_disable_dma,
0177     ._free_dma = vdma_nop,
0178     ._get_dma_residue = vdma_get_dma_residue,
0179     ._dma_setup = vdma_dma_setup
0180 };
0181 
0182 static int fd_request_dma(void)
0183 {
0184     if (can_use_virtual_dma & 1) {
0185         fd_ops = &virt_dma_ops;
0186         return 0;
0187     }
0188     else {
0189         fd_ops = &real_dma_ops;
0190         return request_dma(FLOPPY_DMA, "floppy");
0191     }
0192 }
0193 
0194 static int FDC1 = 0x3f0;
0195 static int FDC2 = -1;
0196 
0197 /*
0198  * Again, the CMOS information not available
0199  */
0200 #define FLOPPY0_TYPE 6
0201 #define FLOPPY1_TYPE 0
0202 
0203 #define N_FDC 2         /* Don't change this! */
0204 #define N_DRIVE 8
0205 
0206 /*
0207  * The PowerPC has no problems with floppy DMA crossing 64k borders.
0208  */
0209 #define CROSS_64KB(a,s) (0)
0210 
0211 #define EXTRA_FLOPPY_PARAMS
0212 
0213 #endif /* __KERNEL__ */
0214 #endif /* __ASM_POWERPC_FLOPPY_H */