diff options
Diffstat (limited to 'drivers/pci/probe.c')
-rw-r--r-- | drivers/pci/probe.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index bd42ed42c199..c31310db0404 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -1356,6 +1356,34 @@ static void pci_msi_setup_pci_dev(struct pci_dev *dev) | |||
1356 | } | 1356 | } |
1357 | 1357 | ||
1358 | /** | 1358 | /** |
1359 | * pci_intx_mask_broken - test PCI_COMMAND_INTX_DISABLE writability | ||
1360 | * @dev: PCI device | ||
1361 | * | ||
1362 | * Test whether PCI_COMMAND_INTX_DISABLE is writable for @dev. Check this | ||
1363 | * at enumeration-time to avoid modifying PCI_COMMAND at run-time. | ||
1364 | */ | ||
1365 | static int pci_intx_mask_broken(struct pci_dev *dev) | ||
1366 | { | ||
1367 | u16 orig, toggle, new; | ||
1368 | |||
1369 | pci_read_config_word(dev, PCI_COMMAND, &orig); | ||
1370 | toggle = orig ^ PCI_COMMAND_INTX_DISABLE; | ||
1371 | pci_write_config_word(dev, PCI_COMMAND, toggle); | ||
1372 | pci_read_config_word(dev, PCI_COMMAND, &new); | ||
1373 | |||
1374 | pci_write_config_word(dev, PCI_COMMAND, orig); | ||
1375 | |||
1376 | /* | ||
1377 | * PCI_COMMAND_INTX_DISABLE was reserved and read-only prior to PCI | ||
1378 | * r2.3, so strictly speaking, a device is not *broken* if it's not | ||
1379 | * writable. But we'll live with the misnomer for now. | ||
1380 | */ | ||
1381 | if (new != toggle) | ||
1382 | return 1; | ||
1383 | return 0; | ||
1384 | } | ||
1385 | |||
1386 | /** | ||
1359 | * pci_setup_device - fill in class and map information of a device | 1387 | * pci_setup_device - fill in class and map information of a device |
1360 | * @dev: the device structure to fill | 1388 | * @dev: the device structure to fill |
1361 | * | 1389 | * |
@@ -1425,6 +1453,8 @@ int pci_setup_device(struct pci_dev *dev) | |||
1425 | } | 1453 | } |
1426 | } | 1454 | } |
1427 | 1455 | ||
1456 | dev->broken_intx_masking = pci_intx_mask_broken(dev); | ||
1457 | |||
1428 | switch (dev->hdr_type) { /* header type */ | 1458 | switch (dev->hdr_type) { /* header type */ |
1429 | case PCI_HEADER_TYPE_NORMAL: /* standard header */ | 1459 | case PCI_HEADER_TYPE_NORMAL: /* standard header */ |
1430 | if (class == PCI_CLASS_BRIDGE_PCI) | 1460 | if (class == PCI_CLASS_BRIDGE_PCI) |
@@ -1700,6 +1730,11 @@ static void program_hpp_type2(struct pci_dev *dev, struct hpp_type2 *hpp) | |||
1700 | /* Initialize Advanced Error Capabilities and Control Register */ | 1730 | /* Initialize Advanced Error Capabilities and Control Register */ |
1701 | pci_read_config_dword(dev, pos + PCI_ERR_CAP, ®32); | 1731 | pci_read_config_dword(dev, pos + PCI_ERR_CAP, ®32); |
1702 | reg32 = (reg32 & hpp->adv_err_cap_and) | hpp->adv_err_cap_or; | 1732 | reg32 = (reg32 & hpp->adv_err_cap_and) | hpp->adv_err_cap_or; |
1733 | /* Don't enable ECRC generation or checking if unsupported */ | ||
1734 | if (!(reg32 & PCI_ERR_CAP_ECRC_GENC)) | ||
1735 | reg32 &= ~PCI_ERR_CAP_ECRC_GENE; | ||
1736 | if (!(reg32 & PCI_ERR_CAP_ECRC_CHKC)) | ||
1737 | reg32 &= ~PCI_ERR_CAP_ECRC_CHKE; | ||
1703 | pci_write_config_dword(dev, pos + PCI_ERR_CAP, reg32); | 1738 | pci_write_config_dword(dev, pos + PCI_ERR_CAP, reg32); |
1704 | 1739 | ||
1705 | /* | 1740 | /* |