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
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.
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]
23 * Copyright (c) 1999-2000 by Sun Microsystems, Inc.
24 * All rights reserved.
27 #pragma ident "%Z%%M% %I% %E% SMI"
31 * 1394 Services Layer Bus Reset Routines
32 * These routines handle all of the tasks relating to 1394 bus resets
37 #include <sys/sunddi.h>
38 #include <sys/types.h>
40 #include <sys/tnf_probe.h>
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>
48 static uint8_t selfid_speed(s1394_selfid_pkt_t
*s
);
50 static int selfid_num_ports(s1394_selfid_pkt_t
*s
);
52 static int selfid_port_type(s1394_selfid_pkt_t
*s
, int port
);
54 static void s1394_hal_stack_push(s1394_hal_t
*hal
, void *o
);
56 static void *s1394_hal_stack_pop(s1394_hal_t
*hal
);
58 static void s1394_hal_queue_insert(s1394_hal_t
*hal
, void *o
);
60 static void *s1394_hal_queue_remove(s1394_hal_t
*hal
);
62 static void s1394_node_number_list_add(s1394_hal_t
*hal
, int node_num
);
64 static void s1394_speed_map_fill_speed_N(s1394_hal_t
*hal
, int min_spd
);
66 static void s1394_speed_map_initialize(s1394_hal_t
*hal
);
68 int s1394_ignore_invalid_gap_cnt
= 0; /* patch for invalid gap_cnts */
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)
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
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.
87 s1394_parse_selfid_buffer(s1394_hal_t
*hal
, void *selfid_buf_addr
,
90 s1394_selfid_pkt_t
*s
;
94 boolean_t error
= B_FALSE
;
97 ASSERT(MUTEX_HELD(&hal
->topology_tree_mutex
));
99 data
= (uint32_t *)selfid_buf_addr
;
101 if (selfid_size
== 0) {
102 /* Initiate a bus reset */
103 s1394_initiate_hal_reset(hal
, CRITICAL
);
105 /* Set error status */
108 /* Release HAL lock and return */
109 goto parse_buffer_done
;
112 /* Convert bytes to quadlets */
113 selfid_size
= selfid_size
>> 2;
115 while (j
< selfid_size
) {
116 valid_pkt_id
= ((data
[j
] & IEEE1394_SELFID_PCKT_ID_MASK
) >>
117 IEEE1394_SELFID_PCKT_ID_SHIFT
);
119 s
= (s1394_selfid_pkt_t
*)(&data
[j
]);
121 /* Test if packet has valid inverse quadlet */
122 if (IEEE1394_SELFID_ISVALID(s
) &&
123 (valid_pkt_id
== IEEE1394_SELFID_PCKT_ID_VALID
)) {
125 hal
->selfid_ptrs
[i
] = s
;
127 /* While this packet contains multiple quadlets */
130 while (IEEE1394_SELFID_ISMORE(s
)) {
132 ((data
[j
] & IEEE1394_SELFID_PCKT_ID_MASK
) >>
133 IEEE1394_SELFID_PCKT_ID_SHIFT
);
135 s
= (s1394_selfid_pkt_t
*)(&data
[j
]);
137 /* Test if packet has valid inverse quadlet */
138 if (IEEE1394_SELFID_ISVALID(s
) &&
140 IEEE1394_SELFID_PCKT_ID_VALID
)) {
143 /* Initiate a bus reset */
144 s1394_initiate_hal_reset(hal
, CRITICAL
);
146 /* Set error status */
149 /* Release HAL lock and return */
150 goto parse_buffer_done
;
155 /* Initiate a bus reset */
156 s1394_initiate_hal_reset(hal
, CRITICAL
);
158 /* Set error status */
161 /* Release HAL lock and return */
162 goto parse_buffer_done
;
166 hal
->number_of_nodes
= i
;
170 return (DDI_FAILURE
);
172 return (DDI_SUCCESS
);
176 * s1394_sort_selfids()
177 * takes the selfid_ptrs[] in the HAL struct and sorts them by node number,
181 s1394_sort_selfids(s1394_hal_t
*hal
)
183 s1394_selfid_pkt_t
*current
;
184 uint_t number_of_nodes
;
188 ASSERT(MUTEX_HELD(&hal
->topology_tree_mutex
));
190 number_of_nodes
= hal
->number_of_nodes
;
192 /* We start at one because the root has no parent to check */
193 for (i
= 1; i
< number_of_nodes
; i
++) {
194 current
= hal
->selfid_ptrs
[i
];
196 while ((j
> 0) && (IEEE1394_SELFID_PHYID(current
) >
197 IEEE1394_SELFID_PHYID(hal
->selfid_ptrs
[j
/ 2]))) {
198 hal
->selfid_ptrs
[j
] = hal
->selfid_ptrs
[j
/ 2];
199 hal
->selfid_ptrs
[j
/ 2] = current
;
204 for (i
= number_of_nodes
- 1; i
> 0; i
--) {
205 current
= hal
->selfid_ptrs
[i
];
206 hal
->selfid_ptrs
[i
] = hal
->selfid_ptrs
[0];
207 hal
->selfid_ptrs
[0] = current
;
209 while (2 * j
+ 1 < i
) {
210 if (2 * j
+ 2 >= i
) {
211 if (IEEE1394_SELFID_PHYID(current
) <
212 IEEE1394_SELFID_PHYID(
213 hal
->selfid_ptrs
[2 * j
+ 1])) {
214 hal
->selfid_ptrs
[j
] =
215 hal
->selfid_ptrs
[2 * j
+ 1];
216 hal
->selfid_ptrs
[2 * j
+ 1] = current
;
222 if (IEEE1394_SELFID_PHYID(hal
->selfid_ptrs
[2 * j
+ 1]) >
223 IEEE1394_SELFID_PHYID(
224 hal
->selfid_ptrs
[2 * j
+ 2])) {
225 if (IEEE1394_SELFID_PHYID(current
) <
226 IEEE1394_SELFID_PHYID(
227 hal
->selfid_ptrs
[2 * j
+ 1])) {
228 hal
->selfid_ptrs
[j
] =
229 hal
->selfid_ptrs
[2 * j
+ 1];
230 hal
->selfid_ptrs
[2 * j
+ 1] = current
;
236 if (IEEE1394_SELFID_PHYID(current
) <
237 IEEE1394_SELFID_PHYID(
238 hal
->selfid_ptrs
[2 * j
+ 2])) {
239 hal
->selfid_ptrs
[j
] =
240 hal
->selfid_ptrs
[2 * j
+ 2];
241 hal
->selfid_ptrs
[2 * j
+ 2] = current
;
253 * examines the "sp" bits for a given packet (see IEEE 1394-1995 4.3.4.1)
254 * and returns the node's speed capabilities.
257 selfid_speed(s1394_selfid_pkt_t
*s
)
261 sp
= ((s
->spkt_data
& IEEE1394_SELFID_SP_MASK
) >>
262 IEEE1394_SELFID_SP_SHIFT
);
271 * To verify higher speeds we should look at PHY register #3
272 * on this node. This will need to be done to support P1394b
275 return (IEEE1394_S400
);
281 * determines whether a packet is multi-part or single, and from this it
282 * calculates the number of ports which have been specified.
283 * (See IEEE 1394-1995 4.3.4.1)
286 selfid_num_ports(s1394_selfid_pkt_t
*s
)
290 while (IEEE1394_SELFID_ISMORE(s
)) {
295 /* Threshold the number of ports at the P1394A defined maximum */
296 /* (see P1394A Draft 3.0 - Section 8.5.1) */
297 if (p
> IEEE1394_MAX_NUM_PORTS
)
298 p
= IEEE1394_MAX_NUM_PORTS
;
305 * determines what type of node the specified port connects to.
306 * (See IEEE 1394-1995 4.3.4.1)
309 selfid_port_type(s1394_selfid_pkt_t
*s
, int port
)
312 int offset
= IEEE1394_SELFID_PORT_OFFSET_FIRST
;
315 /* Calculate which quadlet and bits for this port */
317 block
= (port
>> 3) + 1;
319 /* Move to the correct quadlet */
321 offset
= IEEE1394_SELFID_PORT_OFFSET_OTHERS
;
324 /* Shift by appropriate number of bits and mask */
325 return ((s
->spkt_data
>> (offset
- 2 * port
)) & 0x00000003);
329 * s1394_init_topology_tree()
330 * frees any config rom's allocated in the topology tree before zapping it.
331 * If it gets a bus reset before the tree is marked processed, there will
332 * be memory allocated for cfgrom's being read. If there is no tree copy,
333 * topology would still be topology tree from the previous generation and
334 * if we bzero'd the tree, we will have a memory leak. To avoid this leak,
335 * walk through the tree and free any config roms in nodes that are NOT
336 * matched. (For matched nodes, we ensure that nodes in old and topology
337 * tree point to the same area of memory.)
340 s1394_init_topology_tree(s1394_hal_t
*hal
, boolean_t copied
,
341 ushort_t number_of_nodes
)
344 uint32_t *config_rom
;
348 ASSERT(MUTEX_HELD(&hal
->topology_tree_mutex
));
351 * if copied is false, we want to free any cfgrom memory that is
352 * not referenced to in both topology and old trees. However, we
353 * don't use hal->number_of_nodes as the number of nodes to look at.
354 * The reason being we could be seeing the bus reset before the
355 * state is appropriate for a tree copy (which need
356 * toplogy_tree_processed to be true) and some nodes might have
357 * departed in this generation and hal->number_of_nodes reflects
358 * the number of nodes in this generation. Use number_of_nodes that
359 * gets passed into this routine as the actual number of nodes to
362 if (copied
== B_FALSE
) {
363 /* Free any cfgrom alloced and zap the node */
364 for (i
= 0; i
< number_of_nodes
; i
++) {
365 node
= &hal
->topology_tree
[i
];
366 config_rom
= node
->cfgrom
;
367 if (config_rom
!= NULL
) {
368 if (CFGROM_NEW_ALLOC(node
) == B_TRUE
) {
369 kmem_free((void *)config_rom
,
370 IEEE1394_CONFIG_ROM_SZ
);
376 tree_size
= hal
->number_of_nodes
* sizeof (s1394_node_t
);
377 bzero((void *)hal
->topology_tree
, tree_size
);
381 * s1394_topology_tree_build()
382 * takes the selfid_ptrs[] and builds the topology_tree[] by examining
383 * the node numbers (the order in which the nodes responded to SelfID).
384 * It sets the port pointers, leaf label, parent port, and
385 * s1394_selfid_packet_t pointer in each node.
388 s1394_topology_tree_build(s1394_hal_t
*hal
)
391 uint32_t number_of_nodes
;
392 boolean_t push_to_orphan_stack
= B_FALSE
;
393 boolean_t found_parent
= B_FALSE
;
394 boolean_t found_connection
= B_FALSE
;
398 ASSERT(MUTEX_HELD(&hal
->topology_tree_mutex
));
400 number_of_nodes
= hal
->number_of_nodes
;
402 /* Flush the Stack */
403 hal
->hal_stack_depth
= -1;
405 /* For each node on the bus initialize its topology_tree entry */
406 for (i
= 0; i
< number_of_nodes
; i
++) {
407 /* Make sure that node numbers are correct */
408 if (i
!= IEEE1394_SELFID_PHYID(hal
->selfid_ptrs
[i
])) {
409 /* Initiate a bus reset */
410 s1394_initiate_hal_reset(hal
, CRITICAL
);
412 return (DDI_FAILURE
);
415 hal
->topology_tree
[i
].selfid_packet
= hal
->selfid_ptrs
[i
];
416 hal
->topology_tree
[i
].parent_port
= (char)NO_PARENT
;
417 hal
->topology_tree
[i
].is_a_leaf
= 1;
418 hal
->topology_tree
[i
].node_num
= (uchar_t
)i
;
421 for (i
= 0; i
< number_of_nodes
; i
++) {
422 /* Current node has no parent yet */
423 found_parent
= B_FALSE
;
425 /* Current node has no connections yet */
426 found_connection
= B_FALSE
;
428 /* Initialize all ports on this node */
429 for (j
= 0; j
< IEEE1394_MAX_NUM_PORTS
; j
++)
430 hal
->topology_tree
[i
].phy_port
[j
] = NULL
;
432 /* For each port on the node - highest to lowest */
433 for (j
= selfid_num_ports(hal
->selfid_ptrs
[i
]) - 1;
435 if (selfid_port_type(hal
->selfid_ptrs
[i
], j
) ==
436 IEEE1394_SELFID_PORT_TO_PARENT
) {
438 found_connection
= B_TRUE
;
439 if (found_parent
== B_FALSE
) {
440 push_to_orphan_stack
= B_TRUE
;
441 hal
->topology_tree
[i
].parent_port
=
443 found_parent
= B_TRUE
;
446 /* Initiate a bus reset */
447 s1394_initiate_hal_reset(hal
, CRITICAL
);
449 return (DDI_FAILURE
);
451 } else if (selfid_port_type(hal
->selfid_ptrs
[i
], j
) ==
452 IEEE1394_SELFID_PORT_TO_CHILD
) {
454 found_connection
= B_TRUE
;
455 tmp
= (s1394_node_t
*)s1394_hal_stack_pop(hal
);
457 /* Initiate a bus reset */
458 s1394_initiate_hal_reset(hal
, CRITICAL
);
460 return (DDI_FAILURE
);
463 hal
->topology_tree
[i
].phy_port
[j
] = tmp
;
464 hal
->topology_tree
[i
].is_a_leaf
= 0;
465 tmp
->phy_port
[tmp
->parent_port
] =
466 &hal
->topology_tree
[i
];
470 /* If current node has no parents or children - Invalid */
471 if ((found_connection
== B_FALSE
) && (number_of_nodes
> 1)) {
472 /* Initiate a bus reset */
473 s1394_initiate_hal_reset(hal
, CRITICAL
);
475 return (DDI_FAILURE
);
478 /* Push it on the "Orphan" stack if it has no parent yet */
479 if (push_to_orphan_stack
== B_TRUE
) {
480 push_to_orphan_stack
= B_FALSE
;
481 s1394_hal_stack_push(hal
, &hal
->topology_tree
[i
]);
485 /* If the stack is not empty, then something has gone seriously wrong */
486 if (hal
->hal_stack_depth
!= -1) {
487 /* Initiate a bus reset */
488 s1394_initiate_hal_reset(hal
, CRITICAL
);
490 return (DDI_FAILURE
);
493 /* New topology tree is now valid */
494 hal
->topology_tree_valid
= B_TRUE
;
496 return (DDI_SUCCESS
);
500 * s1394_hal_stack_push()
501 * checks that the stack is not full, and puts the pointer on top of the
502 * HAL's stack if it isn't. This routine is used only by the
503 * h1394_self_ids() interrupt.
506 s1394_hal_stack_push(s1394_hal_t
*hal
, void *obj
)
508 if (hal
->hal_stack_depth
< IEEE1394_MAX_NODES
- 1) {
509 hal
->hal_stack_depth
++;
510 hal
->hal_stack
[hal
->hal_stack_depth
] = obj
;
515 * s1394_hal_stack_pop()
516 * checks that the stack is not empty, and pops and returns the pointer
517 * from the top of the HAL's stack if it isn't. This routine is used
518 * only by the h1394_self_ids() interrupt.
521 s1394_hal_stack_pop(s1394_hal_t
*hal
)
523 if (hal
->hal_stack_depth
> -1) {
524 hal
->hal_stack_depth
--;
525 return (hal
->hal_stack
[hal
->hal_stack_depth
+ 1]);
532 * s1394_hal_queue_insert()
533 * checks that the queue is not full, and puts the object in the front
534 * of the HAL's queue if it isn't. This routine is used only by the
535 * h1394_self_ids() interrupt.
538 s1394_hal_queue_insert(s1394_hal_t
*hal
, void *obj
)
540 if (((hal
->hal_queue_front
+ 1) % IEEE1394_MAX_NODES
) ==
541 hal
->hal_queue_back
) {
545 hal
->hal_queue
[hal
->hal_queue_front
] = obj
;
546 hal
->hal_queue_front
= (hal
->hal_queue_front
+ 1) %
553 * s1394_hal_queue_remove()
554 * checks that the queue is not empty, and pulls the object off the back
555 * of the HAL's queue (and returns it) if it isn't. This routine is used
556 * only by the h1394_self_ids() interrupt.
559 s1394_hal_queue_remove(s1394_hal_t
*hal
)
563 if (hal
->hal_queue_back
== hal
->hal_queue_front
) {
567 tmp
= hal
->hal_queue
[hal
->hal_queue_back
];
568 hal
->hal_queue_back
= (hal
->hal_queue_back
+ 1) %
576 * s1394_node_number_list_add()
577 * checks that the node_number_list is not full and puts the node number
578 * in the list. The function is used primarily by s1394_speed_map_fill()
579 * to keep track of which connections need to be set in the speed_map[].
580 * This routine is used only by the h1394_self_ids() interrupt.
583 s1394_node_number_list_add(s1394_hal_t
*hal
, int node_num
)
585 if (hal
->hal_node_number_list_size
>= IEEE1394_MAX_NODES
- 1) {
589 hal
->hal_node_number_list
[hal
->hal_node_number_list_size
] = node_num
;
590 hal
->hal_node_number_list_size
++;
594 * s1394_topology_tree_mark_all_unvisited()
595 * is used to initialize the topology_tree[] prior to tree traversals.
596 * It resets the "visited" flag for each node in the tree.
599 s1394_topology_tree_mark_all_unvisited(s1394_hal_t
*hal
)
601 uint_t number_of_nodes
;
604 ASSERT(MUTEX_HELD(&hal
->topology_tree_mutex
));
606 number_of_nodes
= hal
->number_of_nodes
;
607 for (i
= 0; i
< number_of_nodes
; i
++)
608 CLEAR_NODE_VISITED(&hal
->topology_tree
[i
]);
612 * s1394_old_tree_mark_all_unvisited()
613 * is used to initialize the old_tree[] prior to tree traversals. It
614 * resets the "visited" flag for each node in the tree.
617 s1394_old_tree_mark_all_unvisited(s1394_hal_t
*hal
)
619 uint_t number_of_nodes
;
622 ASSERT(MUTEX_HELD(&hal
->topology_tree_mutex
));
624 number_of_nodes
= hal
->old_number_of_nodes
;
625 for (i
= 0; i
< number_of_nodes
; i
++)
626 CLEAR_NODE_VISITED(&hal
->old_tree
[i
]);
630 * s1394_old_tree_mark_all_unmatched()
631 * is used to initialize the old_tree[] prior to tree traversals. It
632 * resets the "matched" flag for each node in the tree.
635 s1394_old_tree_mark_all_unmatched(s1394_hal_t
*hal
)
637 uint_t number_of_nodes
;
640 ASSERT(MUTEX_HELD(&hal
->topology_tree_mutex
));
642 number_of_nodes
= hal
->old_number_of_nodes
;
644 for (i
= 0; i
< number_of_nodes
; i
++)
645 CLEAR_NODE_MATCHED(&hal
->old_tree
[i
]);
649 * s1394_copy_old_tree()
650 * switches the pointers for old_tree[] and topology_tree[].
653 s1394_copy_old_tree(s1394_hal_t
*hal
)
657 ASSERT(MUTEX_HELD(&hal
->topology_tree_mutex
));
659 temp
= hal
->old_tree
;
660 hal
->old_tree
= hal
->topology_tree
;
661 hal
->topology_tree
= temp
;
663 hal
->old_number_of_nodes
= hal
->number_of_nodes
;
664 hal
->old_node_id
= hal
->node_id
;
665 hal
->old_generation_count
= hal
->generation_count
;
667 /* Old tree is now valid and filled also */
668 hal
->old_tree_valid
= B_TRUE
;
673 * s1394_match_tree_nodes()
674 * uses the information contained in the SelfID packets of the nodes in
675 * both the old_tree[] and the topology_tree[] to determine which new
676 * nodes correspond to old nodes. Starting with the local node, we
677 * compare both old and new node's ports. Assuming that only one bus
678 * reset has occurred, any node that was connected to another in the old
679 * bus and is still connected to another in the new bus must be connected
680 * (physically) to the same node. Using this information, we can rebuild
681 * and match the old nodes to new ones. Any nodes which aren't matched
682 * are either departing or arriving nodes and must be handled appropriately.
685 s1394_match_tree_nodes(s1394_hal_t
*hal
)
689 uint_t hal_node_num_old
;
693 ASSERT(MUTEX_HELD(&hal
->topology_tree_mutex
));
695 /* To ensure that the queue is empty */
696 hal
->hal_queue_front
= hal
->hal_queue_back
= 0;
698 /* Set up the first matched nodes (which are our own local nodes) */
699 hal_node_num
= IEEE1394_NODE_NUM(hal
->node_id
);
700 hal_node_num_old
= IEEE1394_NODE_NUM(hal
->old_node_id
);
701 hal
->topology_tree
[hal_node_num
].old_node
=
702 &hal
->old_tree
[hal_node_num_old
];
703 hal
->old_tree
[hal_node_num_old
].cur_node
=
704 &hal
->topology_tree
[hal_node_num
];
706 /* Put the node on the queue */
707 s1394_hal_queue_insert(hal
, &hal
->topology_tree
[hal_node_num
]);
709 /* While the queue is not empty, remove a node */
710 while (hal
->hal_queue_front
!= hal
->hal_queue_back
) {
711 tmp
= (s1394_node_t
*)s1394_hal_queue_remove(hal
);
713 /* Mark both old and new nodes as "visited" */
714 SET_NODE_VISITED(tmp
);
715 SET_NODE_VISITED(tmp
->old_node
);
716 tmp
->old_node
->cur_node
= tmp
;
718 /* Mark old and new nodes as "matched" */
719 SET_NODE_MATCHED(tmp
);
720 SET_NODE_MATCHED(tmp
->old_node
);
721 s1394_copy_cfgrom(tmp
, tmp
->old_node
);
723 /* s1394_copy_cfgrom() clears "matched" for some cases... */
724 if ((tmp
->cfgrom
!= NULL
&& CONFIG_ROM_GEN(tmp
->cfgrom
) <= 1) ||
725 NODE_MATCHED(tmp
) == B_TRUE
) {
726 /* Move the target list over to the new node and update */
730 rw_enter(&hal
->target_list_rwlock
, RW_WRITER
);
731 t
= tmp
->target_list
= tmp
->old_node
->target_list
;
734 t
= t
->target_sibling
;
736 rw_exit(&hal
->target_list_rwlock
);
739 for (i
= 0; i
< selfid_num_ports(tmp
->selfid_packet
); i
++) {
740 port_type
= selfid_port_type(tmp
->selfid_packet
, i
);
742 /* Is the new port connected? */
743 if ((port_type
== IEEE1394_SELFID_PORT_TO_CHILD
) ||
744 (port_type
== IEEE1394_SELFID_PORT_TO_PARENT
)) {
745 port_type
= selfid_port_type(
746 tmp
->old_node
->selfid_packet
, i
);
748 /* Is the old port connected? */
750 IEEE1394_SELFID_PORT_TO_CHILD
) ||
752 IEEE1394_SELFID_PORT_TO_PARENT
)) {
753 /* Found a match, check if */
754 /* we've already visited it */
755 if (!NODE_VISITED(tmp
->phy_port
[i
])) {
756 tmp
->phy_port
[i
]->old_node
=
757 tmp
->old_node
->phy_port
[i
];
758 s1394_hal_queue_insert(hal
,
768 * s1394_topology_tree_calculate_diameter()
769 * does a depth-first tree traversal, tracking at each branch the first
770 * and second deepest paths though that branch's children. The diameter
771 * is given by the maximum of these over all branch nodes
774 s1394_topology_tree_calculate_diameter(s1394_hal_t
*hal
)
776 s1394_node_t
*current
;
777 uint_t number_of_nodes
;
782 boolean_t found_a_child
;
785 int local_diameter
= 0;
787 ASSERT(MUTEX_HELD(&hal
->topology_tree_mutex
));
789 number_of_nodes
= hal
->number_of_nodes
;
791 /* Initialize topology tree */
792 for (i
= 0; i
< number_of_nodes
; i
++) {
793 hal
->topology_tree
[i
].max_1st
= 0;
794 hal
->topology_tree
[i
].max_2nd
= 0;
795 hal
->topology_tree
[i
].last_port_checked
= 0;
798 /* Start at the root node */
799 current
= s1394_topology_tree_get_root_node(hal
);
801 /* Flush the stack before we start */
802 hal
->hal_stack_depth
= -1;
806 found_a_child
= B_FALSE
;
807 start
= current
->last_port_checked
;
808 end
= selfid_num_ports(current
->selfid_packet
);
810 /* Check every previously unchecked port for children */
811 for (i
= start
; i
< end
; i
++) {
812 current
->last_port_checked
++;
813 /* If there is a child push it on the stack */
814 if (selfid_port_type(current
->selfid_packet
, i
) ==
815 IEEE1394_SELFID_PORT_TO_CHILD
) {
816 found_a_child
= B_TRUE
;
817 s1394_hal_stack_push(hal
, current
);
818 current
= current
->phy_port
[i
];
823 /* If we reach here and the stack is empty, we're done */
824 if (hal
->hal_stack_depth
== -1) {
829 /* If no children were found, we're at a leaf */
830 if (found_a_child
== B_FALSE
) {
831 distance
= current
->max_1st
+ 1;
832 /* Pop the child and set the appropriate fields */
833 current
= s1394_hal_stack_pop(hal
);
834 if (distance
> current
->max_1st
) {
835 current
->max_2nd
= current
->max_1st
;
836 current
->max_1st
= (uchar_t
)distance
;
838 } else if (distance
> current
->max_2nd
) {
839 current
->max_2nd
= (uchar_t
)distance
;
842 /* Update maximum distance (diameter), if necessary */
843 local_diameter
= current
->max_1st
+ current
->max_2nd
;
844 if (local_diameter
> diameter
)
845 diameter
= local_diameter
;
847 } while (done
== B_FALSE
);
853 * s1394_gap_count_optimize()
854 * looks in a table to find the appropriate gap_count for a given diameter.
855 * (See above - gap_count[])
858 s1394_gap_count_optimize(int diameter
)
860 if ((diameter
>= 0) && (diameter
<= MAX_HOPS
)) {
861 return (gap_count
[diameter
]);
863 cmn_err(CE_NOTE
, "Too may point-to-point links on the 1394"
864 " bus - If new devices have recently been added, remove"
866 return (gap_count
[MAX_HOPS
]);
871 * s1394_get_current_gap_count()
872 * looks at all the SelfID packets to determine the current gap_count on
873 * the 1394 bus. If the gap_counts differ from node to node, it initiates
874 * a bus reset and returns -1.
877 s1394_get_current_gap_count(s1394_hal_t
*hal
)
882 ASSERT(MUTEX_HELD(&hal
->topology_tree_mutex
));
884 /* Grab the first gap_count in the SelfID packets */
885 gap_count
= IEEE1394_SELFID_GAP_CNT(hal
->selfid_ptrs
[0]);
887 /* Compare it too all the rest */
888 for (i
= 1; i
< hal
->number_of_nodes
; i
++) {
890 IEEE1394_SELFID_GAP_CNT(hal
->selfid_ptrs
[i
])) {
892 if (s1394_ignore_invalid_gap_cnt
== 0) {
893 /* Initiate a bus reset */
894 s1394_initiate_hal_reset(hal
, CRITICAL
);
905 * s1394_speed_map_fill()
906 * determines, for each pair of nodes, the maximum speed at which those
907 * nodes can communicate. The speed of each node as well as the speed of
908 * any intermediate nodes on a given path must be accounted for, as the
909 * minimum speed on a given edge determines the maximum speed for all
910 * communications across that edge.
911 * In the method we implement below, a current minimum speed is selected.
912 * With this minimum speed in mind, we create subgraphs of the original
913 * bus which contain only edges that connect two nodes whose speeds are
914 * equal to or greater than the current minimum speed. Then, for each of
915 * the subgraphs, we visit every node, keeping a list of the nodes we've
916 * visited. When this list is completed, we can fill in the entries in
917 * the speed map which correspond to a pairs of these nodes. Doing this
918 * for each subgraph and then for each speed we progressively fill in the
919 * parts of the speed map which weren't previously filled in.
922 s1394_speed_map_fill(s1394_hal_t
*hal
)
924 uint_t number_of_nodes
;
929 ASSERT(MUTEX_HELD(&hal
->topology_tree_mutex
));
931 number_of_nodes
= hal
->number_of_nodes
;
932 s1394_speed_map_initialize(hal
);
934 /* Mark all speed = IEEE1394_S100 nodes in the Speed Map */
935 for (i
= 0; i
< number_of_nodes
; i
++) {
936 if (selfid_speed(hal
->topology_tree
[i
].selfid_packet
) ==
938 hal
->slowest_node_speed
= IEEE1394_S100
;
939 node_num
= IEEE1394_SELFID_PHYID(
940 hal
->topology_tree
[i
].selfid_packet
);
941 for (j
= 0; j
< number_of_nodes
; j
++) {
943 hal
->speed_map
[node_num
][j
] =
945 hal
->speed_map
[j
][node_num
] =
952 s1394_speed_map_fill_speed_N(hal
, IEEE1394_S200
);
953 s1394_speed_map_fill_speed_N(hal
, IEEE1394_S400
);
955 /* Fill in the diagonal */
956 for (i
= 0; i
< number_of_nodes
; i
++) {
957 hal
->speed_map
[i
][i
] =
958 selfid_speed(hal
->topology_tree
[i
].selfid_packet
);
963 * s1394_speed_map_fill_speed_N(),
964 * given a minimum link speed, creates subgraphs of the original bus which
965 * contain only the necessary edges (see speed_map_fill() above). For each
966 * of the subgraphs, it visits and fills in the entries in the speed map
967 * which correspond to a pair of these nodes.
970 s1394_speed_map_fill_speed_N(s1394_hal_t
*hal
, int min_spd
)
973 uint_t number_of_nodes
;
980 ASSERT(MUTEX_HELD(&hal
->topology_tree_mutex
));
982 number_of_nodes
= hal
->number_of_nodes
;
984 /* Prepare the topology tree */
985 s1394_topology_tree_mark_all_unvisited(hal
);
987 /* To ensure that the queue is empty */
988 hal
->hal_queue_front
= hal
->hal_queue_back
= 0;
990 for (i
= 0; i
< number_of_nodes
; i
++) {
991 /* If the node's speed == min_spd and it hasn't been visited */
992 if (!NODE_VISITED(&hal
->topology_tree
[i
]) &&
993 (selfid_speed(hal
->topology_tree
[i
].selfid_packet
) ==
996 if (min_spd
< hal
->slowest_node_speed
)
997 hal
->slowest_node_speed
= (uint8_t)min_spd
;
999 SET_NODE_VISITED(&hal
->topology_tree
[i
]);
1000 s1394_hal_queue_insert(hal
, &hal
->topology_tree
[i
]);
1002 while (hal
->hal_queue_front
!= hal
->hal_queue_back
) {
1003 tmp
= (s1394_node_t
*)s1394_hal_queue_remove(
1005 /* Add node number to the list */
1006 s1394_node_number_list_add(hal
,
1007 IEEE1394_SELFID_PHYID(tmp
->selfid_packet
));
1009 for (j
= 0; j
< IEEE1394_MAX_NUM_PORTS
; j
++) {
1010 if ((tmp
->phy_port
[j
] != NULL
) &&
1011 (!NODE_VISITED(tmp
->phy_port
[j
]))) {
1014 selfid_packet
) >= min_spd
) {
1017 s1394_hal_queue_insert(
1025 /* For each pair, mark speed_map as min_spd */
1026 size
= hal
->hal_node_number_list_size
;
1027 for (j
= 0; j
< size
; j
++) {
1028 for (k
= 0; k
< size
; k
++) {
1031 hal_node_number_list
[j
];
1033 hal_node_number_list
[k
];
1034 hal
->speed_map
[ix_a
][ix_b
] =
1040 /* Flush the Node Number List */
1041 hal
->hal_node_number_list_size
= 0;
1047 * s1394_speed_map_initialize()
1048 * fills in the speed_map with IEEE1394_S100's and SPEED_MAP_INVALID's in
1049 * the appropriate places. These will be overwritten by
1050 * s1394_speed_map_fill().
1053 s1394_speed_map_initialize(s1394_hal_t
*hal
)
1055 uint_t number_of_nodes
;
1058 ASSERT(MUTEX_HELD(&hal
->topology_tree_mutex
));
1060 number_of_nodes
= hal
->number_of_nodes
;
1061 for (i
= 0; i
< number_of_nodes
; i
++) {
1062 for (j
= 0; j
< number_of_nodes
; j
++) {
1064 hal
->speed_map
[i
][j
] = IEEE1394_S100
;
1066 hal
->speed_map
[i
][j
] = SPEED_MAP_INVALID
;
1072 * s1394_speed_map_get()
1073 * queries the speed_map[] for a given pair of nodes.
1076 s1394_speed_map_get(s1394_hal_t
*hal
, uint_t from_node
, uint_t to_node
)
1078 /* If it's not a valid node, then return slowest_node_speed */
1079 if (to_node
>= hal
->number_of_nodes
) {
1080 /* Send at fastest speed everyone will see */
1081 return (hal
->slowest_node_speed
);
1083 /* else return the correct maximum speed */
1084 return (hal
->speed_map
[from_node
][to_node
]);
1088 * s1394_update_speed_map_link_speeds()
1089 * takes into account information from Config ROM queries. Any P1394A
1090 * device can have a link with a different speed than its PHY. In this
1091 * case, the slower speed must be accounted for in order for communication
1092 * with the remote node to work.
1095 s1394_update_speed_map_link_speeds(s1394_hal_t
*hal
)
1097 uint32_t bus_capabilities
;
1099 uint_t number_of_nodes
;
1102 ASSERT(MUTEX_HELD(&hal
->topology_tree_mutex
));
1104 number_of_nodes
= hal
->number_of_nodes
;
1106 for (i
= 0; i
< number_of_nodes
; i
++) {
1108 /* Skip invalid config ROMs */
1109 if (CFGROM_VALID(&hal
->topology_tree
[i
])) {
1111 ASSERT(hal
->topology_tree
[i
].cfgrom
);
1113 bus_capabilities
= hal
->topology_tree
[i
].
1114 cfgrom
[IEEE1212_NODE_CAP_QUAD
];
1116 /* Skip if Bus_Info_Block generation is 0 */
1117 /* because it isn't a P1394a device */
1118 if ((bus_capabilities
& IEEE1394_BIB_GEN_MASK
) != 0) {
1119 link_speed
= (bus_capabilities
&
1120 IEEE1394_BIB_LNK_SPD_MASK
);
1122 for (j
= 0; j
< number_of_nodes
; j
++) {
1123 /* Update if link_speed is slower */
1124 if (hal
->speed_map
[i
][j
] > link_speed
) {
1125 hal
->speed_map
[i
][j
] =
1127 hal
->speed_map
[j
][i
] =
1132 hal
->slowest_node_speed
)
1133 hal
->slowest_node_speed
=
1142 * s1394_get_isoch_rsrc_mgr()
1143 * looks at the SelfID packets to determine the Isochronous Resource
1144 * Manager's node ID. The IRM is the highest numbered node with both
1145 * the "L"-bit and the "C"-bit in its SelfID packets turned on. If no
1146 * IRM is found on the bus, then -1 is returned.
1149 s1394_get_isoch_rsrc_mgr(s1394_hal_t
*hal
)
1153 ASSERT(MUTEX_HELD(&hal
->topology_tree_mutex
));
1155 for (i
= hal
->number_of_nodes
- 1; i
>= 0; i
--) {
1156 /* Highest numbered node with L=1 and C=1 */
1157 if ((IEEE1394_SELFID_ISLINKON(hal
->selfid_ptrs
[i
])) &&
1158 (IEEE1394_SELFID_ISCONTENDER(hal
->selfid_ptrs
[i
]))) {
1164 /* No Isochronous Resource Manager */
1169 * s1394_physical_arreq_setup_all()
1170 * is used to enable the physical filters for the link. If a target has
1171 * registered physical space allocations, then the corresponding node's
1172 * bit is set. This is done for all targets on a HAL (usually after bus
1176 s1394_physical_arreq_setup_all(s1394_hal_t
*hal
)
1178 s1394_target_t
*curr_target
;
1183 ASSERT(MUTEX_NOT_HELD(&hal
->topology_tree_mutex
));
1185 mutex_enter(&hal
->topology_tree_mutex
);
1186 generation
= hal
->generation_count
;
1187 rw_enter(&hal
->target_list_rwlock
, RW_READER
);
1189 curr_target
= hal
->target_head
;
1190 while (curr_target
!= NULL
) {
1191 if ((curr_target
->on_node
!= NULL
) &&
1192 (curr_target
->physical_arreq_enabled
!= 0)) {
1193 node_num
= curr_target
->on_node
->node_num
;
1194 mask
= mask
| (1 << node_num
);
1196 curr_target
= curr_target
->target_next
;
1198 rw_exit(&hal
->target_list_rwlock
);
1199 mutex_exit(&hal
->topology_tree_mutex
);
1202 * Since it is cleared to 0 on bus reset, set the bits for all
1203 * nodes. This call returns DDI_FAILURE if the generation passed
1204 * is invalid or if the HAL is shutdown. In either case, it is
1205 * acceptable to simply ignore the result and return.
1207 (void) HAL_CALL(hal
).physical_arreq_enable_set(
1208 hal
->halinfo
.hal_private
, mask
, generation
);
1212 * s1394_physical_arreq_set_one()
1213 * is used to enable the physical filters for the link. If a target has
1214 * registered physical space allocations, then the corresponding node's
1215 * bit is set. This is done for one target.
1218 s1394_physical_arreq_set_one(s1394_target_t
*target
)
1225 /* Find the HAL this target resides on */
1226 hal
= target
->on_hal
;
1228 ASSERT(MUTEX_NOT_HELD(&hal
->topology_tree_mutex
));
1230 mutex_enter(&hal
->topology_tree_mutex
);
1231 rw_enter(&hal
->target_list_rwlock
, RW_READER
);
1233 if ((target
->on_node
!= NULL
) &&
1234 (target
->physical_arreq_enabled
!= 0)) {
1235 node_num
= target
->on_node
->node_num
;
1236 mask
= mask
| (1 << node_num
);
1238 generation
= hal
->generation_count
;
1240 rw_exit(&hal
->target_list_rwlock
);
1241 mutex_exit(&hal
->topology_tree_mutex
);
1244 * Set the bit corresponding to this node. This call
1245 * returns DDI_FAILURE if the generation passed
1246 * is invalid or if the HAL is shutdown. In either case,
1247 * it is acceptable to simply ignore the result and return.
1249 (void) HAL_CALL(hal
).physical_arreq_enable_set(
1250 hal
->halinfo
.hal_private
, mask
, generation
);
1252 rw_exit(&hal
->target_list_rwlock
);
1253 mutex_exit(&hal
->topology_tree_mutex
);
1258 * s1394_physical_arreq_clear_one()
1259 * is used to disable the physical filters for OpenHCI. If a target frees
1260 * up the last of its registered physical space, then the corresponding
1261 * node's bit is cleared. This is done for one target.
1264 s1394_physical_arreq_clear_one(s1394_target_t
*target
)
1271 /* Find the HAL this target resides on */
1272 hal
= target
->on_hal
;
1274 ASSERT(MUTEX_NOT_HELD(&hal
->topology_tree_mutex
));
1276 mutex_enter(&hal
->topology_tree_mutex
);
1277 rw_enter(&hal
->target_list_rwlock
, RW_READER
);
1279 if ((target
->on_node
!= NULL
) &&
1280 (target
->physical_arreq_enabled
== 0)) {
1281 node_num
= target
->on_node
->node_num
;
1282 mask
= mask
| (1 << node_num
);
1284 generation
= hal
->generation_count
;
1286 rw_exit(&hal
->target_list_rwlock
);
1287 mutex_exit(&hal
->topology_tree_mutex
);
1290 * Set the bit corresponding to this node. This call
1291 * returns DDI_FAILURE if the generation passed
1292 * is invalid or if the HAL is shutdown. In either case,
1293 * it is acceptable to simply ignore the result and return.
1295 (void) HAL_CALL(hal
).physical_arreq_enable_clr(
1296 hal
->halinfo
.hal_private
, mask
, generation
);
1298 rw_exit(&hal
->target_list_rwlock
);
1299 mutex_exit(&hal
->topology_tree_mutex
);
1304 * s1394_topology_tree_get_root_node()
1305 * returns the last entry in topology_tree[] as this must always be the
1309 s1394_topology_tree_get_root_node(s1394_hal_t
*hal
)
1311 ASSERT(MUTEX_HELD(&hal
->topology_tree_mutex
));
1313 return (&hal
->topology_tree
[hal
->number_of_nodes
- 1]);