diff options
author | Jesse Barnes <jbarnes@hobbes.lan> | 2008-06-16 18:29:45 -0400 |
---|---|---|
committer | Jesse Barnes <jbarnes@virtuousgeek.org> | 2008-06-16 18:29:45 -0400 |
commit | 15650a2f644a2f15738cf22807c090d89328f500 (patch) | |
tree | 4fa3d379b9db7b5388494d1083dc7d0305753ae7 | |
parent | d8f3de0d2412bb91639cfefc5b3c79dbf3812212 (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>
-rw-r--r-- | arch/x86/kernel/early-quirks.c | 26 |
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 | ||
136 | static 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 | */ | ||
147 | static 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 | ||
173 | void __init early_quirks(void) | 186 | void __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 | } |