diff options
Diffstat (limited to 'arch/x86/kernel/early-quirks.c')
-rw-r--r-- | arch/x86/kernel/early-quirks.c | 91 |
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 | ||
136 | static 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 | |||
133 | void __init early_quirks(void) | 173 | void __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 | } |