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