Skip to contentSkip to conversation

pci: Fix unaligned access testing AF transaction pending

PATCH In review Alex Williamson 3 participants 3 messages Jun 12, 2014 – Jun 17, 2014 PCI

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 pci: Fix unaligned access testing AF transaction pending

pci_wait_for_pending() uses word access, so we shouldn't be passing an offset that is only byte aligned. Use the control register offset instead, shifting the mask to match.

---
 drivers/pci/pci.c |    9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)
drivers/pci/pci.c +7 -2
index 759475e..81012ec 100644
@@ -3109,8 +3109,13 @@ static int pci_af_flr(struct pci_dev *dev, int probe)
 	if (probe)
 		return 0;
 
-	/* Wait for Transaction Pending bit clean */
-	if (pci_wait_for_pending(dev, pos + PCI_AF_STATUS, PCI_AF_STATUS_TP))
+	/*
+	 * Wait for Transaction Pending bit to clear.  A word-aligned test
+	 * is used, so we use the conrol offset rather than status and shift
+	 * the test bit to match.
+	 */
+	if (pci_wait_for_pending(dev, pos + PCI_AF_CTRL,
+				 PCI_AF_STATUS_TP << 8))
 		goto clear;
 
 	dev_err(&dev->dev, "transaction is not cleared; "
Acked-by on v1 1/1
#1 lore raw
Quoted 7 lines · Alex Williamson

pci_wait_for_pending() uses word access, so we shouldn't be passing an offset that is only byte aligned. Use the control register offset instead, shifting the mask to match.

Quoted 15 lines

---
drivers/pci/pci.c | 9 +++++++--

1 file changed, 7 insertions(+), 2 deletions(-)
drivers/pci/pci.c +0 -2
index 759475e..81012ec 100644
@@ -3109,8 +3109,13 @@ static int pci_af_flr(struct pci_dev *dev, int probe)
 	if (probe)
 		return 0;
 
-	/* Wait for Transaction Pending bit clean */
-	if (pci_wait_for_pending(dev, pos + PCI_AF_STATUS, PCI_AF_STATUS_TP))

drivers/pci/pci.c static int pci_af_flr(struct pci_dev *dev, int probe) · line 3121

Quoted 10 lines
drivers/pci/pci.c +7 -0
+	/*
+	 * Wait for Transaction Pending bit to clear.  A word-aligned test
+	 * is used, so we use the conrol offset rather than status and shift
+	 * the test bit to match.
+	 */
+	if (pci_wait_for_pending(dev, pos + PCI_AF_CTRL,
+				 PCI_AF_STATUS_TP << 8))
 		goto clear;
 
 	dev_err(&dev->dev, "transaction is not cleared; "

Thanks,
Gavin

maintainer
#2 lore raw
In reply to Alex Williamson
Quoted 7 lines · Alex Williamson

pci_wait_for_pending() uses word access, so we shouldn't be passing an offset that is only byte aligned. Use the control register offset instead, shifting the mask to match.

Applied with Gavin's ack to for-linus for v3.16, thanks!

Quoted 25 lines
---
 drivers/pci/pci.c |    9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)
drivers/pci/pci.c +7 -2
index 759475e..81012ec 100644
@@ -3109,8 +3109,13 @@ static int pci_af_flr(struct pci_dev *dev, int probe)
 	if (probe)
 		return 0;
 
-	/* Wait for Transaction Pending bit clean */
-	if (pci_wait_for_pending(dev, pos + PCI_AF_STATUS, PCI_AF_STATUS_TP))
+	/*
+	 * Wait for Transaction Pending bit to clear.  A word-aligned test
+	 * is used, so we use the conrol offset rather than status and shift
+	 * the test bit to match.
+	 */
+	if (pci_wait_for_pending(dev, pos + PCI_AF_CTRL,
+				 PCI_AF_STATUS_TP << 8))
 		goto clear;
 
 	dev_err(&dev->dev, "transaction is not cleared; "