aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rapidio
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/rapidio')
-rw-r--r--drivers/rapidio/rio-scan.c205
1 files changed, 170 insertions, 35 deletions
diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c
index 745670f535e8..48e9041dd1e2 100644
--- a/drivers/rapidio/rio-scan.c
+++ b/drivers/rapidio/rio-scan.c
@@ -54,6 +54,114 @@ static int rio_mport_phys_table[] = {
54 -1, 54 -1,
55}; 55};
56 56
57
58/*
59 * rio_destid_alloc - Allocate next available destID for given network
60 * net: RIO network
61 *
62 * Returns next available device destination ID for the specified RIO network.
63 * Marks allocated ID as one in use.
64 * Returns RIO_INVALID_DESTID if new destID is not available.
65 */
66static u16 rio_destid_alloc(struct rio_net *net)
67{
68 int destid;
69 struct rio_id_table *idtab = &net->destid_table;
70
71 spin_lock(&idtab->lock);
72 destid = find_next_zero_bit(idtab->table, idtab->max, idtab->next);
73 if (destid >= idtab->max)
74 destid = find_first_zero_bit(idtab->table, idtab->max);
75
76 if (destid < idtab->max) {
77 idtab->next = destid + 1;
78 if (idtab->next >= idtab->max)
79 idtab->next = 0;
80 set_bit(destid, idtab->table);
81 destid += idtab->start;
82 } else
83 destid = RIO_INVALID_DESTID;
84
85 spin_unlock(&idtab->lock);
86 return (u16)destid;
87}
88
89/*
90 * rio_destid_reserve - Reserve the specivied destID
91 * net: RIO network
92 * destid: destID to reserve
93 *
94 * Tries to reserve the specified destID.
95 * Returns 0 if successfull.
96 */
97static int rio_destid_reserve(struct rio_net *net, u16 destid)
98{
99 int oldbit;
100 struct rio_id_table *idtab = &net->destid_table;
101
102 destid -= idtab->start;
103 spin_lock(&idtab->lock);
104 oldbit = test_and_set_bit(destid, idtab->table);
105 spin_unlock(&idtab->lock);
106 return oldbit;
107}
108
109/*
110 * rio_destid_free - free a previously allocated destID
111 * net: RIO network
112 * destid: destID to free
113 *
114 * Makes the specified destID available for use.
115 */
116static void rio_destid_free(struct rio_net *net, u16 destid)
117{
118 struct rio_id_table *idtab = &net->destid_table;
119
120 destid -= idtab->start;
121 spin_lock(&idtab->lock);
122 clear_bit(destid, idtab->table);
123 spin_unlock(&idtab->lock);
124}
125
126/*
127 * rio_destid_first - return first destID in use
128 * net: RIO network
129 */
130static u16 rio_destid_first(struct rio_net *net)
131{
132 int destid;
133 struct rio_id_table *idtab = &net->destid_table;
134
135 spin_lock(&idtab->lock);
136 destid = find_first_bit(idtab->table, idtab->max);
137 if (destid >= idtab->max)
138 destid = RIO_INVALID_DESTID;
139 else
140 destid += idtab->start;
141 spin_unlock(&idtab->lock);
142 return (u16)destid;
143}
144
145/*
146 * rio_destid_next - return next destID in use
147 * net: RIO network
148 * from: destination ID from which search shall continue
149 */
150static u16 rio_destid_next(struct rio_net *net, u16 from)
151{
152 int destid;
153 struct rio_id_table *idtab = &net->destid_table;
154
155 spin_lock(&idtab->lock);
156 destid = find_next_bit(idtab->table, idtab->max, from);
157 if (destid >= idtab->max)
158 destid = RIO_INVALID_DESTID;
159 else
160 destid += idtab->start;
161 spin_unlock(&idtab->lock);
162 return (u16)destid;
163}
164
57/** 165/**
58 * rio_get_device_id - Get the base/extended device id for a device 166 * rio_get_device_id - Get the base/extended device id for a device
59 * @port: RIO master port 167 * @port: RIO master port
@@ -171,10 +279,6 @@ static int rio_enum_host(struct rio_mport *port)
171 279
172 /* Set master port destid and init destid ctr */ 280 /* Set master port destid and init destid ctr */
173 rio_local_set_device_id(port, port->host_deviceid); 281 rio_local_set_device_id(port, port->host_deviceid);
174
175 if (next_destid == port->host_deviceid)
176 next_destid++;
177
178 return 0; 282 return 0;
179} 283}
180 284
@@ -441,9 +545,8 @@ static struct rio_dev __devinit *rio_setup_device(struct rio_net *net,
441 if (rio_device_has_destid(port, rdev->src_ops, rdev->dst_ops)) { 545 if (rio_device_has_destid(port, rdev->src_ops, rdev->dst_ops)) {
442 if (do_enum) { 546 if (do_enum) {
443 rio_set_device_id(port, destid, hopcount, next_destid); 547 rio_set_device_id(port, destid, hopcount, next_destid);
444 rdev->destid = next_destid++; 548 rdev->destid = next_destid;
445 if (next_destid == port->host_deviceid) 549 next_destid = rio_destid_alloc(net);
446 next_destid++;
447 } else 550 } else
448 rdev->destid = rio_get_device_id(port, destid, hopcount); 551 rdev->destid = rio_get_device_id(port, destid, hopcount);
449 552
@@ -742,12 +845,7 @@ static u16 rio_get_host_deviceid_lock(struct rio_mport *port, u8 hopcount)
742static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port, 845static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port,
743 u8 hopcount, struct rio_dev *prev, int prev_port) 846 u8 hopcount, struct rio_dev *prev, int prev_port)
744{ 847{
745 int port_num;
746 int cur_destid;
747 int sw_destid;
748 int sw_inport;
749 struct rio_dev *rdev; 848 struct rio_dev *rdev;
750 u16 destid;
751 u32 regval; 849 u32 regval;
752 int tmp; 850 int tmp;
753 851
@@ -813,19 +911,26 @@ static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port,
813 return -1; 911 return -1;
814 912
815 if (rio_is_switch(rdev)) { 913 if (rio_is_switch(rdev)) {
914 int sw_destid;
915 int cur_destid;
916 int sw_inport;
917 u16 destid;
918 int port_num;
919
816 sw_inport = RIO_GET_PORT_NUM(rdev->swpinfo); 920 sw_inport = RIO_GET_PORT_NUM(rdev->swpinfo);
817 rio_route_add_entry(rdev, RIO_GLOBAL_TABLE, 921 rio_route_add_entry(rdev, RIO_GLOBAL_TABLE,
818 port->host_deviceid, sw_inport, 0); 922 port->host_deviceid, sw_inport, 0);
819 rdev->rswitch->route_table[port->host_deviceid] = sw_inport; 923 rdev->rswitch->route_table[port->host_deviceid] = sw_inport;
820 924
821 for (destid = 0; destid < next_destid; destid++) { 925 destid = rio_destid_first(net);
822 if (destid == port->host_deviceid) 926 while (destid != RIO_INVALID_DESTID && destid < next_destid) {
823 continue; 927 if (destid != port->host_deviceid) {
824 rio_route_add_entry(rdev, RIO_GLOBAL_TABLE, 928 rio_route_add_entry(rdev, RIO_GLOBAL_TABLE,
825 destid, sw_inport, 0); 929 destid, sw_inport, 0);
826 rdev->rswitch->route_table[destid] = sw_inport; 930 rdev->rswitch->route_table[destid] = sw_inport;
931 }
932 destid = rio_destid_next(net, destid + 1);
827 } 933 }
828
829 pr_debug( 934 pr_debug(
830 "RIO: found %s (vid %4.4x did %4.4x) with %d ports\n", 935 "RIO: found %s (vid %4.4x did %4.4x) with %d ports\n",
831 rio_name(rdev), rdev->vid, rdev->did, 936 rio_name(rdev), rdev->vid, rdev->did,
@@ -863,19 +968,22 @@ static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port,
863 return -1; 968 return -1;
864 969
865 /* Update routing tables */ 970 /* Update routing tables */
866 if (next_destid > cur_destid) { 971 destid = rio_destid_next(net, cur_destid + 1);
972 if (destid != RIO_INVALID_DESTID) {
867 for (destid = cur_destid; 973 for (destid = cur_destid;
868 destid < next_destid; destid++) { 974 destid < next_destid;) {
869 if (destid == port->host_deviceid) 975 if (destid != port->host_deviceid) {
870 continue; 976 rio_route_add_entry(rdev,
871 rio_route_add_entry(rdev,
872 RIO_GLOBAL_TABLE, 977 RIO_GLOBAL_TABLE,
873 destid, 978 destid,
874 port_num, 979 port_num,
875 0); 980 0);
876 rdev->rswitch-> 981 rdev->rswitch->
877 route_table[destid] = 982 route_table[destid] =
878 port_num; 983 port_num;
984 }
985 destid = rio_destid_next(net,
986 destid + 1);
879 } 987 }
880 } 988 }
881 } else { 989 } else {
@@ -901,11 +1009,8 @@ static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port,
901 rio_init_em(rdev); 1009 rio_init_em(rdev);
902 1010
903 /* Check for empty switch */ 1011 /* Check for empty switch */
904 if (next_destid == sw_destid) { 1012 if (next_destid == sw_destid)
905 next_destid++; 1013 next_destid = rio_destid_alloc(net);
906 if (next_destid == port->host_deviceid)
907 next_destid++;
908 }
909 1014
910 rdev->destid = sw_destid; 1015 rdev->destid = sw_destid;
911 } else 1016 } else
@@ -1043,17 +1148,39 @@ static int rio_mport_is_active(struct rio_mport *port)
1043/** 1148/**
1044 * rio_alloc_net- Allocate and configure a new RIO network 1149 * rio_alloc_net- Allocate and configure a new RIO network
1045 * @port: Master port associated with the RIO network 1150 * @port: Master port associated with the RIO network
1151 * @do_enum: Enumeration/Discovery mode flag
1152 * @start: logical minimal start id for new net
1046 * 1153 *
1047 * Allocates a RIO network structure, initializes per-network 1154 * Allocates a RIO network structure, initializes per-network
1048 * list heads, and adds the associated master port to the 1155 * list heads, and adds the associated master port to the
1049 * network list of associated master ports. Returns a 1156 * network list of associated master ports. Returns a
1050 * RIO network pointer on success or %NULL on failure. 1157 * RIO network pointer on success or %NULL on failure.
1051 */ 1158 */
1052static struct rio_net __devinit *rio_alloc_net(struct rio_mport *port) 1159static struct rio_net __devinit *rio_alloc_net(struct rio_mport *port,
1160 int do_enum, u16 start)
1053{ 1161{
1054 struct rio_net *net; 1162 struct rio_net *net;
1055 1163
1056 net = kzalloc(sizeof(struct rio_net), GFP_KERNEL); 1164 net = kzalloc(sizeof(struct rio_net), GFP_KERNEL);
1165 if (net && do_enum) {
1166 net->destid_table.table = kzalloc(
1167 BITS_TO_LONGS(RIO_MAX_ROUTE_ENTRIES(port->sys_size)) *
1168 sizeof(long),
1169 GFP_KERNEL);
1170
1171 if (net->destid_table.table == NULL) {
1172 pr_err("RIO: failed to allocate destID table\n");
1173 kfree(net);
1174 net = NULL;
1175 } else {
1176 net->destid_table.start = start;
1177 net->destid_table.next = 0;
1178 net->destid_table.max =
1179 RIO_MAX_ROUTE_ENTRIES(port->sys_size);
1180 spin_lock_init(&net->destid_table.lock);
1181 }
1182 }
1183
1057 if (net) { 1184 if (net) {
1058 INIT_LIST_HEAD(&net->node); 1185 INIT_LIST_HEAD(&net->node);
1059 INIT_LIST_HEAD(&net->devices); 1186 INIT_LIST_HEAD(&net->devices);
@@ -1163,12 +1290,16 @@ int __devinit rio_enum_mport(struct rio_mport *mport)
1163 1290
1164 /* If master port has an active link, allocate net and enum peers */ 1291 /* If master port has an active link, allocate net and enum peers */
1165 if (rio_mport_is_active(mport)) { 1292 if (rio_mport_is_active(mport)) {
1166 if (!(net = rio_alloc_net(mport))) { 1293 net = rio_alloc_net(mport, 1, 0);
1294 if (!net) {
1167 printk(KERN_ERR "RIO: failed to allocate new net\n"); 1295 printk(KERN_ERR "RIO: failed to allocate new net\n");
1168 rc = -ENOMEM; 1296 rc = -ENOMEM;
1169 goto out; 1297 goto out;
1170 } 1298 }
1171 1299
1300 /* reserve mport destID in new net */
1301 rio_destid_reserve(net, mport->host_deviceid);
1302
1172 /* Enable Input Output Port (transmitter reviever) */ 1303 /* Enable Input Output Port (transmitter reviever) */
1173 rio_enable_rx_tx_port(mport, 1, 0, 0, 0); 1304 rio_enable_rx_tx_port(mport, 1, 0, 0, 0);
1174 1305
@@ -1176,6 +1307,8 @@ int __devinit rio_enum_mport(struct rio_mport *mport)
1176 rio_local_write_config_32(mport, RIO_COMPONENT_TAG_CSR, 1307 rio_local_write_config_32(mport, RIO_COMPONENT_TAG_CSR,
1177 next_comptag++); 1308 next_comptag++);
1178 1309
1310 next_destid = rio_destid_alloc(net);
1311
1179 if (rio_enum_peer(net, mport, 0, NULL, 0) < 0) { 1312 if (rio_enum_peer(net, mport, 0, NULL, 0) < 0) {
1180 /* A higher priority host won enumeration, bail. */ 1313 /* A higher priority host won enumeration, bail. */
1181 printk(KERN_INFO 1314 printk(KERN_INFO
@@ -1185,6 +1318,8 @@ int __devinit rio_enum_mport(struct rio_mport *mport)
1185 rc = -EBUSY; 1318 rc = -EBUSY;
1186 goto out; 1319 goto out;
1187 } 1320 }
1321 /* free the last allocated destID (unused) */
1322 rio_destid_free(net, next_destid);
1188 rio_update_route_tables(net); 1323 rio_update_route_tables(net);
1189 rio_clear_locks(net); 1324 rio_clear_locks(net);
1190 rio_pw_enable(mport, 1); 1325 rio_pw_enable(mport, 1);
@@ -1265,7 +1400,7 @@ int __devinit rio_disc_mport(struct rio_mport *mport)
1265enum_done: 1400enum_done:
1266 pr_debug("RIO: ... enumeration done\n"); 1401 pr_debug("RIO: ... enumeration done\n");
1267 1402
1268 net = rio_alloc_net(mport); 1403 net = rio_alloc_net(mport, 0, 0);
1269 if (!net) { 1404 if (!net) {
1270 printk(KERN_ERR "RIO: Failed to allocate new net\n"); 1405 printk(KERN_ERR "RIO: Failed to allocate new net\n");
1271 goto bail; 1406 goto bail;