aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firewire/fw-topology.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/firewire/fw-topology.c')
-rw-r--r--drivers/firewire/fw-topology.c66
1 files changed, 32 insertions, 34 deletions
diff --git a/drivers/firewire/fw-topology.c b/drivers/firewire/fw-topology.c
index 7aebb8ae0efa..39e5cd12aa52 100644
--- a/drivers/firewire/fw-topology.c
+++ b/drivers/firewire/fw-topology.c
@@ -135,17 +135,17 @@ static void update_hop_count(struct fw_node *node)
135 int i; 135 int i;
136 136
137 for (i = 0; i < node->port_count; i++) { 137 for (i = 0; i < node->port_count; i++) {
138 if (node->ports[i].node == NULL) 138 if (node->ports[i] == NULL)
139 continue; 139 continue;
140 140
141 if (node->ports[i].node->max_hops > max_child_hops) 141 if (node->ports[i]->max_hops > max_child_hops)
142 max_child_hops = node->ports[i].node->max_hops; 142 max_child_hops = node->ports[i]->max_hops;
143 143
144 if (node->ports[i].node->max_depth > depths[0]) { 144 if (node->ports[i]->max_depth > depths[0]) {
145 depths[1] = depths[0]; 145 depths[1] = depths[0];
146 depths[0] = node->ports[i].node->max_depth; 146 depths[0] = node->ports[i]->max_depth;
147 } else if (node->ports[i].node->max_depth > depths[1]) 147 } else if (node->ports[i]->max_depth > depths[1])
148 depths[1] = node->ports[i].node->max_depth; 148 depths[1] = node->ports[i]->max_depth;
149 } 149 }
150 150
151 node->max_depth = depths[0] + 1; 151 node->max_depth = depths[0] + 1;
@@ -172,7 +172,8 @@ static struct fw_node *build_tree(struct fw_card *card,
172 struct list_head stack, *h; 172 struct list_head stack, *h;
173 u32 *next_sid, *end, q; 173 u32 *next_sid, *end, q;
174 int i, port_count, child_port_count, phy_id, parent_count, stack_depth; 174 int i, port_count, child_port_count, phy_id, parent_count, stack_depth;
175 int gap_count, topology_type; 175 int gap_count;
176 bool beta_repeaters_present;
176 177
177 local_node = NULL; 178 local_node = NULL;
178 node = NULL; 179 node = NULL;
@@ -182,7 +183,7 @@ static struct fw_node *build_tree(struct fw_card *card,
182 phy_id = 0; 183 phy_id = 0;
183 irm_node = NULL; 184 irm_node = NULL;
184 gap_count = SELF_ID_GAP_COUNT(*sid); 185 gap_count = SELF_ID_GAP_COUNT(*sid);
185 topology_type = 0; 186 beta_repeaters_present = false;
186 187
187 while (sid < end) { 188 while (sid < end) {
188 next_sid = count_ports(sid, &port_count, &child_port_count); 189 next_sid = count_ports(sid, &port_count, &child_port_count);
@@ -214,7 +215,7 @@ static struct fw_node *build_tree(struct fw_card *card,
214 215
215 node = fw_node_create(q, port_count, card->color); 216 node = fw_node_create(q, port_count, card->color);
216 if (node == NULL) { 217 if (node == NULL) {
217 fw_error("Out of memory while building topology."); 218 fw_error("Out of memory while building topology.\n");
218 return NULL; 219 return NULL;
219 } 220 }
220 221
@@ -224,11 +225,6 @@ static struct fw_node *build_tree(struct fw_card *card,
224 if (SELF_ID_CONTENDER(q)) 225 if (SELF_ID_CONTENDER(q))
225 irm_node = node; 226 irm_node = node;
226 227
227 if (node->phy_speed == SCODE_BETA)
228 topology_type |= FW_TOPOLOGY_B;
229 else
230 topology_type |= FW_TOPOLOGY_A;
231
232 parent_count = 0; 228 parent_count = 0;
233 229
234 for (i = 0; i < port_count; i++) { 230 for (i = 0; i < port_count; i++) {
@@ -249,12 +245,12 @@ static struct fw_node *build_tree(struct fw_card *card,
249 break; 245 break;
250 246
251 case SELFID_PORT_CHILD: 247 case SELFID_PORT_CHILD:
252 node->ports[i].node = child; 248 node->ports[i] = child;
253 /* 249 /*
254 * Fix up parent reference for this 250 * Fix up parent reference for this
255 * child node. 251 * child node.
256 */ 252 */
257 child->ports[child->color].node = node; 253 child->ports[child->color] = node;
258 child->color = card->color; 254 child->color = card->color;
259 child = fw_node(child->link.next); 255 child = fw_node(child->link.next);
260 break; 256 break;
@@ -278,6 +274,10 @@ static struct fw_node *build_tree(struct fw_card *card,
278 list_add_tail(&node->link, &stack); 274 list_add_tail(&node->link, &stack);
279 stack_depth += 1 - child_port_count; 275 stack_depth += 1 - child_port_count;
280 276
277 if (node->phy_speed == SCODE_BETA &&
278 parent_count + child_port_count > 1)
279 beta_repeaters_present = true;
280
281 /* 281 /*
282 * If all PHYs does not report the same gap count 282 * If all PHYs does not report the same gap count
283 * setting, we fall back to 63 which will force a gap 283 * setting, we fall back to 63 which will force a gap
@@ -295,7 +295,7 @@ static struct fw_node *build_tree(struct fw_card *card,
295 card->root_node = node; 295 card->root_node = node;
296 card->irm_node = irm_node; 296 card->irm_node = irm_node;
297 card->gap_count = gap_count; 297 card->gap_count = gap_count;
298 card->topology_type = topology_type; 298 card->beta_repeaters_present = beta_repeaters_present;
299 299
300 return local_node; 300 return local_node;
301} 301}
@@ -321,7 +321,7 @@ for_each_fw_node(struct fw_card *card, struct fw_node *root,
321 node->color = card->color; 321 node->color = card->color;
322 322
323 for (i = 0; i < node->port_count; i++) { 323 for (i = 0; i < node->port_count; i++) {
324 child = node->ports[i].node; 324 child = node->ports[i];
325 if (!child) 325 if (!child)
326 continue; 326 continue;
327 if (child->color == card->color) 327 if (child->color == card->color)
@@ -382,11 +382,11 @@ static void move_tree(struct fw_node *node0, struct fw_node *node1, int port)
382 struct fw_node *tree; 382 struct fw_node *tree;
383 int i; 383 int i;
384 384
385 tree = node1->ports[port].node; 385 tree = node1->ports[port];
386 node0->ports[port].node = tree; 386 node0->ports[port] = tree;
387 for (i = 0; i < tree->port_count; i++) { 387 for (i = 0; i < tree->port_count; i++) {
388 if (tree->ports[i].node == node1) { 388 if (tree->ports[i] == node1) {
389 tree->ports[i].node = node0; 389 tree->ports[i] = node0;
390 break; 390 break;
391 } 391 }
392 } 392 }
@@ -437,19 +437,17 @@ update_tree(struct fw_card *card, struct fw_node *root)
437 card->irm_node = node0; 437 card->irm_node = node0;
438 438
439 for (i = 0; i < node0->port_count; i++) { 439 for (i = 0; i < node0->port_count; i++) {
440 if (node0->ports[i].node && node1->ports[i].node) { 440 if (node0->ports[i] && node1->ports[i]) {
441 /* 441 /*
442 * This port didn't change, queue the 442 * This port didn't change, queue the
443 * connected node for further 443 * connected node for further
444 * investigation. 444 * investigation.
445 */ 445 */
446 if (node0->ports[i].node->color == card->color) 446 if (node0->ports[i]->color == card->color)
447 continue; 447 continue;
448 list_add_tail(&node0->ports[i].node->link, 448 list_add_tail(&node0->ports[i]->link, &list0);
449 &list0); 449 list_add_tail(&node1->ports[i]->link, &list1);
450 list_add_tail(&node1->ports[i].node->link, 450 } else if (node0->ports[i]) {
451 &list1);
452 } else if (node0->ports[i].node) {
453 /* 451 /*
454 * The nodes connected here were 452 * The nodes connected here were
455 * unplugged; unref the lost nodes and 453 * unplugged; unref the lost nodes and
@@ -457,10 +455,10 @@ update_tree(struct fw_card *card, struct fw_node *root)
457 * them. 455 * them.
458 */ 456 */
459 457
460 for_each_fw_node(card, node0->ports[i].node, 458 for_each_fw_node(card, node0->ports[i],
461 report_lost_node); 459 report_lost_node);
462 node0->ports[i].node = NULL; 460 node0->ports[i] = NULL;
463 } else if (node1->ports[i].node) { 461 } else if (node1->ports[i]) {
464 /* 462 /*
465 * One or more node were connected to 463 * One or more node were connected to
466 * this port. Move the new nodes into 464 * this port. Move the new nodes into
@@ -468,7 +466,7 @@ update_tree(struct fw_card *card, struct fw_node *root)
468 * callbacks for them. 466 * callbacks for them.
469 */ 467 */
470 move_tree(node0, node1, i); 468 move_tree(node0, node1, i);
471 for_each_fw_node(card, node0->ports[i].node, 469 for_each_fw_node(card, node0->ports[i],
472 report_found_node); 470 report_found_node);
473 } 471 }
474 } 472 }