linux-pci.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Yao Hongbo <yaohongbo@linux.alibaba.com>
To: bhelgaas@google.com, lukas@wunner.de
Cc: yaohongbo@linux.alibaba.com, zhangliguang@linux.alibaba.com,
	alikernel-developer@linux.alibaba.com, linux-pci@vger.kernel.org,
	linux-kernel@vger.kernel.org
Subject: [RFC PATCH v2] PCI: Waiting command completed in get_port_device_capability()
Date: Fri,  7 Jan 2022 11:22:49 +0800	[thread overview]
Message-ID: <1641525769-113099-1-git-send-email-yaohongbo@linux.alibaba.com> (raw)

According to the PCIe specification Revision 5.0, section
7.5.3.11 (slot Status Register), if Command Complete notification
is supported,  a write to the slot control register needs to set
the command completed bit, which can indicate the controller is
ready to receive the next command.

However, before probing the pcie hotplug service, there needs to set
HPIE bit in the slot ctrl register to disable hotplug interrupts,
and there is no wait currently.

The interval between the two functions get_port_device_capability() and
pcie_disable_notification() is not long, which may cause the latter to
be interfered by the former.

The command complete event received by pcie_disable_notification() may
belong to the operation of get_port_device_capability().

Signed-off-by: Liguang Zhang <zhangliguang@linux.alibaba.com>
Signed-off-by: Yao Hongbo <yaohongbo@linux.alibaba.com>
---
 drivers/pci/pcie/portdrv_core.c | 40 ++++++++++++++++++++++++++++++++++++++--
 1 file changed, 38 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c
index bda6308..ec2088b6e 100644
--- a/drivers/pci/pcie/portdrv_core.c
+++ b/drivers/pci/pcie/portdrv_core.c
@@ -15,6 +15,7 @@
 #include <linux/string.h>
 #include <linux/slab.h>
 #include <linux/aer.h>
+#include <linux/delay.h>
 
 #include "../pci.h"
 #include "portdrv.h"
@@ -190,6 +191,42 @@ static int pcie_init_service_irqs(struct pci_dev *dev, int *irqs, int mask)
 	return 0;
 }
 
+static void pcie_port_disable_hp_interrupt(struct pci_dev *dev)
+{
+	u16 slot_status;
+	u32 slot_cap;
+	int timeout = 1000;
+
+	pcie_capability_clear_word(dev, PCI_EXP_SLTCTL,
+			PCI_EXP_SLTCTL_CCIE | PCI_EXP_SLTCTL_HPIE);
+
+	/*
+	 * If the command completed notification is not supported,
+	 * we don't need to wait after writing to the slot ctrl register.
+	 */
+	pcie_capability_read_dword(dev, PCI_EXP_SLTCAP, &slot_cap);
+	if (slot_cap & PCI_EXP_SLTCAP_NCCS)
+		return;
+
+	do {
+		pcie_capability_read_word(dev, PCI_EXP_SLTSTA, &slot_status);
+		if (slot_status == (u16) ~0) {
+			pci_info(dev, "%s: no response from device\n",  __func__);
+			return;
+		}
+
+		if (slot_status & PCI_EXP_SLTSTA_CC) {
+			pcie_capability_write_word(dev, PCI_EXP_SLTSTA, PCI_EXP_SLTSTA_CC);
+			return;
+		}
+
+		msleep(10);
+		timeout -= 10;
+	} while (timeout >= 0);
+
+	pci_info(dev, "Timeout on hotplug disable interrupt!\n");
+}
+
 /**
  * get_port_device_capability - discover capabilities of a PCI Express port
  * @dev: PCI Express port to examine
@@ -213,8 +250,7 @@ static int get_port_device_capability(struct pci_dev *dev)
 		 * Disable hot-plug interrupts in case they have been enabled
 		 * by the BIOS and the hot-plug service driver is not loaded.
 		 */
-		pcie_capability_clear_word(dev, PCI_EXP_SLTCTL,
-			  PCI_EXP_SLTCTL_CCIE | PCI_EXP_SLTCTL_HPIE);
+		pcie_port_disable_hp_interrupt(dev);
 	}
 
 #ifdef CONFIG_PCIEAER
-- 
1.8.3.1


             reply	other threads:[~2022-01-07  3:23 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-01-07  3:22 Yao Hongbo [this message]
2022-01-11 18:55 ` [RFC PATCH v2] PCI: Waiting command completed in get_port_device_capability() Bjorn Helgaas
2022-01-11 21:55   ` Lukas Wunner
2022-01-12  7:33   ` Yao Hongbo
2022-01-12 18:01     ` Bjorn Helgaas
2022-01-13  7:34       ` Yao Hongbo
2022-01-13 14:58         ` Bjorn Helgaas

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1641525769-113099-1-git-send-email-yaohongbo@linux.alibaba.com \
    --to=yaohongbo@linux.alibaba.com \
    --cc=alikernel-developer@linux.alibaba.com \
    --cc=bhelgaas@google.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=lukas@wunner.de \
    --cc=zhangliguang@linux.alibaba.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).