Skip to content

Commit a6cb9ee

Browse files
rjwysockitorvalds
authored andcommitted
PCI: Retry BARs restoration for Type 0 headers only
Some shortcomings introduced into pci_restore_state() by commit 26f4106 ("PCI: check for pci bar restore completion and retry") have been fixed by recent commit ebfc5b8 ("PCI: Fix regression in pci_restore_state(), v3"), but that commit treats all PCI devices as those with Type 0 configuration headers. That is not entirely correct, because Type 1 and Type 2 headers have different layouts. In particular, the area occupied by BARs in Type 0 config headers contains the secondary status register in Type 1 ones and it doesn't make sense to retry the restoration of that register even if the value read back from it after a write is not the same as the written one (it very well may be different). For this reason, make pci_restore_state() only retry the restoration of BARs for Type 0 config headers. This effectively makes it behave as before commit 26f4106 for all header types except for Type 0. Tested-by: Mikko Vinni <[email protected]> Signed-off-by: Rafael J. Wysocki <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent 5191d56 commit a6cb9ee

File tree

1 file changed

+15
-9
lines changed

1 file changed

+15
-9
lines changed

drivers/pci/pci.c

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -991,8 +991,8 @@ static void pci_restore_config_dword(struct pci_dev *pdev, int offset,
991991
}
992992
}
993993

994-
static void pci_restore_config_space(struct pci_dev *pdev, int start, int end,
995-
int retry)
994+
static void pci_restore_config_space_range(struct pci_dev *pdev,
995+
int start, int end, int retry)
996996
{
997997
int index;
998998

@@ -1002,6 +1002,18 @@ static void pci_restore_config_space(struct pci_dev *pdev, int start, int end,
10021002
retry);
10031003
}
10041004

1005+
static void pci_restore_config_space(struct pci_dev *pdev)
1006+
{
1007+
if (pdev->hdr_type == PCI_HEADER_TYPE_NORMAL) {
1008+
pci_restore_config_space_range(pdev, 10, 15, 0);
1009+
/* Restore BARs before the command register. */
1010+
pci_restore_config_space_range(pdev, 4, 9, 10);
1011+
pci_restore_config_space_range(pdev, 0, 3, 0);
1012+
} else {
1013+
pci_restore_config_space_range(pdev, 0, 15, 0);
1014+
}
1015+
}
1016+
10051017
/**
10061018
* pci_restore_state - Restore the saved state of a PCI device
10071019
* @dev: - PCI device that we're dealing with
@@ -1015,13 +1027,7 @@ void pci_restore_state(struct pci_dev *dev)
10151027
pci_restore_pcie_state(dev);
10161028
pci_restore_ats_state(dev);
10171029

1018-
pci_restore_config_space(dev, 10, 15, 0);
1019-
/*
1020-
* The Base Address register should be programmed before the command
1021-
* register(s)
1022-
*/
1023-
pci_restore_config_space(dev, 4, 9, 10);
1024-
pci_restore_config_space(dev, 0, 3, 0);
1030+
pci_restore_config_space(dev);
10251031

10261032
pci_restore_pcix_state(dev);
10271033
pci_restore_msi_state(dev);

0 commit comments

Comments
 (0)