Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v2.6.25-rc5 225 lines 5.7 kB view raw
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 */