linux/include/asm-mips/mach-generic/ide.h
<<
>>
Prefs
   1/*
   2 * This file is subject to the terms and conditions of the GNU General Public
   3 * License.  See the file "COPYING" in the main directory of this archive
   4 * for more details.
   5 *
   6 * Copyright (C) 1994-1996  Linus Torvalds & authors
   7 *
   8 * Copied from i386; many of the especially older MIPS or ISA-based platforms
   9 * are basically identical.  Using this file probably implies i8259 PIC
  10 * support in a system but the very least interrupt numbers 0 - 15 need to
  11 * be put aside for legacy devices.
  12 */
  13#ifndef __ASM_MACH_GENERIC_IDE_H
  14#define __ASM_MACH_GENERIC_IDE_H
  15
  16#ifdef __KERNEL__
  17
  18#include <linux/pci.h>
  19#include <linux/stddef.h>
  20#include <asm/processor.h>
  21
  22#ifndef MAX_HWIFS
  23# ifdef CONFIG_BLK_DEV_IDEPCI
  24#define MAX_HWIFS       10
  25# else
  26#define MAX_HWIFS       6
  27# endif
  28#endif
  29
  30#define IDE_ARCH_OBSOLETE_DEFAULTS
  31
  32static __inline__ int ide_probe_legacy(void)
  33{
  34#ifdef CONFIG_PCI
  35        struct pci_dev *dev;
  36        /*
  37         * This can be called on the ide_setup() path, super-early in
  38         * boot.  But the down_read() will enable local interrupts,
  39         * which can cause some machines to crash.  So here we detect
  40         * and flag that situation and bail out early.
  41         */
  42        if (no_pci_devices())
  43                return 0;
  44        dev = pci_get_class(PCI_CLASS_BRIDGE_EISA << 8, NULL);
  45        if (dev)
  46                goto found;
  47        dev = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, NULL);
  48        if (dev)
  49                goto found;
  50        return 0;
  51found:
  52        pci_dev_put(dev);
  53        return 1;
  54#elif defined(CONFIG_EISA) || defined(CONFIG_ISA)
  55        return 1;
  56#else
  57        return 0;
  58#endif
  59}
  60
  61static __inline__ int ide_default_irq(unsigned long base)
  62{
  63        switch (base) {
  64                case 0x1f0: return 14;
  65                case 0x170: return 15;
  66                case 0x1e8: return 11;
  67                case 0x168: return 10;
  68                case 0x1e0: return 8;
  69                case 0x160: return 12;
  70                default:
  71                        return 0;
  72        }
  73}
  74
  75static __inline__ unsigned long ide_default_io_base(int index)
  76{
  77        if (!ide_probe_legacy())
  78                return 0;
  79        /*
  80         *      If PCI is present then it is not safe to poke around
  81         *      the other legacy IDE ports. Only 0x1f0 and 0x170 are
  82         *      defined compatibility mode ports for PCI. A user can
  83         *      override this using ide= but we must default safe.
  84         */
  85        if (no_pci_devices()) {
  86                switch (index) {
  87                case 2: return 0x1e8;
  88                case 3: return 0x168;
  89                case 4: return 0x1e0;
  90                case 5: return 0x160;
  91                }
  92        }
  93        switch (index) {
  94        case 0: return 0x1f0;
  95        case 1: return 0x170;
  96        default:
  97                return 0;
  98        }
  99}
 100
 101#define ide_default_io_ctl(base)        ((base) + 0x206) /* obsolete */
 102
 103#ifdef CONFIG_BLK_DEV_IDEPCI
 104#define ide_init_default_irq(base)      (0)
 105#else
 106#define ide_init_default_irq(base)      ide_default_irq(base)
 107#endif
 108
 109/* MIPS port and memory-mapped I/O string operations.  */
 110static inline void __ide_flush_prologue(void)
 111{
 112#ifdef CONFIG_SMP
 113        if (cpu_has_dc_aliases)
 114                preempt_disable();
 115#endif
 116}
 117
 118static inline void __ide_flush_epilogue(void)
 119{
 120#ifdef CONFIG_SMP
 121        if (cpu_has_dc_aliases)
 122                preempt_enable();
 123#endif
 124}
 125
 126static inline void __ide_flush_dcache_range(unsigned long addr, unsigned long size)
 127{
 128        if (cpu_has_dc_aliases) {
 129                unsigned long end = addr + size;
 130
 131                while (addr < end) {
 132                        local_flush_data_cache_page((void *)addr);
 133                        addr += PAGE_SIZE;
 134                }
 135        }
 136}
 137
 138/*
 139 * insw() and gang might be called with interrupts disabled, so we can't
 140 * send IPIs for flushing due to the potencial of deadlocks, see the comment
 141 * above smp_call_function() in arch/mips/kernel/smp.c.  We work around the
 142 * problem by disabling preemption so we know we actually perform the flush
 143 * on the processor that actually has the lines to be flushed which hopefully
 144 * is even better for performance anyway.
 145 */
 146static inline void __ide_insw(unsigned long port, void *addr,
 147        unsigned int count)
 148{
 149        __ide_flush_prologue();
 150        insw(port, addr, count);
 151        __ide_flush_dcache_range((unsigned long)addr, count * 2);
 152        __ide_flush_epilogue();
 153}
 154
 155static inline void __ide_insl(unsigned long port, void *addr, unsigned int count)
 156{
 157        __ide_flush_prologue();
 158        insl(port, addr, count);
 159        __ide_flush_dcache_range((unsigned long)addr, count * 4);
 160        __ide_flush_epilogue();
 161}
 162
 163static inline void __ide_outsw(unsigned long port, const void *addr,
 164        unsigned long count)
 165{
 166        __ide_flush_prologue();
 167        outsw(port, addr, count);
 168        __ide_flush_dcache_range((unsigned long)addr, count * 2);
 169        __ide_flush_epilogue();
 170}
 171
 172static inline void __ide_outsl(unsigned long port, const void *addr,
 173        unsigned long count)
 174{
 175        __ide_flush_prologue();
 176        outsl(port, addr, count);
 177        __ide_flush_dcache_range((unsigned long)addr, count * 4);
 178        __ide_flush_epilogue();
 179}
 180
 181static inline void __ide_mm_insw(void __iomem *port, void *addr, u32 count)
 182{
 183        __ide_flush_prologue();
 184        readsw(port, addr, count);
 185        __ide_flush_dcache_range((unsigned long)addr, count * 2);
 186        __ide_flush_epilogue();
 187}
 188
 189static inline void __ide_mm_insl(void __iomem *port, void *addr, u32 count)
 190{
 191        __ide_flush_prologue();
 192        readsl(port, addr, count);
 193        __ide_flush_dcache_range((unsigned long)addr, count * 4);
 194        __ide_flush_epilogue();
 195}
 196
 197static inline void __ide_mm_outsw(void __iomem *port, void *addr, u32 count)
 198{
 199        __ide_flush_prologue();
 200        writesw(port, addr, count);
 201        __ide_flush_dcache_range((unsigned long)addr, count * 2);
 202        __ide_flush_epilogue();
 203}
 204
 205static inline void __ide_mm_outsl(void __iomem * port, void *addr, u32 count)
 206{
 207        __ide_flush_prologue();
 208        writesl(port, addr, count);
 209        __ide_flush_dcache_range((unsigned long)addr, count * 4);
 210        __ide_flush_epilogue();
 211}
 212
 213/* ide_insw calls insw, not __ide_insw.  Why? */
 214#undef insw
 215#undef insl
 216#undef outsw
 217#undef outsl
 218#define insw(port, addr, count) __ide_insw(port, addr, count)
 219#define insl(port, addr, count) __ide_insl(port, addr, count)
 220#define outsw(port, addr, count) __ide_outsw(port, addr, count)
 221#define outsl(port, addr, count) __ide_outsl(port, addr, count)
 222
 223#endif /* __KERNEL__ */
 224
 225#endif /* __ASM_MACH_GENERIC_IDE_H */
 226