[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <201204162235.49901.rjw@sisk.pl>
Date: Mon, 16 Apr 2012 22:35:49 +0200
From: "Rafael J. Wysocki" <rjw@...k.pl>
To: Bjorn Helgaas <bhelgaas@...gle.com>
Cc: Mikko Vinni <mmvinni@...oo.com>,
"linux-input@...r.kernel.org" <linux-input@...r.kernel.org>,
"linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>,
Dmitry Torokhov <dmitry.torokhov@...il.com>,
Allen Kay <allen.m.kay@...el.com>,
Jesse Barnes <jbarnes@...tuousgeek.org>,
"linux-pci@...r.kernel.org" <linux-pci@...r.kernel.org>,
Linus Torvalds <torvalds@...ux-foundation.org>
Subject: [PATCH] PCI: Retry BARs restoration for Type 0 headers only
From: Rafael J. Wysocki <rjw@...k.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@...oo.com>
Signed-off-by: Rafael J. Wysocki <rjw@...k.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);
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists