Skip to content

Commit ef61a04

Browse files
FlyGoatbjorn-helgaas
authored andcommitted
PCI: loongson: Limit MRRS to 256
This is a partial revert of 8b3517f ("PCI: loongson: Prevent LS7A MRRS increases") for MIPS-based Loongson. Some MIPS Loongson systems don't support arbitrary Max_Read_Request_Size (MRRS) settings. 8b3517f ("PCI: loongson: Prevent LS7A MRRS increases") worked around that by (1) assuming that firmware configured MRRS to the maximum supported value and (2) preventing the PCI core from increasing MRRS. Unfortunately, some firmware doesn't set that maximum MRRS correctly, which results in devices not being initialized correctly. One symptom, from the Debian report below, is this: ata4.00: exception Emask 0x0 SAct 0x20000000 SErr 0x0 action 0x6 frozen ata4.00: failed command: WRITE FPDMA QUEUED ata4.00: cmd 61/20:e8:00:f0:e1/00:00:00:00:00/40 tag 29 ncq dma 16384 out res 40/00:00:00:00:00/00:00:00:00:00/00 Emask 0x4 (timeout) ata4.00: status: { DRDY } ata4: hard resetting link Limit MRRS to 256 because MIPS Loongson with higher MRRS support is considered rare. This must be done at device enablement stage because the MRRS setting may get lost if PCI_COMMAND_MASTER on the parent bridge is cleared, and we are only sure parent bridge is enabled at this point. Fixes: 8b3517f ("PCI: loongson: Prevent LS7A MRRS increases") Closes: https://bugzilla.kernel.org/show_bug.cgi?id=217680 Link: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1035587 Link: https://lore.kernel.org/r/20231201115028.84351-1-jiaxun.yang@flygoat.com Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Acked-by: Huacai Chen <chenhuacai@loongson.cn> Cc: stable@vger.kernel.org
1 parent b85ea95 commit ef61a04

1 file changed

Lines changed: 41 additions & 5 deletions

File tree

drivers/pci/controller/pci-loongson.c

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -80,13 +80,49 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON,
8080
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON,
8181
DEV_LS7A_LPC, system_bus_quirk);
8282

83+
/*
84+
* Some Loongson PCIe ports have hardware limitations on their Maximum Read
85+
* Request Size. They can't handle anything larger than this. Sane
86+
* firmware will set proper MRRS at boot, so we only need no_inc_mrrs for
87+
* bridges. However, some MIPS Loongson firmware doesn't set MRRS properly,
88+
* so we have to enforce maximum safe MRRS, which is 256 bytes.
89+
*/
90+
#ifdef CONFIG_MIPS
91+
static void loongson_set_min_mrrs_quirk(struct pci_dev *pdev)
92+
{
93+
struct pci_bus *bus = pdev->bus;
94+
struct pci_dev *bridge;
95+
static const struct pci_device_id bridge_devids[] = {
96+
{ PCI_VDEVICE(LOONGSON, DEV_LS2K_PCIE_PORT0) },
97+
{ PCI_VDEVICE(LOONGSON, DEV_LS7A_PCIE_PORT0) },
98+
{ PCI_VDEVICE(LOONGSON, DEV_LS7A_PCIE_PORT1) },
99+
{ PCI_VDEVICE(LOONGSON, DEV_LS7A_PCIE_PORT2) },
100+
{ PCI_VDEVICE(LOONGSON, DEV_LS7A_PCIE_PORT3) },
101+
{ PCI_VDEVICE(LOONGSON, DEV_LS7A_PCIE_PORT4) },
102+
{ PCI_VDEVICE(LOONGSON, DEV_LS7A_PCIE_PORT5) },
103+
{ PCI_VDEVICE(LOONGSON, DEV_LS7A_PCIE_PORT6) },
104+
{ 0, },
105+
};
106+
107+
/* look for the matching bridge */
108+
while (!pci_is_root_bus(bus)) {
109+
bridge = bus->self;
110+
bus = bus->parent;
111+
112+
if (pci_match_id(bridge_devids, bridge)) {
113+
if (pcie_get_readrq(pdev) > 256) {
114+
pci_info(pdev, "limiting MRRS to 256\n");
115+
pcie_set_readrq(pdev, 256);
116+
}
117+
break;
118+
}
119+
}
120+
}
121+
DECLARE_PCI_FIXUP_ENABLE(PCI_ANY_ID, PCI_ANY_ID, loongson_set_min_mrrs_quirk);
122+
#endif
123+
83124
static void loongson_mrrs_quirk(struct pci_dev *pdev)
84125
{
85-
/*
86-
* Some Loongson PCIe ports have h/w limitations of maximum read
87-
* request size. They can't handle anything larger than this. So
88-
* force this limit on any devices attached under these ports.
89-
*/
90126
struct pci_host_bridge *bridge = pci_find_host_bridge(pdev->bus);
91127

92128
bridge->no_inc_mrrs = 1;

0 commit comments

Comments
 (0)