aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
authorJesse Barnes <jbarnes@hobbes.lan>2008-06-16 18:29:45 -0400
committerJesse Barnes <jbarnes@virtuousgeek.org>2008-06-16 18:29:45 -0400
commit15650a2f644a2f15738cf22807c090d89328f500 (patch)
tree4fa3d379b9db7b5388494d1083dc7d0305753ae7 /arch/x86
parentd8f3de0d2412bb91639cfefc5b3c79dbf3812212 (diff)
x86/PCI: fixup early quirk probing
On x86, we do early PCI probing to apply some quirks for chipset bugs. However, in a recent cleanup (7bcbc78dea92fdf0947fa48e248da3c993a5690f) a thinko was introduced that causes us to probe all subfunctions of even single function devices (a function was factored out of an inner loop and a "break" became a "return"). Fix that up by making check_dev_quirk() return a value so we can keep the factored code intact. Acked-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/kernel/early-quirks.c26
1 files changed, 21 insertions, 5 deletions
diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c
index 9f51e1ea9e82..8566fea647eb 100644
--- a/arch/x86/kernel/early-quirks.c
+++ b/arch/x86/kernel/early-quirks.c
@@ -133,7 +133,18 @@ static struct chipset early_qrk[] __initdata = {
133 {} 133 {}
134}; 134};
135 135
136static void __init check_dev_quirk(int num, int slot, int func) 136/**
137 * check_dev_quirk - apply early quirks to a given PCI device
138 * @num: bus number
139 * @slot: slot number
140 * @func: PCI function
141 *
142 * Check the vendor & device ID against the early quirks table.
143 *
144 * If the device is single function, let early_quirks() know so we don't
145 * poke at this device again.
146 */
147static int __init check_dev_quirk(int num, int slot, int func)
137{ 148{
138 u16 class; 149 u16 class;
139 u16 vendor; 150 u16 vendor;
@@ -144,7 +155,7 @@ static void __init check_dev_quirk(int num, int slot, int func)
144 class = read_pci_config_16(num, slot, func, PCI_CLASS_DEVICE); 155 class = read_pci_config_16(num, slot, func, PCI_CLASS_DEVICE);
145 156
146 if (class == 0xffff) 157 if (class == 0xffff)
147 return; 158 return -1; /* no class, treat as single function */
148 159
149 vendor = read_pci_config_16(num, slot, func, PCI_VENDOR_ID); 160 vendor = read_pci_config_16(num, slot, func, PCI_VENDOR_ID);
150 161
@@ -167,7 +178,9 @@ static void __init check_dev_quirk(int num, int slot, int func)
167 type = read_pci_config_byte(num, slot, func, 178 type = read_pci_config_byte(num, slot, func,
168 PCI_HEADER_TYPE); 179 PCI_HEADER_TYPE);
169 if (!(type & 0x80)) 180 if (!(type & 0x80))
170 return; 181 return -1;
182
183 return 0;
171} 184}
172 185
173void __init early_quirks(void) 186void __init early_quirks(void)
@@ -180,6 +193,9 @@ void __init early_quirks(void)
180 /* Poor man's PCI discovery */ 193 /* Poor man's PCI discovery */
181 for (num = 0; num < 32; num++) 194 for (num = 0; num < 32; num++)
182 for (slot = 0; slot < 32; slot++) 195 for (slot = 0; slot < 32; slot++)
183 for (func = 0; func < 8; func++) 196 for (func = 0; func < 8; func++) {
184 check_dev_quirk(num, slot, func); 197 /* Only probe function 0 on single fn devices */
198 if (check_dev_quirk(num, slot, func))
199 break;
200 }
185} 201}