aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rapidio
diff options
context:
space:
mode:
authorAlexandre Bounine <alexandre.bounine@idt.com>2010-10-27 18:34:29 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-10-27 21:03:15 -0400
commit68fe4df5d21294401959fa61d5a7094705ed8f6f (patch)
tree28cd3609514f3a7b1e78e627b069aa5669bc7fd0 /drivers/rapidio
parentae05cbd5adef897d405ce8f90484c1239f79e086 (diff)
rapidio: add relation links between RIO device structures
Create back and forward links between RIO devices. These links are intended for use by error management and hot-plug extensions. Links for redundant RIO connections between switches are not set (will be fixed in a separate patch). 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')
-rw-r--r--drivers/rapidio/rio-scan.c56
1 files changed, 23 insertions, 33 deletions
diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c
index d09c359844f3..d2ea01872d6a 100644
--- a/drivers/rapidio/rio-scan.c
+++ b/drivers/rapidio/rio-scan.c
@@ -444,7 +444,10 @@ static struct rio_dev __devinit *rio_setup_device(struct rio_net *net,
444 444
445 /* If a PE has both switch and other functions, show it as a switch */ 445 /* If a PE has both switch and other functions, show it as a switch */
446 if (rio_is_switch(rdev)) { 446 if (rio_is_switch(rdev)) {
447 rswitch = kzalloc(sizeof(struct rio_switch), GFP_KERNEL); 447 rswitch = kzalloc(sizeof(*rswitch) +
448 RIO_GET_TOTAL_PORTS(rdev->swpinfo) *
449 sizeof(rswitch->nextdev[0]),
450 GFP_KERNEL);
448 if (!rswitch) 451 if (!rswitch)
449 goto cleanup; 452 goto cleanup;
450 rswitch->switchid = next_switchid; 453 rswitch->switchid = next_switchid;
@@ -723,25 +726,6 @@ static u16 rio_get_host_deviceid_lock(struct rio_mport *port, u8 hopcount)
723} 726}
724 727
725/** 728/**
726 * rio_get_swpinfo_tports- Gets total number of ports on the switch
727 * @mport: Master port to send transaction
728 * @destid: Destination ID associated with the switch
729 * @hopcount: Number of hops to the device
730 *
731 * Returns total numbers of ports implemented by the switch device.
732 */
733static u8 rio_get_swpinfo_tports(struct rio_mport *mport, u16 destid,
734 u8 hopcount)
735{
736 u32 result;
737
738 rio_mport_read_config_32(mport, destid, hopcount, RIO_SWP_INFO_CAR,
739 &result);
740
741 return RIO_GET_TOTAL_PORTS(result);
742}
743
744/**
745 * rio_net_add_mport- Add a master port to a RIO network 729 * rio_net_add_mport- Add a master port to a RIO network
746 * @net: RIO network 730 * @net: RIO network
747 * @port: Master port to add 731 * @port: Master port to add
@@ -761,15 +745,16 @@ static void rio_net_add_mport(struct rio_net *net, struct rio_mport *port)
761 * @net: RIO network being enumerated 745 * @net: RIO network being enumerated
762 * @port: Master port to send transactions 746 * @port: Master port to send transactions
763 * @hopcount: Number of hops into the network 747 * @hopcount: Number of hops into the network
748 * @prev: Previous RIO device connected to the enumerated one
749 * @prev_port: Port on previous RIO device
764 * 750 *
765 * Recursively enumerates a RIO network. Transactions are sent via the 751 * Recursively enumerates a RIO network. Transactions are sent via the
766 * master port passed in @port. 752 * master port passed in @port.
767 */ 753 */
768static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port, 754static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port,
769 u8 hopcount) 755 u8 hopcount, struct rio_dev *prev, int prev_port)
770{ 756{
771 int port_num; 757 int port_num;
772 int num_ports;
773 int cur_destid; 758 int cur_destid;
774 int sw_destid; 759 int sw_destid;
775 int sw_inport; 760 int sw_inport;
@@ -814,6 +799,9 @@ static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port,
814 if (rdev) { 799 if (rdev) {
815 /* Add device to the global and bus/net specific list. */ 800 /* Add device to the global and bus/net specific list. */
816 list_add_tail(&rdev->net_list, &net->devices); 801 list_add_tail(&rdev->net_list, &net->devices);
802 rdev->prev = prev;
803 if (prev && rio_is_switch(prev))
804 prev->rswitch->nextdev[prev_port] = rdev;
817 } else 805 } else
818 return -1; 806 return -1;
819 807
@@ -832,14 +820,14 @@ static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port,
832 rdev->rswitch->route_table[destid] = sw_inport; 820 rdev->rswitch->route_table[destid] = sw_inport;
833 } 821 }
834 822
835 num_ports =
836 rio_get_swpinfo_tports(port, RIO_ANY_DESTID(port->sys_size),
837 hopcount);
838 pr_debug( 823 pr_debug(
839 "RIO: found %s (vid %4.4x did %4.4x) with %d ports\n", 824 "RIO: found %s (vid %4.4x did %4.4x) with %d ports\n",
840 rio_name(rdev), rdev->vid, rdev->did, num_ports); 825 rio_name(rdev), rdev->vid, rdev->did,
826 RIO_GET_TOTAL_PORTS(rdev->swpinfo));
841 sw_destid = next_destid; 827 sw_destid = next_destid;
842 for (port_num = 0; port_num < num_ports; port_num++) { 828 for (port_num = 0;
829 port_num < RIO_GET_TOTAL_PORTS(rdev->swpinfo);
830 port_num++) {
843 /*Enable Input Output Port (transmitter reviever)*/ 831 /*Enable Input Output Port (transmitter reviever)*/
844 rio_enable_rx_tx_port(port, 0, 832 rio_enable_rx_tx_port(port, 0,
845 RIO_ANY_DESTID(port->sys_size), 833 RIO_ANY_DESTID(port->sys_size),
@@ -864,7 +852,8 @@ static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port,
864 RIO_ANY_DESTID(port->sys_size), 852 RIO_ANY_DESTID(port->sys_size),
865 port_num, 0); 853 port_num, 0);
866 854
867 if (rio_enum_peer(net, port, hopcount + 1) < 0) 855 if (rio_enum_peer(net, port, hopcount + 1,
856 rdev, port_num) < 0)
868 return -1; 857 return -1;
869 858
870 /* Update routing tables */ 859 /* Update routing tables */
@@ -951,7 +940,6 @@ rio_disc_peer(struct rio_net *net, struct rio_mport *port, u16 destid,
951 u8 hopcount) 940 u8 hopcount)
952{ 941{
953 u8 port_num, route_port; 942 u8 port_num, route_port;
954 int num_ports;
955 struct rio_dev *rdev; 943 struct rio_dev *rdev;
956 u16 ndestid; 944 u16 ndestid;
957 945
@@ -968,11 +956,13 @@ rio_disc_peer(struct rio_net *net, struct rio_mport *port, u16 destid,
968 /* Associated destid is how we accessed this switch */ 956 /* Associated destid is how we accessed this switch */
969 rdev->rswitch->destid = destid; 957 rdev->rswitch->destid = destid;
970 958
971 num_ports = rio_get_swpinfo_tports(port, destid, hopcount);
972 pr_debug( 959 pr_debug(
973 "RIO: found %s (vid %4.4x did %4.4x) with %d ports\n", 960 "RIO: found %s (vid %4.4x did %4.4x) with %d ports\n",
974 rio_name(rdev), rdev->vid, rdev->did, num_ports); 961 rio_name(rdev), rdev->vid, rdev->did,
975 for (port_num = 0; port_num < num_ports; port_num++) { 962 RIO_GET_TOTAL_PORTS(rdev->swpinfo));
963 for (port_num = 0;
964 port_num < RIO_GET_TOTAL_PORTS(rdev->swpinfo);
965 port_num++) {
976 if (RIO_GET_PORT_NUM(rdev->swpinfo) == port_num) 966 if (RIO_GET_PORT_NUM(rdev->swpinfo) == port_num)
977 continue; 967 continue;
978 968
@@ -1167,7 +1157,7 @@ int __devinit rio_enum_mport(struct rio_mport *mport)
1167 /* Enable Input Output Port (transmitter reviever) */ 1157 /* Enable Input Output Port (transmitter reviever) */
1168 rio_enable_rx_tx_port(mport, 1, 0, 0, 0); 1158 rio_enable_rx_tx_port(mport, 1, 0, 0, 0);
1169 1159
1170 if (rio_enum_peer(net, mport, 0) < 0) { 1160 if (rio_enum_peer(net, mport, 0, NULL, 0) < 0) {
1171 /* A higher priority host won enumeration, bail. */ 1161 /* A higher priority host won enumeration, bail. */
1172 printk(KERN_INFO 1162 printk(KERN_INFO
1173 "RIO: master port %d device has lost enumeration to a remote host\n", 1163 "RIO: master port %d device has lost enumeration to a remote host\n",