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