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>
65 shift -= 2; in count_ports()
95 shift = 16 - ((port_index + 5) & 7) * 2; in get_port_type()
101 struct fw_node *node; in fw_node_create() local
103 node = kzalloc(struct_size(node, ports, port_count), GFP_ATOMIC); in fw_node_create()
104 if (node == NULL) in fw_node_create()
107 node->color = color; in fw_node_create()
108 node->node_id = LOCAL_BUS | SELF_ID_PHY_ID(sid); in fw_node_create()
109 node->link_on = SELF_ID_LINK_ON(sid); in fw_node_create()
110 node->phy_speed = SELF_ID_PHY_SPEED(sid); in fw_node_create()
111 node->initiated_reset = SELF_ID_PHY_INITIATOR(sid); in fw_node_create()
112 node->port_count = port_count; in fw_node_create()
114 refcount_set(&node->ref_count, 1); in fw_node_create()
115 INIT_LIST_HEAD(&node->link); in fw_node_create()
117 return node; in fw_node_create()
121 * Compute the maximum hop count for this node and it's children. The
123 * two nodes in the subtree rooted at this node. We need this for
125 * build_tree() below, this is fairly easy to do: for each node we
128 * two cases: either the path goes through this node, in which case
129 * the hop count is the sum of the two biggest child depths plus 2.
131 * containted in a child tree, in which case the max hop count is just
132 * the max hop count of this child.
134 static void update_hop_count(struct fw_node *node) in update_hop_count() argument
136 int depths[2] = { -1, -1 }; in update_hop_count()
140 for (i = 0; i < node->port_count; i++) { in update_hop_count()
141 if (node->ports[i] == NULL) in update_hop_count()
144 if (node->ports[i]->max_hops > max_child_hops) in update_hop_count()
145 max_child_hops = node->ports[i]->max_hops; in update_hop_count()
147 if (node->ports[i]->max_depth > depths[0]) { in update_hop_count()
149 depths[0] = node->ports[i]->max_depth; in update_hop_count()
150 } else if (node->ports[i]->max_depth > depths[1]) in update_hop_count()
151 depths[1] = node->ports[i]->max_depth; in update_hop_count()
154 node->max_depth = depths[0] + 1; in update_hop_count()
155 node->max_hops = max(max_child_hops, depths[0] + depths[1] + 2); in update_hop_count()
173 struct fw_node *node, *child, *local_node, *irm_node; in build_tree() local
181 node = NULL; in build_tree()
212 * start of the child nodes for this node. in build_tree()
215 h = h->prev; in build_tree()
220 child = fw_node(h); in build_tree()
222 node = fw_node_create(q, port_count, card->color); in build_tree()
223 if (node == NULL) { in build_tree()
228 if (phy_id == (card->node_id & 0x3f)) in build_tree()
229 local_node = node; in build_tree()
232 irm_node = node; in build_tree()
241 * parent node at this time, so we in build_tree()
242 * temporarily abuse node->color for in build_tree()
244 * node->ports array where the parent in build_tree()
245 * node should be. Later, when we in build_tree()
246 * handle the parent node, we fix up in build_tree()
250 node->color = i; in build_tree()
254 node->ports[i] = child; in build_tree()
257 * child node. in build_tree()
259 child->ports[child->color] = node; in build_tree()
260 child->color = card->color; in build_tree()
261 child = fw_node(child->link.next); in build_tree()
267 * Check that the node reports exactly one parent in build_tree()
273 fw_err(card, "parent port inconsistency for node %d: " in build_tree()
278 /* Pop the child nodes off the stack and push the new node. */ in build_tree()
279 __list_del(h->prev, &stack); in build_tree()
280 list_add_tail(&node->link, &stack); in build_tree()
281 stack_depth += 1 - child_port_count; in build_tree()
283 if (node->phy_speed == SCODE_BETA && in build_tree()
294 update_hop_count(node); in build_tree()
300 card->root_node = node; in build_tree()
301 card->irm_node = irm_node; in build_tree()
302 card->gap_count = gap_count; in build_tree()
303 card->beta_repeaters_present = beta_repeaters_present; in build_tree()
309 struct fw_node * node,
316 struct fw_node *node, *next, *child, *parent; in for_each_fw_node() local
322 list_add_tail(&root->link, &list); in for_each_fw_node()
324 list_for_each_entry(node, &list, link) { in for_each_fw_node()
325 node->color = card->color; in for_each_fw_node()
327 for (i = 0; i < node->port_count; i++) { in for_each_fw_node()
328 child = node->ports[i]; in for_each_fw_node()
329 if (!child) in for_each_fw_node()
331 if (child->color == card->color) in for_each_fw_node()
332 parent = child; in for_each_fw_node()
334 fw_node_get(child); in for_each_fw_node()
335 list_add_tail(&child->link, &list); in for_each_fw_node()
339 callback(card, node, parent); in for_each_fw_node()
342 list_for_each_entry_safe(node, next, &list, link) in for_each_fw_node()
343 fw_node_put(node); in for_each_fw_node()
347 struct fw_node *node, struct fw_node *parent) in report_lost_node() argument
349 fw_node_event(card, node, FW_NODE_DESTROYED); in report_lost_node()
350 fw_node_put(node); in report_lost_node()
352 /* Topology has changed - reset bus manager retry counter */ in report_lost_node()
353 card->bm_retries = 0; in report_lost_node()
357 struct fw_node *node, struct fw_node *parent) in report_found_node() argument
359 int b_path = (node->phy_speed == SCODE_BETA); in report_found_node()
363 node->max_speed = parent->max_speed < node->phy_speed ? in report_found_node()
364 parent->max_speed : node->phy_speed; in report_found_node()
365 node->b_path = parent->b_path && b_path; in report_found_node()
367 node->max_speed = node->phy_speed; in report_found_node()
368 node->b_path = b_path; in report_found_node()
371 fw_node_event(card, node, FW_NODE_CREATED); in report_found_node()
373 /* Topology has changed - reset bus manager retry counter */ in report_found_node()
374 card->bm_retries = 0; in report_found_node()
381 spin_lock_irqsave(&card->lock, flags); in fw_destroy_nodes()
382 card->color++; in fw_destroy_nodes()
383 if (card->local_node != NULL) in fw_destroy_nodes()
384 for_each_fw_node(card, card->local_node, report_lost_node); in fw_destroy_nodes()
385 card->local_node = NULL; in fw_destroy_nodes()
386 spin_unlock_irqrestore(&card->lock, flags); in fw_destroy_nodes()
394 tree = node1->ports[port]; in move_tree()
395 node0->ports[port] = tree; in move_tree()
396 for (i = 0; i < tree->port_count; i++) { in move_tree()
397 if (tree->ports[i] == node1) { in move_tree()
398 tree->ports[i] = node0; in move_tree()
416 list_add_tail(&card->local_node->link, &list0); in update_tree()
418 list_add_tail(&root->link, &list1); in update_tree()
423 while (&node0->link != &list0) { in update_tree()
424 WARN_ON(node0->port_count != node1->port_count); in update_tree()
426 if (node0->link_on && !node1->link_on) in update_tree()
428 else if (!node0->link_on && node1->link_on) in update_tree()
430 else if (node1->initiated_reset && node1->link_on) in update_tree()
435 node0->node_id = node1->node_id; in update_tree()
436 node0->color = card->color; in update_tree()
437 node0->link_on = node1->link_on; in update_tree()
438 node0->initiated_reset = node1->initiated_reset; in update_tree()
439 node0->max_hops = node1->max_hops; in update_tree()
440 node1->color = card->color; in update_tree()
443 if (card->root_node == node1) in update_tree()
444 card->root_node = node0; in update_tree()
445 if (card->irm_node == node1) in update_tree()
446 card->irm_node = node0; in update_tree()
448 for (i = 0; i < node0->port_count; i++) { in update_tree()
449 if (node0->ports[i] && node1->ports[i]) { in update_tree()
452 * connected node for further in update_tree()
455 if (node0->ports[i]->color == card->color) in update_tree()
457 list_add_tail(&node0->ports[i]->link, &list0); in update_tree()
458 list_add_tail(&node1->ports[i]->link, &list1); in update_tree()
459 } else if (node0->ports[i]) { in update_tree()
467 for_each_fw_node(card, node0->ports[i], in update_tree()
469 node0->ports[i] = NULL; in update_tree()
470 } else if (node1->ports[i]) { in update_tree()
472 * One or more node were connected to in update_tree()
478 for_each_fw_node(card, node0->ports[i], in update_tree()
483 node0 = fw_node(node0->link.next); in update_tree()
484 next1 = fw_node(node1->link.next); in update_tree()
493 int node_count = (card->root_node->node_id & 0x3f) + 1; in update_topology_map()
494 __be32 *map = card->topology_map; in update_topology_map()
497 *map++ = cpu_to_be32(be32_to_cpu(card->topology_map[1]) + 1); in update_topology_map()
500 while (self_id_count--) in update_topology_map()
503 fw_compute_block_crc(card->topology_map); in update_topology_map()
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 spin_lock_irqsave(&card->lock, flags); in fw_core_handle_bus_reset()
525 card->broadcast_channel_allocated = card->broadcast_channel_auto_allocated; in fw_core_handle_bus_reset()
526 card->node_id = node_id; in fw_core_handle_bus_reset()
532 card->generation = generation; in fw_core_handle_bus_reset()
533 card->reset_jiffies = get_jiffies_64(); in fw_core_handle_bus_reset()
534 card->bm_node_id = 0xffff; in fw_core_handle_bus_reset()
535 card->bm_abdicate = bm_abdicate; in fw_core_handle_bus_reset()
542 card->color++; in fw_core_handle_bus_reset()
547 } else if (card->local_node == NULL) { in fw_core_handle_bus_reset()
548 card->local_node = local_node; in fw_core_handle_bus_reset()
554 spin_unlock_irqrestore(&card->lock, flags); in fw_core_handle_bus_reset()