lkml.org 
[lkml]   [2012]   [Apr]   [16]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH] PCI: Retry BARs restoration for Type 0 headers only
Date
From: Rafael J. Wysocki <rjw@sisk.pl>

Some shortcomings introduced into pci_restore_state() by commit
26f41062f28d ("PCI: check for pci bar restore completion and
retry") have been fixed by recent commit ebfc5b802fa76 ("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 26f41062f28d for all header types except for Type 0.

Tested-by: Mikko Vinni <mmvinni@yahoo.com>
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
---
drivers/pci/pci.c | 18 +++++++++++-------
1 file changed, 11 insertions(+), 7 deletions(-)

Index: linux/drivers/pci/pci.c
===================================================================
--- linux.orig/drivers/pci/pci.c
+++ linux/drivers/pci/pci.c
@@ -1015,13 +1015,17 @@ void pci_restore_state(struct pci_dev *d
pci_restore_pcie_state(dev);
pci_restore_ats_state(dev);

- pci_restore_config_space(dev, 10, 15, 0);
- /*
- * The Base Address register should be programmed before the command
- * register(s)
- */
- pci_restore_config_space(dev, 4, 9, 10);
- pci_restore_config_space(dev, 0, 3, 0);
+ if (dev->hdr_type == PCI_HEADER_TYPE_NORMAL) {
+ pci_restore_config_space(dev, 10, 15, 0);
+ /*
+ * The Base Address register should be programmed before the
+ * command register(s)
+ */
+ pci_restore_config_space(dev, 4, 9, 10);
+ pci_restore_config_space(dev, 0, 3, 0);
+ } else {
+ pci_restore_config_space(dev, 0, 15, 0);
+ }

pci_restore_pcix_state(dev);
pci_restore_msi_state(dev);

\
 
 \ /
  Last update: 2012-04-16 22:39    [W:0.088 / U:0.788 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site