From: Alexandre Bounine <alexandre.bounine@idt.com>
To: akpm@linux-foundation.org, linux-kernel@vger.kernel.org,
linuxppc-dev@ozlabs.org
Cc: Alexandre Bounine <alexandre.bounine@idt.com>
Subject: [PATCH 7/9] RapidIO: Add handling for PW message from a lost device
Date: Fri, 13 Aug 2010 11:18:04 -0400 [thread overview]
Message-ID: <1281712686-31308-8-git-send-email-alexandre.bounine@idt.com> (raw)
In-Reply-To: <1281712686-31308-1-git-send-email-alexandre.bounine@idt.com>
Add check if PW message source device is accessible and change PW message
handler to recover if PW message source device is not available anymore (power
down or link disconnect).
To avoid possible loss of notification, the PW message handler scans the route
back from the source device to identify end of the broken link.
Signed-off-by: Alexandre Bounine <alexandre.bounine@idt.com>
Reviewed-by: Thomas Moll <thomas.moll@sysgo.com>
Cc: Matt Porter <mporter@kernel.crashing.org>
Cc: Li Yang <leoli@freescale.com>
Cc: Kumar Gala <galak@kernel.crashing.org>
---
drivers/rapidio/rio.c | 111 ++++++++++++++++++++++++++++++++++++++++++++++--
drivers/rapidio/rio.h | 2 +
2 files changed, 108 insertions(+), 5 deletions(-)
diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c
index f58df11..22f7847 100644
--- a/drivers/rapidio/rio.c
+++ b/drivers/rapidio/rio.c
@@ -495,6 +495,90 @@ int rio_set_port_lockout(struct rio_dev *rdev, u32 pnum, int lock)
}
/**
+ * rio_chk_dev_route - Validate route to the specified device.
+ * @rdev: Pointer to RIO device control structure
+ * @nrdev: Pointer to last active device on the route to rdev
+ * @npnum: nrdev port number on the route to rdev
+ *
+ * Follows a route to the specified RIO device to determine the last available
+ * device (and corresponding RIO port) on the route.
+ */
+static int
+rio_chk_dev_route(struct rio_dev *rdev, struct rio_dev **nrdev, int *npnum)
+{
+ u32 result;
+ int p_port, rc = -EIO;
+ struct rio_dev *prev = NULL;
+
+ while (rdev->prev && (rdev->prev->pef & RIO_PEF_SWITCH)) {
+ if (rio_read_config_32(rdev->prev, RIO_DEV_ID_CAR, &result)) {
+ rdev = rdev->prev;
+ continue;
+ }
+
+ prev = rdev->prev;
+ for (p_port = 0; p_port < prev->rswitch->nports; p_port++)
+ if (prev->rswitch->nextdev[p_port] == rdev)
+ break;
+
+ if (p_port < prev->rswitch->nports) {
+ pr_debug("RIO: link failed on [%s]-P%d\n",
+ rio_name(prev), p_port);
+ *nrdev = prev;
+ *npnum = p_port;
+ rc = 0;
+ } else {
+ pr_debug("RIO: failed to trace route to %s\n",
+ rio_name(prev));
+ }
+
+ break;
+ }
+
+ return rc;
+}
+
+/**
+ * rio_mport_chk_dev_access - Validate access to the specified device.
+ * @mport: Master port to send transactions
+ * @destid: Device destination ID in network
+ * @hopcount: Number of hops into the network
+ */
+static int
+rio_mport_chk_dev_access(struct rio_mport *mport, u16 destid, u8 hopcount)
+{
+ int i = 0;
+ u32 tmp;
+
+ while (rio_mport_read_config_32(mport, destid, hopcount,
+ RIO_DEV_ID_CAR, &tmp)) {
+ i++;
+ if (i == RIO_MAX_CHK_RETRY)
+ return -EIO;
+ mdelay(1);
+ }
+
+ return 0;
+}
+
+/**
+ * rio_chk_dev_access - Validate access to the specified device.
+ * @rdev: Pointer to RIO device control structure
+ */
+static int rio_chk_dev_access(struct rio_dev *rdev)
+{
+ u8 hopcount = 0xff;
+ u16 destid = rdev->destid;
+
+ if (rdev->rswitch) {
+ destid = rdev->rswitch->destid;
+ hopcount = rdev->rswitch->hopcount;
+ }
+
+ return rio_mport_chk_dev_access(rdev->net->hport, destid, hopcount);
+}
+
+/**
* rio_clr_err_stopped - Clears port Error-stopped states.
* @rdev: Pointer to RIO device control structure
* @pnum: Switch port number to clear errors
@@ -627,8 +711,8 @@ int rio_inb_pwrite_handler(union rio_pw_msg *pw_msg)
rdev = rio_get_comptag(pw_msg->em.comptag, NULL);
if (rdev == NULL) {
- /* Someting bad here (probably enumeration error) */
- pr_err("RIO: %s No matching device for CTag 0x%08x\n",
+ /* Device removed or enumeration error */
+ pr_debug("RIO: %s No matching device for CTag 0x%08x\n",
__func__, pw_msg->em.comptag);
return -EIO;
}
@@ -659,6 +743,26 @@ int rio_inb_pwrite_handler(union rio_pw_msg *pw_msg)
return 0;
}
+ portnum = pw_msg->em.is_port & 0xFF;
+
+ /* Check if device and route to it are functional:
+ * Sometimes devices may send PW message(s) just before being
+ * powered down (or link being lost).
+ */
+ if (rio_chk_dev_access(rdev)) {
+ pr_debug("RIO: device access failed - get link partner\n");
+ /* Scan route to the device and identify failed link.
+ * This will replace device and port reported in PW message.
+ * PW message should not be used after this point.
+ */
+ if (rio_chk_dev_route(rdev, &rdev, &portnum)) {
+ pr_err("RIO: Route trace for %s failed\n",
+ rio_name(rdev));
+ return -EIO;
+ }
+ pw_msg = NULL;
+ }
+
/* For End-point devices processing stops here */
if (!(rdev->pef & RIO_PEF_SWITCH))
return 0;
@@ -676,9 +780,6 @@ int rio_inb_pwrite_handler(union rio_pw_msg *pw_msg)
/*
* Process the port-write notification from switch
*/
-
- portnum = pw_msg->em.is_port & 0xFF;
-
if (rdev->rswitch->em_handle)
rdev->rswitch->em_handle(rdev, portnum);
diff --git a/drivers/rapidio/rio.h b/drivers/rapidio/rio.h
index f27b7a9..bc71ba1 100644
--- a/drivers/rapidio/rio.h
+++ b/drivers/rapidio/rio.h
@@ -14,6 +14,8 @@
#include <linux/list.h>
#include <linux/rio.h>
+#define RIO_MAX_CHK_RETRY 3
+
/* Functions internal to the RIO core code */
extern u32 rio_mport_get_feature(struct rio_mport *mport, int local, u16 destid,
--
1.7.0.5
next prev parent reply other threads:[~2010-08-13 15:20 UTC|newest]
Thread overview: 36+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-08-13 15:17 [PATCH 0/9] RapidIO: Set of patches to add Gen2 switches Alexandre Bounine
2010-08-13 15:17 ` [PATCH 1/9] RapidIO: fix RapidIO sysfs hierarchy Alexandre Bounine
2010-08-13 15:17 ` [PATCH 2/9] RapidIO, powerpc/85xx: modify RIO port-write interrupt handler Alexandre Bounine
2010-08-16 12:12 ` Micha Nelissen
2010-08-16 15:27 ` Bounine, Alexandre
2010-08-17 7:12 ` Micha Nelissen
2010-08-17 17:16 ` Bounine, Alexandre
2010-08-13 15:18 ` [PATCH 3/9] RapidIO: Add the ingress port number into the RIO switch data structure Alexandre Bounine
2010-08-16 12:14 ` Micha Nelissen
2010-08-16 13:40 ` Bounine, Alexandre
2010-08-13 15:18 ` [PATCH 4/9] RapidIO: Add relation links between RIO device structures Alexandre Bounine
2010-08-16 12:18 ` Micha Nelissen
2010-08-16 14:00 ` Bounine, Alexandre
2010-08-17 7:08 ` Micha Nelissen
2010-08-17 17:47 ` Bounine, Alexandre
2010-08-13 15:18 ` [PATCH 5/9] RapidIO: Add default handler for error_stopped state Alexandre Bounine
2010-08-16 12:21 ` Micha Nelissen
2010-08-16 14:47 ` Bounine, Alexandre
2010-08-13 15:18 ` [PATCH 6/9] RapidIO: Add switch-specific sysfs initialization callback Alexandre Bounine
2010-08-16 12:25 ` Micha Nelissen
2010-08-16 17:10 ` Bounine, Alexandre
2010-08-17 7:18 ` Micha Nelissen
2010-08-17 17:20 ` Bounine, Alexandre
2010-08-13 15:18 ` Alexandre Bounine [this message]
2010-08-16 12:29 ` [PATCH 7/9] RapidIO: Add handling for PW message from a lost device Micha Nelissen
2010-08-16 18:02 ` Bounine, Alexandre
2010-08-17 7:22 ` Micha Nelissen
2010-08-17 12:44 ` Bounine, Alexandre
2010-08-13 15:18 ` [PATCH 8/9] RapidIO: Add device access check into the enumeration Alexandre Bounine
2010-08-13 15:18 ` [PATCH 9/9] RapidIO: Add support for IDT CPS Gen2 switches Alexandre Bounine
2010-08-16 12:36 ` Micha Nelissen
2010-08-16 18:30 ` Bounine, Alexandre
2010-08-16 12:30 ` [PATCH 0/9] RapidIO: Set of patches to add " Micha Nelissen
2010-08-16 18:18 ` Bounine, Alexandre
2010-08-17 7:31 ` Micha Nelissen
2010-08-17 18:13 ` Bounine, Alexandre
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=1281712686-31308-8-git-send-email-alexandre.bounine@idt.com \
--to=alexandre.bounine@idt.com \
--cc=akpm@linux-foundation.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linuxppc-dev@ozlabs.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox