PCI: read-modify-write the pcie device control register when initiating pcie flr
authorShmulik Ravid <shmulikr@broadcom.com>
Thu, 3 Dec 2009 20:27:51 +0000 (22:27 +0200)
committerJesse Barnes <jbarnes@virtuousgeek.org>
Fri, 4 Dec 2009 23:49:44 +0000 (15:49 -0800)
The pcie_flr routine writes the device control register with the FLR bit
set clearing all other fields for the FLR duration. Among other fields,
the Max_Payload_Size is also cleared which can cause errors if there are
transactions lurking in the HW pipeline. The patch replaces the blank
write with read-modify-write of the control register keeping the other
fields intact.

Signed-off-by: Shmulik Ravid <shmulikr@broadcom.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
drivers/pci/pci.c

index be91a09..6af212c 100644 (file)
@@ -2140,7 +2140,7 @@ static int pcie_flr(struct pci_dev *dev, int probe)
        int i;
        int pos;
        u32 cap;
-       u16 status;
+       u16 status, control;
 
        pos = pci_pcie_cap(dev);
        if (!pos)
@@ -2167,8 +2167,10 @@ static int pcie_flr(struct pci_dev *dev, int probe)
                        "proceeding with reset anyway\n");
 
 clear:
-       pci_write_config_word(dev, pos + PCI_EXP_DEVCTL,
-                               PCI_EXP_DEVCTL_BCR_FLR);
+       pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &control);
+       control |= PCI_EXP_DEVCTL_BCR_FLR;
+       pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, control);
+
        msleep(100);
 
        return 0;