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