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