diff options
author | Alexandre Bounine <alexandre.bounine@idt.com> | 2010-10-27 18:34:34 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-27 21:03:16 -0400 |
commit | af84ca38aff94061dd0711edbb99b0900a9c28fd (patch) | |
tree | 31f51e9106c0a0944ec168dc25399f12ab2fa527 /drivers/rapidio/rio.c | |
parent | a3725c45c114bd06e091802f90533332d1e93819 (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.c | 16 |
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 | */ |
446 | static struct rio_dev *rio_get_comptag(u32 comp_tag, struct rio_dev *from) | 446 | struct 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 | |||
507 | rio_chk_dev_route(struct rio_dev *rdev, struct rio_dev **nrdev, int *npnum) | 507 | rio_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)); |
539 | err_out: | 537 | err_out: |
540 | return rc; | 538 | return rc; |
541 | } | 539 | } |