diff options
author | Alexandre Bounine <alexandre.bounine@idt.com> | 2010-10-27 15:34:34 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-27 18:03:16 -0700 |
commit | af84ca38aff94061dd0711edbb99b0900a9c28fd (patch) | |
tree | 31f51e9106c0a0944ec168dc25399f12ab2fa527 /drivers/rapidio/rio.c | |
parent | a3725c45c114bd06e091802f90533332d1e93819 (diff) | |
download | lwn-af84ca38aff94061dd0711edbb99b0900a9c28fd.tar.gz lwn-af84ca38aff94061dd0711edbb99b0900a9c28fd.zip |
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, * @from is not %NULL, searches continue from next device on the global * list. */ -static struct rio_dev *rio_get_comptag(u32 comp_tag, struct rio_dev *from) +struct rio_dev *rio_get_comptag(u32 comp_tag, struct rio_dev *from) { struct list_head *n; struct rio_dev *rdev; @@ -507,7 +507,7 @@ static int rio_chk_dev_route(struct rio_dev *rdev, struct rio_dev **nrdev, int *npnum) { u32 result; - int p_port, rc = -EIO; + int p_port, dstid, rc = -EIO; struct rio_dev *prev = NULL; /* Find switch with failed RIO link */ @@ -522,20 +522,18 @@ rio_chk_dev_route(struct rio_dev *rdev, struct rio_dev **nrdev, int *npnum) if (prev == NULL) goto err_out; - /* Find port with failed RIO link */ - for (p_port = 0; - p_port < RIO_GET_TOTAL_PORTS(prev->swpinfo); p_port++) - if (prev->rswitch->nextdev[p_port] == rdev) - break; + dstid = (rdev->pef & RIO_PEF_SWITCH) ? + rdev->rswitch->destid : rdev->destid; + p_port = prev->rswitch->route_table[dstid]; - if (p_port < RIO_GET_TOTAL_PORTS(prev->swpinfo)) { + if (p_port != RIO_INVALID_ROUTE) { 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)); + pr_debug("RIO: failed to trace route to %s\n", rio_name(rdev)); err_out: return rc; } |