aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rapidio/rio.c
diff options
context:
space:
mode:
authorAlexandre Bounine <alexandre.bounine@idt.com>2010-10-27 18:34:34 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-10-27 21:03:16 -0400
commitaf84ca38aff94061dd0711edbb99b0900a9c28fd (patch)
tree31f51e9106c0a0944ec168dc25399f12ab2fa527 /drivers/rapidio/rio.c
parenta3725c45c114bd06e091802f90533332d1e93819 (diff)
rapidio: add handling of redundant routes
Detects RIO link to the already enumerated device and properly sets links between device objects. Changes to the enumeration/discovery logic: 1. Use Master Enable bit to signal end of the enumeration - agents may start their discovery process as soon as they see this bit set (Component Tag register was used before for this purpose). 2. Enumerator sets Component Tag (!= 0) immediately during device setup. This allows to identify the device if the redundant route exists in a RIO system. Signed-off-by: Alexandre Bounine <alexandre.bounine@idt.com> Cc: 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> Cc: Micha Nelissen <micha@neli.hopto.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/rapidio/rio.c')
-rw-r--r--drivers/rapidio/rio.c16
1 files changed, 7 insertions, 9 deletions
diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c
index fa5e3cbe4c83..7f18a65c4ed0 100644
--- a/drivers/rapidio/rio.c
+++ b/drivers/rapidio/rio.c
@@ -443,7 +443,7 @@ rio_mport_get_physefb(struct rio_mport *port, int local,
443 * @from is not %NULL, searches continue from next device on the global 443 * @from is not %NULL, searches continue from next device on the global
444 * list. 444 * list.
445 */ 445 */
446static struct rio_dev *rio_get_comptag(u32 comp_tag, struct rio_dev *from) 446struct rio_dev *rio_get_comptag(u32 comp_tag, struct rio_dev *from)
447{ 447{
448 struct list_head *n; 448 struct list_head *n;
449 struct rio_dev *rdev; 449 struct rio_dev *rdev;
@@ -507,7 +507,7 @@ static int
507rio_chk_dev_route(struct rio_dev *rdev, struct rio_dev **nrdev, int *npnum) 507rio_chk_dev_route(struct rio_dev *rdev, struct rio_dev **nrdev, int *npnum)
508{ 508{
509 u32 result; 509 u32 result;
510 int p_port, rc = -EIO; 510 int p_port, dstid, rc = -EIO;
511 struct rio_dev *prev = NULL; 511 struct rio_dev *prev = NULL;
512 512
513 /* Find switch with failed RIO link */ 513 /* Find switch with failed RIO link */
@@ -522,20 +522,18 @@ rio_chk_dev_route(struct rio_dev *rdev, struct rio_dev **nrdev, int *npnum)
522 if (prev == NULL) 522 if (prev == NULL)
523 goto err_out; 523 goto err_out;
524 524
525 /* Find port with failed RIO link */ 525 dstid = (rdev->pef & RIO_PEF_SWITCH) ?
526 for (p_port = 0; 526 rdev->rswitch->destid : rdev->destid;
527 p_port < RIO_GET_TOTAL_PORTS(prev->swpinfo); p_port++) 527 p_port = prev->rswitch->route_table[dstid];
528 if (prev->rswitch->nextdev[p_port] == rdev)
529 break;
530 528
531 if (p_port < RIO_GET_TOTAL_PORTS(prev->swpinfo)) { 529 if (p_port != RIO_INVALID_ROUTE) {
532 pr_debug("RIO: link failed on [%s]-P%d\n", 530 pr_debug("RIO: link failed on [%s]-P%d\n",
533 rio_name(prev), p_port); 531 rio_name(prev), p_port);
534 *nrdev = prev; 532 *nrdev = prev;
535 *npnum = p_port; 533 *npnum = p_port;
536 rc = 0; 534 rc = 0;
537 } else 535 } else
538 pr_debug("RIO: failed to trace route to %s\n", rio_name(prev)); 536 pr_debug("RIO: failed to trace route to %s\n", rio_name(rdev));
539err_out: 537err_out:
540 return rc; 538 return rc;
541} 539}