aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/kernel/pci-common.c8
-rw-r--r--arch/tile/kernel/pci_gx.c9
-rw-r--r--arch/x86/pci/acpi.c9
-rw-r--r--drivers/pci/hotplug/pcihp_slot.c5
-rw-r--r--drivers/pci/pci.c3
-rw-r--r--drivers/pci/probe.c66
-rw-r--r--include/linux/pci.h2
7 files changed, 52 insertions, 50 deletions
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index f46914a0f33e..d35ec34de1b4 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -1672,12 +1672,8 @@ void pcibios_scan_phb(struct pci_controller *hose)
1672 /* Configure PCI Express settings */ 1672 /* Configure PCI Express settings */
1673 if (bus && !pci_has_flag(PCI_PROBE_ONLY)) { 1673 if (bus && !pci_has_flag(PCI_PROBE_ONLY)) {
1674 struct pci_bus *child; 1674 struct pci_bus *child;
1675 list_for_each_entry(child, &bus->children, node) { 1675 list_for_each_entry(child, &bus->children, node)
1676 struct pci_dev *self = child->self; 1676 pcie_bus_configure_settings(child);
1677 if (!self)
1678 continue;
1679 pcie_bus_configure_settings(child, self->pcie_mpss);
1680 }
1681 } 1677 }
1682} 1678}
1683 1679
diff --git a/arch/tile/kernel/pci_gx.c b/arch/tile/kernel/pci_gx.c
index 11425633b2d7..6640e7bbeaa2 100644
--- a/arch/tile/kernel/pci_gx.c
+++ b/arch/tile/kernel/pci_gx.c
@@ -508,13 +508,8 @@ static void fixup_read_and_payload_sizes(struct pci_controller *controller)
508 rc_dev_cap.word); 508 rc_dev_cap.word);
509 509
510 /* Configure PCI Express MPS setting. */ 510 /* Configure PCI Express MPS setting. */
511 list_for_each_entry(child, &root_bus->children, node) { 511 list_for_each_entry(child, &root_bus->children, node)
512 struct pci_dev *self = child->self; 512 pcie_bus_configure_settings(child);
513 if (!self)
514 continue;
515
516 pcie_bus_configure_settings(child, self->pcie_mpss);
517 }
518 513
519 /* 514 /*
520 * Set the mac_config register in trio based on the MPS/MRS of the link. 515 * Set the mac_config register in trio based on the MPS/MRS of the link.
diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c
index d641897a1f4e..b30e937689d6 100644
--- a/arch/x86/pci/acpi.c
+++ b/arch/x86/pci/acpi.c
@@ -568,13 +568,8 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
568 */ 568 */
569 if (bus) { 569 if (bus) {
570 struct pci_bus *child; 570 struct pci_bus *child;
571 list_for_each_entry(child, &bus->children, node) { 571 list_for_each_entry(child, &bus->children, node)
572 struct pci_dev *self = child->self; 572 pcie_bus_configure_settings(child);
573 if (!self)
574 continue;
575
576 pcie_bus_configure_settings(child, self->pcie_mpss);
577 }
578 } 573 }
579 574
580 if (bus && node != -1) { 575 if (bus && node != -1) {
diff --git a/drivers/pci/hotplug/pcihp_slot.c b/drivers/pci/hotplug/pcihp_slot.c
index fec2d5b75440..16f920352317 100644
--- a/drivers/pci/hotplug/pcihp_slot.c
+++ b/drivers/pci/hotplug/pcihp_slot.c
@@ -160,9 +160,8 @@ void pci_configure_slot(struct pci_dev *dev)
160 (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI))) 160 (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI)))
161 return; 161 return;
162 162
163 if (dev->bus && dev->bus->self) 163 if (dev->bus)
164 pcie_bus_configure_settings(dev->bus, 164 pcie_bus_configure_settings(dev->bus);
165 dev->bus->self->pcie_mpss);
166 165
167 memset(&hpp, 0, sizeof(hpp)); 166 memset(&hpp, 0, sizeof(hpp));
168 ret = pci_get_hp_params(dev, &hpp); 167 ret = pci_get_hp_params(dev, &hpp);
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index d3fdce8f3d65..4e15bc9712fd 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -3939,8 +3939,6 @@ int pcie_set_readrq(struct pci_dev *dev, int rq)
3939 if (pcie_bus_config == PCIE_BUS_PERFORMANCE) { 3939 if (pcie_bus_config == PCIE_BUS_PERFORMANCE) {
3940 int mps = pcie_get_mps(dev); 3940 int mps = pcie_get_mps(dev);
3941 3941
3942 if (mps < 0)
3943 return mps;
3944 if (mps < rq) 3942 if (mps < rq)
3945 rq = mps; 3943 rq = mps;
3946 } 3944 }
@@ -3957,7 +3955,6 @@ EXPORT_SYMBOL(pcie_set_readrq);
3957 * @dev: PCI device to query 3955 * @dev: PCI device to query
3958 * 3956 *
3959 * Returns maximum payload size in bytes 3957 * Returns maximum payload size in bytes
3960 * or appropriate error value.
3961 */ 3958 */
3962int pcie_get_mps(struct pci_dev *dev) 3959int pcie_get_mps(struct pci_dev *dev)
3963{ 3960{
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 4ab388a6cc26..a57762fbe10e 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1491,24 +1491,23 @@ static int pcie_find_smpss(struct pci_dev *dev, void *data)
1491 if (!pci_is_pcie(dev)) 1491 if (!pci_is_pcie(dev))
1492 return 0; 1492 return 0;
1493 1493
1494 /* For PCIE hotplug enabled slots not connected directly to a 1494 /*
1495 * PCI-E root port, there can be problems when hotplugging 1495 * We don't have a way to change MPS settings on devices that have
1496 * devices. This is due to the possibility of hotplugging a 1496 * drivers attached. A hot-added device might support only the minimum
1497 * device into the fabric with a smaller MPS that the devices 1497 * MPS setting (MPS=128). Therefore, if the fabric contains a bridge
1498 * currently running have configured. Modifying the MPS on the 1498 * where devices may be hot-added, we limit the fabric MPS to 128 so
1499 * running devices could cause a fatal bus error due to an 1499 * hot-added devices will work correctly.
1500 * incoming frame being larger than the newly configured MPS. 1500 *
1501 * To work around this, the MPS for the entire fabric must be 1501 * However, if we hot-add a device to a slot directly below a Root
1502 * set to the minimum size. Any devices hotplugged into this 1502 * Port, it's impossible for there to be other existing devices below
1503 * fabric will have the minimum MPS set. If the PCI hotplug 1503 * the port. We don't limit the MPS in this case because we can
1504 * slot is directly connected to the root port and there are not 1504 * reconfigure MPS on both the Root Port and the hot-added device,
1505 * other devices on the fabric (which seems to be the most 1505 * and there are no other devices involved.
1506 * common case), then this is not an issue and MPS discovery 1506 *
1507 * will occur as normal. 1507 * Note that this PCIE_BUS_SAFE path assumes no peer-to-peer DMA.
1508 */ 1508 */
1509 if (dev->is_hotplug_bridge && (!list_is_singular(&dev->bus->devices) || 1509 if (dev->is_hotplug_bridge &&
1510 (dev->bus->self && 1510 pci_pcie_type(dev) != PCI_EXP_TYPE_ROOT_PORT)
1511 pci_pcie_type(dev->bus->self) != PCI_EXP_TYPE_ROOT_PORT)))
1512 *smpss = 0; 1511 *smpss = 0;
1513 1512
1514 if (*smpss > dev->pcie_mpss) 1513 if (*smpss > dev->pcie_mpss)
@@ -1583,6 +1582,22 @@ static void pcie_write_mrrs(struct pci_dev *dev)
1583 "with pci=pcie_bus_safe.\n"); 1582 "with pci=pcie_bus_safe.\n");
1584} 1583}
1585 1584
1585static void pcie_bus_detect_mps(struct pci_dev *dev)
1586{
1587 struct pci_dev *bridge = dev->bus->self;
1588 int mps, p_mps;
1589
1590 if (!bridge)
1591 return;
1592
1593 mps = pcie_get_mps(dev);
1594 p_mps = pcie_get_mps(bridge);
1595
1596 if (mps != p_mps)
1597 dev_warn(&dev->dev, "Max Payload Size %d, but upstream %s set to %d; if necessary, use \"pci=pcie_bus_safe\" and report a bug\n",
1598 mps, pci_name(bridge), p_mps);
1599}
1600
1586static int pcie_bus_configure_set(struct pci_dev *dev, void *data) 1601static int pcie_bus_configure_set(struct pci_dev *dev, void *data)
1587{ 1602{
1588 int mps, orig_mps; 1603 int mps, orig_mps;
@@ -1590,13 +1605,18 @@ static int pcie_bus_configure_set(struct pci_dev *dev, void *data)
1590 if (!pci_is_pcie(dev)) 1605 if (!pci_is_pcie(dev))
1591 return 0; 1606 return 0;
1592 1607
1608 if (pcie_bus_config == PCIE_BUS_TUNE_OFF) {
1609 pcie_bus_detect_mps(dev);
1610 return 0;
1611 }
1612
1593 mps = 128 << *(u8 *)data; 1613 mps = 128 << *(u8 *)data;
1594 orig_mps = pcie_get_mps(dev); 1614 orig_mps = pcie_get_mps(dev);
1595 1615
1596 pcie_write_mps(dev, mps); 1616 pcie_write_mps(dev, mps);
1597 pcie_write_mrrs(dev); 1617 pcie_write_mrrs(dev);
1598 1618
1599 dev_info(&dev->dev, "PCI-E Max Payload Size set to %4d/%4d (was %4d), " 1619 dev_info(&dev->dev, "Max Payload Size set to %4d/%4d (was %4d), "
1600 "Max Read Rq %4d\n", pcie_get_mps(dev), 128 << dev->pcie_mpss, 1620 "Max Read Rq %4d\n", pcie_get_mps(dev), 128 << dev->pcie_mpss,
1601 orig_mps, pcie_get_readrq(dev)); 1621 orig_mps, pcie_get_readrq(dev));
1602 1622
@@ -1607,25 +1627,25 @@ static int pcie_bus_configure_set(struct pci_dev *dev, void *data)
1607 * parents then children fashion. If this changes, then this code will not 1627 * parents then children fashion. If this changes, then this code will not
1608 * work as designed. 1628 * work as designed.
1609 */ 1629 */
1610void pcie_bus_configure_settings(struct pci_bus *bus, u8 mpss) 1630void pcie_bus_configure_settings(struct pci_bus *bus)
1611{ 1631{
1612 u8 smpss; 1632 u8 smpss;
1613 1633
1614 if (!pci_is_pcie(bus->self)) 1634 if (!bus->self)
1615 return; 1635 return;
1616 1636
1617 if (pcie_bus_config == PCIE_BUS_TUNE_OFF) 1637 if (!pci_is_pcie(bus->self))
1618 return; 1638 return;
1619 1639
1620 /* FIXME - Peer to peer DMA is possible, though the endpoint would need 1640 /* FIXME - Peer to peer DMA is possible, though the endpoint would need
1621 * to be aware to the MPS of the destination. To work around this, 1641 * to be aware of the MPS of the destination. To work around this,
1622 * simply force the MPS of the entire system to the smallest possible. 1642 * simply force the MPS of the entire system to the smallest possible.
1623 */ 1643 */
1624 if (pcie_bus_config == PCIE_BUS_PEER2PEER) 1644 if (pcie_bus_config == PCIE_BUS_PEER2PEER)
1625 smpss = 0; 1645 smpss = 0;
1626 1646
1627 if (pcie_bus_config == PCIE_BUS_SAFE) { 1647 if (pcie_bus_config == PCIE_BUS_SAFE) {
1628 smpss = mpss; 1648 smpss = bus->self->pcie_mpss;
1629 1649
1630 pcie_find_smpss(bus->self, &smpss); 1650 pcie_find_smpss(bus->self, &smpss);
1631 pci_walk_bus(bus, pcie_find_smpss, &smpss); 1651 pci_walk_bus(bus, pcie_find_smpss, &smpss);
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 82d1c78d3d91..b3b716524be5 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -675,7 +675,7 @@ struct pci_driver {
675/* these external functions are only available when PCI support is enabled */ 675/* these external functions are only available when PCI support is enabled */
676#ifdef CONFIG_PCI 676#ifdef CONFIG_PCI
677 677
678void pcie_bus_configure_settings(struct pci_bus *bus, u8 smpss); 678void pcie_bus_configure_settings(struct pci_bus *bus);
679 679
680enum pcie_bus_config_types { 680enum pcie_bus_config_types {
681 PCIE_BUS_TUNE_OFF, 681 PCIE_BUS_TUNE_OFF,