Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v2.6.23-rc5 195 lines 5.0 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_default_irq(unsigned long base) 33{ 34 switch (base) { 35 case 0x1f0: return 14; 36 case 0x170: return 15; 37 case 0x1e8: return 11; 38 case 0x168: return 10; 39 case 0x1e0: return 8; 40 case 0x160: return 12; 41 default: 42 return 0; 43 } 44} 45 46static __inline__ unsigned long ide_default_io_base(int index) 47{ 48 /* 49 * If PCI is present then it is not safe to poke around 50 * the other legacy IDE ports. Only 0x1f0 and 0x170 are 51 * defined compatibility mode ports for PCI. A user can 52 * override this using ide= but we must default safe. 53 */ 54 if (no_pci_devices()) { 55 switch (index) { 56 case 2: return 0x1e8; 57 case 3: return 0x168; 58 case 4: return 0x1e0; 59 case 5: return 0x160; 60 } 61 } 62 switch (index) { 63 case 0: return 0x1f0; 64 case 1: return 0x170; 65 default: 66 return 0; 67 } 68} 69 70#define IDE_ARCH_OBSOLETE_INIT 71#define ide_default_io_ctl(base) ((base) + 0x206) /* obsolete */ 72 73#ifdef CONFIG_BLK_DEV_IDEPCI 74#define ide_init_default_irq(base) (0) 75#else 76#define ide_init_default_irq(base) ide_default_irq(base) 77#endif 78 79/* MIPS port and memory-mapped I/O string operations. */ 80static inline void __ide_flush_prologue(void) 81{ 82#ifdef CONFIG_SMP 83 if (cpu_has_dc_aliases) 84 preempt_disable(); 85#endif 86} 87 88static inline void __ide_flush_epilogue(void) 89{ 90#ifdef CONFIG_SMP 91 if (cpu_has_dc_aliases) 92 preempt_enable(); 93#endif 94} 95 96static inline void __ide_flush_dcache_range(unsigned long addr, unsigned long size) 97{ 98 if (cpu_has_dc_aliases) { 99 unsigned long end = addr + size; 100 101 while (addr < end) { 102 local_flush_data_cache_page((void *)addr); 103 addr += PAGE_SIZE; 104 } 105 } 106} 107 108/* 109 * insw() and gang might be called with interrupts disabled, so we can't 110 * send IPIs for flushing due to the potencial of deadlocks, see the comment 111 * above smp_call_function() in arch/mips/kernel/smp.c. We work around the 112 * problem by disabling preemption so we know we actually perform the flush 113 * on the processor that actually has the lines to be flushed which hopefully 114 * is even better for performance anyway. 115 */ 116static inline void __ide_insw(unsigned long port, void *addr, 117 unsigned int count) 118{ 119 __ide_flush_prologue(); 120 insw(port, addr, count); 121 __ide_flush_dcache_range((unsigned long)addr, count * 2); 122 __ide_flush_epilogue(); 123} 124 125static inline void __ide_insl(unsigned long port, void *addr, unsigned int count) 126{ 127 __ide_flush_prologue(); 128 insl(port, addr, count); 129 __ide_flush_dcache_range((unsigned long)addr, count * 4); 130 __ide_flush_epilogue(); 131} 132 133static inline void __ide_outsw(unsigned long port, const void *addr, 134 unsigned long count) 135{ 136 __ide_flush_prologue(); 137 outsw(port, addr, count); 138 __ide_flush_dcache_range((unsigned long)addr, count * 2); 139 __ide_flush_epilogue(); 140} 141 142static inline void __ide_outsl(unsigned long port, const void *addr, 143 unsigned long count) 144{ 145 __ide_flush_prologue(); 146 outsl(port, addr, count); 147 __ide_flush_dcache_range((unsigned long)addr, count * 4); 148 __ide_flush_epilogue(); 149} 150 151static inline void __ide_mm_insw(void __iomem *port, void *addr, u32 count) 152{ 153 __ide_flush_prologue(); 154 readsw(port, addr, count); 155 __ide_flush_dcache_range((unsigned long)addr, count * 2); 156 __ide_flush_epilogue(); 157} 158 159static inline void __ide_mm_insl(void __iomem *port, void *addr, u32 count) 160{ 161 __ide_flush_prologue(); 162 readsl(port, addr, count); 163 __ide_flush_dcache_range((unsigned long)addr, count * 4); 164 __ide_flush_epilogue(); 165} 166 167static inline void __ide_mm_outsw(void __iomem *port, void *addr, u32 count) 168{ 169 __ide_flush_prologue(); 170 writesw(port, addr, count); 171 __ide_flush_dcache_range((unsigned long)addr, count * 2); 172 __ide_flush_epilogue(); 173} 174 175static inline void __ide_mm_outsl(void __iomem * port, void *addr, u32 count) 176{ 177 __ide_flush_prologue(); 178 writesl(port, addr, count); 179 __ide_flush_dcache_range((unsigned long)addr, count * 4); 180 __ide_flush_epilogue(); 181} 182 183/* ide_insw calls insw, not __ide_insw. Why? */ 184#undef insw 185#undef insl 186#undef outsw 187#undef outsl 188#define insw(port, addr, count) __ide_insw(port, addr, count) 189#define insl(port, addr, count) __ide_insl(port, addr, count) 190#define outsw(port, addr, count) __ide_outsw(port, addr, count) 191#define outsl(port, addr, count) __ide_outsl(port, addr, count) 192 193#endif /* __KERNEL__ */ 194 195#endif /* __ASM_MACH_GENERIC_IDE_H */