PCI: Enable CRS Software Visibility for root port if it is supported
Per PCIe r3.0, sec 2.3.2, an endpoint may respond to a Configuration Request with a Completion with Configuration Request Retry Status (CRS). This terminates the Configuration Request. When the CRS Software Visibility feature is disabled (as it is by default), a Root Complex must handle a CRS Completion by re-issuing the Configuration Request. This is invisible to software. From the CPU's point of view, an endpoint that always responds with CRS causes a hang because the Root Complex never supplies data to complete the CPU read. When CRS Software Visibility is enabled, a Root Complex that receives a CRS Completion for a read of the Vendor ID must return data of 0x0001. The Vendor ID of 0x0001 indicates to software that the endpoint is not ready. We now have more devices that require CRS Software Visibility. For example, a PLX 8713 NT bridge may respond with CRS until it has been configured via I2C, and the I2C configuration is completely independent of PCI enumeration. Enable CRS Software Visibility if it is supported. This allows a system with such a device to work (though the PCI core times out waiting for it to become ready, and we have to rescan the bus after it is ready). This essentially revertsad7edfe049
("[PCI] Do not enable CRS Software Visibility by default"). The failures that led toad7edfe049
should be addressed by89665a6a71
("PCI: Check only the Vendor ID to identify Configuration Request Retry"). [bhelgaas: changelog] Link: http://lkml.kernel.org/r/20071029061532.5d10dfc6@snowcone Link: http://lkml.kernel.org/r/alpine.LFD.0.9999.0712271023090.21557@woody.linux-foundation.org Signed-off-by: Rajat Jain <rajatxjain@gmail.com> Signed-off-by: Rajat Jain <rajatjain@juniper.net> Signed-off-by: Guenter Roeck <groeck@juniper.net> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
This commit is contained in:
parent
89665a6a71
commit
f3dbd802b3
|
@ -740,6 +740,17 @@ struct pci_bus *pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev,
|
|||
}
|
||||
EXPORT_SYMBOL(pci_add_new_bus);
|
||||
|
||||
static void pci_enable_crs(struct pci_dev *pdev)
|
||||
{
|
||||
u16 root_cap = 0;
|
||||
|
||||
/* Enable CRS Software Visibility if supported */
|
||||
pcie_capability_read_word(pdev, PCI_EXP_RTCAP, &root_cap);
|
||||
if (root_cap & PCI_EXP_RTCAP_CRSVIS)
|
||||
pcie_capability_set_word(pdev, PCI_EXP_RTCTL,
|
||||
PCI_EXP_RTCTL_CRSSVE);
|
||||
}
|
||||
|
||||
/*
|
||||
* If it's a bridge, configure it and scan the bus behind it.
|
||||
* For CardBus bridges, we don't scan behind as the devices will
|
||||
|
@ -787,6 +798,8 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int pass)
|
|||
pci_write_config_word(dev, PCI_BRIDGE_CONTROL,
|
||||
bctl & ~PCI_BRIDGE_CTL_MASTER_ABORT);
|
||||
|
||||
pci_enable_crs(dev);
|
||||
|
||||
if ((secondary || subordinate) && !pcibios_assign_all_busses() &&
|
||||
!is_cardbus && !broken) {
|
||||
unsigned int cmax;
|
||||
|
|
|
@ -552,6 +552,7 @@
|
|||
#define PCI_EXP_RTCTL_PMEIE 0x0008 /* PME Interrupt Enable */
|
||||
#define PCI_EXP_RTCTL_CRSSVE 0x0010 /* CRS Software Visibility Enable */
|
||||
#define PCI_EXP_RTCAP 30 /* Root Capabilities */
|
||||
#define PCI_EXP_RTCAP_CRSVIS 0x0001 /* CRS Software Visibility capability */
|
||||
#define PCI_EXP_RTSTA 32 /* Root Status */
|
||||
#define PCI_EXP_RTSTA_PME 0x00010000 /* PME status */
|
||||
#define PCI_EXP_RTSTA_PENDING 0x00020000 /* PME pending */
|
||||
|
|
Loading…
Reference in a new issue