From: Yinghai Lu <yinghai.lu@oracle.com>
To: Jesse Barnes <jbarnes@virtuousgeek.org>
Cc: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
"linux-pci@vger.kernel.org" <linux-pci@vger.kernel.org>
Subject: [RFC PATCH] pciehp: Wait for link get trained in pci_check_link_status()
Date: Mon, 07 Nov 2011 17:13:28 -0800 [thread overview]
Message-ID: <4EB88238.4050409@oracle.com> (raw)
Found one PCI Express Modules has link training error after hotplug.
It turns out that after DLLLA is set, LT is still set for a while.
So pciehp will delcare that hotplug fail in 1s.
HW guys say that pciehp is against PCI-e SPEC:
From PCI Express Base Specification Revision 2.1, Section 6.7.3.3:
Software must allow 1 second after the Data Link Layer Link Active bit reads 1b
before it is permitted to determine that a hot plugged device which fails to
return a Successful Completion for a Valid Configuration Request is a broken
device (see section 6.6).
Try to wait for long enough by adding LT checking in 1s.
Signed-off-by: Yinghai Lu <yinghai.lu@oracle.com>
---
drivers/pci/hotplug/pciehp_hpc.c | 52 +++++++++++++++++++++++++++------------
1 file changed, 37 insertions(+), 15 deletions(-)
Index: linux-2.6/drivers/pci/hotplug/pciehp_hpc.c
===================================================================
--- linux-2.6.orig/drivers/pci/hotplug/pciehp_hpc.c
+++ linux-2.6/drivers/pci/hotplug/pciehp_hpc.c
@@ -241,28 +241,49 @@ static int pcie_write_cmd(struct control
return retval;
}
-static inline int check_link_active(struct controller *ctrl)
+static inline bool
+check_link_status_bits(struct controller *ctrl, u16 mask, u16 val)
{
u16 link_status;
if (pciehp_readw(ctrl, PCI_EXP_LNKSTA, &link_status))
- return 0;
- return !!(link_status & PCI_EXP_LNKSTA_DLLLA);
+ return false;
+
+ if ((link_status & mask) == val)
+ return true;
+
+ return false;
}
-static void pcie_wait_link_active(struct controller *ctrl)
+static bool
+pcie_wait_link_status_bits(struct controller *ctrl, u16 mask, u16 val)
{
int timeout = 1000;
- if (check_link_active(ctrl))
- return;
+ if (check_link_status_bits(ctrl, mask, val))
+ return true;
while (timeout > 0) {
- msleep(10);
- timeout -= 10;
- if (check_link_active(ctrl))
- return;
+ msleep(20);
+ timeout -= 20;
+ if (check_link_status_bits(ctrl, mask, val))
+ return true;
}
- ctrl_dbg(ctrl, "Data Link Layer Link Active not set in 1000 msec\n");
+
+ return false;
+}
+
+static void pcie_wait_link_active(struct controller *ctrl)
+{
+ if (!pcie_wait_link_status_bits(ctrl, PCI_EXP_LNKSTA_DLLLA,
+ PCI_EXP_LNKSTA_DLLLA))
+ ctrl_dbg(ctrl,
+ "Data Link Layer Link Active not set in 1000 msec\n");
+}
+
+static void pcie_wait_link_training_done(struct controller *ctrl)
+{
+ if (!pcie_wait_link_status_bits(ctrl, PCI_EXP_LNKSTA_LT, 0))
+ ctrl_dbg(ctrl, "Link Training is not done in 1000 msec\n");
}
int pciehp_check_link_status(struct controller *ctrl)
@@ -275,10 +296,11 @@ int pciehp_check_link_status(struct cont
* hot-plug capable downstream port. But old controller might
* not implement it. In this case, we wait for 1000 ms.
*/
- if (ctrl->link_active_reporting)
- pcie_wait_link_active(ctrl);
- else
- msleep(1000);
+ if (ctrl->link_active_reporting) {
+ pcie_wait_link_active(ctrl);
+ pcie_wait_link_training_done(ctrl);
+ } else
+ msleep(1000);
retval = pciehp_readw(ctrl, PCI_EXP_LNKSTA, &lnk_status);
if (retval) {
next reply other threads:[~2011-11-08 1:13 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-11-08 1:13 Yinghai Lu [this message]
2011-11-08 9:19 ` [RFC PATCH] pciehp: Wait for link get trained in pci_check_link_status() Kenji Kaneshige
2011-11-08 15:27 ` Yinghai Lu
2011-11-08 21:54 ` Yinghai Lu
2011-11-10 7:39 ` Kenji Kaneshige
2011-11-10 7:40 ` [PATCH 1/2] pciehp: wait 1000 ms before Link Training check Kenji Kaneshige
2011-11-10 19:10 ` Yinghai Lu
2011-11-10 7:42 ` [PATCH 2/2] pciehp: wait 100 ms after " Kenji Kaneshige
2011-11-10 19:10 ` Yinghai Lu
2011-11-11 17:32 ` Jesse Barnes
2011-11-11 17:33 ` Yinghai Lu
2011-11-11 17:40 ` Greg KH
[not found] ` <4ECDA602.9060103@oracle.com>
2011-11-27 3:25 ` pciehp for stable Greg KH
2011-12-02 23:21 ` Greg KH
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=4EB88238.4050409@oracle.com \
--to=yinghai.lu@oracle.com \
--cc=jbarnes@virtuousgeek.org \
--cc=kaneshige.kenji@jp.fujitsu.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.