xref: /titanic_44/usr/src/uts/common/io/1394/s1394_bus_reset.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright (c) 1999-2000 by Sun Microsystems, Inc.
24  * All rights reserved.
25  */
26 
27 #pragma	ident	"%Z%%M%	%I%	%E% SMI"
28 
29 /*
30  * s1394_bus_reset.c
31  *    1394 Services Layer Bus Reset Routines
32  *    These routines handle all of the tasks relating to 1394 bus resets
33  */
34 
35 #include <sys/conf.h>
36 #include <sys/ddi.h>
37 #include <sys/sunddi.h>
38 #include <sys/types.h>
39 #include <sys/kmem.h>
40 #include <sys/tnf_probe.h>
41 
42 #include <sys/1394/t1394.h>
43 #include <sys/1394/s1394.h>
44 #include <sys/1394/h1394.h>
45 #include <sys/1394/ieee1394.h>
46 #include <sys/1394/ieee1212.h>
47 
48 static uint8_t selfid_speed(s1394_selfid_pkt_t *s);
49 
50 static int selfid_num_ports(s1394_selfid_pkt_t *s);
51 
52 static int selfid_port_type(s1394_selfid_pkt_t *s, int port);
53 
54 static void s1394_hal_stack_push(s1394_hal_t *hal, void *o);
55 
56 static void *s1394_hal_stack_pop(s1394_hal_t *hal);
57 
58 static void s1394_hal_queue_insert(s1394_hal_t *hal, void *o);
59 
60 static void *s1394_hal_queue_remove(s1394_hal_t *hal);
61 
62 static void s1394_node_number_list_add(s1394_hal_t *hal, int node_num);
63 
64 static void s1394_speed_map_fill_speed_N(s1394_hal_t *hal, int min_spd);
65 
66 static void s1394_speed_map_initialize(s1394_hal_t *hal);
67 
68 int s1394_ignore_invalid_gap_cnt = 0; /* patch for invalid gap_cnts */
69 
70 /*
71  * Gap_count look-up table (See IEEE P1394a Table C-2) - Draft 3.0
72  * (modified from original table IEEE 1394-1995 8.4.6.2)
73  */
74 static int gap_count[MAX_HOPS + 1] = {
75 	0, 5, 7, 8, 10, 13, 16, 18, 21,
76 	24, 26, 29, 32, 35, 37, 40, 43,
77 	46, 48, 51, 54, 57, 59, 62
78 };
79 
80 /*
81  * s1394_parse_selfid_buffer()
82  *    takes the SelfID data buffer and parses it, testing whether each packet
83  *    is valid (has a correct inverse packet) and setting the pointers in
84  *    selfid_ptrs[] to the appropriate offsets within the buffer.
85  */
86 int
s1394_parse_selfid_buffer(s1394_hal_t * hal,void * selfid_buf_addr,uint32_t selfid_size)87 s1394_parse_selfid_buffer(s1394_hal_t *hal, void *selfid_buf_addr,
88     uint32_t selfid_size)
89 {
90 	s1394_selfid_pkt_t *s;
91 	uint32_t	   *data;
92 	uint_t		   i = 0;
93 	uint_t		   j = 0;
94 	boolean_t	   error = B_FALSE;
95 	int		   valid_pkt_id;
96 
97 	TNF_PROBE_0_DEBUG(s1394_parse_selfid_buffer_enter,
98 	    S1394_TNF_SL_BR_STACK, "");
99 
100 	ASSERT(MUTEX_HELD(&hal->topology_tree_mutex));
101 
102 	data = (uint32_t *)selfid_buf_addr;
103 
104 	if (selfid_size == 0) {
105 		TNF_PROBE_1(s1394_parse_selfid_buffer_error,
106 		    S1394_TNF_SL_BR_ERROR, "", tnf_string, msg,
107 		    "SelfID buffer error - zero size");
108 
109 		/* Initiate a bus reset */
110 		s1394_initiate_hal_reset(hal, CRITICAL);
111 
112 		/* Set error status */
113 		error = B_TRUE;
114 
115 		/* Release HAL lock and return */
116 		goto parse_buffer_done;
117 	}
118 
119 	/* Convert bytes to quadlets */
120 	selfid_size = selfid_size >> 2;
121 
122 	while (j < selfid_size) {
123 		valid_pkt_id = ((data[j] & IEEE1394_SELFID_PCKT_ID_MASK) >>
124 		    IEEE1394_SELFID_PCKT_ID_SHIFT);
125 
126 		s = (s1394_selfid_pkt_t *)(&data[j]);
127 
128 		/* Test if packet has valid inverse quadlet */
129 		if (IEEE1394_SELFID_ISVALID(s) &&
130 		    (valid_pkt_id == IEEE1394_SELFID_PCKT_ID_VALID)) {
131 
132 			hal->selfid_ptrs[i] = s;
133 
134 			/* While this packet contains multiple quadlets */
135 			j += 2;
136 
137 			while (IEEE1394_SELFID_ISMORE(s)) {
138 				valid_pkt_id =
139 				    ((data[j] & IEEE1394_SELFID_PCKT_ID_MASK) >>
140 				    IEEE1394_SELFID_PCKT_ID_SHIFT);
141 
142 				s = (s1394_selfid_pkt_t *)(&data[j]);
143 
144 				/* Test if packet has valid inverse quadlet */
145 				if (IEEE1394_SELFID_ISVALID(s) &&
146 				    (valid_pkt_id ==
147 					IEEE1394_SELFID_PCKT_ID_VALID)) {
148 					j += 2;
149 				} else {
150 					TNF_PROBE_1(
151 					    s1394_parse_selfid_buffer_error,
152 					    S1394_TNF_SL_BR_ERROR, "",
153 					    tnf_string, msg, "SelfID packet "
154 					    "error - invalid inverse");
155 
156 					/* Initiate a bus reset */
157 					s1394_initiate_hal_reset(hal, CRITICAL);
158 
159 					/* Set error status */
160 					error = B_TRUE;
161 
162 					/* Release HAL lock and return */
163 					goto parse_buffer_done;
164 				}
165 			}
166 			i++;
167 		} else {
168 			TNF_PROBE_1(s1394_parse_selfid_buffer_error,
169 			    S1394_TNF_SL_BR_ERROR, "", tnf_string, msg,
170 			    "SelfID packet error - invalid inverse");
171 
172 			/* Initiate a bus reset */
173 			s1394_initiate_hal_reset(hal, CRITICAL);
174 
175 			/* Set error status */
176 			error = B_TRUE;
177 
178 			/* Release HAL lock and return */
179 			goto parse_buffer_done;
180 		}
181 	}
182 
183 	hal->number_of_nodes = i;
184 
185 parse_buffer_done:
186 	TNF_PROBE_0_DEBUG(s1394_parse_selfid_buffer_exit,
187 	    S1394_TNF_SL_BR_STACK, "");
188 	if (error == B_TRUE)
189 		return (DDI_FAILURE);
190 	else
191 		return (DDI_SUCCESS);
192 }
193 
194 /*
195  * s1394_sort_selfids()
196  *    takes the selfid_ptrs[] in the HAL struct and sorts them by node number,
197  *    using a heapsort.
198  */
199 void
s1394_sort_selfids(s1394_hal_t * hal)200 s1394_sort_selfids(s1394_hal_t *hal)
201 {
202 	s1394_selfid_pkt_t *current;
203 	uint_t		   number_of_nodes;
204 	int		   i;
205 	int		   j;
206 
207 	TNF_PROBE_0_DEBUG(s1394_sort_selfids_enter, S1394_TNF_SL_BR_STACK, "");
208 
209 	ASSERT(MUTEX_HELD(&hal->topology_tree_mutex));
210 
211 	number_of_nodes = hal->number_of_nodes;
212 
213 	/* We start at one because the root has no parent to check */
214 	for (i = 1; i < number_of_nodes; i++) {
215 		current = hal->selfid_ptrs[i];
216 		j = i;
217 		while ((j > 0) && (IEEE1394_SELFID_PHYID(current) >
218 		    IEEE1394_SELFID_PHYID(hal->selfid_ptrs[j / 2]))) {
219 			hal->selfid_ptrs[j] = hal->selfid_ptrs[j / 2];
220 			hal->selfid_ptrs[j / 2] = current;
221 			j = j / 2;
222 		}
223 	}
224 
225 	for (i = number_of_nodes - 1; i > 0; i--) {
226 		current = hal->selfid_ptrs[i];
227 		hal->selfid_ptrs[i] = hal->selfid_ptrs[0];
228 		hal->selfid_ptrs[0] = current;
229 		j = 0;
230 		while (2 * j + 1 < i) {
231 			if (2 * j + 2 >= i) {
232 				if (IEEE1394_SELFID_PHYID(current) <
233 				    IEEE1394_SELFID_PHYID(
234 					hal->selfid_ptrs[2 * j + 1])) {
235 					hal->selfid_ptrs[j] =
236 					    hal->selfid_ptrs[2 * j + 1];
237 					hal->selfid_ptrs[2 * j + 1] = current;
238 					j = 2 * j + 1;
239 				}
240 				break;
241 			}
242 
243 			if (IEEE1394_SELFID_PHYID(hal->selfid_ptrs[2 * j + 1]) >
244 			    IEEE1394_SELFID_PHYID(
245 				hal->selfid_ptrs[2 * j + 2])) {
246 				if (IEEE1394_SELFID_PHYID(current) <
247 				    IEEE1394_SELFID_PHYID(
248 					hal->selfid_ptrs[2 * j + 1])) {
249 					hal->selfid_ptrs[j] =
250 					    hal->selfid_ptrs[2 * j + 1];
251 					hal->selfid_ptrs[2 * j + 1] = current;
252 					j = 2 * j + 1;
253 				} else {
254 					break;
255 				}
256 			} else {
257 				if (IEEE1394_SELFID_PHYID(current) <
258 				    IEEE1394_SELFID_PHYID(
259 					hal->selfid_ptrs[2 * j + 2])) {
260 					hal->selfid_ptrs[j] =
261 					    hal->selfid_ptrs[2 * j + 2];
262 					hal->selfid_ptrs[2 * j + 2] = current;
263 					j = 2 * j + 2;
264 				} else {
265 					break;
266 				}
267 			}
268 		}
269 	}
270 
271 	TNF_PROBE_0_DEBUG(s1394_sort_selfids_exit, S1394_TNF_SL_BR_STACK, "");
272 }
273 
274 /*
275  * selfid_speed()
276  *    examines the "sp" bits for a given packet (see IEEE 1394-1995 4.3.4.1)
277  *    and returns the node's speed capabilities.
278  */
279 static uint8_t
selfid_speed(s1394_selfid_pkt_t * s)280 selfid_speed(s1394_selfid_pkt_t *s)
281 {
282 	uint32_t sp;
283 
284 	sp = ((s->spkt_data & IEEE1394_SELFID_SP_MASK) >>
285 	    IEEE1394_SELFID_SP_SHIFT);
286 
287 	switch (sp) {
288 	case IEEE1394_S100:
289 	case IEEE1394_S200:
290 	case IEEE1394_S400:
291 		return (sp);
292 
293 	/*
294 	 * To verify higher speeds we should look at PHY register #3
295 	 * on this node.  This will need to be done to support P1394b
296 	 */
297 	default:
298 		return (IEEE1394_S400);
299 	}
300 }
301 
302 /*
303  * selfid_num_ports()
304  *    determines whether a packet is multi-part or single, and from this it
305  *    calculates the number of ports which have been specified.
306  *    (See IEEE 1394-1995 4.3.4.1)
307  */
308 static int
selfid_num_ports(s1394_selfid_pkt_t * s)309 selfid_num_ports(s1394_selfid_pkt_t *s)
310 {
311 	int	p = 3;
312 
313 	while (IEEE1394_SELFID_ISMORE(s)) {
314 		p += 8;
315 		s++;
316 	}
317 
318 	/* Threshold the number of ports at the P1394A defined maximum */
319 	/* (see P1394A Draft 3.0 - Section 8.5.1) */
320 	if (p > IEEE1394_MAX_NUM_PORTS)
321 		p = IEEE1394_MAX_NUM_PORTS;
322 
323 	return (p);
324 }
325 
326 /*
327  * selfid_port_type()
328  *    determines what type of node the specified port connects to.
329  *    (See IEEE 1394-1995 4.3.4.1)
330  */
331 static int
selfid_port_type(s1394_selfid_pkt_t * s,int port)332 selfid_port_type(s1394_selfid_pkt_t *s, int port)
333 {
334 	int	block;
335 	int	offset = IEEE1394_SELFID_PORT_OFFSET_FIRST;
336 
337 	if (port > selfid_num_ports(s)) {
338 		TNF_PROBE_1(selfid_port_type_error,
339 		    "1394 s1394 error",
340 		    "Invalid port number requested for node",
341 		    tnf_uint, node_num, IEEE1394_SELFID_PHYID(s));
342 	}
343 
344 	if (port > 2) {
345 		/* Calculate which quadlet and bits for this port */
346 		port -= 3;
347 		block = (port >> 3) + 1;
348 		port = port % 8;
349 		/* Move to the correct quadlet */
350 		s += block;
351 		offset = IEEE1394_SELFID_PORT_OFFSET_OTHERS;
352 	}
353 
354 	/* Shift by appropriate number of bits and mask */
355 	return ((s->spkt_data >> (offset - 2 * port)) & 0x00000003);
356 }
357 
358 /*
359  * s1394_init_topology_tree()
360  *    frees any config rom's allocated in the topology tree before zapping it.
361  *    If it gets a bus reset before the tree is marked processed, there will
362  *    be memory allocated for cfgrom's being read. If there is no tree copy,
363  *    topology would still be topology tree from the previous generation and
364  *    if we bzero'd the tree, we will have a memory leak. To avoid this leak,
365  *    walk through the tree and free any config roms in nodes that are NOT
366  *    matched. (For matched nodes, we ensure that nodes in old and topology
367  *    tree point to the same area of memory.)
368  */
369 void
s1394_init_topology_tree(s1394_hal_t * hal,boolean_t copied,ushort_t number_of_nodes)370 s1394_init_topology_tree(s1394_hal_t *hal, boolean_t copied,
371     ushort_t number_of_nodes)
372 {
373 	s1394_node_t	*node;
374 	uint32_t	*config_rom;
375 	uint_t		tree_size;
376 	int		i;
377 
378 	TNF_PROBE_0_DEBUG(s1394_init_topology_tree_enter,
379 	    S1394_TNF_SL_BR_STACK, "");
380 
381 	ASSERT(MUTEX_HELD(&hal->topology_tree_mutex));
382 
383 	/*
384 	 * if copied is false, we want to free any cfgrom memory that is
385 	 * not referenced to in both topology and old trees. However, we
386 	 * don't use hal->number_of_nodes as the number of nodes to look at.
387 	 * The reason being we could be seeing the bus reset before the
388 	 * state is appropriate for a tree copy (which need
389 	 * toplogy_tree_processed to be true) and some nodes might have
390 	 * departed in this generation and hal->number_of_nodes reflects
391 	 * the number of nodes in this generation. Use number_of_nodes that
392 	 * gets passed into this routine as the actual number of nodes to
393 	 * look at.
394 	 */
395 	if (copied == B_FALSE) {
396 		/* Free any cfgrom alloced and zap the node */
397 		for (i = 0; i < number_of_nodes; i++) {
398 			node = &hal->topology_tree[i];
399 			config_rom = node->cfgrom;
400 			if (config_rom != NULL) {
401 				if (CFGROM_NEW_ALLOC(node) == B_TRUE) {
402 					TNF_PROBE_2_DEBUG(
403 					    s1394_init_top_tree_free_cfgrom,
404 					    S1394_TNF_SL_BR_STACK,
405 					    "cfgrom free", tnf_int, node_num, i,
406 					    tnf_opaque, cfgrom, config_rom);
407 					kmem_free((void *)config_rom,
408 					    IEEE1394_CONFIG_ROM_SZ);
409 				} else {
410 					TNF_PROBE_2_DEBUG(s1394_init_top_tree,
411 					    S1394_TNF_SL_BR_STACK, "",
412 					    tnf_int, node_num, i,
413 					    tnf_opaque, cfgrom, config_rom);
414 				}
415 			}
416 		}
417 	}
418 
419 	tree_size = hal->number_of_nodes * sizeof (s1394_node_t);
420 	bzero((void *)hal->topology_tree, tree_size);
421 
422 	TNF_PROBE_0_DEBUG(s1394_init_topology_tree_exit,
423 	    S1394_TNF_SL_BR_STACK, "");
424 }
425 
426 /*
427  * s1394_topology_tree_build()
428  *    takes the selfid_ptrs[] and builds the topology_tree[] by examining
429  *    the node numbers (the order in which the nodes responded to SelfID).
430  *    It sets the port pointers, leaf label, parent port, and
431  *    s1394_selfid_packet_t pointer in each node.
432  */
433 int
s1394_topology_tree_build(s1394_hal_t * hal)434 s1394_topology_tree_build(s1394_hal_t *hal)
435 {
436 	s1394_node_t	*tmp;
437 	uint32_t	number_of_nodes;
438 	boolean_t	push_to_orphan_stack = B_FALSE;
439 	boolean_t	found_parent = B_FALSE;
440 	boolean_t	found_connection = B_FALSE;
441 	int		i;
442 	int		j;
443 
444 	/*
445 	 * The method for building the tree is described in IEEE 1394-1995
446 	 * (Annex E.3.4).  We use an "Orphan" stack to keep track of Child
447 	 * nodes which have yet to find their Parent node.
448 	 */
449 
450 	TNF_PROBE_0_DEBUG(s1394_topology_tree_build_enter,
451 	    S1394_TNF_SL_BR_STACK, "");
452 
453 	ASSERT(MUTEX_HELD(&hal->topology_tree_mutex));
454 
455 	number_of_nodes = hal->number_of_nodes;
456 
457 	/* Flush the Stack */
458 	hal->hal_stack_depth = -1;
459 
460 	/* For each node on the bus initialize its topology_tree entry */
461 	for (i = 0; i < number_of_nodes; i++) {
462 		/* Make sure that node numbers are correct */
463 		if (i != IEEE1394_SELFID_PHYID(hal->selfid_ptrs[i])) {
464 			TNF_PROBE_1(s1394_topology_tree_build_error,
465 			    S1394_TNF_SL_BR_ERROR, "", tnf_string, msg,
466 			    "SelfIDs - Invalid node numbering");
467 
468 			/* Initiate a bus reset */
469 			s1394_initiate_hal_reset(hal, CRITICAL);
470 
471 			TNF_PROBE_0_DEBUG(s1394_topology_tree_build_exit,
472 			    S1394_TNF_SL_BR_STACK, "");
473 			return (DDI_FAILURE);
474 		}
475 
476 		hal->topology_tree[i].selfid_packet = hal->selfid_ptrs[i];
477 		hal->topology_tree[i].parent_port = (char)NO_PARENT;
478 		hal->topology_tree[i].is_a_leaf = 1;
479 		hal->topology_tree[i].node_num = (uchar_t)i;
480 	}
481 
482 	for (i = 0; i < number_of_nodes; i++) {
483 		/* Current node has no parent yet */
484 		found_parent = B_FALSE;
485 
486 		/* Current node has no connections yet */
487 		found_connection = B_FALSE;
488 
489 		/* Initialize all ports on this node */
490 		for (j = 0; j < IEEE1394_MAX_NUM_PORTS; j++)
491 			hal->topology_tree[i].phy_port[j] = NULL;
492 
493 		/* For each port on the node - highest to lowest */
494 		for (j = selfid_num_ports(hal->selfid_ptrs[i]) - 1;
495 		    j >= 0; j--) {
496 			if (selfid_port_type(hal->selfid_ptrs[i], j) ==
497 			    IEEE1394_SELFID_PORT_TO_PARENT) {
498 
499 				found_connection = B_TRUE;
500 				if (found_parent == B_FALSE) {
501 					push_to_orphan_stack = B_TRUE;
502 					hal->topology_tree[i].parent_port =
503 					    (char)j;
504 					found_parent = B_TRUE;
505 
506 				} else {
507 					TNF_PROBE_1(
508 					    s1394_topology_tree_build_error,
509 					    S1394_TNF_SL_BR_ERROR, "",
510 					    tnf_string, msg, "SelfID packet - "
511 					    "Has multiple parents");
512 
513 					/* Initiate a bus reset */
514 					s1394_initiate_hal_reset(hal, CRITICAL);
515 
516 					TNF_PROBE_0_DEBUG(
517 					    s1394_topology_tree_build_exit,
518 					    S1394_TNF_SL_BR_STACK, "");
519 					return (DDI_FAILURE);
520 				}
521 			} else if (selfid_port_type(hal->selfid_ptrs[i], j) ==
522 			    IEEE1394_SELFID_PORT_TO_CHILD) {
523 
524 				found_connection = B_TRUE;
525 				tmp = (s1394_node_t *)s1394_hal_stack_pop(hal);
526 				if (tmp == NULL) {
527 					TNF_PROBE_1(
528 					    s1394_topology_tree_build_error,
529 					    S1394_TNF_SL_BR_ERROR, "",
530 					    tnf_string, msg, "Topology Tree "
531 					    "invalid - Tree build failed");
532 
533 					/* Initiate a bus reset */
534 					s1394_initiate_hal_reset(hal, CRITICAL);
535 
536 					TNF_PROBE_0_DEBUG(
537 					    s1394_topology_tree_build_exit,
538 					    S1394_TNF_SL_BR_STACK, "");
539 					return (DDI_FAILURE);
540 				}
541 
542 				hal->topology_tree[i].phy_port[j] = tmp;
543 				hal->topology_tree[i].is_a_leaf = 0;
544 				tmp->phy_port[tmp->parent_port] =
545 				    &hal->topology_tree[i];
546 			}
547 		}
548 
549 		/* If current node has no parents or children - Invalid */
550 		if ((found_connection == B_FALSE) && (number_of_nodes > 1)) {
551 			TNF_PROBE_1(s1394_topology_tree_build_error,
552 			    S1394_TNF_SL_BR_ERROR, "", tnf_string, msg,
553 			    "SelfID packet - Has no connections");
554 
555 			/* Initiate a bus reset */
556 			s1394_initiate_hal_reset(hal, CRITICAL);
557 
558 			TNF_PROBE_0_DEBUG(s1394_topology_tree_build_exit,
559 			    S1394_TNF_SL_BR_STACK, "");
560 			return (DDI_FAILURE);
561 		}
562 
563 		/* Push it on the "Orphan" stack if it has no parent yet */
564 		if (push_to_orphan_stack == B_TRUE) {
565 			push_to_orphan_stack = B_FALSE;
566 			s1394_hal_stack_push(hal, &hal->topology_tree[i]);
567 		}
568 	}
569 
570 	/* If the stack is not empty, then something has gone seriously wrong */
571 	if (hal->hal_stack_depth != -1) {
572 		TNF_PROBE_1(s1394_topology_tree_build_error,
573 		    S1394_TNF_SL_BR_ERROR, "", tnf_string, msg,
574 		    "Topology Tree invalid - Tree build failed");
575 
576 		/* Initiate a bus reset */
577 		s1394_initiate_hal_reset(hal, CRITICAL);
578 
579 		TNF_PROBE_0_DEBUG(s1394_topology_tree_build_exit,
580 		    S1394_TNF_SL_BR_STACK, "");
581 		return (DDI_FAILURE);
582 	}
583 
584 	/* New topology tree is now valid */
585 	hal->topology_tree_valid = B_TRUE;
586 
587 	TNF_PROBE_0_DEBUG(s1394_topology_tree_build_exit,
588 	    S1394_TNF_SL_BR_STACK, "");
589 	return (DDI_SUCCESS);
590 }
591 
592 /*
593  * s1394_hal_stack_push()
594  *    checks that the stack is not full, and puts the pointer on top of the
595  *    HAL's stack if it isn't.  This routine is used only by the
596  *    h1394_self_ids() interrupt.
597  */
598 static void
s1394_hal_stack_push(s1394_hal_t * hal,void * obj)599 s1394_hal_stack_push(s1394_hal_t *hal, void *obj)
600 {
601 	TNF_PROBE_0_DEBUG(s1394_hal_stack_push_enter,
602 	    S1394_TNF_SL_BR_STACK, "");
603 
604 	if (hal->hal_stack_depth < IEEE1394_MAX_NODES - 1) {
605 		hal->hal_stack_depth++;
606 		hal->hal_stack[hal->hal_stack_depth] = obj;
607 	} else {
608 		TNF_PROBE_1(s1394_hal_stack_push_error,
609 		    S1394_TNF_SL_BR_ERROR, "", tnf_string, msg,
610 		    "HAL stack - Overflow");
611 		TNF_PROBE_0_DEBUG(s1394_hal_stack_push_exit,
612 		    S1394_TNF_SL_BR_STACK, "");
613 		return;
614 	}
615 
616 	TNF_PROBE_0_DEBUG(s1394_hal_stack_push_exit,
617 	    S1394_TNF_SL_BR_STACK, "");
618 }
619 
620 /*
621  * s1394_hal_stack_pop()
622  *    checks that the stack is not empty, and pops and returns the pointer
623  *    from the top of the HAL's stack if it isn't.  This routine is used
624  *    only by the h1394_self_ids() interrupt.
625  */
626 static void *
s1394_hal_stack_pop(s1394_hal_t * hal)627 s1394_hal_stack_pop(s1394_hal_t *hal)
628 {
629 	TNF_PROBE_0_DEBUG(s1394_hal_stack_pop_enter,
630 	    S1394_TNF_SL_BR_STACK, "");
631 
632 	if (hal->hal_stack_depth > -1) {
633 		hal->hal_stack_depth--;
634 		TNF_PROBE_0_DEBUG(s1394_hal_stack_pop_exit,
635 		    S1394_TNF_SL_BR_STACK, "");
636 		return (hal->hal_stack[hal->hal_stack_depth + 1]);
637 
638 	} else {
639 		TNF_PROBE_1(s1394_hal_stack_pop_error,
640 		    S1394_TNF_SL_BR_ERROR, "", tnf_string, msg,
641 		    "HAL stack - Underflow");
642 		TNF_PROBE_0_DEBUG(s1394_hal_stack_pop_exit,
643 		    S1394_TNF_SL_BR_STACK, "");
644 		return (NULL);
645 	}
646 }
647 
648 /*
649  * s1394_hal_queue_insert()
650  *    checks that the queue is not full, and puts the object in the front
651  *    of the HAL's queue if it isn't.  This routine is used only by the
652  *    h1394_self_ids() interrupt.
653  */
654 static void
s1394_hal_queue_insert(s1394_hal_t * hal,void * obj)655 s1394_hal_queue_insert(s1394_hal_t *hal, void *obj)
656 {
657 	TNF_PROBE_0_DEBUG(s1394_hal_queue_insert_enter,
658 	    S1394_TNF_SL_BR_STACK, "");
659 
660 	if (((hal->hal_queue_front + 1) % IEEE1394_MAX_NODES) ==
661 	    hal->hal_queue_back) {
662 		TNF_PROBE_1(s1394_hal_queue_insert_error,
663 		    S1394_TNF_SL_BR_ERROR, "", tnf_string, msg,
664 		    "HAL Queue - Overflow");
665 		TNF_PROBE_0_DEBUG(s1394_hal_queue_insert_exit,
666 		    S1394_TNF_SL_BR_STACK, "");
667 		return;
668 
669 	} else {
670 		hal->hal_queue[hal->hal_queue_front] = obj;
671 		hal->hal_queue_front = (hal->hal_queue_front + 1) %
672 		    IEEE1394_MAX_NODES;
673 	}
674 
675 	TNF_PROBE_0_DEBUG(s1394_hal_queue_insert_exit,
676 	    S1394_TNF_SL_BR_STACK, "");
677 }
678 
679 
680 /*
681  * s1394_hal_queue_remove()
682  *    checks that the queue is not empty, and pulls the object off the back
683  *    of the HAL's queue (and returns it) if it isn't.  This routine is used
684  *    only by the h1394_self_ids() interrupt.
685  */
686 static void *
s1394_hal_queue_remove(s1394_hal_t * hal)687 s1394_hal_queue_remove(s1394_hal_t *hal)
688 {
689 	void	*tmp;
690 
691 	TNF_PROBE_0_DEBUG(s1394_hal_queue_remove_enter,
692 	    S1394_TNF_SL_BR_STACK, "");
693 
694 	if (hal->hal_queue_back == hal->hal_queue_front) {
695 		TNF_PROBE_1(s1394_hal_queue_remove_error,
696 		    S1394_TNF_SL_BR_ERROR, "", tnf_string, msg,
697 		    "HAL Queue - Underflow");
698 		TNF_PROBE_0_DEBUG(s1394_hal_queue_remove_exit,
699 		    S1394_TNF_SL_BR_STACK, "");
700 		return (NULL);
701 
702 	} else {
703 		tmp = hal->hal_queue[hal->hal_queue_back];
704 		hal->hal_queue_back = (hal->hal_queue_back + 1) %
705 		    IEEE1394_MAX_NODES;
706 		TNF_PROBE_0_DEBUG(s1394_hal_queue_remove_exit,
707 		    S1394_TNF_SL_BR_STACK, "");
708 		return (tmp);
709 	}
710 }
711 
712 
713 /*
714  * s1394_node_number_list_add()
715  *    checks that the node_number_list is not full and puts the node number
716  *    in the list.  The function is used primarily by s1394_speed_map_fill()
717  *    to keep track of which connections need to be set in the speed_map[].
718  *    This routine is used only by the h1394_self_ids() interrupt.
719  */
720 static void
s1394_node_number_list_add(s1394_hal_t * hal,int node_num)721 s1394_node_number_list_add(s1394_hal_t *hal, int node_num)
722 {
723 	TNF_PROBE_1_DEBUG(s1394_node_number_list_add_enter,
724 	    S1394_TNF_SL_BR_STACK, "", tnf_int, node_num, node_num);
725 
726 	if (hal->hal_node_number_list_size >= IEEE1394_MAX_NODES - 1) {
727 		TNF_PROBE_1(s1394_node_number_list_add_error,
728 		    S1394_TNF_SL_BR_ERROR, "", tnf_string, msg,
729 		    "Node Number List - Overflow");
730 		TNF_PROBE_0_DEBUG(s1394_node_number_list_add_exit,
731 		    S1394_TNF_SL_BR_STACK, "");
732 		return;
733 	}
734 
735 	hal->hal_node_number_list[hal->hal_node_number_list_size] = node_num;
736 	hal->hal_node_number_list_size++;
737 
738 	TNF_PROBE_0_DEBUG(s1394_node_number_list_add_exit,
739 	    S1394_TNF_SL_BR_STACK, "");
740 }
741 
742 /*
743  * s1394_topology_tree_mark_all_unvisited()
744  *    is used to initialize the topology_tree[] prior to tree traversals.
745  *    It resets the "visited" flag for each node in the tree.
746  */
747 void
s1394_topology_tree_mark_all_unvisited(s1394_hal_t * hal)748 s1394_topology_tree_mark_all_unvisited(s1394_hal_t *hal)
749 {
750 	uint_t	number_of_nodes;
751 	int	i;
752 
753 	TNF_PROBE_0_DEBUG(s1394_topology_tree_mark_all_unvisited_enter,
754 	    S1394_TNF_SL_BR_STACK, "");
755 
756 	ASSERT(MUTEX_HELD(&hal->topology_tree_mutex));
757 
758 	number_of_nodes = hal->number_of_nodes;
759 	for (i = 0; i < number_of_nodes; i++)
760 		CLEAR_NODE_VISITED(&hal->topology_tree[i]);
761 
762 	TNF_PROBE_0_DEBUG(s1394_topology_tree_mark_all_unvisited_exit,
763 	    S1394_TNF_SL_BR_STACK, "");
764 }
765 
766 /*
767  * s1394_old_tree_mark_all_unvisited()
768  *    is used to initialize the old_tree[] prior to tree traversals.  It
769  *    resets the "visited" flag for each node in the tree.
770  */
771 void
s1394_old_tree_mark_all_unvisited(s1394_hal_t * hal)772 s1394_old_tree_mark_all_unvisited(s1394_hal_t *hal)
773 {
774 	uint_t	number_of_nodes;
775 	int	i;
776 
777 	TNF_PROBE_0_DEBUG(s1394_old_tree_mark_all_unvisited_enter,
778 	    S1394_TNF_SL_BR_STACK, "");
779 
780 	ASSERT(MUTEX_HELD(&hal->topology_tree_mutex));
781 
782 	number_of_nodes = hal->old_number_of_nodes;
783 	for (i = 0; i < number_of_nodes; i++)
784 		CLEAR_NODE_VISITED(&hal->old_tree[i]);
785 
786 	TNF_PROBE_0_DEBUG(s1394_old_tree_mark_all_unvisited_exit,
787 	    S1394_TNF_SL_BR_STACK, "");
788 }
789 
790 /*
791  * s1394_old_tree_mark_all_unmatched()
792  *    is used to initialize the old_tree[] prior to tree traversals.  It
793  *    resets the "matched" flag for each node in the tree.
794  */
795 void
s1394_old_tree_mark_all_unmatched(s1394_hal_t * hal)796 s1394_old_tree_mark_all_unmatched(s1394_hal_t *hal)
797 {
798 	uint_t	number_of_nodes;
799 	int	i;
800 
801 	TNF_PROBE_0_DEBUG(s1394_old_tree_mark_all_unmatched_enter,
802 	    S1394_TNF_SL_BR_STACK, "");
803 
804 	ASSERT(MUTEX_HELD(&hal->topology_tree_mutex));
805 
806 	number_of_nodes = hal->old_number_of_nodes;
807 
808 	for (i = 0; i < number_of_nodes; i++)
809 	    CLEAR_NODE_MATCHED(&hal->old_tree[i]);
810 
811 	TNF_PROBE_0_DEBUG(s1394_old_tree_mark_all_unmatched_exit,
812 	    S1394_TNF_SL_BR_STACK, "");
813 }
814 
815 /*
816  * s1394_copy_old_tree()
817  *    switches the pointers for old_tree[] and topology_tree[].
818  */
819 void
s1394_copy_old_tree(s1394_hal_t * hal)820 s1394_copy_old_tree(s1394_hal_t *hal)
821 {
822 	s1394_node_t	*temp;
823 
824 	TNF_PROBE_0_DEBUG(s1394_copy_old_tree_enter,
825 	    S1394_TNF_SL_BR_STACK, "");
826 
827 	ASSERT(MUTEX_HELD(&hal->topology_tree_mutex));
828 
829 	temp = hal->old_tree;
830 	hal->old_tree = hal->topology_tree;
831 	hal->topology_tree = temp;
832 
833 	hal->old_number_of_nodes = hal->number_of_nodes;
834 	hal->old_node_id = hal->node_id;
835 	hal->old_generation_count = hal->generation_count;
836 
837 	/* Old tree is now valid and filled also */
838 	hal->old_tree_valid = B_TRUE;
839 
840 	TNF_PROBE_0_DEBUG(s1394_copy_old_tree_exit,
841 	    S1394_TNF_SL_BR_STACK, "");
842 }
843 
844 
845 /*
846  * s1394_match_tree_nodes()
847  *    uses the information contained in the SelfID packets of the nodes in
848  *    both the old_tree[] and the topology_tree[] to determine which new
849  *    nodes correspond to old nodes.  Starting with the local node, we
850  *    compare both old and new node's ports.  Assuming that only one bus
851  *    reset has occurred, any node that was connected to another in the old
852  *    bus and is still connected to another in the new bus must be connected
853  *    (physically) to the same node.  Using this information, we can rebuild
854  *    and match the old nodes to new ones.  Any nodes which aren't matched
855  *    are either departing or arriving nodes and must be handled appropriately.
856  */
857 void
s1394_match_tree_nodes(s1394_hal_t * hal)858 s1394_match_tree_nodes(s1394_hal_t *hal)
859 {
860 	s1394_node_t	*tmp;
861 	uint_t		hal_node_num;
862 	uint_t		hal_node_num_old;
863 	int		i;
864 	int		port_type;
865 
866 	TNF_PROBE_0_DEBUG(s1394_match_tree_nodes_enter,
867 	    S1394_TNF_SL_BR_STACK, "");
868 
869 	ASSERT(MUTEX_HELD(&hal->topology_tree_mutex));
870 
871 	/* To ensure that the queue is empty */
872 	hal->hal_queue_front = hal->hal_queue_back = 0;
873 
874 	/* Set up the first matched nodes (which are our own local nodes) */
875 	hal_node_num = IEEE1394_NODE_NUM(hal->node_id);
876 	hal_node_num_old = IEEE1394_NODE_NUM(hal->old_node_id);
877 	hal->topology_tree[hal_node_num].old_node =
878 	    &hal->old_tree[hal_node_num_old];
879 	hal->old_tree[hal_node_num_old].cur_node =
880 	    &hal->topology_tree[hal_node_num];
881 
882 	/* Put the node on the queue */
883 	s1394_hal_queue_insert(hal, &hal->topology_tree[hal_node_num]);
884 
885 	/* While the queue is not empty, remove a node */
886 	while (hal->hal_queue_front != hal->hal_queue_back) {
887 		tmp = (s1394_node_t *)s1394_hal_queue_remove(hal);
888 
889 	    /* Mark both old and new nodes as "visited" */
890 	    SET_NODE_VISITED(tmp);
891 	    SET_NODE_VISITED(tmp->old_node);
892 	    tmp->old_node->cur_node = tmp;
893 
894 	    /* Mark old and new nodes as "matched" */
895 	    SET_NODE_MATCHED(tmp);
896 	    SET_NODE_MATCHED(tmp->old_node);
897 	    s1394_copy_cfgrom(tmp, tmp->old_node);
898 
899 	    /* s1394_copy_cfgrom() clears "matched" for some cases... */
900 	    if ((tmp->cfgrom != NULL && CONFIG_ROM_GEN(tmp->cfgrom) <= 1) ||
901 		NODE_MATCHED(tmp) == B_TRUE) {
902 		/* Move the target list over to the new node and update */
903 		/* the node info. */
904 			s1394_target_t *t;
905 
906 			rw_enter(&hal->target_list_rwlock, RW_WRITER);
907 			t = tmp->target_list = tmp->old_node->target_list;
908 			while (t != NULL) {
909 				t->on_node = tmp;
910 				t = t->target_sibling;
911 			}
912 			rw_exit(&hal->target_list_rwlock);
913 		}
914 
915 		for (i = 0; i < selfid_num_ports(tmp->selfid_packet); i++) {
916 			port_type = selfid_port_type(tmp->selfid_packet, i);
917 
918 			/* Is the new port connected? */
919 			if ((port_type == IEEE1394_SELFID_PORT_TO_CHILD) ||
920 			    (port_type == IEEE1394_SELFID_PORT_TO_PARENT)) {
921 				port_type = selfid_port_type(
922 				    tmp->old_node->selfid_packet, i);
923 
924 				/* Is the old port connected? */
925 				if ((port_type ==
926 					IEEE1394_SELFID_PORT_TO_CHILD) ||
927 				    (port_type ==
928 					IEEE1394_SELFID_PORT_TO_PARENT)) {
929 					/* Found a match, check if */
930 					/* we've already visited it */
931 					if (!NODE_VISITED(tmp->phy_port[i])) {
932 						tmp->phy_port[i]->old_node =
933 						    tmp->old_node->phy_port[i];
934 						s1394_hal_queue_insert(hal,
935 						    tmp->phy_port[i]);
936 					}
937 				}
938 			}
939 		}
940 	}
941 
942 	TNF_PROBE_0_DEBUG(s1394_match_tree_nodes_exit,
943 	    S1394_TNF_SL_BR_STACK, "");
944 }
945 
946 /*
947  * s1394_topology_tree_calculate_diameter()
948  *    does a depth-first tree traversal, tracking at each branch the first
949  *    and second deepest paths though that branch's children.  The diameter
950  *    is given by the maximum of these over all branch nodes
951  */
952 int
s1394_topology_tree_calculate_diameter(s1394_hal_t * hal)953 s1394_topology_tree_calculate_diameter(s1394_hal_t *hal)
954 {
955 	s1394_node_t	*current;
956 	uint_t		number_of_nodes;
957 	int		i;
958 	int		start;
959 	int		end;
960 	boolean_t	done;
961 	boolean_t	found_a_child;
962 	int		distance = 0;
963 	int		diameter = 0;
964 	int		local_diameter = 0;
965 
966 	TNF_PROBE_0_DEBUG(s1394_topology_tree_calculate_diameter_enter,
967 	    S1394_TNF_SL_BR_STACK, "");
968 
969 	ASSERT(MUTEX_HELD(&hal->topology_tree_mutex));
970 
971 	number_of_nodes = hal->number_of_nodes;
972 
973 	/* Initialize topology tree */
974 	for (i = 0; i < number_of_nodes; i++) {
975 		hal->topology_tree[i].max_1st = 0;
976 		hal->topology_tree[i].max_2nd = 0;
977 		hal->topology_tree[i].last_port_checked = 0;
978 	}
979 
980 	/* Start at the root node */
981 	current = s1394_topology_tree_get_root_node(hal);
982 
983 	/* Flush the stack before we start */
984 	hal->hal_stack_depth = -1;
985 
986 	do {
987 		done		= B_FALSE;
988 		found_a_child	= B_FALSE;
989 		start		= current->last_port_checked;
990 		end		= selfid_num_ports(current->selfid_packet);
991 
992 		/* Check every previously unchecked port for children */
993 		for (i = start; i < end; i++) {
994 			current->last_port_checked++;
995 			/* If there is a child push it on the stack */
996 			if (selfid_port_type(current->selfid_packet, i) ==
997 			    IEEE1394_SELFID_PORT_TO_CHILD) {
998 				found_a_child = B_TRUE;
999 				s1394_hal_stack_push(hal, current);
1000 				current = current->phy_port[i];
1001 				break;
1002 			}
1003 		}
1004 
1005 		/* If we reach here and the stack is empty, we're done */
1006 		if (hal->hal_stack_depth == -1) {
1007 			done = B_TRUE;
1008 			continue;
1009 		}
1010 
1011 		/* If no children were found, we're at a leaf */
1012 		if (found_a_child == B_FALSE) {
1013 			distance = current->max_1st + 1;
1014 			/* Pop the child and set the appropriate fields */
1015 			current = s1394_hal_stack_pop(hal);
1016 			if (distance > current->max_1st) {
1017 				current->max_2nd = current->max_1st;
1018 				current->max_1st = (uchar_t)distance;
1019 
1020 			} else if (distance > current->max_2nd) {
1021 				current->max_2nd = (uchar_t)distance;
1022 			}
1023 
1024 			/* Update maximum distance (diameter), if necessary */
1025 			local_diameter = current->max_1st + current->max_2nd;
1026 			if (local_diameter > diameter)
1027 				diameter = local_diameter;
1028 		}
1029 	} while (done == B_FALSE);
1030 
1031 	TNF_PROBE_0_DEBUG(s1394_topology_tree_calculate_diameter_exit,
1032 	    S1394_TNF_SL_BR_STACK, "");
1033 	return (diameter);
1034 }
1035 
1036 /*
1037  * s1394_gap_count_optimize()
1038  *    looks in a table to find the appropriate gap_count for a given diameter.
1039  *    (See above - gap_count[])
1040  */
1041 int
s1394_gap_count_optimize(int diameter)1042 s1394_gap_count_optimize(int diameter)
1043 {
1044 	if ((diameter >= 0) && (diameter <= MAX_HOPS)) {
1045 		return (gap_count[diameter]);
1046 	} else {
1047 		cmn_err(CE_NOTE, "Too may point-to-point links on the 1394"
1048 		    " bus - If new devices have recently been added, remove"
1049 		    " them.");
1050 		return (gap_count[MAX_HOPS]);
1051 	}
1052 }
1053 
1054 /*
1055  * s1394_get_current_gap_count()
1056  *    looks at all the SelfID packets to determine the current gap_count on
1057  *    the 1394 bus.  If the gap_counts differ from node to node, it initiates
1058  *    a bus reset and returns -1.
1059  */
1060 int
s1394_get_current_gap_count(s1394_hal_t * hal)1061 s1394_get_current_gap_count(s1394_hal_t *hal)
1062 {
1063 	int	i;
1064 	int	gap_count = -1;
1065 
1066 	TNF_PROBE_0_DEBUG(s1394_get_current_gap_count_enter,
1067 	    S1394_TNF_SL_BR_STACK, "");
1068 
1069 	ASSERT(MUTEX_HELD(&hal->topology_tree_mutex));
1070 
1071 	/* Grab the first gap_count in the SelfID packets */
1072 	gap_count = IEEE1394_SELFID_GAP_CNT(hal->selfid_ptrs[0]);
1073 
1074 	/* Compare it too all the rest */
1075 	for (i = 1; i < hal->number_of_nodes; i++) {
1076 		if (gap_count !=
1077 		    IEEE1394_SELFID_GAP_CNT(hal->selfid_ptrs[i])) {
1078 
1079 			/* Inconsistent gap counts */
1080 			TNF_PROBE_1(s1394_get_current_gap_count_error,
1081 			    S1394_TNF_SL_BR_ERROR, "", tnf_string, msg,
1082 			    "Inconsistent gap count");
1083 
1084 			if (s1394_ignore_invalid_gap_cnt == 0) {
1085 				/* Initiate a bus reset */
1086 				s1394_initiate_hal_reset(hal, CRITICAL);
1087 			}
1088 
1089 			TNF_PROBE_0_DEBUG(s1394_get_current_gap_count_exit,
1090 			    S1394_TNF_SL_BR_STACK, "");
1091 			return (-1);
1092 		}
1093 	}
1094 
1095 	TNF_PROBE_0_DEBUG(s1394_get_current_gap_count_exit,
1096 	    S1394_TNF_SL_BR_STACK, "");
1097 	return (gap_count);
1098 }
1099 
1100 /*
1101  * s1394_speed_map_fill()
1102  *    determines, for each pair of nodes, the maximum speed at which those
1103  *    nodes can communicate.  The speed of each node as well as the speed of
1104  *    any intermediate nodes on a given path must be accounted for, as the
1105  *    minimum speed on a given edge determines the maximum speed for all
1106  *    communications across that edge.
1107  *    In the method we implement below, a current minimum speed is selected.
1108  *    With this minimum speed in mind, we create subgraphs of the original
1109  *    bus which contain only edges that connect two nodes whose speeds are
1110  *    equal to or greater than the current minimum speed.  Then, for each of
1111  *    the subgraphs, we visit every node, keeping a list of the nodes we've
1112  *    visited.  When this list is completed, we can fill in the entries in
1113  *    the speed map which correspond to a pairs of these nodes.  Doing this
1114  *    for each subgraph and then for each speed we progressively fill in the
1115  *    parts of the speed map which weren't previously filled in.
1116  */
1117 void
s1394_speed_map_fill(s1394_hal_t * hal)1118 s1394_speed_map_fill(s1394_hal_t *hal)
1119 {
1120 	uint_t	number_of_nodes;
1121 	int	i;
1122 	int	j;
1123 	int	node_num;
1124 
1125 	TNF_PROBE_0_DEBUG(s1394_speed_map_fill_enter,
1126 	    S1394_TNF_SL_BR_STACK, "");
1127 
1128 	ASSERT(MUTEX_HELD(&hal->topology_tree_mutex));
1129 
1130 	number_of_nodes = hal->number_of_nodes;
1131 	s1394_speed_map_initialize(hal);
1132 
1133 	/* Mark all speed = IEEE1394_S100 nodes in the Speed Map */
1134 	for (i = 0; i < number_of_nodes; i++) {
1135 		if (selfid_speed(hal->topology_tree[i].selfid_packet) ==
1136 		    IEEE1394_S100) {
1137 			hal->slowest_node_speed = IEEE1394_S100;
1138 			node_num = IEEE1394_SELFID_PHYID(
1139 			    hal->topology_tree[i].selfid_packet);
1140 			for (j = 0; j < number_of_nodes; j++) {
1141 				if (j != node_num) {
1142 					hal->speed_map[node_num][j] =
1143 					    IEEE1394_S100;
1144 					hal->speed_map[j][node_num] =
1145 					    IEEE1394_S100;
1146 				}
1147 			}
1148 		}
1149 	}
1150 
1151 	s1394_speed_map_fill_speed_N(hal, IEEE1394_S200);
1152 	s1394_speed_map_fill_speed_N(hal, IEEE1394_S400);
1153 
1154 	/* Fill in the diagonal */
1155 	for (i = 0; i < number_of_nodes; i++) {
1156 		hal->speed_map[i][i] =
1157 		    selfid_speed(hal->topology_tree[i].selfid_packet);
1158 	}
1159 
1160 	TNF_PROBE_0_DEBUG(s1394_speed_map_fill_exit,
1161 	    S1394_TNF_SL_BR_STACK, "");
1162 }
1163 
1164 /*
1165  * s1394_speed_map_fill_speed_N(),
1166  *    given a minimum link speed, creates subgraphs of the original bus which
1167  *    contain only the necessary edges (see speed_map_fill() above).  For each
1168  *    of the subgraphs, it visits and fills in the entries in the speed map
1169  *    which correspond to a pair of these nodes.
1170  */
1171 static void
s1394_speed_map_fill_speed_N(s1394_hal_t * hal,int min_spd)1172 s1394_speed_map_fill_speed_N(s1394_hal_t *hal, int min_spd)
1173 {
1174 	s1394_node_t	*tmp;
1175 	uint_t		number_of_nodes;
1176 	int		i;
1177 	int		j;
1178 	int		k;
1179 	int		size;
1180 	int		ix_a, ix_b;
1181 
1182 	TNF_PROBE_0_DEBUG(s1394_speed_map_fill_speed_N_enter,
1183 	    S1394_TNF_SL_BR_STACK, "");
1184 
1185 	ASSERT(MUTEX_HELD(&hal->topology_tree_mutex));
1186 
1187 	number_of_nodes = hal->number_of_nodes;
1188 
1189 	/* Prepare the topology tree */
1190 	s1394_topology_tree_mark_all_unvisited(hal);
1191 
1192 	/* To ensure that the queue is empty */
1193 	hal->hal_queue_front = hal->hal_queue_back = 0;
1194 
1195 	for (i = 0; i < number_of_nodes; i++) {
1196 		/* If the node's speed == min_spd and it hasn't been visited */
1197 		if (!NODE_VISITED(&hal->topology_tree[i]) &&
1198 		    (selfid_speed(hal->topology_tree[i].selfid_packet) ==
1199 			min_spd)) {
1200 
1201 			if (min_spd < hal->slowest_node_speed)
1202 				hal->slowest_node_speed = (uint8_t)min_spd;
1203 
1204 			SET_NODE_VISITED(&hal->topology_tree[i]);
1205 			s1394_hal_queue_insert(hal, &hal->topology_tree[i]);
1206 
1207 			while (hal->hal_queue_front != hal->hal_queue_back) {
1208 				tmp = (s1394_node_t *)s1394_hal_queue_remove(
1209 				    hal);
1210 				/* Add node number to the list */
1211 				s1394_node_number_list_add(hal,
1212 				    IEEE1394_SELFID_PHYID(tmp->selfid_packet));
1213 
1214 				for (j = 0; j < IEEE1394_MAX_NUM_PORTS; j++) {
1215 					if ((tmp->phy_port[j] != NULL) &&
1216 					    (!NODE_VISITED(tmp->phy_port[j]))) {
1217 						if (selfid_speed(
1218 						    tmp->phy_port[j]->
1219 						    selfid_packet) >= min_spd) {
1220 							SET_NODE_VISITED(
1221 							    tmp->phy_port[j]);
1222 							s1394_hal_queue_insert(
1223 							    hal,
1224 							    tmp->phy_port[j]);
1225 						}
1226 					}
1227 				}
1228 			}
1229 
1230 			/* For each pair, mark speed_map as min_spd */
1231 			size = hal->hal_node_number_list_size;
1232 			for (j = 0; j < size; j++) {
1233 				for (k = 0; k < size; k++) {
1234 					if (j != k) {
1235 						ix_a = hal->
1236 						    hal_node_number_list[j];
1237 						ix_b = hal->
1238 						    hal_node_number_list[k];
1239 						hal->speed_map[ix_a][ix_b] =
1240 						    (uint8_t)min_spd;
1241 					}
1242 				}
1243 			}
1244 
1245 			/* Flush the Node Number List */
1246 			hal->hal_node_number_list_size = 0;
1247 		}
1248 	}
1249 
1250 	TNF_PROBE_0_DEBUG(s1394_speed_map_fill_speed_N_exit,
1251 	    S1394_TNF_SL_BR_STACK, "");
1252 }
1253 
1254 /*
1255  * s1394_speed_map_initialize()
1256  *    fills in the speed_map with IEEE1394_S100's and SPEED_MAP_INVALID's in
1257  *    the appropriate places.  These will be overwritten by
1258  *    s1394_speed_map_fill().
1259  */
1260 static void
s1394_speed_map_initialize(s1394_hal_t * hal)1261 s1394_speed_map_initialize(s1394_hal_t *hal)
1262 {
1263 	uint_t	number_of_nodes;
1264 	int	i, j;
1265 
1266 	TNF_PROBE_0_DEBUG(s1394_speed_map_initialize_enter,
1267 	    S1394_TNF_SL_BR_STACK, "");
1268 
1269 	ASSERT(MUTEX_HELD(&hal->topology_tree_mutex));
1270 
1271 	number_of_nodes = hal->number_of_nodes;
1272 	for (i = 0; i < number_of_nodes; i++) {
1273 		for (j = 0; j < number_of_nodes; j++) {
1274 			if (i != j)
1275 				hal->speed_map[i][j] = IEEE1394_S100;
1276 			else
1277 				hal->speed_map[i][j] = SPEED_MAP_INVALID;
1278 		}
1279 	}
1280 
1281 	TNF_PROBE_0_DEBUG(s1394_speed_map_initialize_exit,
1282 	    S1394_TNF_SL_BR_STACK, "");
1283 }
1284 
1285 /*
1286  * s1394_speed_map_get()
1287  *    queries the speed_map[] for a given pair of nodes.
1288  */
1289 uint8_t
s1394_speed_map_get(s1394_hal_t * hal,uint_t from_node,uint_t to_node)1290 s1394_speed_map_get(s1394_hal_t *hal, uint_t from_node, uint_t to_node)
1291 {
1292 	/* If it's not a valid node, then return slowest_node_speed */
1293 	if (to_node >= hal->number_of_nodes) {
1294 		/* Send at fastest speed everyone will see */
1295 		return (hal->slowest_node_speed);
1296 	}
1297 	/* else return the correct maximum speed */
1298 	return (hal->speed_map[from_node][to_node]);
1299 }
1300 
1301 /*
1302  * s1394_update_speed_map_link_speeds()
1303  *    takes into account information from Config ROM queries.  Any P1394A
1304  *    device can have a link with a different speed than its PHY.  In this
1305  *    case, the slower speed must be accounted for in order for communication
1306  *    with the remote node to work.
1307  */
1308 void
s1394_update_speed_map_link_speeds(s1394_hal_t * hal)1309 s1394_update_speed_map_link_speeds(s1394_hal_t *hal)
1310 {
1311 	uint32_t bus_capabilities;
1312 	uint8_t	 link_speed;
1313 	uint_t	 number_of_nodes;
1314 	int	 i, j;
1315 
1316 	TNF_PROBE_0_DEBUG(s1394_update_speed_map_link_speeds_enter,
1317 	    S1394_TNF_SL_BR_STACK, "");
1318 
1319 	ASSERT(MUTEX_HELD(&hal->topology_tree_mutex));
1320 
1321 	number_of_nodes = hal->number_of_nodes;
1322 
1323 	for (i = 0; i < number_of_nodes; i++) {
1324 
1325 		/* Skip invalid config ROMs */
1326 		if (CFGROM_VALID(&hal->topology_tree[i])) {
1327 
1328 			ASSERT(hal->topology_tree[i].cfgrom);
1329 
1330 			bus_capabilities = hal->topology_tree[i].
1331 			    cfgrom[IEEE1212_NODE_CAP_QUAD];
1332 
1333 			/* Skip if Bus_Info_Block generation is 0 */
1334 			/* because it isn't a P1394a device */
1335 			if ((bus_capabilities & IEEE1394_BIB_GEN_MASK) != 0) {
1336 				link_speed = (bus_capabilities &
1337 				    IEEE1394_BIB_LNK_SPD_MASK);
1338 
1339 				for (j = 0; j < number_of_nodes; j++) {
1340 					/* Update if link_speed is slower */
1341 					if (hal->speed_map[i][j] > link_speed) {
1342 						hal->speed_map[i][j] =
1343 						    link_speed;
1344 						hal->speed_map[j][i] =
1345 						    link_speed;
1346 					}
1347 
1348 					if (link_speed <
1349 					    hal->slowest_node_speed)
1350 						hal->slowest_node_speed =
1351 						    link_speed;
1352 				}
1353 			}
1354 		}
1355 	}
1356 
1357 	TNF_PROBE_0_DEBUG(s1394_update_speed_map_link_speeds_exit,
1358 	    S1394_TNF_SL_BR_STACK, "");
1359 }
1360 
1361 /*
1362  * s1394_get_isoch_rsrc_mgr()
1363  *    looks at the SelfID packets to determine the Isochronous Resource
1364  *    Manager's node ID.  The IRM is the highest numbered node with both
1365  *    the "L"-bit and the "C"-bit in its SelfID packets turned on.  If no
1366  *    IRM is found on the bus, then -1 is returned.
1367  */
1368 int
s1394_get_isoch_rsrc_mgr(s1394_hal_t * hal)1369 s1394_get_isoch_rsrc_mgr(s1394_hal_t *hal)
1370 {
1371 	int	i;
1372 
1373 	TNF_PROBE_0_DEBUG(s1394_get_isoch_rsrc_mgr_enter, S1394_TNF_SL_BR_STACK,
1374 	    "");
1375 
1376 	ASSERT(MUTEX_HELD(&hal->topology_tree_mutex));
1377 
1378 	for (i = hal->number_of_nodes - 1; i >= 0; i--) {
1379 		/* Highest numbered node with L=1 and C=1 */
1380 		if ((IEEE1394_SELFID_ISLINKON(hal->selfid_ptrs[i])) &&
1381 		    (IEEE1394_SELFID_ISCONTENDER(hal->selfid_ptrs[i]))) {
1382 
1383 			TNF_PROBE_0_DEBUG(s1394_get_isoch_rsrc_mgr_exit,
1384 			    S1394_TNF_SL_BR_STACK, "");
1385 			return (i);
1386 		}
1387 	}
1388 
1389 	/* No Isochronous Resource Manager */
1390 	TNF_PROBE_0_DEBUG(s1394_get_isoch_rsrc_mgr_exit, S1394_TNF_SL_BR_STACK,
1391 	    "");
1392 	return (-1);
1393 }
1394 
1395 /*
1396  * s1394_physical_arreq_setup_all()
1397  *    is used to enable the physical filters for the link.  If a target has
1398  *    registered physical space allocations, then the corresponding node's
1399  *    bit is set.  This is done for all targets on a HAL (usually after bus
1400  *    reset).
1401  */
1402 void
s1394_physical_arreq_setup_all(s1394_hal_t * hal)1403 s1394_physical_arreq_setup_all(s1394_hal_t *hal)
1404 {
1405 	s1394_target_t	*curr_target;
1406 	uint64_t	mask = 0;
1407 	uint32_t	node_num;
1408 	uint_t		generation;
1409 
1410 	TNF_PROBE_0_DEBUG(s1394_physical_arreq_setup_all_enter,
1411 	    S1394_TNF_SL_BR_STACK, "");
1412 
1413 	ASSERT(MUTEX_NOT_HELD(&hal->topology_tree_mutex));
1414 
1415 	mutex_enter(&hal->topology_tree_mutex);
1416 	generation = hal->generation_count;
1417 	rw_enter(&hal->target_list_rwlock, RW_READER);
1418 
1419 	curr_target = hal->target_head;
1420 	while (curr_target != NULL) {
1421 		if ((curr_target->on_node != NULL) &&
1422 		    (curr_target->physical_arreq_enabled != 0)) {
1423 			node_num = curr_target->on_node->node_num;
1424 			mask = mask | (1 << node_num);
1425 		}
1426 		curr_target = curr_target->target_next;
1427 	}
1428 	rw_exit(&hal->target_list_rwlock);
1429 	mutex_exit(&hal->topology_tree_mutex);
1430 
1431 	/*
1432 	 * Since it is cleared to 0 on bus reset, set the bits for all
1433 	 * nodes.  This call returns DDI_FAILURE if the generation passed
1434 	 * is invalid or if the HAL is shutdown.  In either case, it is
1435 	 * acceptable to simply ignore the result and return.
1436 	 */
1437 	(void) HAL_CALL(hal).physical_arreq_enable_set(
1438 	    hal->halinfo.hal_private, mask, generation);
1439 
1440 	TNF_PROBE_0_DEBUG(s1394_physical_arreq_setup_all_exit,
1441 	    S1394_TNF_SL_BR_STACK, "");
1442 }
1443 
1444 /*
1445  * s1394_physical_arreq_set_one()
1446  *    is used to enable the physical filters for the link.  If a target has
1447  *    registered physical space allocations, then the corresponding node's
1448  *    bit is set.  This is done for one target.
1449  */
1450 void
s1394_physical_arreq_set_one(s1394_target_t * target)1451 s1394_physical_arreq_set_one(s1394_target_t *target)
1452 {
1453 	s1394_hal_t	*hal;
1454 	uint64_t	mask = 0;
1455 	uint32_t	node_num;
1456 	uint_t		generation;
1457 
1458 	TNF_PROBE_0_DEBUG(s1394_physical_arreq_set_one_enter,
1459 	    S1394_TNF_SL_STACK, "");
1460 
1461 	/* Find the HAL this target resides on */
1462 	hal = target->on_hal;
1463 
1464 	ASSERT(MUTEX_NOT_HELD(&hal->topology_tree_mutex));
1465 
1466 	mutex_enter(&hal->topology_tree_mutex);
1467 	rw_enter(&hal->target_list_rwlock, RW_READER);
1468 
1469 	if ((target->on_node != NULL) &&
1470 	    (target->physical_arreq_enabled != 0)) {
1471 		node_num = target->on_node->node_num;
1472 		mask = mask | (1 << node_num);
1473 
1474 		generation = hal->generation_count;
1475 
1476 		rw_exit(&hal->target_list_rwlock);
1477 		mutex_exit(&hal->topology_tree_mutex);
1478 
1479 		/*
1480 		 * Set the bit corresponding to this node.  This call
1481 		 * returns DDI_FAILURE if the generation passed
1482 		 * is invalid or if the HAL is shutdown.  In either case,
1483 		 * it is acceptable to simply ignore the result and return.
1484 		 */
1485 		(void) HAL_CALL(hal).physical_arreq_enable_set(
1486 		    hal->halinfo.hal_private, mask, generation);
1487 	} else {
1488 		rw_exit(&hal->target_list_rwlock);
1489 		mutex_exit(&hal->topology_tree_mutex);
1490 	}
1491 
1492 	TNF_PROBE_0_DEBUG(s1394_physical_arreq_set_one_exit,
1493 	    S1394_TNF_SL_STACK, "");
1494 }
1495 
1496 /*
1497  * s1394_physical_arreq_clear_one()
1498  *    is used to disable the physical filters for OpenHCI.  If a target frees
1499  *    up the last of its registered physical space, then the corresponding
1500  *    node's bit is cleared.  This is done for one target.
1501  */
1502 void
s1394_physical_arreq_clear_one(s1394_target_t * target)1503 s1394_physical_arreq_clear_one(s1394_target_t *target)
1504 {
1505 	s1394_hal_t	*hal;
1506 	uint64_t	mask = 0;
1507 	uint32_t	node_num;
1508 	uint_t		generation;
1509 
1510 	TNF_PROBE_0_DEBUG(s1394_physical_arreq_clear_one_enter,
1511 	    S1394_TNF_SL_STACK, "");
1512 
1513 	/* Find the HAL this target resides on */
1514 	hal = target->on_hal;
1515 
1516 	ASSERT(MUTEX_NOT_HELD(&hal->topology_tree_mutex));
1517 
1518 	mutex_enter(&hal->topology_tree_mutex);
1519 	rw_enter(&hal->target_list_rwlock, RW_READER);
1520 
1521 	if ((target->on_node != NULL) &&
1522 	    (target->physical_arreq_enabled == 0)) {
1523 		node_num = target->on_node->node_num;
1524 		mask = mask | (1 << node_num);
1525 
1526 		generation = hal->generation_count;
1527 
1528 		rw_exit(&hal->target_list_rwlock);
1529 		mutex_exit(&hal->topology_tree_mutex);
1530 
1531 		/*
1532 		 * Set the bit corresponding to this node.  This call
1533 		 * returns DDI_FAILURE if the generation passed
1534 		 * is invalid or if the HAL is shutdown.  In either case,
1535 		 * it is acceptable to simply ignore the result and return.
1536 		 */
1537 		(void) HAL_CALL(hal).physical_arreq_enable_clr(
1538 		    hal->halinfo.hal_private, mask, generation);
1539 	} else {
1540 		rw_exit(&hal->target_list_rwlock);
1541 		mutex_exit(&hal->topology_tree_mutex);
1542 	}
1543 
1544 
1545 	TNF_PROBE_0_DEBUG(s1394_physical_arreq_clear_one_exit,
1546 	    S1394_TNF_SL_STACK, "");
1547 }
1548 
1549 /*
1550  * s1394_topology_tree_get_root_node()
1551  *    returns the last entry in topology_tree[] as this must always be the
1552  *    root node.
1553  */
1554 s1394_node_t *
s1394_topology_tree_get_root_node(s1394_hal_t * hal)1555 s1394_topology_tree_get_root_node(s1394_hal_t *hal)
1556 {
1557 	TNF_PROBE_0_DEBUG(s1394_topology_tree_get_root_node_enter,
1558 	    S1394_TNF_SL_STACK, "");
1559 
1560 	ASSERT(MUTEX_HELD(&hal->topology_tree_mutex));
1561 
1562 	TNF_PROBE_0_DEBUG(s1394_topology_tree_get_root_node_exit,
1563 	    S1394_TNF_SL_STACK, "");
1564 
1565 	return (&hal->topology_tree[hal->number_of_nodes - 1]);
1566 }
1567