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 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 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 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 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 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 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 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 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 * 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 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 * 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 * 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