Lines 115-120
static void pci_enable_msi(device_t dev
Link Here
|
115 |
uint16_t data); |
115 |
uint16_t data); |
116 |
static void pci_enable_msix(device_t dev, u_int index, |
116 |
static void pci_enable_msix(device_t dev, u_int index, |
117 |
uint64_t address, uint32_t data); |
117 |
uint64_t address, uint32_t data); |
|
|
118 |
static void pci_fix_asus_smbus(device_t dev); |
118 |
static void pci_mask_msix(device_t dev, u_int index); |
119 |
static void pci_mask_msix(device_t dev, u_int index); |
119 |
static void pci_unmask_msix(device_t dev, u_int index); |
120 |
static void pci_unmask_msix(device_t dev, u_int index); |
120 |
static int pci_msi_blacklisted(void); |
121 |
static int pci_msi_blacklisted(void); |
Lines 207-260
struct pci_quirk {
Link Here
|
207 |
#define PCI_QUIRK_UNMAP_REG 4 /* Ignore PCI map register */ |
208 |
#define PCI_QUIRK_UNMAP_REG 4 /* Ignore PCI map register */ |
208 |
#define PCI_QUIRK_DISABLE_MSIX 5 /* MSI-X doesn't work */ |
209 |
#define PCI_QUIRK_DISABLE_MSIX 5 /* MSI-X doesn't work */ |
209 |
#define PCI_QUIRK_MSI_INTX_BUG 6 /* PCIM_CMD_INTxDIS disables MSI */ |
210 |
#define PCI_QUIRK_MSI_INTX_BUG 6 /* PCIM_CMD_INTxDIS disables MSI */ |
|
|
211 |
#define PCI_QUIRK_FIXUP_ROUTINE 7 /* PCI needs a fix to continue */ |
210 |
int arg1; |
212 |
int arg1; |
211 |
int arg2; |
213 |
int arg2; |
|
|
214 |
void (*fixup_func)(device_t dev); |
212 |
}; |
215 |
}; |
213 |
|
216 |
|
214 |
static const struct pci_quirk pci_quirks[] = { |
217 |
static const struct pci_quirk pci_quirks[] = { |
215 |
/* The Intel 82371AB and 82443MX have a map register at offset 0x90. */ |
218 |
/* The Intel 82371AB and 82443MX have a map register at offset 0x90. */ |
216 |
{ 0x71138086, PCI_QUIRK_MAP_REG, 0x90, 0 }, |
219 |
{ 0x71138086, PCI_QUIRK_MAP_REG, 0x90, 0, NULL }, |
217 |
{ 0x719b8086, PCI_QUIRK_MAP_REG, 0x90, 0 }, |
220 |
{ 0x719b8086, PCI_QUIRK_MAP_REG, 0x90, 0, NULL }, |
218 |
/* As does the Serverworks OSB4 (the SMBus mapping register) */ |
221 |
/* As does the Serverworks OSB4 (the SMBus mapping register) */ |
219 |
{ 0x02001166, PCI_QUIRK_MAP_REG, 0x90, 0 }, |
222 |
{ 0x02001166, PCI_QUIRK_MAP_REG, 0x90, 0, NULL }, |
220 |
|
223 |
|
221 |
/* |
224 |
/* |
222 |
* MSI doesn't work with the ServerWorks CNB20-HE Host Bridge |
225 |
* MSI doesn't work with the ServerWorks CNB20-HE Host Bridge |
223 |
* or the CMIC-SL (AKA ServerWorks GC_LE). |
226 |
* or the CMIC-SL (AKA ServerWorks GC_LE). |
224 |
*/ |
227 |
*/ |
225 |
{ 0x00141166, PCI_QUIRK_DISABLE_MSI, 0, 0 }, |
228 |
{ 0x00141166, PCI_QUIRK_DISABLE_MSI, 0, 0, NULL }, |
226 |
{ 0x00171166, PCI_QUIRK_DISABLE_MSI, 0, 0 }, |
229 |
{ 0x00171166, PCI_QUIRK_DISABLE_MSI, 0, 0, NULL }, |
227 |
|
230 |
|
228 |
/* |
231 |
/* |
229 |
* MSI doesn't work on earlier Intel chipsets including |
232 |
* MSI doesn't work on earlier Intel chipsets including |
230 |
* E7500, E7501, E7505, 845, 865, 875/E7210, and 855. |
233 |
* E7500, E7501, E7505, 845, 865, 875/E7210, and 855. |
231 |
*/ |
234 |
*/ |
232 |
{ 0x25408086, PCI_QUIRK_DISABLE_MSI, 0, 0 }, |
235 |
{ 0x25408086, PCI_QUIRK_DISABLE_MSI, 0, 0, NULL }, |
233 |
{ 0x254c8086, PCI_QUIRK_DISABLE_MSI, 0, 0 }, |
236 |
{ 0x254c8086, PCI_QUIRK_DISABLE_MSI, 0, 0, NULL }, |
234 |
{ 0x25508086, PCI_QUIRK_DISABLE_MSI, 0, 0 }, |
237 |
{ 0x25508086, PCI_QUIRK_DISABLE_MSI, 0, 0, NULL }, |
235 |
{ 0x25608086, PCI_QUIRK_DISABLE_MSI, 0, 0 }, |
238 |
{ 0x25608086, PCI_QUIRK_DISABLE_MSI, 0, 0, NULL }, |
236 |
{ 0x25708086, PCI_QUIRK_DISABLE_MSI, 0, 0 }, |
239 |
{ 0x25708086, PCI_QUIRK_DISABLE_MSI, 0, 0, NULL }, |
237 |
{ 0x25788086, PCI_QUIRK_DISABLE_MSI, 0, 0 }, |
240 |
{ 0x25788086, PCI_QUIRK_DISABLE_MSI, 0, 0, NULL }, |
238 |
{ 0x35808086, PCI_QUIRK_DISABLE_MSI, 0, 0 }, |
241 |
{ 0x35808086, PCI_QUIRK_DISABLE_MSI, 0, 0, NULL }, |
239 |
|
242 |
|
240 |
/* |
243 |
/* |
241 |
* MSI doesn't work with devices behind the AMD 8131 HT-PCIX |
244 |
* MSI doesn't work with devices behind the AMD 8131 HT-PCIX |
242 |
* bridge. |
245 |
* bridge. |
243 |
*/ |
246 |
*/ |
244 |
{ 0x74501022, PCI_QUIRK_DISABLE_MSI, 0, 0 }, |
247 |
{ 0x74501022, PCI_QUIRK_DISABLE_MSI, 0, 0, NULL }, |
245 |
|
248 |
|
246 |
/* |
249 |
/* |
247 |
* MSI-X allocation doesn't work properly for devices passed through |
250 |
* MSI-X allocation doesn't work properly for devices passed through |
248 |
* by VMware up to at least ESXi 5.1. |
251 |
* by VMware up to at least ESXi 5.1. |
249 |
*/ |
252 |
*/ |
250 |
{ 0x079015ad, PCI_QUIRK_DISABLE_MSIX, 0, 0 }, /* PCI/PCI-X */ |
253 |
{ 0x079015ad, PCI_QUIRK_DISABLE_MSIX, 0, 0, NULL }, /* PCI/PCI-X */ |
251 |
{ 0x07a015ad, PCI_QUIRK_DISABLE_MSIX, 0, 0 }, /* PCIe */ |
254 |
{ 0x07a015ad, PCI_QUIRK_DISABLE_MSIX, 0, 0, NULL }, /* PCIe */ |
252 |
|
255 |
|
253 |
/* |
256 |
/* |
254 |
* Some virtualization environments emulate an older chipset |
257 |
* Some virtualization environments emulate an older chipset |
255 |
* but support MSI just fine. QEMU uses the Intel 82440. |
258 |
* but support MSI just fine. QEMU uses the Intel 82440. |
256 |
*/ |
259 |
*/ |
257 |
{ 0x12378086, PCI_QUIRK_ENABLE_MSI_VM, 0, 0 }, |
260 |
{ 0x12378086, PCI_QUIRK_ENABLE_MSI_VM, 0, 0, NULL }, |
258 |
|
261 |
|
259 |
/* |
262 |
/* |
260 |
* HPET MMIO base address may appear in Bar1 for AMD SB600 SMBus |
263 |
* HPET MMIO base address may appear in Bar1 for AMD SB600 SMBus |
Lines 264-290
static const struct pci_quirk pci_quirks
Link Here
|
264 |
* For SB600 A21 and later, firmware must set the bit to hide it. |
267 |
* For SB600 A21 and later, firmware must set the bit to hide it. |
265 |
* For SB700 and later, it is unused and hardcoded to zero. |
268 |
* For SB700 and later, it is unused and hardcoded to zero. |
266 |
*/ |
269 |
*/ |
267 |
{ 0x43851002, PCI_QUIRK_UNMAP_REG, 0x14, 0 }, |
270 |
{ 0x43851002, PCI_QUIRK_UNMAP_REG, 0x14, 0, NULL }, |
268 |
|
271 |
|
269 |
/* |
272 |
/* |
270 |
* Atheros AR8161/AR8162/E2200 Ethernet controllers have a bug that |
273 |
* Atheros AR8161/AR8162/E2200 Ethernet controllers have a bug that |
271 |
* MSI interrupt does not assert if PCIM_CMD_INTxDIS bit of the |
274 |
* MSI interrupt does not assert if PCIM_CMD_INTxDIS bit of the |
272 |
* command register is set. |
275 |
* command register is set. |
273 |
*/ |
276 |
*/ |
274 |
{ 0x10911969, PCI_QUIRK_MSI_INTX_BUG, 0, 0 }, |
277 |
{ 0x10911969, PCI_QUIRK_MSI_INTX_BUG, 0, 0, NULL }, |
275 |
{ 0xE0911969, PCI_QUIRK_MSI_INTX_BUG, 0, 0 }, |
278 |
{ 0xE0911969, PCI_QUIRK_MSI_INTX_BUG, 0, 0, NULL }, |
276 |
{ 0x10901969, PCI_QUIRK_MSI_INTX_BUG, 0, 0 }, |
279 |
{ 0x10901969, PCI_QUIRK_MSI_INTX_BUG, 0, 0, NULL }, |
277 |
|
280 |
|
278 |
/* |
281 |
/* |
279 |
* Broadcom BCM5714(S)/BCM5715(S)/BCM5780(S) Ethernet MACs don't |
282 |
* Broadcom BCM5714(S)/BCM5715(S)/BCM5780(S) Ethernet MACs don't |
280 |
* issue MSI interrupts with PCIM_CMD_INTxDIS set either. |
283 |
* issue MSI interrupts with PCIM_CMD_INTxDIS set either. |
281 |
*/ |
284 |
*/ |
282 |
{ 0x166814e4, PCI_QUIRK_MSI_INTX_BUG, 0, 0 }, /* BCM5714 */ |
285 |
{ 0x166814e4, PCI_QUIRK_MSI_INTX_BUG, 0, 0, NULL }, /* BCM5714 */ |
283 |
{ 0x166914e4, PCI_QUIRK_MSI_INTX_BUG, 0, 0 }, /* BCM5714S */ |
286 |
{ 0x166914e4, PCI_QUIRK_MSI_INTX_BUG, 0, 0, NULL }, /* BCM5714S */ |
284 |
{ 0x166a14e4, PCI_QUIRK_MSI_INTX_BUG, 0, 0 }, /* BCM5780 */ |
287 |
{ 0x166a14e4, PCI_QUIRK_MSI_INTX_BUG, 0, 0, NULL }, /* BCM5780 */ |
285 |
{ 0x166b14e4, PCI_QUIRK_MSI_INTX_BUG, 0, 0 }, /* BCM5780S */ |
288 |
{ 0x166b14e4, PCI_QUIRK_MSI_INTX_BUG, 0, 0, NULL }, /* BCM5780S */ |
286 |
{ 0x167814e4, PCI_QUIRK_MSI_INTX_BUG, 0, 0 }, /* BCM5715 */ |
289 |
{ 0x167814e4, PCI_QUIRK_MSI_INTX_BUG, 0, 0, NULL }, /* BCM5715 */ |
287 |
{ 0x167914e4, PCI_QUIRK_MSI_INTX_BUG, 0, 0 }, /* BCM5715S */ |
290 |
{ 0x167914e4, PCI_QUIRK_MSI_INTX_BUG, 0, 0, NULL }, /* BCM5715S */ |
|
|
291 |
|
292 |
/* |
293 |
* The ASUS P4B-motherboards needs a hack to enable the Intel 801SMBus |
294 |
*/ |
295 |
{ 0x24408086, PCI_QUIRK_FIXUP_ROUTINE, 0, 0, &pci_fix_asus_smbus }, |
296 |
{ 0x24C08086, PCI_QUIRK_FIXUP_ROUTINE, 0, 0, &pci_fix_asus_smbus }, |
288 |
|
297 |
|
289 |
{ 0 } |
298 |
{ 0 } |
290 |
}; |
299 |
}; |
Lines 575-580
pci_fixancient(pcicfgregs *cfg)
Link Here
|
575 |
cfg->hdrtype = PCIM_HDRTYPE_BRIDGE; |
584 |
cfg->hdrtype = PCIM_HDRTYPE_BRIDGE; |
576 |
} |
585 |
} |
577 |
|
586 |
|
|
|
587 |
/* asus p4b/p4pe hack */ |
588 |
|
589 |
static void |
590 |
pci_fix_asus_smbus(device_t dev) |
591 |
{ |
592 |
int pmccfg; |
593 |
|
594 |
/* read subsystem vendor-id */ |
595 |
pmccfg = pci_read_config(dev, 0xF2, 2); |
596 |
printf(" [-] pmccfg: %.4x\n",pmccfg); |
597 |
if( pmccfg & 0x8 ){ |
598 |
pmccfg &= ~0x8; |
599 |
pci_write_config(dev, 0xF2, pmccfg, 2); |
600 |
pmccfg = pci_read_config(dev, 0xF2, 2); |
601 |
if( pmccfg & 0x8 ) |
602 |
printf("Could not enable Intel 801SMBus!\n"); |
603 |
else |
604 |
printf("Enabled Intel 801SMBus\n"); |
605 |
} |
606 |
} |
607 |
|
578 |
/* extract header type specific config data */ |
608 |
/* extract header type specific config data */ |
579 |
|
609 |
|
580 |
static void |
610 |
static void |
Lines 3423-3428
pci_add_resources(device_t bus, device_t
Link Here
|
3423 |
* Skip quirked resources. |
3453 |
* Skip quirked resources. |
3424 |
*/ |
3454 |
*/ |
3425 |
for (q = &pci_quirks[0]; q->devid != 0; q++) |
3455 |
for (q = &pci_quirks[0]; q->devid != 0; q++) |
|
|
3456 |
if (q->devid == ((cfg->device << 16) | cfg->vendor)){ |
3457 |
if (q->type == PCI_QUIRK_MAP_REG) |
3458 |
pci_add_map(bus, dev, q->arg1, rl, force, 0); |
3459 |
else if (q->type == PCI_QUIRK_FIXUP_ROUTINE) |
3460 |
q->fixup_func(dev); |
3461 |
} |
3426 |
if (q->devid == devid && |
3462 |
if (q->devid == devid && |
3427 |
q->type == PCI_QUIRK_UNMAP_REG && |
3463 |
q->type == PCI_QUIRK_UNMAP_REG && |
3428 |
q->arg1 == PCIR_BAR(i)) |
3464 |
q->arg1 == PCIR_BAR(i)) |