Lines Matching +full:child +full:- +full:node
1 // SPDX-License-Identifier: GPL-2.0-or-later
5 * Copyright (C) 2004-2006 Kristian Hoegsberg <krh@bitplanet.net>
11 #include <linux/firewire-constants.h>
66 shift -= 2; in count_ports()
96 shift = 16 - ((port_index + 5) & 7) * 2; in get_port_type()
102 struct fw_node *node; in fw_node_create() local
104 node = kzalloc(struct_size(node, ports, port_count), GFP_ATOMIC); in fw_node_create()
105 if (node == NULL) in fw_node_create()
108 node->color = color; in fw_node_create()
109 node->node_id = LOCAL_BUS | SELF_ID_PHY_ID(sid); in fw_node_create()
110 node->link_on = SELF_ID_LINK_ON(sid); in fw_node_create()
111 node->phy_speed = SELF_ID_PHY_SPEED(sid); in fw_node_create()
112 node->initiated_reset = SELF_ID_PHY_INITIATOR(sid); in fw_node_create()
113 node->port_count = port_count; in fw_node_create()
115 refcount_set(&node->ref_count, 1); in fw_node_create()
116 INIT_LIST_HEAD(&node->link); in fw_node_create()
118 return node; in fw_node_create()
122 * Compute the maximum hop count for this node and it's children. The
124 * two nodes in the subtree rooted at this node. We need this for
126 * build_tree() below, this is fairly easy to do: for each node we
129 * two cases: either the path goes through this node, in which case
130 * the hop count is the sum of the two biggest child depths plus 2.
132 * containted in a child tree, in which case the max hop count is just
133 * the max hop count of this child.
135 static void update_hop_count(struct fw_node *node) in update_hop_count() argument
137 int depths[2] = { -1, -1 }; in update_hop_count()
141 for (i = 0; i < node->port_count; i++) { in update_hop_count()
142 if (node->ports[i] == NULL) in update_hop_count()
145 if (node->ports[i]->max_hops > max_child_hops) in update_hop_count()
146 max_child_hops = node->ports[i]->max_hops; in update_hop_count()
148 if (node->ports[i]->max_depth > depths[0]) { in update_hop_count()
150 depths[0] = node->ports[i]->max_depth; in update_hop_count()
151 } else if (node->ports[i]->max_depth > depths[1]) in update_hop_count()
152 depths[1] = node->ports[i]->max_depth; in update_hop_count()
155 node->max_depth = depths[0] + 1; in update_hop_count()
156 node->max_hops = max(max_child_hops, depths[0] + depths[1] + 2); in update_hop_count()
174 struct fw_node *node, *child, *local_node, *irm_node; in build_tree() local
182 node = NULL; in build_tree()
213 * start of the child nodes for this node. in build_tree()
216 h = h->prev; in build_tree()
221 child = fw_node(h); in build_tree()
223 node = fw_node_create(q, port_count, card->color); in build_tree()
224 if (node == NULL) { in build_tree()
229 if (phy_id == (card->node_id & 0x3f)) in build_tree()
230 local_node = node; in build_tree()
233 irm_node = node; in build_tree()
242 * parent node at this time, so we in build_tree()
243 * temporarily abuse node->color for in build_tree()
245 * node->ports array where the parent in build_tree()
246 * node should be. Later, when we in build_tree()
247 * handle the parent node, we fix up in build_tree()
251 node->color = i; in build_tree()
255 node->ports[i] = child; in build_tree()
258 * child node. in build_tree()
260 child->ports[child->color] = node; in build_tree()
261 child->color = card->color; in build_tree()
262 child = fw_node(child->link.next); in build_tree()
268 * Check that the node reports exactly one parent in build_tree()
274 fw_err(card, "parent port inconsistency for node %d: " in build_tree()
279 /* Pop the child nodes off the stack and push the new node. */ in build_tree()
280 __list_del(h->prev, &stack); in build_tree()
281 list_add_tail(&node->link, &stack); in build_tree()
282 stack_depth += 1 - child_port_count; in build_tree()
284 if (node->phy_speed == SCODE_BETA && in build_tree()
295 update_hop_count(node); in build_tree()
301 card->root_node = node; in build_tree()
302 card->irm_node = irm_node; in build_tree()
303 card->gap_count = gap_count; in build_tree()
304 card->beta_repeaters_present = beta_repeaters_present; in build_tree()
310 struct fw_node * node,
317 struct fw_node *node, *next, *child, *parent; in for_each_fw_node() local
323 list_add_tail(&root->link, &list); in for_each_fw_node()
325 list_for_each_entry(node, &list, link) { in for_each_fw_node()
326 node->color = card->color; in for_each_fw_node()
328 for (i = 0; i < node->port_count; i++) { in for_each_fw_node()
329 child = node->ports[i]; in for_each_fw_node()
330 if (!child) in for_each_fw_node()
332 if (child->color == card->color) in for_each_fw_node()
333 parent = child; in for_each_fw_node()
335 fw_node_get(child); in for_each_fw_node()
336 list_add_tail(&child->link, &list); in for_each_fw_node()
340 callback(card, node, parent); in for_each_fw_node()
343 list_for_each_entry_safe(node, next, &list, link) in for_each_fw_node()
344 fw_node_put(node); in for_each_fw_node()
348 struct fw_node *node, struct fw_node *parent) in report_lost_node() argument
350 fw_node_event(card, node, FW_NODE_DESTROYED); in report_lost_node()
351 fw_node_put(node); in report_lost_node()
353 /* Topology has changed - reset bus manager retry counter */ in report_lost_node()
354 card->bm_retries = 0; in report_lost_node()
358 struct fw_node *node, struct fw_node *parent) in report_found_node() argument
360 int b_path = (node->phy_speed == SCODE_BETA); in report_found_node()
364 node->max_speed = parent->max_speed < node->phy_speed ? in report_found_node()
365 parent->max_speed : node->phy_speed; in report_found_node()
366 node->b_path = parent->b_path && b_path; in report_found_node()
368 node->max_speed = node->phy_speed; in report_found_node()
369 node->b_path = b_path; in report_found_node()
372 fw_node_event(card, node, FW_NODE_CREATED); in report_found_node()
374 /* Topology has changed - reset bus manager retry counter */ in report_found_node()
375 card->bm_retries = 0; in report_found_node()
378 /* Must be called with card->lock held */
381 card->color++; in fw_destroy_nodes()
382 if (card->local_node != NULL) in fw_destroy_nodes()
383 for_each_fw_node(card, card->local_node, report_lost_node); in fw_destroy_nodes()
384 card->local_node = NULL; in fw_destroy_nodes()
392 tree = node1->ports[port]; in move_tree()
393 node0->ports[port] = tree; in move_tree()
394 for (i = 0; i < tree->port_count; i++) { in move_tree()
395 if (tree->ports[i] == node1) { in move_tree()
396 tree->ports[i] = node0; in move_tree()
414 list_add_tail(&card->local_node->link, &list0); in update_tree()
416 list_add_tail(&root->link, &list1); in update_tree()
421 while (&node0->link != &list0) { in update_tree()
422 WARN_ON(node0->port_count != node1->port_count); in update_tree()
424 if (node0->link_on && !node1->link_on) in update_tree()
426 else if (!node0->link_on && node1->link_on) in update_tree()
428 else if (node1->initiated_reset && node1->link_on) in update_tree()
433 node0->node_id = node1->node_id; in update_tree()
434 node0->color = card->color; in update_tree()
435 node0->link_on = node1->link_on; in update_tree()
436 node0->initiated_reset = node1->initiated_reset; in update_tree()
437 node0->max_hops = node1->max_hops; in update_tree()
438 node1->color = card->color; in update_tree()
441 if (card->root_node == node1) in update_tree()
442 card->root_node = node0; in update_tree()
443 if (card->irm_node == node1) in update_tree()
444 card->irm_node = node0; in update_tree()
446 for (i = 0; i < node0->port_count; i++) { in update_tree()
447 if (node0->ports[i] && node1->ports[i]) { in update_tree()
450 * connected node for further in update_tree()
453 if (node0->ports[i]->color == card->color) in update_tree()
455 list_add_tail(&node0->ports[i]->link, &list0); in update_tree()
456 list_add_tail(&node1->ports[i]->link, &list1); in update_tree()
457 } else if (node0->ports[i]) { in update_tree()
465 for_each_fw_node(card, node0->ports[i], in update_tree()
467 node0->ports[i] = NULL; in update_tree()
468 } else if (node1->ports[i]) { in update_tree()
470 * One or more node were connected to in update_tree()
476 for_each_fw_node(card, node0->ports[i], in update_tree()
481 node0 = fw_node(node0->link.next); in update_tree()
482 next1 = fw_node(node1->link.next); in update_tree()
491 int node_count = (card->root_node->node_id & 0x3f) + 1; in update_topology_map()
492 __be32 *map = card->topology_map; in update_topology_map()
495 *map++ = cpu_to_be32(be32_to_cpu(card->topology_map[1]) + 1); in update_topology_map()
498 while (self_id_count--) in update_topology_map()
501 fw_compute_block_crc(card->topology_map); in update_topology_map()
510 spin_lock_irqsave(&card->lock, flags); in fw_core_handle_bus_reset()
517 if (!is_next_generation(generation, card->generation) && in fw_core_handle_bus_reset()
518 card->local_node != NULL) { in fw_core_handle_bus_reset()
520 card->bm_retries = 0; in fw_core_handle_bus_reset()
523 card->broadcast_channel_allocated = card->broadcast_channel_auto_allocated; in fw_core_handle_bus_reset()
524 card->node_id = node_id; in fw_core_handle_bus_reset()
530 card->generation = generation; in fw_core_handle_bus_reset()
531 card->reset_jiffies = get_jiffies_64(); in fw_core_handle_bus_reset()
532 card->bm_node_id = 0xffff; in fw_core_handle_bus_reset()
533 card->bm_abdicate = bm_abdicate; in fw_core_handle_bus_reset()
540 card->color++; in fw_core_handle_bus_reset()
545 } else if (card->local_node == NULL) { in fw_core_handle_bus_reset()
546 card->local_node = local_node; in fw_core_handle_bus_reset()
552 spin_unlock_irqrestore(&card->lock, flags); in fw_core_handle_bus_reset()