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 32extern int mips_system_has_legacy_ide; 33 34static __inline__ int ide_probe_legacy(void) 35{ 36#ifdef CONFIG_PCI 37 return mips_system_has_legacy_ide; 38#elif defined(CONFIG_EISA) || defined(CONFIG_ISA) 39 return 1; 40#else 41 return 0; 42#endif 43} 44 45static __inline__ int ide_default_irq(unsigned long base) 46{ 47 if (ide_probe_legacy()) 48 switch (base) { 49 case 0x1f0: 50 return 14; 51 case 0x170: 52 return 15; 53 case 0x1e8: 54 return 11; 55 case 0x168: 56 return 10; 57 case 0x1e0: 58 return 8; 59 case 0x160: 60 return 12; 61 default: 62 return 0; 63 } 64 else 65 return 0; 66} 67 68static __inline__ unsigned long ide_default_io_base(int index) 69{ 70 if (ide_probe_legacy()) 71 switch (index) { 72 case 0: 73 return 0x1f0; 74 case 1: 75 return 0x170; 76 case 2: 77 return 0x1e8; 78 case 3: 79 return 0x168; 80 case 4: 81 return 0x1e0; 82 case 5: 83 return 0x160; 84 default: 85 return 0; 86 } 87 else 88 return 0; 89} 90 91#define IDE_ARCH_OBSOLETE_INIT 92#define ide_default_io_ctl(base) ((base) + 0x206) /* obsolete */ 93 94#ifdef CONFIG_BLK_DEV_IDEPCI 95#define ide_init_default_irq(base) (0) 96#else 97#define ide_init_default_irq(base) ide_default_irq(base) 98#endif 99 100/* MIPS port and memory-mapped I/O string operations. */ 101static inline void __ide_flush_prologue(void) 102{ 103#ifdef CONFIG_SMP 104 if (cpu_has_dc_aliases) 105 preempt_disable(); 106#endif 107} 108 109static inline void __ide_flush_epilogue(void) 110{ 111#ifdef CONFIG_SMP 112 if (cpu_has_dc_aliases) 113 preempt_enable(); 114#endif 115} 116 117static inline void __ide_flush_dcache_range(unsigned long addr, unsigned long size) 118{ 119 if (cpu_has_dc_aliases) { 120 unsigned long end = addr + size; 121 122 while (addr < end) { 123 local_flush_data_cache_page((void *)addr); 124 addr += PAGE_SIZE; 125 } 126 } 127} 128 129static inline void __ide_insw(unsigned long port, void *addr, 130 unsigned int count) 131{ 132 __ide_flush_prologue(); 133 insw(port, addr, count); 134 __ide_flush_dcache_range((unsigned long)addr, count * 2); 135 __ide_flush_epilogue(); 136} 137 138static inline void __ide_insl(unsigned long port, void *addr, unsigned int count) 139{ 140 __ide_flush_prologue(); 141 insl(port, addr, count); 142 __ide_flush_dcache_range((unsigned long)addr, count * 4); 143 __ide_flush_epilogue(); 144} 145 146static inline void __ide_outsw(unsigned long port, const void *addr, 147 unsigned long count) 148{ 149 __ide_flush_prologue(); 150 outsw(port, addr, count); 151 __ide_flush_dcache_range((unsigned long)addr, count * 2); 152 __ide_flush_epilogue(); 153} 154 155static inline void __ide_outsl(unsigned long port, const void *addr, 156 unsigned long count) 157{ 158 __ide_flush_prologue(); 159 outsl(port, addr, count); 160 __ide_flush_dcache_range((unsigned long)addr, count * 4); 161 __ide_flush_epilogue(); 162} 163 164static inline void __ide_mm_insw(void __iomem *port, void *addr, u32 count) 165{ 166 __ide_flush_prologue(); 167 readsw(port, addr, count); 168 __ide_flush_dcache_range((unsigned long)addr, count * 2); 169 __ide_flush_epilogue(); 170} 171 172static inline void __ide_mm_insl(void __iomem *port, void *addr, u32 count) 173{ 174 __ide_flush_prologue(); 175 readsl(port, addr, count); 176 __ide_flush_dcache_range((unsigned long)addr, count * 4); 177 __ide_flush_epilogue(); 178} 179 180static inline void __ide_mm_outsw(void __iomem *port, void *addr, u32 count) 181{ 182 __ide_flush_prologue(); 183 writesw(port, addr, count); 184 __ide_flush_dcache_range((unsigned long)addr, count * 2); 185 __ide_flush_epilogue(); 186} 187 188static inline void __ide_mm_outsl(void __iomem * port, void *addr, u32 count) 189{ 190 __ide_flush_prologue(); 191 writesl(port, addr, count); 192 __ide_flush_dcache_range((unsigned long)addr, count * 4); 193 __ide_flush_epilogue(); 194} 195 196/* ide_insw calls insw, not __ide_insw. Why? */ 197#undef insw 198#undef insl 199#undef outsw 200#undef outsl 201#define insw(port, addr, count) __ide_insw(port, addr, count) 202#define insl(port, addr, count) __ide_insl(port, addr, count) 203#define outsw(port, addr, count) __ide_outsw(port, addr, count) 204#define outsl(port, addr, count) __ide_outsl(port, addr, count) 205 206#endif /* __KERNEL__ */ 207 208#endif /* __ASM_MACH_GENERIC_IDE_H */ 209