aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/early-quirks.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/early-quirks.c')
-rw-r--r--arch/x86/kernel/early-quirks.c91
1 files changed, 47 insertions, 44 deletions
diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c
index b55258e49208..3f88e437e843 100644
--- a/arch/x86/kernel/early-quirks.c
+++ b/arch/x86/kernel/early-quirks.c
@@ -32,10 +32,13 @@ static void __init fix_hypertransport_config(int num, int slot, int func)
32 */ 32 */
33 htcfg = read_pci_config(num, slot, func, 0x68); 33 htcfg = read_pci_config(num, slot, func, 0x68);
34 if (htcfg & (1 << 18)) { 34 if (htcfg & (1 << 18)) {
35 printk(KERN_INFO "Detected use of extended apic ids on hypertransport bus\n"); 35 printk(KERN_INFO "Detected use of extended apic ids "
36 "on hypertransport bus\n");
36 if ((htcfg & (1 << 17)) == 0) { 37 if ((htcfg & (1 << 17)) == 0) {
37 printk(KERN_INFO "Enabling hypertransport extended apic interrupt broadcast\n"); 38 printk(KERN_INFO "Enabling hypertransport extended "
38 printk(KERN_INFO "Note this is a bios bug, please contact your hw vendor\n"); 39 "apic interrupt broadcast\n");
40 printk(KERN_INFO "Note this is a bios bug, "
41 "please contact your hw vendor\n");
39 htcfg |= (1 << 17); 42 htcfg |= (1 << 17);
40 write_pci_config(num, slot, func, 0x68, htcfg); 43 write_pci_config(num, slot, func, 0x68, htcfg);
41 } 44 }
@@ -130,6 +133,43 @@ static struct chipset early_qrk[] __initdata = {
130 {} 133 {}
131}; 134};
132 135
136static void check_dev_quirk(int num, int slot, int func)
137{
138 u16 class;
139 u16 vendor;
140 u16 device;
141 u8 type;
142 int i;
143
144 class = read_pci_config_16(num, slot, func, PCI_CLASS_DEVICE);
145
146 if (class == 0xffff)
147 return;
148
149 vendor = read_pci_config_16(num, slot, func, PCI_VENDOR_ID);
150
151 device = read_pci_config_16(num, slot, func, PCI_DEVICE_ID);
152
153 for (i = 0; early_qrk[i].f != NULL; i++) {
154 if (((early_qrk[i].vendor == PCI_ANY_ID) ||
155 (early_qrk[i].vendor == vendor)) &&
156 ((early_qrk[i].device == PCI_ANY_ID) ||
157 (early_qrk[i].device == device)) &&
158 (!((early_qrk[i].class ^ class) &
159 early_qrk[i].class_mask))) {
160 if ((early_qrk[i].flags &
161 QFLAG_DONE) != QFLAG_DONE)
162 early_qrk[i].f(num, slot, func);
163 early_qrk[i].flags |= QFLAG_APPLIED;
164 }
165 }
166
167 type = read_pci_config_byte(num, slot, func,
168 PCI_HEADER_TYPE);
169 if (!(type & 0x80))
170 return;
171}
172
133void __init early_quirks(void) 173void __init early_quirks(void)
134{ 174{
135 int num, slot, func; 175 int num, slot, func;
@@ -138,45 +178,8 @@ void __init early_quirks(void)
138 return; 178 return;
139 179
140 /* Poor man's PCI discovery */ 180 /* Poor man's PCI discovery */
141 for (num = 0; num < 32; num++) { 181 for (num = 0; num < 32; num++)
142 for (slot = 0; slot < 32; slot++) { 182 for (slot = 0; slot < 32; slot++)
143 for (func = 0; func < 8; func++) { 183 for (func = 0; func < 8; func++)
144 u16 class; 184 check_dev_quirk(num, slot, func);
145 u16 vendor;
146 u16 device;
147 u8 type;
148 int i;
149
150 class = read_pci_config_16(num,slot,func,
151 PCI_CLASS_REVISION);
152 if (class == 0xffff)
153 break;
154
155 vendor = read_pci_config_16(num, slot, func,
156 PCI_VENDOR_ID);
157
158 device = read_pci_config_16(num, slot, func,
159 PCI_DEVICE_ID);
160
161 for(i=0;early_qrk[i].f != NULL;i++) {
162 if (((early_qrk[i].vendor == PCI_ANY_ID) ||
163 (early_qrk[i].vendor == vendor)) &&
164 ((early_qrk[i].device == PCI_ANY_ID) ||
165 (early_qrk[i].device == device)) &&
166 (!((early_qrk[i].class ^ class) &
167 early_qrk[i].class_mask))) {
168 if ((early_qrk[i].flags & QFLAG_DONE) != QFLAG_DONE)
169 early_qrk[i].f(num, slot, func);
170 early_qrk[i].flags |= QFLAG_APPLIED;
171
172 }
173 }
174
175 type = read_pci_config_byte(num, slot, func,
176 PCI_HEADER_TYPE);
177 if (!(type & 0x80))
178 break;
179 }
180 }
181 }
182} 185}