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 2005 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 /*
  28  * Copyright 2019 Joyent, Inc.
  29  */
  30 
  31 /*
  32  * s1394_dev_disc.c
  33  *    1394 Services Layer Device Discovery Routines
  34  *    This file contains the bus reset thread code, bus manager routines and
  35  *    various routines that are used to implement remote Config ROM reading.
  36  *
  37  *    FUTURE:
  38  *    Rescan the bus if invalid nodes are seen.
  39  *    Investigate taskq for reading phase2 config rom reads.
  40  *    If we are reading the entire bus info blk, we should attempt
  41  *    a block read and fallback to quad reads if this fails.
  42  */
  43 
  44 #include <sys/conf.h>
  45 #include <sys/sysmacros.h>
  46 #include <sys/ddi.h>
  47 #include <sys/sunddi.h>
  48 #include <sys/cmn_err.h>
  49 #include <sys/sunndi.h>
  50 #include <sys/modctl.h>
  51 #include <sys/ddi_impldefs.h>
  52 #include <sys/types.h>
  53 #include <sys/kmem.h>
  54 #include <sys/kstat.h>
  55 #include <sys/varargs.h>
  56 
  57 #include <sys/tnf_probe.h>
  58 
  59 #include <sys/1394/t1394.h>
  60 #include <sys/1394/s1394.h>
  61 #include <sys/1394/h1394.h>
  62 #include <sys/1394/ieee1394.h>
  63 #include <sys/1394/ieee1212.h>
  64 
  65 /* hcmd_ret_t */
  66 typedef enum {
  67         S1394_HCMD_INVALID,
  68         S1394_HCMD_NODE_DONE,
  69         S1394_HCMD_NODE_EXPECT_MORE,
  70         S1394_HCMD_LOCK_FAILED
  71 } hcmd_ret_t;
  72 
  73 #define QUAD_TO_CFGROM_ADDR(b, n, q, addr) {                    \
  74         uint64_t bl = (b);                                      \
  75         uint64_t nl = (n);                                      \
  76         addr = ((bl) << IEEE1394_ADDR_BUS_ID_SHIFT) |             \
  77                 ((nl) << IEEE1394_ADDR_PHY_ID_SHIFT);             \
  78         addr += IEEE1394_CONFIG_ROM_ADDR + ((q) << 2);            \
  79 }
  80 
  81 #define CFGROM_READ_PAUSE(d)                                            \
  82         ((s1394_cfgrom_read_delay_ms == 0) ? (void) 0 :                 \
  83         delay(drv_usectohz((d) * 1000)))
  84 
  85 #define BUMP_CFGROM_READ_DELAY(n)                                       \
  86         (n)->cfgrom_read_delay += s1394_cfgrom_read_delay_incr
  87 
  88 #define CFGROM_GET_READ_DELAY(n, d)                                     \
  89         ((d) = (n)->cfgrom_read_delay)
  90 
  91 #define SETUP_QUAD_READ(n, reset_fails, quadlet, cnt)                   \
  92 {                                                                       \
  93         int i = (reset_fails);                                          \
  94         if (i != 0) {                                                   \
  95                 (n)->cfgrom_read_fails = 0;                          \
  96                 (n)->cfgrom_read_delay = (uchar_t)s1394_cfgrom_read_delay_ms; \
  97         }                                                               \
  98         (n)->cfgrom_quad_to_read = (quadlet);                                \
  99         (n)->cfgrom_quad_read_cnt = (cnt);                           \
 100 }
 101 
 102 static void s1394_wait_for_events(s1394_hal_t *hal, int firsttime);
 103 
 104 static int s1394_wait_for_cfgrom_callbacks(s1394_hal_t *hal, uint_t wait_gen,
 105     hcmd_ret_t(*handle_cmd_fn)(s1394_hal_t *hal, cmd1394_cmd_t *cmd));
 106 
 107 static void s1394_flush_cmplq(s1394_hal_t *hal);
 108 
 109 static void s1394_br_thread_exit(s1394_hal_t *hal);
 110 
 111 static void s1394_target_bus_reset_notifies(s1394_hal_t *hal,
 112     t1394_localinfo_t *localinfo);
 113 
 114 static int s1394_alloc_cfgrom(s1394_hal_t *hal, s1394_node_t *node,
 115     s1394_status_t *status);
 116 
 117 static int s1394_cfgrom_scan_phase1(s1394_hal_t *hal);
 118 
 119 static hcmd_ret_t s1394_br_thread_handle_cmd_phase1(s1394_hal_t *hal,
 120     cmd1394_cmd_t *cmd);
 121 
 122 static int s1394_cfgrom_scan_phase2(s1394_hal_t *hal);
 123 
 124 static hcmd_ret_t s1394_br_thread_handle_cmd_phase2(s1394_hal_t *hal,
 125     cmd1394_cmd_t *cmd);
 126 
 127 static int s1394_read_config_quadlet(s1394_hal_t *hal, cmd1394_cmd_t *cmd,
 128     s1394_status_t *status);
 129 
 130 static void s1394_cfgrom_read_callback(cmd1394_cmd_t *cmd);
 131 
 132 static void s1394_get_quad_info(cmd1394_cmd_t *cmd, uint32_t *node_num,
 133     uint32_t *quadlet, uint32_t *data);
 134 
 135 static int s1394_match_GUID(s1394_hal_t *hal, s1394_node_t *nnode);
 136 
 137 static int s1394_match_all_GUIDs(s1394_hal_t *hal);
 138 
 139 static void s1394_become_bus_mgr(void *arg);
 140 
 141 static void s1394_become_bus_mgr_callback(cmd1394_cmd_t *cmd);
 142 
 143 static int s1394_bus_mgr_processing(s1394_hal_t *hal);
 144 
 145 static int s1394_do_bus_mgr_processing(s1394_hal_t *hal);
 146 
 147 static void s1394_bus_mgr_timers_stop(s1394_hal_t *hal,
 148     timeout_id_t *bus_mgr_query_tid, timeout_id_t *bus_mgr_tid);
 149 
 150 static void s1394_bus_mgr_timers_start(s1394_hal_t *hal,
 151     timeout_id_t *bus_mgr_query_tid, timeout_id_t *bus_mgr_tid);
 152 
 153 static int s1394_cycle_master_capable(s1394_hal_t *hal);
 154 
 155 static int s1394_do_phy_config_pkt(s1394_hal_t *hal, int new_root,
 156     int new_gap_cnt, uint32_t IRM_flags);
 157 
 158 static void s1394_phy_config_callback(cmd1394_cmd_t *cmd);
 159 
 160 static int s1394_calc_next_quad(s1394_hal_t *hal, s1394_node_t *node,
 161     uint32_t quadlet, uint32_t *nextquadp);
 162 
 163 static int s1394_cfgrom_read_retry_cnt = 3;     /* 1 + 3 retries */
 164 static int s1394_cfgrom_read_delay_ms = 20;     /* start with 20ms */
 165 static int s1394_cfgrom_read_delay_incr = 10;   /* 10ms increments */
 166 static int s1394_enable_crc_validation = 0;
 167 static int s1394_turn_off_dir_stack = 0;
 168 static int s1394_crcsz_is_cfgsz = 0;
 169 static int s1394_enable_rio_pass1_workarounds = 0;
 170 
 171 /*
 172  * s1394_br_thread()
 173  *    is the bus reset thread. Its sole purpose is to read/reread config roms
 174  *    as appropriate and do bus reset time things (bus manager processing,
 175  *    isoch resource reallocation etc.).
 176  */
 177 void
 178 s1394_br_thread(s1394_hal_t *hal)
 179 {
 180         TNF_PROBE_0_DEBUG(s1394_br_thread_enter, S1394_TNF_SL_HOTPLUG_STACK,
 181             "");
 182 
 183         ASSERT(MUTEX_NOT_HELD(&hal->topology_tree_mutex));
 184 
 185         /* Initialize the Bus Mgr timers */
 186         hal->bus_mgr_timeout_id = 0;
 187         hal->bus_mgr_query_timeout_id = 0;
 188 
 189         /* Initialize the cmpletion Q */
 190         mutex_enter(&hal->br_cmplq_mutex);
 191         hal->br_cmplq_head = hal->br_cmplq_tail = NULL;
 192         mutex_exit(&hal->br_cmplq_mutex);
 193 
 194         s1394_wait_for_events(hal, 1);
 195 
 196         for (;;) {
 197                 ASSERT(MUTEX_NOT_HELD(&hal->topology_tree_mutex));
 198 
 199                 TNF_PROBE_0_DEBUG(s1394_br_thread_wait,
 200                     S1394_TNF_SL_HOTPLUG_STACK, "");
 201 
 202                 s1394_wait_for_events(hal, 0);
 203 
 204                 ASSERT(MUTEX_NOT_HELD(&hal->topology_tree_mutex));
 205 
 206                 TNF_PROBE_1_DEBUG(s1394_br_thread_restart,
 207                     S1394_TNF_SL_HOTPLUG_STACK, "",
 208                     tnf_int, hal_instance, ddi_get_instance(hal->halinfo.dip));
 209 
 210                 /* stop bus manager timeouts, if needed */
 211                 s1394_bus_mgr_timers_stop(hal, &hal->bus_mgr_query_timeout_id,
 212                     &hal->bus_mgr_timeout_id);
 213 
 214                 s1394_flush_cmplq(hal);
 215 
 216                 /* start timers for checking bus manager, if needed */
 217                 s1394_bus_mgr_timers_start(hal, &hal->bus_mgr_query_timeout_id,
 218                     &hal->bus_mgr_timeout_id);
 219 
 220                 /* Try to reallocate all isoch resources */
 221                 s1394_isoch_rsrc_realloc(hal);
 222 
 223                 if (s1394_cfgrom_scan_phase1(hal) != DDI_SUCCESS) {
 224                         TNF_PROBE_0_DEBUG(br_thread_phase1_restart,
 225                             S1394_TNF_SL_HOTPLUG_STACK, "");
 226                         continue;
 227                 }
 228 
 229                 TNF_PROBE_1_DEBUG(s1394_br_thread_phase1_done,
 230                     S1394_TNF_SL_HOTPLUG_STACK, "",
 231                     tnf_int, hal_instance, ddi_get_instance(hal->halinfo.dip));
 232 
 233                 if (s1394_bus_mgr_processing(hal) != DDI_SUCCESS) {
 234                         TNF_PROBE_0_DEBUG(br_thread_bus_mgr_restart,
 235                             S1394_TNF_SL_HOTPLUG_STACK, "");
 236                         continue;
 237                 }
 238 
 239                 TNF_PROBE_1_DEBUG(s1394_br_thread_bus_mgr_proc_done,
 240                     S1394_TNF_SL_HOTPLUG_STACK, "",
 241                     tnf_int, hal_instance, ddi_get_instance(hal->halinfo.dip));
 242 
 243                 ASSERT(MUTEX_NOT_HELD(&hal->topology_tree_mutex));
 244 
 245                 if (s1394_cfgrom_scan_phase2(hal) != DDI_SUCCESS) {
 246                         TNF_PROBE_0_DEBUG(br_thread_phase2_restart,
 247                             S1394_TNF_SL_HOTPLUG_STACK, "");
 248                         continue;
 249                 }
 250 
 251                 TNF_PROBE_1_DEBUG(s1394_br_thread_done,
 252                     S1394_TNF_SL_HOTPLUG_STACK, "",
 253                     tnf_int, hal_instance, ddi_get_instance(hal->halinfo.dip));
 254 
 255                 ASSERT(MUTEX_NOT_HELD(&hal->topology_tree_mutex));
 256         }
 257 }
 258 
 259 /*
 260  * s1394_wait_for_events()
 261  *    blocks waiting for a cv_signal on the bus reset condition variable.
 262  *    Used by the bus reset thread for synchronizing with the bus reset/
 263  *    self id interrupt callback from the hal. Does CPR initialization
 264  *    first time it is called. If services layer sees a valid self id
 265  *    buffer, it builds the topology tree and signals the bus reset thread
 266  *    to read the config roms as appropriate (indicated by BR_THR_CFGROM_SCAN).
 267  *    If the services layer wishes to kill the bus reset thread, it signals
 268  *    this by signaling a BR_THR_GO_AWAY event.
 269  */
 270 static void
 271 s1394_wait_for_events(s1394_hal_t *hal, int firsttime)
 272 {
 273         uint_t event;
 274 
 275         TNF_PROBE_0_DEBUG(s1394_wait_for_events_enter,
 276             S1394_TNF_SL_HOTPLUG_STACK, "");
 277 
 278         ASSERT(MUTEX_NOT_HELD(&hal->br_thread_mutex));
 279         ASSERT(MUTEX_NOT_HELD(&hal->topology_tree_mutex));
 280 
 281         if (firsttime)
 282                 CALLB_CPR_INIT(&hal->hal_cprinfo, &hal->br_thread_mutex,
 283                     callb_generic_cpr, "s1394_br_thread");
 284 
 285         /* Check and wait for a BUS RESET */
 286         mutex_enter(&hal->br_thread_mutex);
 287         while ((event = hal->br_thread_ev_type) == 0) {
 288                 CALLB_CPR_SAFE_BEGIN(&hal->hal_cprinfo);
 289                 cv_wait(&hal->br_thread_cv, &hal->br_thread_mutex);
 290                 CALLB_CPR_SAFE_END(&hal->hal_cprinfo, &hal->br_thread_mutex);
 291         }
 292 
 293         if (event & BR_THR_GO_AWAY) {
 294                 TNF_PROBE_1(s1394_wait_for_events, S1394_TNF_SL_HOTPLUG_STACK,
 295                     "", tnf_string, msg, "Go away set");
 296                 s1394_br_thread_exit(hal);
 297                 TNF_PROBE_0_DEBUG(s1394_wait_for_events_exit,
 298                     S1394_TNF_SL_HOTPLUG_STACK, "");
 299                 /*NOTREACHED*/
 300                 return;
 301         }
 302 
 303         if (firsttime) {
 304                 TNF_PROBE_0_DEBUG(s1394_wait_for_events_exit,
 305                     S1394_TNF_SL_HOTPLUG_STACK, "");
 306                 mutex_exit(&hal->br_thread_mutex);
 307                 return;
 308         }
 309 
 310         mutex_enter(&hal->topology_tree_mutex);
 311         if (event & BR_THR_CFGROM_SCAN) {
 312                 TNF_PROBE_2_DEBUG(s1394_wait_for_events_scan,
 313                     S1394_TNF_SL_HOTPLUG_STACK, "",
 314                     tnf_int, br_thread_gen, hal->br_cfgrom_read_gen,
 315                     tnf_int, hal_generation, hal->generation_count);
 316         }
 317         hal->br_cfgrom_read_gen = hal->generation_count;
 318 
 319         hal->br_thread_ev_type &= ~BR_THR_CFGROM_SCAN;
 320         mutex_exit(&hal->topology_tree_mutex);
 321         mutex_exit(&hal->br_thread_mutex);
 322 
 323         TNF_PROBE_0_DEBUG(s1394_wait_for_events_exit,
 324             S1394_TNF_SL_HOTPLUG_STACK, "");
 325 }
 326 
 327 /*
 328  * s1394_wait_for_cfgrom_callbacks()
 329  *    Waits for completed config rom reads. Takes each completion off the
 330  *    completion queue and passes it to the "completion handler" function
 331  *    that was passed in as an argument. Further processing of the completion
 332  *    queue depends on the return status of the completion handler. If there
 333  *    is a bus reset while waiting for completions or if the services layer
 334  *    signals BR_THR_GO_AWAY, quits waiting for completions and returns
 335  *    non-zero. Also returns non-zero if completion handler returns
 336  *    S1394_HCMD_LOCK_FAILED.  Returns 0 if config roms for all nodes have
 337  *    been dealt with.
 338  */
 339 static int
 340 s1394_wait_for_cfgrom_callbacks(s1394_hal_t *hal, uint_t wait_gen,
 341     hcmd_ret_t(*handle_cmd_fn)(s1394_hal_t *hal, cmd1394_cmd_t *cmd))
 342 {
 343         cmd1394_cmd_t *cmd;
 344         s1394_cmd_priv_t *s_priv;
 345         int ret, done = 0;
 346         hcmd_ret_t cmdret;
 347 
 348         ASSERT(MUTEX_NOT_HELD(&hal->topology_tree_mutex));
 349 
 350         TNF_PROBE_1_DEBUG(s1394_wait_for_cfgrom_callbacks_enter,
 351             S1394_TNF_SL_HOTPLUG_STACK, "", tnf_uint, wait_gen, wait_gen);
 352 
 353         ret = DDI_SUCCESS;
 354 
 355         while (!done) {
 356                 mutex_enter(&hal->br_cmplq_mutex);
 357                 mutex_enter(&hal->topology_tree_mutex);
 358                 while (wait_gen == hal->generation_count &&
 359                     (hal->br_thread_ev_type & BR_THR_GO_AWAY) == 0 &&
 360                     hal->br_cmplq_head == NULL) {
 361                         mutex_exit(&hal->topology_tree_mutex);
 362                         cv_wait(&hal->br_cmplq_cv, &hal->br_cmplq_mutex);
 363                         mutex_enter(&hal->topology_tree_mutex);
 364                 }
 365                 ASSERT(MUTEX_HELD(&hal->topology_tree_mutex));
 366                 if (wait_gen != hal->generation_count ||
 367                     (hal->br_thread_ev_type & BR_THR_GO_AWAY) != 0) {
 368 
 369 #if !defined(NPROBE) && defined(TNF_DEBUG)
 370                         int hal_gen = hal->generation_count;
 371 #endif
 372 
 373                         mutex_exit(&hal->topology_tree_mutex);
 374                         mutex_exit(&hal->br_cmplq_mutex);
 375                         s1394_flush_cmplq(hal);
 376                         TNF_PROBE_1_DEBUG(s1394_wait_for_cfgrom_callbacks_exit,
 377                             S1394_TNF_SL_HOTPLUG_STACK, "", tnf_int, hal_gen,
 378                             hal_gen);
 379                         return (DDI_FAILURE);
 380                 }
 381                 mutex_exit(&hal->topology_tree_mutex);
 382 
 383                 if ((cmd = hal->br_cmplq_head) != NULL) {
 384                         s_priv = S1394_GET_CMD_PRIV(cmd);
 385 
 386                         hal->br_cmplq_head = s_priv->cmd_priv_next;
 387                 }
 388                 if (cmd == hal->br_cmplq_tail)
 389                         hal->br_cmplq_tail = NULL;
 390                 mutex_exit(&hal->br_cmplq_mutex);
 391 
 392                 if (cmd != NULL) {
 393                         if (cmd->bus_generation != wait_gen) {
 394                                 TNF_PROBE_3(
 395                                     s1394_wait_for_cfgrom_callbacks,
 396                                     S1394_TNF_SL_HOTPLUG_STACK, "",
 397                                     tnf_string, msg, "command gen != wait_gen",
 398                                     tnf_uint, cmd_gen, cmd->bus_generation,
 399                                     tnf_uint, wait_gen, wait_gen);
 400                                 (void) s1394_free_cmd(hal, &cmd);
 401                                 continue;
 402                         }
 403                         cmdret = (*handle_cmd_fn)(hal, cmd);
 404                         TNF_PROBE_2_DEBUG(s1394_wait_for_cfgrom_callbacks,
 405                             S1394_TNF_SL_HOTPLUG_STACK, "",
 406                             tnf_opaque, cmd, cmd, tnf_int, cmdret, cmdret);
 407                         ASSERT(cmdret != S1394_HCMD_INVALID);
 408                         if (cmdret == S1394_HCMD_LOCK_FAILED) {
 409                                 /* flush completion queue */
 410                                 ret = DDI_FAILURE;
 411                                 s1394_flush_cmplq(hal);
 412                                 break;
 413                         } else if (cmdret == S1394_HCMD_NODE_DONE) {
 414                                 if (--hal->cfgroms_being_read == 0) {
 415                                         /* All done */
 416                                         break;
 417                                 }
 418                         } else {
 419                                 ASSERT(cmdret == S1394_HCMD_NODE_EXPECT_MORE);
 420                                 done = 0;
 421                         }
 422                 }
 423         }
 424 
 425         TNF_PROBE_0_DEBUG(s1394_wait_for_cfgrom_callbacks_exit,
 426             S1394_TNF_SL_HOTPLUG_STACK, "");
 427 
 428         return (ret);
 429 }
 430 
 431 /*
 432  * s1394_flush_cmplq()
 433  *    Frees all cmds on the completion queue.
 434  */
 435 static void
 436 s1394_flush_cmplq(s1394_hal_t *hal)
 437 {
 438         s1394_cmd_priv_t *s_priv;
 439         cmd1394_cmd_t *cmd, *tcmd;
 440 
 441         ASSERT(MUTEX_NOT_HELD(&hal->topology_tree_mutex));
 442 
 443         TNF_PROBE_0_DEBUG(s1394_flush_cmplq_enter, S1394_TNF_SL_HOTPLUG_STACK,
 444             "");
 445 
 446         cmd = NULL;
 447 
 448         do {
 449                 mutex_enter(&hal->br_cmplq_mutex);
 450                 cmd = hal->br_cmplq_head;
 451                 hal->br_cmplq_head = hal->br_cmplq_tail = NULL;
 452                 mutex_exit(&hal->br_cmplq_mutex);
 453 
 454                 while (cmd != NULL) {
 455                         s_priv = S1394_GET_CMD_PRIV(cmd);
 456 
 457                         tcmd = s_priv->cmd_priv_next;
 458                         TNF_PROBE_2_DEBUG(s1394_flush_cmplq,
 459                             S1394_TNF_SL_HOTPLUG_STACK, "", tnf_opaque, cmd,
 460                             cmd, tnf_uint, cmd_gen, cmd->bus_generation);
 461                         (void) s1394_free_cmd(hal, &cmd);
 462                         cmd = tcmd;
 463                 }
 464 
 465                 mutex_enter(&hal->br_cmplq_mutex);
 466                 cmd = hal->br_cmplq_head;
 467                 mutex_exit(&hal->br_cmplq_mutex);
 468 
 469         } while (cmd != NULL);
 470 
 471         TNF_PROBE_0_DEBUG(s1394_flush_cmplq_exit, S1394_TNF_SL_HOTPLUG_STACK,
 472             "");
 473 
 474 }
 475 
 476 /*
 477  * s1394_br_thread_exit()
 478  *    Flushes the completion queue and calls thread_exit() (which effectively
 479  *    kills the bus reset thread).
 480  */
 481 static void
 482 s1394_br_thread_exit(s1394_hal_t *hal)
 483 {
 484         ASSERT(MUTEX_HELD(&hal->br_thread_mutex));
 485         ASSERT(MUTEX_NOT_HELD(&hal->topology_tree_mutex));
 486         TNF_PROBE_0(s1394_br_thread_exit_enter, S1394_TNF_SL_HOTPLUG_STACK, "");
 487         s1394_flush_cmplq(hal);
 488 #ifndef __lock_lint
 489         CALLB_CPR_EXIT(&hal->hal_cprinfo);
 490 #endif
 491         hal->br_thread_ev_type &= ~BR_THR_GO_AWAY;
 492         thread_exit();
 493         /*NOTREACHED*/
 494 }
 495 
 496 /*
 497  * s1394_target_bus_reset_notifies()
 498  *    tells the ndi event framework to invoke any callbacks registered for
 499  *    "bus reset event".
 500  */
 501 static void
 502 s1394_target_bus_reset_notifies(s1394_hal_t *hal, t1394_localinfo_t *localinfo)
 503 {
 504         ddi_eventcookie_t cookie;
 505 
 506         ASSERT(MUTEX_NOT_HELD(&hal->topology_tree_mutex));
 507 
 508         TNF_PROBE_2_DEBUG(s1394_target_bus_reset_notifies_enter,
 509             S1394_TNF_SL_HOTPLUG_STACK, "", tnf_uint, bus_gen,
 510             localinfo->bus_generation, tnf_uint, node_id,
 511             localinfo->local_nodeID);
 512 
 513         if (ndi_event_retrieve_cookie(hal->hal_ndi_event_hdl, NULL,
 514             DDI_DEVI_BUS_RESET_EVENT, &cookie, NDI_EVENT_NOPASS) ==
 515             NDI_SUCCESS) {
 516                 (void) ndi_event_run_callbacks(hal->hal_ndi_event_hdl, NULL,
 517                     cookie, localinfo);
 518         }
 519         TNF_PROBE_0_DEBUG(s1394_target_bus_reset_notifies_exit,
 520             S1394_TNF_SL_HOTPLUG_STACK, "");
 521 }
 522 
 523 /*
 524  * s1394_alloc_cfgrom()
 525  *    Allocates config rom for the node. Sets CFGROM_NEW_ALLOC bit in the
 526  *    node cfgrom state. Drops topology_tree_mutex around the calls to
 527  *    kmem_zalloc(). If re-locking fails, returns DDI_FAILURE, else returns
 528  *    DDI_SUCCESS.
 529  */
 530 static int
 531 s1394_alloc_cfgrom(s1394_hal_t *hal, s1394_node_t *node, s1394_status_t *status)
 532 {
 533         uint32_t *cfgrom;
 534 
 535         ASSERT(MUTEX_HELD(&hal->topology_tree_mutex));
 536 
 537         TNF_PROBE_0_DEBUG(s1394_alloc_cfgrom_enter, S1394_TNF_SL_HOTPLUG_STACK,
 538             "");
 539 
 540         *status = S1394_NOSTATUS;
 541 
 542         /*
 543          * if cfgrom is non-NULL, this has to be generation changed
 544          * case (where we allocate cfgrom again to reread the cfgrom)
 545          */
 546         ASSERT(node->cfgrom == NULL || (node->cfgrom != NULL &&
 547             CFGROM_GEN_CHANGED(node) == B_TRUE));
 548 
 549         /*
 550          * if node matched, either cfgrom has to be NULL or link should be
 551          * off in the last matched node or config rom generations changed.
 552          */
 553         ASSERT(NODE_MATCHED(node) == B_FALSE || (NODE_MATCHED(node) == B_TRUE &&
 554             (node->cfgrom == NULL || LINK_ACTIVE(node->old_node) == B_FALSE) ||
 555             CFGROM_GEN_CHANGED(node) == B_TRUE));
 556 
 557         s1394_unlock_tree(hal);
 558         cfgrom = (uint32_t *)kmem_zalloc(IEEE1394_CONFIG_ROM_SZ, KM_SLEEP);
 559         if (s1394_lock_tree(hal) != DDI_SUCCESS) {
 560                 kmem_free(cfgrom, IEEE1394_CONFIG_ROM_SZ);
 561                 *status |= S1394_LOCK_FAILED;
 562                 TNF_PROBE_1(s1394_alloc_cfgrom, S1394_TNF_SL_HOTPLUG_ERROR,
 563                     "", tnf_string, msg, "cannot relock the tree");
 564                 TNF_PROBE_0_DEBUG(s1394_alloc_cfgrom_exit,
 565                     S1394_TNF_SL_HOTPLUG_STACK, "");
 566                 return (DDI_FAILURE);
 567         }
 568         node->cfgrom = cfgrom;
 569         node->cfgrom_size = IEEE1394_CONFIG_ROM_QUAD_SZ;
 570         SET_CFGROM_NEW_ALLOC(node);
 571         ASSERT(MUTEX_HELD(&hal->topology_tree_mutex));
 572         TNF_PROBE_3(s1394_alloc_cfgrom_exit, S1394_TNF_SL_HOTPLUG_STACK,
 573             "cfgrom alloc", tnf_uint, hal_gen, hal->generation_count, tnf_uint,
 574             node_num, node->node_num, tnf_opaque, cfgrom, cfgrom);
 575         return (DDI_SUCCESS);
 576 }
 577 
 578 /*
 579  * s1394_free_cfgrom()
 580  *    Marks the config rom invalid and frees up the config based on otpions.
 581  */
 582 void
 583 s1394_free_cfgrom(s1394_hal_t *hal, s1394_node_t *node,
 584     s1394_free_cfgrom_t options)
 585 {
 586         ASSERT(MUTEX_HELD(&hal->topology_tree_mutex));
 587         ASSERT(node->cfgrom != NULL);
 588 
 589         TNF_PROBE_0_DEBUG(s1394_free_cfgrom_enter, S1394_TNF_SL_HOTPLUG_STACK,
 590             "");
 591 
 592         if (options == S1394_FREE_CFGROM_BOTH) {
 593                 /*
 594                  * free in both old and new trees; will be called with
 595                  * new node.
 596                  */
 597                 s1394_node_t *onode = node->old_node;
 598 
 599                 if (NODE_MATCHED(node) == B_TRUE && onode->cfgrom != NULL)
 600                         ASSERT(onode->cfgrom == node->cfgrom);
 601 
 602                 TNF_PROBE_4(s1394_free_cfgrom_both,
 603                     S1394_TNF_SL_HOTPLUG_STACK, "cfgrom free", tnf_uint,
 604                     hal_gen, hal->generation_count, tnf_int, node_num,
 605                     node->node_num, tnf_opaque, old_cfgrom, onode->cfgrom,
 606                     tnf_opaque, cfgrom, node->cfgrom);
 607 
 608                 if (onode != NULL && onode->cfgrom != NULL && onode->cfgrom !=
 609                     node->cfgrom)
 610                         kmem_free(onode->cfgrom, IEEE1394_CONFIG_ROM_SZ);
 611 
 612                 kmem_free(node->cfgrom, IEEE1394_CONFIG_ROM_SZ);
 613                 onode->cfgrom = NULL;
 614                 node->cfgrom = NULL;
 615 
 616                 CLEAR_CFGROM_STATE(onode);
 617                 CLEAR_CFGROM_STATE(node);
 618 
 619         } else if (options == S1394_FREE_CFGROM_NEW) {
 620 
 621                 TNF_PROBE_2(s1394_free_cfgrom_new,
 622                     S1394_TNF_SL_HOTPLUG_STACK, "cfgrom free",
 623                     tnf_int, node_num, node->node_num,
 624                     tnf_opaque, cfgrom, node->cfgrom);
 625 
 626                 ASSERT(CFGROM_NEW_ALLOC(node) == B_TRUE);
 627                 kmem_free(node->cfgrom, IEEE1394_CONFIG_ROM_SZ);
 628                 CLEAR_CFGROM_NEW_ALLOC(node);
 629                 node->cfgrom = NULL;
 630                 CLEAR_CFGROM_STATE(node);
 631 
 632         } else if (options == S1394_FREE_CFGROM_OLD) {
 633 
 634                 /* freeing in old tree */
 635                 TNF_PROBE_2_DEBUG(s1394_free_cfgrom_old,
 636                     S1394_TNF_SL_HOTPLUG_STACK, "cfgrom free",
 637                     tnf_int, node_num, node->node_num,
 638                     tnf_opaque, cfgrom, node->cfgrom);
 639                 kmem_free(node->cfgrom, IEEE1394_CONFIG_ROM_SZ);
 640                 node->cfgrom = NULL;
 641                 CLEAR_CFGROM_STATE(node);
 642         }
 643 
 644         TNF_PROBE_0_DEBUG(s1394_free_cfgrom_exit, S1394_TNF_SL_HOTPLUG_STACK,
 645             "");
 646 }
 647 
 648 /*
 649  * s1394_copy_cfgrom()
 650  *    Copies config rom info from "from" node to "to" node. Clears
 651  *    CFGROM_NEW_ALLOC bit in cfgrom state in bothe nodes. (CFGROM_NEW_ALLOC
 652  *    acts as a reference count. If set, only the node in the current tree
 653  *    has a pointer to it; if clear, both the node in the current tree as
 654  *    well as the corresponding node in the old tree point to the same memory).
 655  */
 656 void
 657 s1394_copy_cfgrom(s1394_node_t *to, s1394_node_t *from)
 658 {
 659         TNF_PROBE_3_DEBUG(s1394_copy_cfgrom_enter, S1394_TNF_SL_HOTPLUG_STACK,
 660             "", tnf_int, to_node, to->node_num, tnf_int,
 661             from_node, from->node_num, tnf_opaque, from_cfgrom, from->cfgrom);
 662 
 663         ASSERT(to->cfgrom == NULL);
 664 
 665         to->cfgrom = from->cfgrom;
 666         to->cfgrom_state = from->cfgrom_state;
 667         to->cfgrom_valid_size = from->cfgrom_valid_size;
 668         to->cfgrom_size = from->cfgrom_size;
 669         to->node_state = from->node_state;
 670 
 671         bcopy(from->dir_stack, to->dir_stack,
 672             offsetof(s1394_node_t, cfgrom_quad_to_read) -
 673             offsetof(s1394_node_t, dir_stack));
 674 
 675         to->cfgrom_quad_to_read = from->cfgrom_quad_to_read;
 676 
 677         CLEAR_CFGROM_NEW_ALLOC(to);
 678         CLEAR_CFGROM_NEW_ALLOC(from);
 679 
 680         /*
 681          * old link off, new link on => handled in s1394_cfgrom_scan_phase1
 682          * old link on, new link off => handled in s1394_process_old_tree
 683          */
 684         if (LINK_ACTIVE(from) == B_FALSE) {
 685                 /*
 686                  * if last time around, link was off, there wouldn't
 687                  * have been config rom allocated.
 688                  */
 689                 ASSERT(from->cfgrom == NULL);
 690                 TNF_PROBE_0_DEBUG(s1394_copy_cfgrom_exit,
 691                     S1394_TNF_SL_HOTPLUG_STACK, "");
 692                 return;
 693         } else {
 694                 s1394_selfid_pkt_t *selfid_pkt = to->selfid_packet;
 695 
 696                 if (IEEE1394_SELFID_ISLINKON(selfid_pkt))
 697                         SET_LINK_ACTIVE(to);
 698         }
 699 
 700         TNF_PROBE_0_DEBUG(s1394_copy_cfgrom_exit,
 701             S1394_TNF_SL_HOTPLUG_STACK, "");
 702 }
 703 
 704 /*
 705  * s1394_read_bus_info_blk()
 706  *    Attempts to kick off reading IEEE1212_NODE_CAP_QUAD quad or quad 0.
 707  *    Increments cfgroms_being_read by 1. Returns DDI_SUCCESS command was
 708  *    issued, else sets status to the failure reason and returns DDI_FAILURE.
 709  */
 710 static int
 711 s1394_read_bus_info_blk(s1394_hal_t *hal, s1394_node_t *node,
 712     s1394_status_t *status)
 713 {
 714         uint32_t quadlet;
 715         cmd1394_cmd_t *cmd;
 716         uchar_t node_num;
 717 
 718         ASSERT(MUTEX_HELD(&hal->topology_tree_mutex));
 719         ASSERT(LINK_ACTIVE(node) == B_TRUE);
 720 
 721         node_num = node->node_num;
 722 
 723         TNF_PROBE_2_DEBUG(s1394_read_bus_info_blk_enter,
 724             S1394_TNF_SL_HOTPLUG_STACK, "", tnf_uint, hal_gen,
 725             hal->generation_count, tnf_int, node_num, node_num);
 726 
 727         /*
 728          * drop the topology lock around command allocation. Return failure
 729          * if either command allocation fails or cannot reacquire the lock
 730          */
 731         s1394_unlock_tree(hal);
 732         *status = S1394_NOSTATUS;
 733 
 734         if (s1394_alloc_cmd(hal, 0, &cmd) != DDI_SUCCESS) {
 735                 TNF_PROBE_1(s1394_read_bus_info_blk, S1394_TNF_SL_HOTPLUG_ERROR,
 736                     "", tnf_string, msg, "command allocation failed");
 737                 *status |= S1394_CMD_ALLOC_FAILED;
 738         }
 739         if (s1394_lock_tree(hal) != DDI_SUCCESS) {
 740                 *status |= S1394_LOCK_FAILED;
 741                 TNF_PROBE_1(s1394_read_bus_info_blk, S1394_TNF_SL_HOTPLUG_ERROR,
 742                     "", tnf_string, msg, "unable to relock the tree");
 743                 /* free the cmd allocated above */
 744                 if (((*status) & S1394_CMD_ALLOC_FAILED) != 0)
 745                         (void) s1394_free_cmd(hal, (cmd1394_cmd_t **)&cmd);
 746         }
 747         if (((*status) & (S1394_CMD_ALLOC_FAILED | S1394_LOCK_FAILED)) != 0) {
 748                 TNF_PROBE_0_DEBUG(s1394_read_bus_info_blk_exit,
 749                     S1394_TNF_SL_HOTPLUG_STACK, "");
 750                 return (DDI_FAILURE);
 751         }
 752 
 753         /* allocate cfgrom if needed */
 754         if (node->cfgrom == NULL && s1394_alloc_cfgrom(hal, node, status) !=
 755             DDI_SUCCESS) {
 756                 ASSERT(((*status) & S1394_LOCK_FAILED) != 0);
 757                 (void) s1394_free_cmd(hal, (cmd1394_cmd_t **)&cmd);
 758                 ASSERT(MUTEX_NOT_HELD(&hal->topology_tree_mutex));
 759                 TNF_PROBE_1(s1394_read_bus_info_blk, S1394_TNF_SL_HOTPLUG_ERROR,
 760                     "", tnf_string, msg, "config rom allocation failed");
 761                 TNF_PROBE_0_DEBUG(s1394_read_bus_info_blk_exit,
 762                     S1394_TNF_SL_HOTPLUG_STACK, "");
 763                 return (DDI_FAILURE);
 764         }
 765 
 766         /*
 767          * if this is a matched node, read quad 2 (node capabilities) to
 768          * see if the generation count changed.
 769          */
 770         quadlet = CFGROM_BIB_READ(node) ? IEEE1212_NODE_CAP_QUAD : 0;
 771 
 772         /*
 773          * read bus info block at 100Mbit. This will help us with the cases
 774          * where LINK is slower than PHY; s1394 uses PHY speed till speed map
 775          * is updated.
 776          */
 777         cmd->completion_callback = s1394_cfgrom_read_callback;
 778         cmd->bus_generation = hal->generation_count;
 779         cmd->cmd_options = (CMD1394_CANCEL_ON_BUS_RESET |
 780             CMD1394_OVERRIDE_ADDR | CMD1394_OVERRIDE_SPEED);
 781         cmd->cmd_speed = IEEE1394_S100;
 782         cmd->cmd_type = CMD1394_ASYNCH_RD_QUAD;
 783 
 784         QUAD_TO_CFGROM_ADDR(IEEE1394_LOCAL_BUS, node_num,
 785             quadlet, cmd->cmd_addr);
 786 
 787         TNF_PROBE_3_DEBUG(s1394_read_bus_info_blk,
 788             S1394_TNF_SL_HOTPLUG_STACK, "", tnf_uint, hal_gen,
 789             hal->generation_count, tnf_int, node_num, node_num, tnf_uint,
 790             quadlet, quadlet);
 791 
 792         TNF_PROBE_5_DEBUG(s1394_read_bus_info_blk,
 793             S1394_TNF_SL_HOTPLUG_STACK, "", tnf_int,
 794             node_num, node_num, tnf_int, parsed, CFGROM_PARSED(node), tnf_int,
 795             matched, NODE_MATCHED(node), tnf_int, visited,
 796             NODE_VISITED(node), tnf_int, generation_changed,
 797             CFGROM_GEN_CHANGED(node));
 798 
 799         SETUP_QUAD_READ(node, 1, quadlet, 1);
 800         if (s1394_read_config_quadlet(hal, cmd, status) != DDI_SUCCESS) {
 801                 TNF_PROBE_1(s1394_read_bus_info_blk, S1394_TNF_SL_HOTPLUG_ERROR,
 802                     "", tnf_string, msg, "Unable to start read");
 803                 /* free the command if it wasn't handed over to the HAL */
 804                 if (((*status) & S1394_CMD_INFLIGHT) == 0) {
 805                         (void) s1394_free_cmd(hal, (cmd1394_cmd_t **)&cmd);
 806                 }
 807                 if (((*status) & S1394_LOCK_FAILED) != 0) {
 808                         ASSERT(MUTEX_NOT_HELD(&hal->topology_tree_mutex));
 809                 }
 810                 TNF_PROBE_0_DEBUG(s1394_read_bus_info_blk_exit,
 811                     S1394_TNF_SL_HOTPLUG_STACK, "");
 812                 return (DDI_FAILURE);
 813         }
 814 
 815         hal->cfgroms_being_read++;
 816         ASSERT(MUTEX_HELD(&hal->topology_tree_mutex));
 817 
 818         TNF_PROBE_1_DEBUG(s1394_read_bus_info_blk_exit,
 819             S1394_TNF_SL_HOTPLUG_STACK, "", tnf_int, cfgrom_read_cnt,
 820             hal->cfgroms_being_read);
 821 
 822         return (DDI_SUCCESS);
 823 }
 824 
 825 /*
 826  * s1394_read_rest_of_cfgrom()
 827  *    Attempts to start reading node->cfgrom_quad_to_read quadlet. Increments
 828  *    cfgroms_being_read by 1 and returns DDI_SUCCESS if command was issued,
 829  *    else sets status to the failure reason and returns DDI_FAILURE.
 830  */
 831 int
 832 s1394_read_rest_of_cfgrom(s1394_hal_t *hal, s1394_node_t *node,
 833     s1394_status_t *status)
 834 {
 835         cmd1394_cmd_t *cmd;
 836         uchar_t node_num = node->node_num;
 837 
 838         ASSERT(MUTEX_HELD(&hal->topology_tree_mutex));
 839         ASSERT(LINK_ACTIVE(node) == B_TRUE);
 840 
 841         TNF_PROBE_2_DEBUG(s1394_read_rest_of_cfgrom_enter,
 842             S1394_TNF_SL_HOTPLUG_STACK, "", tnf_uint, hal_gen,
 843             hal->generation_count, tnf_int, node_num, node_num);
 844 
 845         /*
 846          * drop the topology lock around command allocation. Return failure
 847          * if either command allocation fails or cannot reacquire the lock
 848          */
 849         s1394_unlock_tree(hal);
 850         *status = S1394_NOSTATUS;
 851 
 852         if (s1394_alloc_cmd(hal, 0, &cmd) != DDI_SUCCESS) {
 853                 *status |= S1394_CMD_ALLOC_FAILED;
 854                 TNF_PROBE_1(s1394_read_rest_of_cfgrom,
 855                     S1394_TNF_SL_HOTPLUG_ERROR, "", tnf_string, msg,
 856                     "command allocation failed");
 857         }
 858         if (s1394_lock_tree(hal) != DDI_SUCCESS) {
 859                 *status |= S1394_LOCK_FAILED;
 860                 /* free if we allocated a cmd above */
 861                 if (((*status) & S1394_CMD_ALLOC_FAILED) == 0)
 862                         (void) s1394_free_cmd(hal, (cmd1394_cmd_t **)&cmd);
 863                 TNF_PROBE_1(s1394_read_rest_of_cfgrom,
 864                     S1394_TNF_SL_HOTPLUG_ERROR, "", tnf_string, msg,
 865                     "unable to relock the tree");
 866         }
 867         if (((*status) & (S1394_CMD_ALLOC_FAILED | S1394_LOCK_FAILED)) != 0) {
 868                 TNF_PROBE_0_DEBUG(s1394_read_rest_of_cfgrom_exit,
 869                     S1394_TNF_SL_HOTPLUG_STACK, "");
 870                 return (DDI_FAILURE);
 871         }
 872 
 873         cmd->completion_callback = s1394_cfgrom_read_callback;
 874         cmd->bus_generation = hal->generation_count;
 875         cmd->cmd_options = (CMD1394_CANCEL_ON_BUS_RESET |
 876             CMD1394_OVERRIDE_ADDR);
 877         cmd->cmd_type = CMD1394_ASYNCH_RD_QUAD;
 878 
 879         TNF_PROBE_2_DEBUG(s1394_read_rest_of_cfgrom, S1394_TNF_SL_HOTPLUG_STACK,
 880             "", tnf_uint, hal_gen, hal->generation_count, tnf_int, node_num,
 881             node->node_num);
 882 
 883         QUAD_TO_CFGROM_ADDR(IEEE1394_LOCAL_BUS, node_num,
 884             node->cfgrom_quad_to_read, cmd->cmd_addr);
 885         SETUP_QUAD_READ(node, 1, node->cfgrom_quad_to_read, 1);
 886         if (s1394_read_config_quadlet(hal, cmd, status) != DDI_SUCCESS) {
 887                 TNF_PROBE_1(s1394_read_rest_of_cfgrom_exit,
 888                     S1394_TNF_SL_HOTPLUG_ERROR, "", tnf_string, msg,
 889                     "unable to start read");
 890                 /* free the command if it wasn't handed over to the HAL */
 891                 if (((*status) & S1394_CMD_INFLIGHT) == 0) {
 892                         (void) s1394_free_cmd(hal, (cmd1394_cmd_t **)&cmd);
 893                 }
 894                 if (((*status) & S1394_LOCK_FAILED) != 0) {
 895                         ASSERT(MUTEX_NOT_HELD(&hal->topology_tree_mutex));
 896                 }
 897                 TNF_PROBE_0_DEBUG(s1394_read_rest_of_cfgrom_exit,
 898                     S1394_TNF_SL_HOTPLUG_STACK, "");
 899                 return (DDI_FAILURE);
 900         }
 901 
 902         hal->cfgroms_being_read++;
 903         ASSERT(MUTEX_HELD(&hal->topology_tree_mutex));
 904 
 905         TNF_PROBE_1_DEBUG(s1394_read_rest_of_cfgrom_exit,
 906             S1394_TNF_SL_HOTPLUG_STACK, "", tnf_int, cfgrom_read_cnt,
 907             hal->cfgroms_being_read);
 908 
 909         return (DDI_SUCCESS);
 910 }
 911 
 912 /*
 913  * s1394_cfgrom_scan_phase1()
 914  *    Attempts to read bus info blocks for nodes as needed. Returns DDI_FAILURE
 915  *    if bus reset generations changed (as indicated by s1394_lock_tree()
 916  *    return status) or if any of the callees return failure, else returns
 917  *    DDI_SUCCESS.
 918  */
 919 static int
 920 s1394_cfgrom_scan_phase1(s1394_hal_t *hal)
 921 {
 922         uint32_t number_of_nodes;
 923         int ret;
 924         int node;
 925         int wait_in_gen;
 926         int wait_for_cbs;
 927         uint_t hal_node_num;
 928         uint_t hal_node_num_old;
 929         s1394_node_t *nnode, *onode;
 930         s1394_selfid_pkt_t *selfid_pkt;
 931         s1394_status_t status;
 932 
 933         TNF_PROBE_0_DEBUG(s1394_cfgrom_scan_phase1_enter,
 934             S1394_TNF_SL_HOTPLUG_STACK, "");
 935 
 936         ASSERT(MUTEX_NOT_HELD(&hal->topology_tree_mutex));
 937 
 938         if (s1394_lock_tree(hal) != DDI_SUCCESS) {
 939                 TNF_PROBE_0_DEBUG(s1394_cfgrom_scan_phase1_exit,
 940                     S1394_TNF_SL_HOTPLUG_STACK, "");
 941                 return (DDI_FAILURE);
 942         }
 943         wait_for_cbs = 0;
 944         number_of_nodes = hal->number_of_nodes;
 945         hal->cfgroms_being_read = 0;
 946         hal_node_num = IEEE1394_NODE_NUM(hal->node_id);
 947         hal_node_num_old = IEEE1394_NODE_NUM(hal->old_node_id);
 948         s1394_unlock_tree(hal);
 949 
 950         ret = DDI_SUCCESS;
 951 
 952         /* Send requests for all new node config ROM 0 */
 953         for (node = 0; node < number_of_nodes; node++) {
 954 
 955                 status = S1394_UNKNOWN;
 956 
 957                 if (s1394_lock_tree(hal) != DDI_SUCCESS) {
 958                         status = S1394_LOCK_FAILED;
 959                         break;
 960                 }
 961 
 962                 nnode = &hal->topology_tree[node];
 963                 onode = nnode->old_node;
 964                 /* if node matched, onode should be non NULL */
 965                 ASSERT(NODE_MATCHED(nnode) == B_FALSE || (NODE_MATCHED(nnode) ==
 966                     B_TRUE && onode != NULL));
 967 
 968                 /*
 969                  * Read bus info block if it is a brand new node (MATCHED is 0)
 970                  * or if matched but link was off in previous generations or
 971                  * or if matched but had invalid cfgrom in last generation
 972                  * or if matched but config rom generation > 1 (this is to
 973                  * check if config rom generation changed between bus resets).
 974                  */
 975                 if ((node != hal_node_num) &&
 976                     ((NODE_MATCHED(nnode) == B_FALSE) ||
 977                     (NODE_MATCHED(nnode) == B_TRUE && LINK_ACTIVE(onode) ==
 978                     B_FALSE) || (NODE_MATCHED(nnode) == B_TRUE &&
 979                     (onode->cfgrom == NULL || CFGROM_VALID(onode) ==
 980                     B_FALSE)) || (NODE_MATCHED(nnode) == B_TRUE &&
 981                     nnode->cfgrom != NULL && CONFIG_ROM_GEN(nnode->cfgrom) >
 982                     1))) {
 983 
 984                         SET_NODE_VISITED(nnode);
 985                         selfid_pkt = nnode->selfid_packet;
 986                         if (IEEE1394_SELFID_ISLINKON(selfid_pkt)) {
 987 
 988                                 SET_LINK_ACTIVE(nnode);
 989 
 990                                 status = S1394_UNKNOWN;
 991 
 992                                 if (s1394_read_bus_info_blk(hal, nnode,
 993                                     &status) != DDI_SUCCESS) {
 994                                         if ((status & S1394_LOCK_FAILED) != 0)
 995                                                 break;
 996                                 } else {
 997                                         wait_for_cbs++;
 998                                         wait_in_gen = hal->br_cfgrom_read_gen;
 999                                 }
1000                         } else {
1001                                 /*
1002                                  * Special case: if link was active last
1003                                  * time around, this should be treated as
1004                                  * node going away.
1005                                  */
1006                                 CLEAR_LINK_ACTIVE(nnode);
1007                                 if (NODE_MATCHED(nnode) == B_TRUE &&
1008                                     LINK_ACTIVE(onode) == B_TRUE) {
1009                                         CLEAR_CFGROM_STATE(nnode);
1010                                         TNF_PROBE_3(s1394_cfgrom_scan_phase1,
1011                                             S1394_TNF_SL_HOTPLUG_ERROR,
1012                                             "", tnf_string, msg,
1013                                             "link lost power", tnf_int, node,
1014                                             node, tnf_int, onode,
1015                                             onode->node_num);
1016                                 }
1017                         }
1018                 } else {
1019                         if (node == hal_node_num) {
1020                                 onode = &hal->old_tree[hal_node_num_old];
1021                                 /* Set up the local matched nodes */
1022                                 if (onode) {
1023                                         nnode->old_node = onode;
1024                                         SET_NODE_MATCHED(nnode);
1025                                         SET_NODE_MATCHED(onode);
1026                                         s1394_copy_cfgrom(nnode, onode);
1027                                 }
1028                         }
1029                 }
1030                 s1394_unlock_tree(hal);
1031         }
1032 
1033         ASSERT(MUTEX_NOT_HELD(&hal->topology_tree_mutex));
1034 
1035         if ((status & S1394_LOCK_FAILED) != 0) {
1036                 TNF_PROBE_1(s1394_cfrom_scan_phase1_exit,
1037                     S1394_TNF_SL_HOTPLUG_STACK, "",
1038                     tnf_string, msg, "Generations changed");
1039                 return (DDI_FAILURE);
1040         }
1041 
1042         /*
1043          * If we started any reads, wait for completion callbacks
1044          */
1045         if (wait_for_cbs != 0) {
1046                 ret = s1394_wait_for_cfgrom_callbacks(hal, wait_in_gen,
1047                     s1394_br_thread_handle_cmd_phase1);
1048         }
1049 
1050         ASSERT(MUTEX_NOT_HELD(&hal->topology_tree_mutex));
1051 
1052         TNF_PROBE_0_DEBUG(s1394_cfrom_scan_phase1_exit,
1053             S1394_TNF_SL_HOTPLUG_STACK, "");
1054 
1055         return (ret);
1056 }
1057 
1058 /*
1059  * s1394_br_thread_handle_cmd_phase1()
1060  *    Process the cmd completion for phase 1 config rom reads. If we
1061  *    successfully read IEEE1212_NODE_CAP_QUAD quadlet and config rom gen
1062  *    did not change, move targets hanging off the old node to the current
1063  *    node. If config rom generations change, alloc new config rom and start
1064  *    re-reading the new config rom. If all of bus info block is read (as
1065  *    required), mark the node as CFGROM_BIB_READ. If config rom read fails
1066  *    retry if not too many failures. Topology tree mutex is dropped and
1067  *    reacquired in this routine. If reacquiring fails, returns
1068  *    S1394_HCMD_LOCK_FAILED. If the entire bus info block is read, returns
1069  *    S1394_HCMD_NODE_DONE, else returns S1394_HCMD_NODE_EXPECT_MORE (to
1070  *    indicate not done with the node yet).
1071  *
1072  *    If we cannot read any of the quadlets in the bus info block, cfgrom
1073  *    is marked invalid in this generation (a side effect of calling
1074  *    s1394_free_cfgrom()). We free cfgrom in this routine only if the failure
1075  *    is not due to bus generations changing.
1076  */
1077 static hcmd_ret_t
1078 s1394_br_thread_handle_cmd_phase1(s1394_hal_t *hal, cmd1394_cmd_t *cmd)
1079 {
1080         s1394_target_t *t;
1081         s1394_node_t *node, *onode;
1082         uint32_t node_num, quadlet, data;
1083         int freecmd, done, locked;
1084         hcmd_ret_t cmdret;
1085         uchar_t readdelay;
1086         s1394_status_t status;
1087 
1088         s1394_get_quad_info(cmd, &node_num, &quadlet, &data);
1089         ASSERT(quadlet == 0 || quadlet < IEEE1394_BIB_QUAD_SZ);
1090 
1091         TNF_PROBE_0_DEBUG(s1394_br_thread_handle_cmd_phase1_enter,
1092             S1394_TNF_SL_HOTPLUG_STACK, "");
1093 
1094         cmdret = S1394_HCMD_NODE_EXPECT_MORE;
1095 
1096         locked = 1;
1097         freecmd = 1;
1098 
1099         if (s1394_lock_tree(hal) != DDI_SUCCESS) {
1100                 TNF_PROBE_1(s1394_br_thread_handle_cmd_phase1,
1101                     S1394_TNF_SL_HOTPLUG_STACK, "", tnf_string, msg,
1102                     "unable to lock tree");
1103                 locked = 0;
1104                 goto bail;
1105         }
1106 
1107         node = &hal->topology_tree[node_num];
1108 
1109         if (cmd->cmd_result == CMD1394_CMDSUCCESS) {
1110 
1111                 int reread = 0;
1112 
1113                 done = 0;
1114 
1115                 if (quadlet == IEEE1212_NODE_CAP_QUAD &&
1116                     CFGROM_BIB_READ(node)) {
1117 
1118                         int cur_gen = ((data & IEEE1394_BIB_GEN_MASK) >>
1119                             IEEE1394_BIB_GEN_SHIFT);
1120 
1121                         /*
1122                          * node->old_node can be NULL if this is a new node &
1123                          * we are doing a rescan
1124                          */
1125                         onode = node->old_node;
1126                         if (CONFIG_ROM_GEN(node->cfgrom) == cur_gen) {
1127 
1128                                 if (CFGROM_PARSED(node) == B_TRUE) {
1129                                         rw_enter(&hal->target_list_rwlock,
1130                                             RW_WRITER);
1131                                         /* Update the target list, if any */
1132                                         if (onode != NULL &&
1133                                             (t = onode->target_list) != NULL) {
1134                                                 node->target_list = t;
1135                                                 while (t != NULL) {
1136                                                         t->on_node = node;
1137                                                         t = t->target_sibling;
1138                                                 }
1139                                         }
1140                                         rw_exit(&hal->target_list_rwlock);
1141                                 }
1142                                 SET_NODE_MATCHED(node);
1143                                 if (onode)
1144                                         SET_NODE_MATCHED(onode);
1145                                 node->cfgrom_quad_to_read =
1146                                     IEEE1394_BIB_QUAD_SZ;
1147                                 done++;
1148                         } else {
1149 
1150                                 TNF_PROBE_4(s1394_br_thread_handle_cmd_phase1,
1151                                     S1394_TNF_SL_HOTPLUG_STACK, "", tnf_string,
1152                                     msg, "config rom generation changed",
1153                                     tnf_int, node_num, node_num,
1154                                     tnf_int, cur_gen, cur_gen, tnf_int, old_gen,
1155                                     CONFIG_ROM_GEN(node->cfgrom));
1156 
1157                                 SET_CFGROM_GEN_CHANGED(node);
1158                                 if (onode != NULL)
1159                                         SET_CFGROM_GEN_CHANGED(onode);
1160                                 /*
1161                                  * Reset BIB_READ flag and start reading entire
1162                                  * config rom.
1163                                  */
1164                                 CLEAR_CFGROM_BIB_READ(node);
1165                                 reread = 1;
1166 
1167                                 /*
1168                                  * if generations changed, allocate cfgrom for
1169                                  * the new generation. s1394_match_GUID() will
1170                                  * free up the cfgrom from the old generation.
1171                                  */
1172                                 if (s1394_alloc_cfgrom(hal, node, &status) !=
1173                                     DDI_SUCCESS) {
1174                                         ASSERT((status & S1394_LOCK_FAILED) !=
1175                                             0);
1176                                         ASSERT(MUTEX_NOT_HELD(&hal->
1177                                             topology_tree_mutex));
1178                                         locked = 0;
1179                                         /* we failed to relock the tree */
1180                                         goto bail;
1181                                 }
1182                         }
1183                 }
1184 
1185                 /*
1186                  * we end up here if we don't have bus_info_blk for this
1187                  * node or if config rom generation changed.
1188                  */
1189 
1190                 /*
1191                  * Pass1 Rio bug workaround. Due to this bug, if we read
1192                  * past quadlet 5 of the config rom, the PCI bus gets wedged.
1193                  * Avoid the hang by not reading past quadlet 5.
1194                  * We identify a remote Rio by the node vendor id part of
1195                  * quad 3 (which is == SUNW == S1394_SUNW_OUI (0x80020)).
1196                  */
1197                 if (s1394_enable_rio_pass1_workarounds != 0) {
1198                         if ((quadlet == 3) && ((data >> 8) == S1394_SUNW_OUI)) {
1199                                 node->cfgrom_size = IEEE1394_BIB_QUAD_SZ;
1200                                 node->cfgrom_valid_size = IEEE1394_BIB_QUAD_SZ;
1201                         }
1202                 }
1203 
1204                 if (!done) {
1205 
1206                         if (reread)
1207                                 quadlet = 0;
1208                         else
1209                                 node->cfgrom[quadlet++] = data;
1210 
1211                         /* if we don't have the entire bus_info_blk... */
1212                         if (quadlet < IEEE1394_BIB_QUAD_SZ) {
1213 
1214                                 CFGROM_GET_READ_DELAY(node, readdelay);
1215                                 SETUP_QUAD_READ(node, 1, quadlet, 1);
1216                                 s1394_unlock_tree(hal);
1217                                 CFGROM_READ_PAUSE(readdelay);
1218                                 /* get next quadlet */
1219                                 if (s1394_lock_tree(hal) != DDI_SUCCESS) {
1220                                         TNF_PROBE_3(
1221                                             s1394_br_thread_handle_cmd_phase1,
1222                                             S1394_TNF_SL_HOTPLUG_STACK, "",
1223                                             tnf_string, msg,
1224                                             "unable to relock tree", tnf_uint,
1225                                             node_num, node_num, tnf_int,
1226                                             quad_to_read, quadlet);
1227                                         locked = 0;
1228                                 } else if (s1394_read_config_quadlet(hal, cmd,
1229                                     &status) != DDI_SUCCESS) {
1230                                         /*
1231                                          * Failed to get going. If command was
1232                                          * successfully handed over to the HAL,
1233                                          * don't free it (it will get freed
1234                                          * later in the callback).
1235                                          */
1236                                         TNF_PROBE_3(
1237                                             s1394_br_thread_handle_cmd_phase1,
1238                                             S1394_TNF_SL_HOTPLUG_STACK, "",
1239                                             tnf_string, msg,
1240                                             "unable to read", tnf_uint,
1241                                             node_num, node_num, tnf_int,
1242                                             quad_to_read, quadlet);
1243                                         if ((status & S1394_CMD_INFLIGHT) !=
1244                                             0) {
1245                                                 freecmd = 0;
1246                                         }
1247                                         if ((status & S1394_LOCK_FAILED) != 0) {
1248                                                 locked = 0;
1249                                         } else {
1250                                                 if (CFGROM_NEW_ALLOC(node) ==
1251                                                     B_TRUE) {
1252                                                         s1394_free_cfgrom(hal,
1253                                                             node,
1254                                                         S1394_FREE_CFGROM_NEW);
1255                                                 } else {
1256                                                         CLEAR_CFGROM_STATE(
1257                                                             node);
1258                                                 }
1259                                         }
1260                                         done++;
1261                                 } else {
1262                                         freecmd = 0;
1263                                 }
1264                         } else {
1265                                 /* got all of bus_info_blk */
1266                                 SET_CFGROM_BIB_READ(node);
1267                                 if (node->cfgrom_size == IEEE1394_BIB_QUAD_SZ)
1268                                     SET_CFGROM_ALL_READ(node);
1269                                 node->cfgrom_quad_to_read = quadlet;
1270                                 done++;
1271                                 TNF_PROBE_3_DEBUG(
1272                                     s1394_br_thread_handle_cmd_phase1,
1273                                     S1394_TNF_SL_HOTPLUG_STACK,
1274                                     "", tnf_string, msg, "read bus info blk",
1275                                     tnf_int, node_num, node->node_num,
1276                                     tnf_opaque, cfgrom, node->cfgrom);
1277                         }
1278                 }
1279         } else {
1280                 done = 1;
1281                 node->cfgrom_read_fails++;
1282                 BUMP_CFGROM_READ_DELAY(node);
1283 
1284                 /* retry if not too many failures */
1285                 if (node->cfgrom_read_fails < s1394_cfgrom_read_retry_cnt) {
1286                         CFGROM_GET_READ_DELAY(node, readdelay);
1287                         SETUP_QUAD_READ(node, 0, quadlet, 1);
1288                         s1394_unlock_tree(hal);
1289                         CFGROM_READ_PAUSE(readdelay);
1290                         if (s1394_lock_tree(hal) != DDI_SUCCESS) {
1291                                 TNF_PROBE_3(
1292                                     s1394_br_thread_handle_cmd_phase1,
1293                                     S1394_TNF_SL_HOTPLUG_ERROR, "",
1294                                     tnf_string, msg,
1295                                     "unable to relock tree", tnf_uint,
1296                                     node_num, node_num, tnf_int,
1297                                     quad_to_read, quadlet);
1298                                 locked = 0;
1299                         } else if (s1394_read_config_quadlet(hal, cmd,
1300                             &status) != DDI_SUCCESS) {
1301                                 /*
1302                                  * Failed to get going. If command was
1303                                  * successfully handed over to the HAL,
1304                                  * don't free it (it will get freed
1305                                  * later in the callback).
1306                                  */
1307                                 TNF_PROBE_3(
1308                                     s1394_br_thread_handle_cmd_phase1,
1309                                     S1394_TNF_SL_HOTPLUG_ERROR, "", tnf_string,
1310                                     msg, "unable to re-read", tnf_uint,
1311                                     node_num, node_num, tnf_int, quad_to_read,
1312                                     quadlet);
1313                                 if ((status & S1394_CMD_INFLIGHT) != 0) {
1314                                         freecmd = 0;
1315                                 }
1316                                 if ((status & S1394_LOCK_FAILED) != 0) {
1317                                         locked = 0;
1318                                 } else {
1319                                         if (CFGROM_NEW_ALLOC(node) == B_TRUE) {
1320                                                 s1394_free_cfgrom(hal, node,
1321                                                     S1394_FREE_CFGROM_NEW);
1322                                         } else {
1323                                                 CLEAR_CFGROM_STATE(node);
1324                                         }
1325                                 }
1326                         } else {
1327                                 done = 0;
1328                                 freecmd = 0;
1329                         }
1330                 } else {
1331                         TNF_PROBE_4(s1394_br_thread_handle_cmd_phase1,
1332                             S1394_TNF_SL_HOTPLUG_STACK, "", tnf_string, msg,
1333                             "retries exceeded", tnf_int, node_num, node_num,
1334                             tnf_int, quadlet, quadlet, tnf_opaque, cfgrom,
1335                             node->cfgrom);
1336                         if (CFGROM_NEW_ALLOC(node) == B_TRUE) {
1337                                 s1394_free_cfgrom(hal, node,
1338                                     S1394_FREE_CFGROM_NEW);
1339                         } else {
1340                                 CLEAR_CFGROM_STATE(node);
1341                         }
1342                 }
1343         }
1344 bail:
1345         if (freecmd) {
1346                 (void) s1394_free_cmd(hal, &cmd);
1347         }
1348 
1349         if (done) {
1350                 cmdret = S1394_HCMD_NODE_DONE;
1351                 TNF_PROBE_2_DEBUG(s1394_br_thread_handle_cmd_phase1,
1352                     S1394_TNF_SL_HOTPLUG_STACK, "", tnf_string, msg,
1353                     "done with node", tnf_int, node_num, node_num);
1354         }
1355 
1356         /* if we are bailing out because locking failed, locked == 0 */
1357         if (locked == 0)
1358                 cmdret = S1394_HCMD_LOCK_FAILED;
1359         else
1360                 s1394_unlock_tree(hal);
1361 
1362         TNF_PROBE_0_DEBUG(s1394_br_thread_handle_cmd_phase1_exit,
1363             S1394_TNF_SL_HOTPLUG_STACK, "");
1364 
1365         return (cmdret);
1366 }
1367 
1368 /*
1369  * s1394_cfgrom_scan_phase2()
1370  *    Handles phase 2 of bus reset processing. Matches GUIDs between old
1371  *    and new topology trees to identify which node moved where. Processes
1372  *    the old topology tree (involves offlining any nodes that got unplugged
1373  *    between the last generation and the current generation). Updates speed
1374  *    map, sets up physical AR request filer and does isoch resource
1375  *    realloc failure notification and bus reset notifications. Then resends
1376  *    any commands that were issued by targets while the reset was being
1377  *    processed. Finally, the current topology tree is processed. This involves
1378  *    reading config rom past the bus info block for new nodes and parsing
1379  *    the config rom, creating a devinfo for each unit directory found in the
1380  *    config rom.
1381  *    Returns DDI_FAILURE if there was bus reset during any of the function
1382  *    calls (as indicated by lock failures) or if any of the routines callees
1383  *    return failure, else returns DDI_SUCCESS.
1384  */
1385 static int
1386 s1394_cfgrom_scan_phase2(s1394_hal_t *hal)
1387 {
1388         int ret;
1389         uint_t wait_gen;
1390         int wait_for_cbs = 0;
1391         t1394_localinfo_t localinfo;
1392 
1393         ASSERT(MUTEX_NOT_HELD(&hal->topology_tree_mutex));
1394 
1395         TNF_PROBE_0_DEBUG(s1394_cfgrom_scan_phase2_enter,
1396             S1394_TNF_SL_HOTPLUG_STACK, "");
1397 
1398         if (s1394_lock_tree(hal) != DDI_SUCCESS) {
1399                 TNF_PROBE_0_DEBUG(s1394_cfgrom_scan_phase2_exit,
1400                     S1394_TNF_SL_HOTPLUG_STACK, "");
1401                 return (DDI_FAILURE);
1402         }
1403 
1404         if (s1394_match_all_GUIDs(hal) == DDI_SUCCESS) {
1405                 s1394_unlock_tree(hal);
1406         }
1407 
1408         if (s1394_process_old_tree(hal) != DDI_SUCCESS) {
1409                 ASSERT(MUTEX_NOT_HELD(&hal->topology_tree_mutex));
1410                 TNF_PROBE_1(s1394_cfgrom_scan_phase2,
1411                     S1394_TNF_SL_HOTPLUG_ERROR, "", tnf_string, msg,
1412                     "non-success return from process_old_tree");
1413                 TNF_PROBE_0_DEBUG(s1394_cfgrom_scan_phase2_exit,
1414                     S1394_TNF_SL_HOTPLUG_STACK, "");
1415                 return (DDI_FAILURE);
1416         }
1417 
1418         if (s1394_lock_tree(hal) != DDI_SUCCESS) {
1419                 TNF_PROBE_1(s1394_cfgrom_scan_phase2,
1420                     S1394_TNF_SL_HOTPLUG_ERROR, "", tnf_string, msg,
1421                     "unable to relock the tree");
1422                 TNF_PROBE_0_DEBUG(s1394_cfgrom_scan_phase2_exit,
1423                     S1394_TNF_SL_HOTPLUG_STACK, "");
1424                 return (DDI_FAILURE);
1425         }
1426 
1427         s1394_update_speed_map_link_speeds(hal);
1428         s1394_unlock_tree(hal);
1429 
1430         /* Setup physical AR request filters */
1431         s1394_physical_arreq_setup_all(hal);
1432 
1433         /* Notify targets of isoch resource realloc failures */
1434         s1394_isoch_rsrc_realloc_notify(hal);
1435 
1436         /* Notify targets of the end of bus reset processing */
1437         if (s1394_lock_tree(hal) != DDI_SUCCESS) {
1438                 TNF_PROBE_1(s1394_cfgrom_scan_phase2,
1439                     S1394_TNF_SL_HOTPLUG_ERROR, "", tnf_string, msg,
1440                     "unable to relock the tree after isoch notify");
1441                 TNF_PROBE_0_DEBUG(s1394_cfgrom_scan_phase2_exit,
1442                     S1394_TNF_SL_HOTPLUG_STACK, "");
1443                 return (DDI_FAILURE);
1444         }
1445 
1446         localinfo.bus_generation = hal->generation_count;
1447         localinfo.local_nodeID = hal->node_id;
1448 
1449         s1394_unlock_tree(hal);
1450         s1394_target_bus_reset_notifies(hal, &localinfo);
1451         if (s1394_lock_tree(hal) != DDI_SUCCESS) {
1452                 TNF_PROBE_1(s1394_cfgrom_scan_phase2,
1453                     S1394_TNF_SL_HOTPLUG_ERROR, "", tnf_string, msg,
1454                     "unable to relock the tree after reset notify");
1455                 TNF_PROBE_0_DEBUG(s1394_cfgrom_scan_phase2_exit,
1456                     S1394_TNF_SL_HOTPLUG_STACK, "");
1457                 return (DDI_FAILURE);
1458         }
1459 
1460         /* Set HAL state to normal */
1461         if (hal->disable_requests_bit == 0)
1462                 hal->hal_state = S1394_HAL_NORMAL;
1463         else
1464                 hal->hal_state = S1394_HAL_DREQ;
1465 
1466         s1394_unlock_tree(hal);
1467 
1468         /* Flush the pending Q */
1469         s1394_resend_pending_cmds(hal);
1470 
1471         if (s1394_process_topology_tree(hal, &wait_for_cbs, &wait_gen)) {
1472                 TNF_PROBE_1(s1394_cfgrom_scan_phase2,
1473                     S1394_TNF_SL_HOTPLUG_ERROR, "", tnf_string, msg,
1474                     "non-success return from process_topology_tree");
1475                 TNF_PROBE_0_DEBUG(s1394_cfgrom_scan_phase2_exit,
1476                     S1394_TNF_SL_HOTPLUG_STACK, "");
1477                 ASSERT(MUTEX_NOT_HELD(&hal->topology_tree_mutex));
1478                 return (DDI_FAILURE);
1479         }
1480 
1481         if (s1394_lock_tree(hal) != DDI_SUCCESS) {
1482                 TNF_PROBE_1(s1394_cfgrom_scan_phase2,
1483                     S1394_TNF_SL_HOTPLUG_ERROR, "", tnf_string, msg,
1484                     "unable to relock after processing topology tree");
1485                 TNF_PROBE_0_DEBUG(s1394_cfgrom_scan_phase2_exit,
1486                     S1394_TNF_SL_HOTPLUG_STACK, "");
1487                 return (DDI_FAILURE);
1488         }
1489 
1490         s1394_print_node_info(hal);
1491 
1492         s1394_unlock_tree(hal);
1493 
1494         ASSERT(MUTEX_NOT_HELD(&hal->topology_tree_mutex));
1495 
1496         ret = DDI_SUCCESS;
1497 
1498         /*
1499          * If we started any reads, wait for completion callbacks
1500          */
1501         if (wait_for_cbs != 0) {
1502                 ret = s1394_wait_for_cfgrom_callbacks(hal, wait_gen,
1503                     s1394_br_thread_handle_cmd_phase2);
1504 
1505                 TNF_PROBE_2_DEBUG(s1394_cfgrom_scan_phase2,
1506                     S1394_TNF_SL_HOTPLUG_STACK, "", tnf_string, msg,
1507                     "returned from waiting for cfgrom callbacks", tnf_int, ret,
1508                     ret);
1509         }
1510 
1511         ASSERT(MUTEX_NOT_HELD(&hal->topology_tree_mutex));
1512 
1513         TNF_PROBE_0_DEBUG(s1394_cfgrom_scan_phase2_exit,
1514             S1394_TNF_SL_HOTPLUG_STACK, "");
1515 
1516         return (ret);
1517 }
1518 
1519 /*
1520  * s1394_br_thread_handle_cmd_phase2()
1521  *    Process the cmd completion for phase 2 config rom reads. If all the
1522  *    needed quads are read, validates the config rom; if config rom is
1523  *    invalid (crc failures), frees the config rom, else marks the config rom
1524  *    valid and calls s1394_update_devinfo_tree() to parse the config rom.
1525  *    If need to get more quadlets, attempts to kick off the read and returns
1526  *    S1394_HCMD_NODE_EXPECT_MORE if successfully started the read. If a bus
1527  *    reset is seen while in this routine, returns S1394_HCMD_LOCK_FAILED. If
1528  *    done with the node (with or withoug crc errors), returns
1529  *    S1394_HCMD_NODE_DONE, else returns S1394_HCMD_NODE_EXPECT_MORE (to
1530  *    indicate not done with the node yet).
1531  */
1532 static hcmd_ret_t
1533 s1394_br_thread_handle_cmd_phase2(s1394_hal_t *hal, cmd1394_cmd_t *cmd)
1534 {
1535         s1394_node_t *node;
1536         uint32_t node_num, quadlet, data;
1537         int update_devinfo, locked, freecmd, done;
1538         hcmd_ret_t cmdret;
1539         uchar_t readdelay;
1540         s1394_status_t status;
1541 
1542         TNF_PROBE_0_DEBUG(s1394_br_thread_handle_cmd_phase2_enter,
1543             S1394_TNF_SL_HOTPLUG_STACK, "");
1544 
1545         /*
1546          * we end up here if this is a brand new node or if it is a known node
1547          * but the config ROM changed (and triggered a re-read).
1548          */
1549         s1394_get_quad_info(cmd, &node_num, &quadlet, &data);
1550         ASSERT(quadlet == IEEE1394_BIB_QUAD_SZ || quadlet <
1551             IEEE1394_CONFIG_ROM_QUAD_SZ);
1552 
1553         locked = freecmd = done = 1;
1554         cmdret = S1394_HCMD_NODE_EXPECT_MORE;
1555 
1556         update_devinfo = 0;
1557 
1558         if (s1394_lock_tree(hal) != DDI_SUCCESS) {
1559                 TNF_PROBE_3(s1394_br_thread_handle_cmd_phase2,
1560                     S1394_TNF_SL_HOTPLUG_ERROR, "", tnf_string, msg,
1561                     "unable to lock tree", tnf_int, node_num, node_num,
1562                     tnf_int, quadlet, quadlet);
1563                 locked = 0;
1564                 goto bail;
1565         }
1566 
1567         node = &hal->topology_tree[node_num];
1568 
1569         if (cmd->cmd_result == CMD1394_CMDSUCCESS) {
1570 
1571                 ASSERT(CFGROM_BIB_READ(node) == B_TRUE);
1572 
1573                 node->cfgrom[quadlet] = data;
1574 
1575                 if (s1394_calc_next_quad(hal, node, quadlet, &quadlet) != 0) {
1576                         /*
1577                          * Done with this node. Mark config rom valid and
1578                          * update the devinfo tree for this node.
1579                          */
1580                         TNF_PROBE_4_DEBUG(s1394_br_thread_handle_cmd_phase2,
1581                             S1394_TNF_SL_HOTPLUG_STACK, "", tnf_string, msg,
1582                             "all read", tnf_int, node_num, node->node_num,
1583                             tnf_opaque, cfgrom, node->cfgrom, tnf_int, quadlet,
1584                             quadlet);
1585 
1586                         node->cfgrom_valid_size = quadlet + 1;
1587                         if (s1394_valid_cfgrom(hal, node) == B_TRUE) {
1588                                 SET_CFGROM_ALL_READ(node);
1589                                 update_devinfo++;
1590                         } else {
1591                                 s1394_free_cfgrom(hal, node,
1592                                     S1394_FREE_CFGROM_BOTH);
1593                         }
1594                 } else {
1595                         CFGROM_GET_READ_DELAY(node, readdelay);
1596                         SETUP_QUAD_READ(node, 1, quadlet, 1);
1597                         s1394_unlock_tree(hal);
1598                         CFGROM_READ_PAUSE(readdelay);
1599                         if (s1394_lock_tree(hal) != DDI_SUCCESS) {
1600                                 locked = 0;
1601                                 TNF_PROBE_3(s1394_br_thread_handle_cmd_phase2,
1602                                     S1394_TNF_SL_HOTPLUG_ERROR, "", tnf_string,
1603                                     msg, "unable to relock the tree",
1604                                     tnf_int, node_num, node->node_num,
1605                                     tnf_int, quadlet, quadlet);
1606                         } else if (s1394_read_config_quadlet(hal, cmd,
1607                             &status) != DDI_SUCCESS) {
1608                                 /* give up on this guy */
1609                                 TNF_PROBE_3(s1394_br_thread_handle_cmd_phase2,
1610                                     S1394_TNF_SL_HOTPLUG_ERROR, "", tnf_string,
1611                                     msg, "cannot start quadlet read", tnf_int,
1612                                     node_num, node_num, tnf_int, quadlet,
1613                                     quadlet);
1614 
1615                                 if ((status & S1394_CMD_INFLIGHT) != 0) {
1616                                         freecmd = 0;
1617                                 }
1618                                 if ((status & S1394_LOCK_FAILED) != 0) {
1619                                         locked = 0;
1620                                 } else {
1621                                         node->cfgrom_valid_size = quadlet;
1622                                         if (s1394_valid_cfgrom(hal, node) ==
1623                                             B_TRUE) {
1624                                                 SET_CFGROM_ALL_READ(node);
1625                                                 update_devinfo++;
1626                                         } else {
1627                                                 s1394_free_cfgrom(hal, node,
1628                                                     S1394_FREE_CFGROM_BOTH);
1629                                         }
1630                                 }
1631                         } else {
1632                                 /* successfully started next read */
1633                                 done = 0;
1634                                 freecmd = 0;
1635                         }
1636                 }
1637         } else {
1638                 node->cfgrom_read_fails++;
1639                 BUMP_CFGROM_READ_DELAY(node);
1640 
1641                 /* retry if not too many failures */
1642                 if (node->cfgrom_read_fails < s1394_cfgrom_read_retry_cnt) {
1643                         CFGROM_GET_READ_DELAY(node, readdelay);
1644                         s1394_unlock_tree(hal);
1645                         SETUP_QUAD_READ(node, 0, quadlet, 1);
1646                         CFGROM_READ_PAUSE(readdelay);
1647                         if (s1394_lock_tree(hal) != DDI_SUCCESS) {
1648                                 locked = 0;
1649                                 TNF_PROBE_3(s1394_br_thread_handle_cmd_phase2,
1650                                     S1394_TNF_SL_HOTPLUG_ERROR, "", tnf_string,
1651                                     msg, "unable to relock for reread",
1652                                     tnf_int, node_num, node->node_num,
1653                                     tnf_int, quadlet, quadlet);
1654                         } else if (s1394_read_config_quadlet(hal, cmd,
1655                             &status) != DDI_SUCCESS) {
1656                                 if ((status & S1394_CMD_INFLIGHT) != 0) {
1657                                         freecmd = 0;
1658                                 }
1659                                 if ((status & S1394_LOCK_FAILED) != 0) {
1660                                         locked = 0;
1661                                 } else {
1662                                         /* stop further reads */
1663                                         TNF_PROBE_4(
1664                                             s1394_br_thread_handle_cmd_phase2,
1665                                             S1394_TNF_SL_HOTPLUG_ERROR, "",
1666                                             tnf_string, msg, "unable to retry",
1667                                             tnf_int, node_num, node->node_num,
1668                                             tnf_int, quadlet, quadlet,
1669                                             tnf_opaque, cfgrom, node->cfgrom);
1670                                         node->cfgrom_valid_size = quadlet + 1;
1671                                         if (s1394_valid_cfgrom(hal, node) ==
1672                                             B_TRUE) {
1673                                                 SET_CFGROM_ALL_READ(node);
1674                                                 update_devinfo++;
1675                                         } else {
1676                                                 s1394_free_cfgrom(hal, node,
1677                                                     S1394_FREE_CFGROM_BOTH);
1678                                         }
1679                                 }
1680                         } else {
1681                                 /* successfully started next read */
1682                                 done = 0;
1683                                 freecmd = 0;
1684                         }
1685                 } else {
1686 
1687                         TNF_PROBE_4(s1394_br_thread_handle_cmd_phase2,
1688                             S1394_TNF_SL_HOTPLUG_ERROR, "", tnf_string, msg,
1689                             "retries exceeded", tnf_int, node_num, node_num,
1690                             tnf_int, quadlet, quadlet, tnf_opaque, cfgrom,
1691                             node->cfgrom);
1692 
1693                         node->cfgrom_valid_size = quadlet + 1;
1694                         if (s1394_valid_cfgrom(hal, node) == B_TRUE) {
1695                                 SET_CFGROM_ALL_READ(node);
1696                                 update_devinfo++;
1697                         } else {
1698                                 s1394_free_cfgrom(hal, node,
1699                                     S1394_FREE_CFGROM_BOTH);
1700                         }
1701                 }
1702         }
1703 bail:
1704         if (freecmd) {
1705                 (void) s1394_free_cmd(hal, &cmd);
1706         }
1707 
1708         if (done) {
1709                 cmdret = S1394_HCMD_NODE_DONE;
1710                 TNF_PROBE_2_DEBUG(s1394_br_thread_handle_cmd_phase2,
1711                     S1394_TNF_SL_HOTPLUG_STACK, "", tnf_string, msg,
1712                     "done with a node", tnf_int, node_num, node_num);
1713         }
1714 
1715         if (update_devinfo) {
1716                 ASSERT(locked);
1717                 /*
1718                  * s1394_update_devinfo_tree() drops and reacquires the
1719                  * topology_tree_mutex. If tree lock fails, it returns
1720                  * a DDI_FAILURE. Set locked to 0 so in this case so that
1721                  * we will return S1394_HCMD_LOCK_FAILED below
1722                  */
1723                 if (s1394_update_devinfo_tree(hal, node) != DDI_SUCCESS) {
1724                         ASSERT(MUTEX_NOT_HELD(&hal->topology_tree_mutex));
1725                         locked = 0;
1726                         TNF_PROBE_2(s1394_br_thread_handle_cmd_phase2,
1727                             S1394_TNF_SL_HOTPLUG_ERROR, "", tnf_string, msg,
1728                             "update devinfo returned failure", tnf_int,
1729                             node_num, node_num);
1730                 }
1731         }
1732 
1733         /* if we are bailing out because locking failed, locked == 0 */
1734         if (locked == 0)
1735                 cmdret = S1394_HCMD_LOCK_FAILED;
1736         else
1737                 s1394_unlock_tree(hal);
1738 
1739         TNF_PROBE_1_DEBUG(s1394_br_thread_handle_cmd_phase2_exit,
1740             S1394_TNF_SL_HOTPLUG_STACK, "", tnf_int, cmdret, (int)cmdret);
1741 
1742         return (cmdret);
1743 }
1744 
1745 /*
1746  * s1394_read_config_quadlet()
1747  *    Starts the reads of a config quadlet (deduced cmd_addr).  Returns
1748  *    DDI_SUCCESS if the read was started with no errors, else DDI_FAILURE
1749  *    is returned, with status indicating the reason for the failure(s).
1750  */
1751 static int
1752 s1394_read_config_quadlet(s1394_hal_t *hal, cmd1394_cmd_t *cmd,
1753     s1394_status_t *status)
1754 {
1755         s1394_node_t *node;
1756         int ret, err, node_num, quadlet;
1757 
1758         ASSERT(MUTEX_HELD(&hal->topology_tree_mutex));
1759         node_num = IEEE1394_ADDR_PHY_ID(cmd->cmd_addr);
1760         node = &hal->topology_tree[node_num];
1761         quadlet = node->cfgrom_quad_to_read;
1762 
1763         TNF_PROBE_2_DEBUG(s1394_read_config_quadlet_enter,
1764             S1394_TNF_SL_HOTPLUG_STACK, "", tnf_uint, node_num, node_num,
1765             tnf_uint, quadlet, quadlet);
1766 
1767         /* Calculate the 64-bit address */
1768         QUAD_TO_CFGROM_ADDR(IEEE1394_LOCAL_BUS, node_num, quadlet,
1769             cmd->cmd_addr);
1770 
1771         *status = S1394_NOSTATUS;
1772 
1773         ret = s1394_setup_asynch_command(hal, NULL, cmd, S1394_CMD_READ, &err);
1774 
1775         if (ret != DDI_SUCCESS) {
1776                 *status |= S1394_UNKNOWN;
1777                 ASSERT(MUTEX_HELD(&hal->topology_tree_mutex));
1778                 TNF_PROBE_3(s1394_read_config_quadlet,
1779                     S1394_TNF_SL_HOTPLUG_ERROR, "", tnf_string, msg,
1780                     "failure from setup asynch command", tnf_uint, node_num,
1781                     node_num, tnf_uint, quadlet, quadlet);
1782                 TNF_PROBE_0_DEBUG(s1394_read_config_quadlet_exit,
1783                     S1394_TNF_SL_HOTPLUG_STACK, "");
1784                 return (DDI_FAILURE);
1785         }
1786 
1787         s1394_unlock_tree(hal);
1788         ret = DDI_SUCCESS;
1789         /* Send the command out */
1790         if (s1394_xfer_asynch_command(hal, cmd, &err) == DDI_SUCCESS) {
1791                 /* Callers can expect a callback now */
1792                 *status |= S1394_CMD_INFLIGHT;
1793         } else {
1794 
1795                 s1394_cmd_priv_t *s_priv;
1796 
1797                 TNF_PROBE_3(s1394_read_config_quadlet,
1798                     S1394_TNF_SL_HOTPLUG_ERROR, "", tnf_string, msg,
1799                     "failure from xfer asynch command",
1800                     tnf_int, quadlet, quadlet, tnf_int, node_num, node_num);
1801 
1802                 /* Remove from queue */
1803                 s1394_remove_q_asynch_cmd(hal, cmd);
1804                 s_priv = S1394_GET_CMD_PRIV(cmd);
1805 
1806                 s_priv->cmd_in_use = B_FALSE;
1807 
1808                 *status |= S1394_XFER_FAILED;
1809                 ret = DDI_FAILURE;
1810         }
1811 
1812         if (s1394_lock_tree(hal) != DDI_SUCCESS) {
1813                 *status |= S1394_LOCK_FAILED;
1814                 ret = DDI_FAILURE;
1815                 TNF_PROBE_1(s1394_read_config_quadlet,
1816                     S1394_TNF_SL_HOTPLUG_ERROR, "", tnf_string, msg,
1817                     "unable to relock the tree");
1818         }
1819 
1820         TNF_PROBE_0_DEBUG(s1394_read_config_quadlet_exit,
1821             S1394_TNF_SL_HOTPLUG_STACK, "");
1822 
1823         return (ret);
1824 }
1825 
1826 /*
1827  * s1394_cfgrom_read_callback()
1828  *    callback routine for config rom reads. Frees the command if it failed
1829  *    due to bus reset else appends the command to the completion queue
1830  *    and signals the completion queue cv.
1831  */
1832 static void
1833 s1394_cfgrom_read_callback(cmd1394_cmd_t *cmd)
1834 {
1835         cmd1394_cmd_t *tcmd;
1836         s1394_cmd_priv_t *s_priv;
1837         s1394_hal_t *hal;
1838 
1839 #if defined(DEBUG)
1840         uint32_t node_num, quadlet, data;
1841 #endif
1842 
1843         TNF_PROBE_0_DEBUG(s1394_cfgrom_read_callback_enter,
1844             S1394_TNF_SL_HOTPLUG_STACK, "");
1845 
1846         /* Get the Services Layer private area */
1847         s_priv = S1394_GET_CMD_PRIV(cmd);
1848 
1849         hal = (s1394_hal_t *)s_priv->sent_on_hal;
1850 
1851 #if defined(DEBUG)
1852 
1853         s1394_get_quad_info(cmd, &node_num, &quadlet, &data);
1854 
1855         TNF_PROBE_5_DEBUG(s1394_cfgrom_read_callback,
1856             S1394_TNF_SL_HOTPLUG_STACK, "", tnf_uint, gen, cmd->bus_generation,
1857             tnf_int, quadlet, quadlet,
1858             tnf_int, node_num, node_num,
1859             tnf_int, data, data, tnf_int, result, cmd->cmd_result);
1860 #endif
1861 
1862         if (cmd->cmd_result == CMD1394_EBUSRESET) {
1863                 (void) s1394_free_cmd(hal, (cmd1394_cmd_t **)&cmd);
1864         } else {
1865                 mutex_enter(&hal->br_cmplq_mutex);
1866 
1867                 /* Put the command on completion queue */
1868                 s_priv->cmd_priv_next = NULL;
1869                 if ((tcmd = hal->br_cmplq_tail) != NULL) {
1870                         s_priv = S1394_GET_CMD_PRIV(tcmd);
1871 
1872                         s_priv->cmd_priv_next = cmd;
1873                 }
1874 
1875                 hal->br_cmplq_tail = cmd;
1876 
1877                 if (hal->br_cmplq_head == NULL)
1878                         hal->br_cmplq_head = cmd;
1879 
1880                 cv_signal(&hal->br_cmplq_cv);
1881                 mutex_exit(&hal->br_cmplq_mutex);
1882         }
1883 
1884         TNF_PROBE_0_DEBUG(s1394_cfgrom_read_callback_exit,
1885             S1394_TNF_SL_HOTPLUG_STACK, "");
1886 }
1887 
1888 /*
1889  * s1394_cfgrom_parse_unit_dir()
1890  *    Parses the unit directory passed in and returns reg[2...5] of reg
1891  *    property (see 1275 binding for reg property defintion). Currently,
1892  *    returns 0 for all the values since none of the existing devices implement
1893  *    this and future devices, per P1212r, need a binding change.
1894  */
1895 /* ARGSUSED */
1896 void
1897 s1394_cfgrom_parse_unit_dir(uint32_t *unit_dir, uint32_t *addr_hi,
1898     uint32_t *addr_lo, uint32_t *size_hi, uint32_t *size_lo)
1899 {
1900         TNF_PROBE_0_DEBUG(s1394_cfgrom_parse_unit_dir_enter,
1901             S1394_TNF_SL_HOTPLUG_STACK, "");
1902         *addr_hi = *addr_lo = *size_hi = *size_lo = 0;
1903         TNF_PROBE_0_DEBUG(s1394_cfgrom_parse_unit_dir_exit,
1904             S1394_TNF_SL_HOTPLUG_STACK, "");
1905 }
1906 
1907 /*
1908  * s1394_get_quad_info()
1909  *    Helper routine that picks apart the various fields of a 1394 address
1910  */
1911 static void
1912 s1394_get_quad_info(cmd1394_cmd_t *cmd, uint32_t *node_num, uint32_t *quadlet,
1913     uint32_t *data)
1914 {
1915         uint64_t addr;
1916 
1917         TNF_PROBE_0_DEBUG(s1394_get_quad_info_enter,
1918             S1394_TNF_SL_HOTPLUG_STACK, "");
1919 
1920         addr = cmd->cmd_addr;
1921         *node_num = IEEE1394_ADDR_PHY_ID(addr);
1922         *quadlet = ((addr & IEEE1394_ADDR_OFFSET_MASK) -
1923             IEEE1394_CONFIG_ROM_ADDR);
1924         *quadlet = (*quadlet >> 2);
1925         *data = T1394_DATA32(cmd->cmd_u.q.quadlet_data);
1926 
1927         TNF_PROBE_0_DEBUG(s1394_get_quad_info_exit,
1928             S1394_TNF_SL_HOTPLUG_STACK, "");
1929 }
1930 
1931 /*
1932  * s1394_match_GUID()
1933  *    attempts to match nnode (which is in the current topology tree) with
1934  *    a node in the old topology tree by comparing GUIDs. If a match is found
1935  *    the old_node field of the current node and cur_node field of the old
1936  *    are set point to each other. Also, this routine makes both the nodes
1937  *    point at the same config rom.  If unable to relock the tree, returns
1938  *    DDI_FAILURE, else returns DDI_SUCCESS.
1939  */
1940 static int
1941 s1394_match_GUID(s1394_hal_t *hal, s1394_node_t *nnode)
1942 {
1943         int old_node;
1944         int gen_changed;
1945         uint32_t old_a, old_b;
1946         uint32_t new_a, new_b;
1947         s1394_node_t *onode;
1948         s1394_target_t *t;
1949         int     ret = DDI_SUCCESS;
1950 
1951         TNF_PROBE_0_DEBUG(s1394_match_GUID_enter, S1394_TNF_SL_HOTPLUG_STACK,
1952             "");
1953 
1954         ASSERT(nnode->cfgrom != NULL);
1955         ASSERT(CFGROM_BIB_READ(nnode));
1956 
1957         new_a = nnode->node_guid_hi;
1958         new_b = nnode->node_guid_lo;
1959 
1960         for (old_node = 0; old_node < hal->old_number_of_nodes; old_node++) {
1961 
1962                 onode = &hal->old_tree[old_node];
1963                 if (onode->cfgrom == NULL || CFGROM_BIB_READ(onode) == B_FALSE)
1964                         continue;
1965 
1966                 old_a = onode->node_guid_hi;
1967                 old_b = onode->node_guid_lo;
1968 
1969                 if ((old_a == new_a) && (old_b == new_b)) {
1970 
1971                         if (NODE_MATCHED(onode) == B_TRUE) {
1972                                 TNF_PROBE_4(s1394_match_GUID_duplicate,
1973                                     S1394_TNF_SL_HOTPLUG_ERROR, "",
1974                                     tnf_uint, guid_hi, old_a,
1975                                     tnf_uint, guid_lo, old_b,
1976                                     tnf_uint, old_node_num, old_node,
1977                                     tnf_uint, node_num, nnode->node_num);
1978                                 cmn_err(CE_NOTE, "!Duplicate GUIDs: %08x%08x",
1979                                     old_a, old_b);
1980                                 /* offline the new node that last matched */
1981                                 ret = s1394_offline_node(hal, onode->cur_node);
1982                                 /* and make the current new node invalid */
1983                                 ASSERT(CFGROM_NEW_ALLOC(nnode) == B_TRUE);
1984                                 s1394_free_cfgrom(hal, nnode,
1985                                     S1394_FREE_CFGROM_NEW);
1986                                 break;
1987                         }
1988 
1989                         /*
1990                          * If there is indeed a cfgrom gen change,
1991                          * CFGROM_GEN_CHANGED() will be set iff we are matching
1992                          * tree nodes. Otherwise, CONFIG_ROM_GEN(old) !=
1993                          * CONFIG_ROM_GEN(new).
1994                          */
1995                         if (CFGROM_GEN_CHANGED(nnode) == B_TRUE ||
1996                             (CONFIG_ROM_GEN(onode->cfgrom) !=
1997                             CONFIG_ROM_GEN(nnode->cfgrom))) {
1998                                 gen_changed = 1;
1999                                 TNF_PROBE_4_DEBUG(s1394_match_GUID_gen_change,
2000                                     S1394_TNF_SL_HOTPLUG_STACK, "",
2001                                     tnf_opaque, old_cfgrom, onode->cfgrom,
2002                                     tnf_int, old_gen,
2003                                     CONFIG_ROM_GEN(onode->cfgrom), tnf_opaque,
2004                                     cfgrom, nnode->cfgrom, tnf_int, new_gen,
2005                                     CONFIG_ROM_GEN(nnode->cfgrom));
2006                         } else {
2007                                 gen_changed = 0;
2008                         }
2009 
2010                         onode->cur_node = nnode;
2011                         nnode->old_node = onode;
2012                         nnode->node_state = onode->node_state;
2013                         SET_NODE_VISITED(onode);
2014                         SET_NODE_MATCHED(onode);
2015                         SET_NODE_MATCHED(nnode);
2016                         /*
2017                          * If generations changed, need to offline any targets
2018                          * hanging off the old node, prior to freeing up old
2019                          * cfgrom. If the generations didn't change, we can
2020                          * free up the new config rom and copy all info from
2021                          * the old node (this helps in picking up further
2022                          * reads from where the last generation left off).
2023                          */
2024                         if (gen_changed == 1) {
2025                                 if (s1394_offline_node(hal, onode)) {
2026                                         ret = DDI_FAILURE;
2027                                         break;
2028                                 }
2029                                 TNF_PROBE_2(s1394_match_GUID_gen_freecfg,
2030                                     S1394_TNF_SL_HOTPLUG_STACK, "",
2031                                     tnf_opaque, old_cfgrom, onode->cfgrom,
2032                                     tnf_opaque, new_cfgrom, nnode->cfgrom);
2033                                 s1394_free_cfgrom(hal, onode,
2034                                     S1394_FREE_CFGROM_OLD);
2035                                 CLEAR_CFGROM_PARSED(nnode);
2036                                 CLEAR_CFGROM_NEW_ALLOC(nnode);
2037                                 CLEAR_CFGROM_NEW_ALLOC(onode);
2038                                 onode->cfgrom = nnode->cfgrom;
2039                                 /* done */
2040                                 break;
2041                         }
2042 
2043                         /*
2044                          * Free up cfgrom memory in the new_node and
2045                          * point it at the same config rom as the old one.
2046                          */
2047                         if (onode->cfgrom != nnode->cfgrom) {
2048 
2049                                 TNF_PROBE_5_DEBUG(s1394_match_GUID,
2050                                     S1394_TNF_SL_HOTPLUG_STACK, "",
2051                                     tnf_int, node_num, nnode->node_num,
2052                                     tnf_opaque, cfgrom, nnode->cfgrom,
2053                                     tnf_int, old_node_num, old_node,
2054                                     tnf_opaque, old_cfgrom, onode->cfgrom,
2055                                     tnf_uint, cfgrom_state,
2056                                     nnode->cfgrom_state);
2057 
2058                                 ASSERT(CFGROM_NEW_ALLOC(nnode) == B_TRUE);
2059                                 s1394_free_cfgrom(hal, nnode,
2060                                     S1394_FREE_CFGROM_NEW);
2061                         }
2062                         nnode->cfgrom = onode->cfgrom;
2063                         nnode->cfgrom_state = onode->cfgrom_state;
2064                         nnode->cfgrom_valid_size = onode->cfgrom_valid_size;
2065                         nnode->cfgrom_size = onode->cfgrom_size;
2066                         nnode->cfgrom_quad_to_read = onode->cfgrom_quad_to_read;
2067                         bcopy(onode->dir_stack, nnode->dir_stack,
2068                             offsetof(s1394_node_t, cfgrom_quad_to_read) -
2069                             offsetof(s1394_node_t, dir_stack));
2070                         CLEAR_CFGROM_NEW_ALLOC(nnode);
2071                         CLEAR_CFGROM_NEW_ALLOC(onode);
2072 
2073                         if (CFGROM_PARSED(nnode) == B_TRUE) {
2074                                 rw_enter(&hal->target_list_rwlock, RW_WRITER);
2075                                 /* Update the target list */
2076                                 if ((t = onode->target_list) != NULL) {
2077                                         nnode->target_list = t;
2078                                         while (t != NULL) {
2079                                                 t->on_node = nnode;
2080                                                 t = t->target_sibling;
2081                                         }
2082                                 }
2083                                 rw_exit(&hal->target_list_rwlock);
2084                         }
2085                         break;
2086                 }
2087         }
2088 
2089         TNF_PROBE_0_DEBUG(s1394_match_GUID_exit, S1394_TNF_SL_HOTPLUG_STACK,
2090             "");
2091 
2092         return (ret);
2093 }
2094 
2095 /*
2096  * s1394_match_all_GUIDs()
2097  *    attempt to match each node in the current topology tree with the a
2098  *    node in the old topology tree.  If unable to relock the tree, returns
2099  *    DDI_FAILURE, else returns DDI_SUCCESS.
2100  */
2101 static int
2102 s1394_match_all_GUIDs(s1394_hal_t *hal)
2103 {
2104         int node;
2105         int ret = DDI_SUCCESS;
2106         s1394_node_t *nnode;
2107 
2108         TNF_PROBE_0_DEBUG(s1394_match_all_GUIDs_enter,
2109             S1394_TNF_SL_HOTPLUG_STACK, "");
2110 
2111         ASSERT(MUTEX_HELD(&hal->topology_tree_mutex));
2112 
2113         for (node = 0; node < hal->number_of_nodes; node++) {
2114                 nnode = &hal->topology_tree[node];
2115                 if (LINK_ACTIVE(nnode) == B_FALSE || CFGROM_BIB_READ(nnode) ==
2116                     B_FALSE)
2117                         continue;
2118                 if (NODE_MATCHED(nnode)) {
2119                         /*
2120                          * Skip if node matched. If config rom generations
2121                          * changed, we want to call s1394_match_GUID() even
2122                          * if the nodes matched.
2123                          */
2124                         int gen_changed;
2125                         s1394_node_t *onode = nnode->old_node;
2126 
2127                         gen_changed = (onode && onode->cfgrom &&
2128                             CONFIG_ROM_GEN(onode->cfgrom) != CONFIG_ROM_GEN(
2129                             nnode->cfgrom)) ? 1 : 0;
2130 
2131                         if (CFGROM_GEN_CHANGED(nnode) == 0 && gen_changed == 0)
2132                                 continue;
2133                 }
2134 
2135                 if (s1394_match_GUID(hal, nnode) == DDI_FAILURE) {
2136                         ret = DDI_FAILURE;
2137                 }
2138         }
2139 
2140         TNF_PROBE_0_DEBUG(s1394_match_all_GUIDs_exit,
2141             S1394_TNF_SL_HOTPLUG_STACK, "");
2142 
2143         return (ret);
2144 }
2145 
2146 /*
2147  * s1394_valid_cfgrom()
2148  *    Performs crc check on the config rom. Returns B_TRUE if config rom has
2149  *    good CRC else returns B_FALSE.
2150  */
2151 /* ARGSUSED */
2152 boolean_t
2153 s1394_valid_cfgrom(s1394_hal_t *hal, s1394_node_t *node)
2154 {
2155         uint32_t crc_len, crc_value, CRC, CRC_old, quad0;
2156 
2157         TNF_PROBE_0_DEBUG(s1394_valid_cfgrom_enter, S1394_TNF_SL_HOTPLUG_STACK,
2158             "");
2159 
2160         ASSERT(MUTEX_HELD(&hal->topology_tree_mutex));
2161         ASSERT(node->cfgrom);
2162 
2163         if (s1394_enable_crc_validation == 0) {
2164                 TNF_PROBE_1_DEBUG(s1394_valid_cfgrom_exit,
2165                     S1394_TNF_SL_HOTPLUG_STACK, "", tnf_string, msg,
2166                     "validation turned off");
2167                 return (B_TRUE);
2168         }
2169 
2170         quad0 = node->cfgrom[0];
2171         crc_len = (quad0 >> IEEE1394_CFG_ROM_CRC_LEN_SHIFT) &
2172             IEEE1394_CFG_ROM_CRC_LEN_MASK;
2173         crc_value = quad0 & IEEE1394_CFG_ROM_CRC_VALUE_MASK;
2174 
2175         if (node->cfgrom_valid_size < crc_len + 1) {
2176                 TNF_PROBE_4(s1394_valid_cfgrom_not_enough,
2177                     S1394_TNF_SL_HOTPLUG_ERROR, "",
2178                     tnf_uint, node_guid_hi, node->node_guid_hi,
2179                     tnf_uint, node_guid_lo, node->node_guid_lo,
2180                     tnf_uint, crc_len, crc_len,
2181                     tnf_uint, valid_size, node->cfgrom_valid_size);
2182                 TNF_PROBE_0_DEBUG(s1394_valid_cfgrom_exit,
2183                     S1394_TNF_SL_HOTPLUG_STACK, "");
2184                 return (B_FALSE);
2185         }
2186 
2187         CRC = s1394_CRC16(&node->cfgrom[1], crc_len);
2188 
2189         if (CRC != crc_value) {
2190                 CRC_old = s1394_CRC16_old(&node->cfgrom[1], crc_len);
2191                 if (CRC_old == crc_value) {
2192                         TNF_PROBE_4_DEBUG(s1394_valid_cfgrom_busted_crc,
2193                             S1394_TNF_SL_HOTPLUG_ERROR, "",
2194                             tnf_uint, node_guid_hi, node->node_guid_hi,
2195                             tnf_uint, node_guid_lo, node->node_guid_lo,
2196                             tnf_uint, node_num, node->node_num,
2197                             tnf_uint, crc_len, crc_len);
2198                         TNF_PROBE_0_DEBUG(s1394_valid_cfgrom_exit,
2199                             S1394_TNF_SL_HOTPLUG_STACK, "");
2200                         return (B_TRUE);
2201                 }
2202 
2203                 cmn_err(CE_NOTE,
2204                     "!Bad CRC in config rom (node's GUID %08x%08x)",
2205                     node->node_guid_hi, node->node_guid_lo);
2206 
2207                 TNF_PROBE_5(s1394_valid_cfgrom_bad_crc,
2208                     S1394_TNF_SL_HOTPLUG_ERROR, "",
2209                     tnf_uint, node_guid_hi, node->node_guid_hi,
2210                     tnf_uint, node_guid_lo, node->node_guid_lo,
2211                     tnf_uint, crc_len, crc_len,
2212                     tnf_uint, crc, crc_value, tnf_uint, crc_computed, CRC);
2213                 TNF_PROBE_0_DEBUG(s1394_valid_cfgrom_exit,
2214                     S1394_TNF_SL_HOTPLUG_STACK, "");
2215                 return (B_FALSE);
2216         }
2217 
2218         TNF_PROBE_3_DEBUG(s1394_valid_cfgrom_exit, S1394_TNF_SL_HOTPLUG_STACK,
2219             "", tnf_uint, node_num, node->node_num, tnf_uint, crc_len, crc_len,
2220             tnf_uint, crc, crc_value);
2221 
2222         return (B_TRUE);
2223 }
2224 
2225 /*
2226  * s1394_valid_dir()
2227  *    Performs crc check on a directory.  Returns B_TRUE if dir has good CRC
2228  *    else returns B_FALSE.
2229  */
2230 /*ARGSUSED*/
2231 boolean_t
2232 s1394_valid_dir(s1394_hal_t *hal, s1394_node_t *node,
2233     uint32_t key, uint32_t *dir)
2234 {
2235         uint32_t dir_len, crc_value, CRC, CRC_old, quad0;
2236 
2237         TNF_PROBE_0_DEBUG(s1394_valid_dir_enter, S1394_TNF_SL_HOTPLUG_STACK,
2238             "");
2239 
2240         /*
2241          * Ideally, we would like to do crc validations for the entire cfgrom
2242          * as well as the individual directories. However, we have seen devices
2243          * that have valid directories but busted cfgrom crc and devices that
2244          * have bad crcs in directories as well as for the entire cfgrom. This
2245          * is sad, but unfortunately, real world!
2246          */
2247         if (s1394_enable_crc_validation == 0) {
2248                 TNF_PROBE_1_DEBUG(s1394_valid_dir_exit,
2249                     S1394_TNF_SL_HOTPLUG_STACK, "", tnf_string, msg,
2250                     "validation turned off");
2251                 return (B_TRUE);
2252         }
2253 
2254         quad0 = dir[0];
2255 
2256         dir_len = IEEE1212_DIR_LEN(quad0);
2257         crc_value = IEEE1212_DIR_CRC(quad0);
2258 
2259         ASSERT(MUTEX_HELD(&hal->topology_tree_mutex));
2260 
2261         CRC = s1394_CRC16(&dir[1], dir_len);
2262 
2263         if (CRC != crc_value) {
2264                 CRC_old = s1394_CRC16_old(&dir[1], dir_len);
2265                 if (CRC_old == crc_value) {
2266                         TNF_PROBE_5_DEBUG(s1394_valid_dir_crc_old,
2267                             S1394_TNF_SL_HOTPLUG_STACK, "",
2268                             tnf_uint, node_guid_hi, node->node_guid_hi,
2269                             tnf_uint, node_guid_lo, node->node_guid_lo,
2270                             tnf_uint, node_num, node->node_num,
2271                             tnf_uint, key, key, tnf_uint, dir_len, dir_len);
2272                         TNF_PROBE_0_DEBUG(s1394_valid_dir_exit,
2273                             S1394_TNF_SL_HOTPLUG_STACK, "");
2274                         return (B_TRUE);
2275                 }
2276 
2277                 TNF_PROBE_5(s1394_valid_dir_bad_crc,
2278                     S1394_TNF_SL_HOTPLUG_STACK, "",
2279                     tnf_uint, node_guid_hi, node->node_guid_hi,
2280                     tnf_uint, node_guid_lo, node->node_guid_lo,
2281                     tnf_uint, node_num, node->node_num,
2282                     tnf_uint, key, key, tnf_uint, dir_len, dir_len);
2283 
2284                 TNF_PROBE_0_DEBUG(s1394_valid_dir_exit,
2285                             S1394_TNF_SL_HOTPLUG_STACK, "");
2286                 return (B_FALSE);
2287         }
2288 
2289         TNF_PROBE_4_DEBUG(s1394_valid_dir,
2290             S1394_TNF_SL_HOTPLUG_STACK, "",
2291             tnf_uint, node_guid_hi, node->node_guid_hi,
2292             tnf_uint, node_guid_lo, node->node_guid_lo,
2293             tnf_uint, node_num, node->node_num, tnf_uint, key, key);
2294 
2295         return (B_TRUE);
2296 }
2297 
2298 /*
2299  * s1394_become_bus_mgr()
2300  *    is a callback from a timeout() setup by the main br_thread.  After
2301  *    a bus reset, depending on the Bus Manager's incumbancy and the state
2302  *    of its abdicate bit, a timer of a certain length is set.  After this
2303  *    time expires, the local host may attempt to become the Bus Manager.
2304  *    This is done by sending a request to the current IRM on the bus.  The
2305  *    IRM holds the BUS_MANAGER_ID register.  Depending on whether or not
2306  *    the local host is already the IRM, we will send a request onto the
2307  *    1394 bus or call into the HAL.
2308  */
2309 static void
2310 s1394_become_bus_mgr(void *arg)
2311 {
2312         s1394_hal_t      *hal;
2313         s1394_cmd_priv_t *s_priv;
2314         cmd1394_cmd_t    *cmd;
2315         uint64_t         Bus_Mgr_ID_addr;
2316         uint32_t         hal_node_num;
2317         uint32_t         old_value;
2318         uint32_t         generation;
2319         uint_t           curr_bus_mgr;
2320         uint_t           bm_node;
2321         uint_t           IRM_node;
2322         int              err;
2323         int              ret;
2324 
2325         TNF_PROBE_0_DEBUG(s1394_become_bus_mgr_enter, S1394_TNF_SL_BR_STACK,
2326             "");
2327 
2328         hal = (s1394_hal_t *)arg;
2329 
2330         /* Lock the topology tree */
2331         mutex_enter(&hal->topology_tree_mutex);
2332 
2333         hal_node_num = IEEE1394_NODE_NUM(hal->node_id);
2334         generation   = hal->generation_count;
2335         IRM_node = hal->IRM_node;
2336 
2337         mutex_enter(&hal->bus_mgr_node_mutex);
2338         bm_node = hal->bus_mgr_node;
2339         mutex_exit(&hal->bus_mgr_node_mutex);
2340 
2341         /* Unlock the topology tree */
2342         mutex_exit(&hal->topology_tree_mutex);
2343 
2344         /* Make sure we aren't already the Bus Manager */
2345         if (bm_node != -1) {
2346                 TNF_PROBE_0_DEBUG(s1394_become_bus_mgr_exit,
2347                     S1394_TNF_SL_BR_STACK, "");
2348                 return;
2349         }
2350 
2351         /* Send compare-swap to BUS_MANAGER_ID */
2352         /* register on the Isoch Rsrc Mgr */
2353         if (IRM_node == hal_node_num) {
2354                 /* Local */
2355                 ret = HAL_CALL(hal).csr_cswap32(hal->halinfo.hal_private,
2356                     generation, (IEEE1394_SCSR_BUSMGR_ID &
2357                     IEEE1394_CSR_OFFSET_MASK), S1394_INVALID_NODE_NUM,
2358                     hal_node_num, &old_value);
2359                 if (ret != DDI_SUCCESS) {
2360                         TNF_PROBE_1(s1394_become_bus_mgr_error,
2361                             S1394_TNF_SL_BR_ERROR, "", tnf_string, msg,
2362                             "Error in cswap32");
2363                         TNF_PROBE_0_DEBUG(s1394_become_bus_mgr_exit,
2364                             S1394_TNF_SL_BR_STACK, "");
2365                         return;
2366                 }
2367                 curr_bus_mgr = IEEE1394_NODE_NUM(old_value);
2368 
2369                 mutex_enter(&hal->bus_mgr_node_mutex);
2370                 if ((curr_bus_mgr == S1394_INVALID_NODE_NUM) ||
2371                     (curr_bus_mgr == hal_node_num)) {
2372                         hal->bus_mgr_node = hal_node_num;
2373                         hal->incumbent_bus_mgr = B_TRUE;
2374                 } else {
2375                         hal->bus_mgr_node = curr_bus_mgr;
2376                         hal->incumbent_bus_mgr = B_FALSE;
2377                 }
2378                 cv_signal(&hal->bus_mgr_node_cv);
2379                 mutex_exit(&hal->bus_mgr_node_mutex);
2380 
2381         } else {
2382                 /* Remote */
2383                 if (s1394_alloc_cmd(hal, T1394_ALLOC_CMD_NOSLEEP, &cmd) !=
2384                     DDI_SUCCESS) {
2385                         TNF_PROBE_1(s1394_become_bus_mgr_error,
2386                             S1394_TNF_SL_BR_ERROR, "", tnf_string, msg,
2387                             "Error in s1394_alloc_cmd()");
2388                         TNF_PROBE_0_DEBUG(s1394_become_bus_mgr_exit,
2389                             S1394_TNF_SL_BR_STACK, "");
2390                         return;
2391                 }
2392 
2393                 cmd->cmd_options        = (CMD1394_CANCEL_ON_BUS_RESET |
2394                     CMD1394_OVERRIDE_ADDR);
2395                 cmd->cmd_type                   = CMD1394_ASYNCH_LOCK_32;
2396                 cmd->completion_callback   = s1394_become_bus_mgr_callback;
2397                 Bus_Mgr_ID_addr            = (IEEE1394_ADDR_BUS_ID_MASK |
2398                     IEEE1394_SCSR_BUSMGR_ID) |
2399                     (((uint64_t)hal->IRM_node) << IEEE1394_ADDR_PHY_ID_SHIFT);
2400                 cmd->cmd_addr                   = Bus_Mgr_ID_addr;
2401                 cmd->bus_generation     = generation;
2402                 cmd->cmd_u.l32.arg_value   = T1394_DATA32(
2403                     S1394_INVALID_NODE_NUM);
2404                 cmd->cmd_u.l32.data_value  = T1394_DATA32(hal_node_num);
2405                 cmd->cmd_u.l32.num_retries = 0;
2406                 cmd->cmd_u.l32.lock_type   = CMD1394_LOCK_COMPARE_SWAP;
2407 
2408                 /* Get the Services Layer private area */
2409                 s_priv = S1394_GET_CMD_PRIV(cmd);
2410 
2411                 /* Lock the topology tree */
2412                 mutex_enter(&hal->topology_tree_mutex);
2413 
2414                 ret = s1394_setup_asynch_command(hal, NULL, cmd,
2415                     S1394_CMD_LOCK, &err);
2416 
2417                 /* Unlock the topology tree */
2418                 mutex_exit(&hal->topology_tree_mutex);
2419 
2420                 /* Command has now been put onto the queue! */
2421                 if (ret != DDI_SUCCESS) {
2422                         /* Need to free the command */
2423                         (void) s1394_free_cmd(hal, (cmd1394_cmd_t **)&cmd);
2424                         TNF_PROBE_1(s1394_become_bus_mgr_error,
2425                             S1394_TNF_SL_BR_ERROR, "", tnf_string, msg,
2426                             "Error in s1394_setup_asynch_command()");
2427                         TNF_PROBE_0_DEBUG(s1394_become_bus_mgr_exit,
2428                             S1394_TNF_SL_BR_STACK, "");
2429                         return;
2430                 }
2431 
2432                 /* Send the command out */
2433                 ret = s1394_xfer_asynch_command(hal, cmd, &err);
2434 
2435                 if (ret != DDI_SUCCESS) {
2436                         /* Remove cmd outstanding request Q */
2437                         s1394_remove_q_asynch_cmd(hal, cmd);
2438 
2439                         s_priv->cmd_in_use = B_FALSE;
2440 
2441                         mutex_enter(&hal->bus_mgr_node_mutex);
2442 
2443                         /* Don't know who the bus_mgr is */
2444                         hal->bus_mgr_node = S1394_INVALID_NODE_NUM;
2445                         hal->incumbent_bus_mgr = B_FALSE;
2446 
2447                         cv_signal(&hal->bus_mgr_node_cv);
2448                         mutex_exit(&hal->bus_mgr_node_mutex);
2449 
2450                         /* Need to free the command */
2451                         (void) s1394_free_cmd(hal, (cmd1394_cmd_t **)&cmd);
2452                 }
2453         }
2454 
2455         TNF_PROBE_0_DEBUG(s1394_become_bus_mgr_exit, S1394_TNF_SL_BR_STACK,
2456             "");
2457 }
2458 
2459 /*
2460  * s1394_become_bus_mgr_callback()
2461  *    is the callback used by s1394_become_bus_mgr() when it is necessary
2462  *    to send the Bus Manager request to a remote IRM.  After the completion
2463  *    of the compare-swap request, this routine looks at the "old_value"
2464  *    in the request to determine whether or not it has become the Bus
2465  *    Manager for the current generation.  It sets the bus_mgr_node and
2466  *    incumbent_bus_mgr fields to their appropriate values.
2467  */
2468 static void
2469 s1394_become_bus_mgr_callback(cmd1394_cmd_t *cmd)
2470 {
2471         s1394_cmd_priv_t *s_priv;
2472         s1394_hal_t *hal;
2473         uint32_t hal_node_num;
2474         uint32_t temp;
2475         uint_t curr_bus_mgr;
2476 
2477         TNF_PROBE_0_DEBUG(s1394_become_bus_mgr_callback_enter,
2478             S1394_TNF_SL_BR_STACK, "");
2479 
2480         /* Get the Services Layer private area */
2481         s_priv = S1394_GET_CMD_PRIV(cmd);
2482 
2483         hal = (s1394_hal_t *)s_priv->sent_on_hal;
2484 
2485         /* Lock the topology tree */
2486         mutex_enter(&hal->topology_tree_mutex);
2487 
2488         hal_node_num = IEEE1394_NODE_NUM(hal->node_id);
2489 
2490         /* Was the command successful? */
2491         if (cmd->cmd_result == CMD1394_CMDSUCCESS) {
2492                 temp = T1394_DATA32(cmd->cmd_u.l32.old_value);
2493                 curr_bus_mgr = IEEE1394_NODE_NUM(temp);
2494                 mutex_enter(&hal->bus_mgr_node_mutex);
2495                 if ((curr_bus_mgr == S1394_INVALID_NODE_NUM) ||
2496                     (curr_bus_mgr == hal_node_num)) {
2497 
2498                         hal->bus_mgr_node = hal_node_num;
2499                         hal->incumbent_bus_mgr = B_TRUE;
2500 
2501                 } else {
2502                         hal->bus_mgr_node = curr_bus_mgr;
2503                         hal->incumbent_bus_mgr = B_FALSE;
2504                 }
2505                 cv_signal(&hal->bus_mgr_node_cv);
2506                 mutex_exit(&hal->bus_mgr_node_mutex);
2507 
2508         } else {
2509                 TNF_PROBE_2(s1394_become_bus_mgr_callback_error,
2510                     S1394_TNF_SL_BR_ERROR, "", tnf_string, msg,
2511                     "Error while attempting to become bus manager",
2512                     tnf_uint, status, cmd->cmd_result);
2513 
2514                 mutex_enter(&hal->bus_mgr_node_mutex);
2515 
2516                 /* Don't know who the bus_mgr is */
2517                 hal->bus_mgr_node = S1394_INVALID_NODE_NUM;
2518                 hal->incumbent_bus_mgr = B_FALSE;
2519 
2520                 cv_signal(&hal->bus_mgr_node_cv);
2521                 mutex_exit(&hal->bus_mgr_node_mutex);
2522         }
2523 
2524         /* Need to free the command */
2525         (void) s1394_free_cmd(hal, (cmd1394_cmd_t **)&cmd);
2526 
2527         /* Unlock the topology tree */
2528         mutex_exit(&hal->topology_tree_mutex);
2529 
2530         TNF_PROBE_0_DEBUG(s1394_become_bus_mgr_callback_exit,
2531             S1394_TNF_SL_BR_STACK, "");
2532 }
2533 
2534 /*
2535  * s1394_bus_mgr_processing()
2536  *    is called following "phase1" completion of reading Bus_Info_Blocks.
2537  *    Its purpose is to determine whether the local node is capable of
2538  *    becoming the Bus Manager (has the IRMC bit set) and if so to call
2539  *    the s1394_do_bus_mgr_processing() routine.
2540  *    NOTE: we overload DDI_FAILURE return value to mean jump back to
2541  *    the start of bus reset processing.
2542  */
2543 static int
2544 s1394_bus_mgr_processing(s1394_hal_t *hal)
2545 {
2546         int ret;
2547         int IRM_node_num;
2548 
2549         TNF_PROBE_0_DEBUG(s1394_bus_mgr_processing_enter,
2550             S1394_TNF_SL_BR_STACK, "");
2551 
2552         ASSERT(MUTEX_NOT_HELD(&hal->topology_tree_mutex));
2553 
2554         if (s1394_lock_tree(hal) != DDI_SUCCESS) {
2555                 return (DDI_FAILURE);
2556         }
2557         IRM_node_num = hal->IRM_node;
2558         s1394_unlock_tree(hal);
2559 
2560         ret = DDI_SUCCESS;
2561 
2562         /* If we are IRM capable, then do bus_mgr stuff... */
2563         if (hal->halinfo.bus_capabilities & IEEE1394_BIB_IRMC_MASK) {
2564                 /* If there is an IRM, then do bus_mgr stuff */
2565                 if (IRM_node_num != -1) {
2566                         if (s1394_do_bus_mgr_processing(hal))
2567                                 ret = DDI_FAILURE;
2568                 }
2569         }
2570 
2571         ASSERT(MUTEX_NOT_HELD(&hal->topology_tree_mutex));
2572 
2573         TNF_PROBE_0_DEBUG(s1394_bus_mgr_processing_exit,
2574             S1394_TNF_SL_BR_STACK, "");
2575         return (ret);
2576 }
2577 
2578 /*
2579  * s1394_do_bus_mgr_processing()
2580  *    is used to perform those operations expected of the Bus Manager.
2581  *    After being called, s1394_do_bus_mgr_processing() looks at the value
2582  *    in bus_mgr_node and waits if it is -1 (Bus Manager has not been
2583  *    chosen yet).  Then, if there is more than one node on the 1394 bus,
2584  *    and we are either the Bus Manager or (if there is no Bus Manager)
2585  *    the IRM, it optimizes the gap_count and/or sets the cycle master's
2586  *    root holdoff bit (to ensure that the cycle master is/stays root).
2587  *
2588  *    NOTE: we overload DDI_FAILURE return value to mean jump back to
2589  *    the start of bus reset processing.
2590  */
2591 static int
2592 s1394_do_bus_mgr_processing(s1394_hal_t *hal)
2593 {
2594         int     ret;
2595         int     IRM_flags, hal_bus_mgr_node;
2596         int     IRM_node_num;
2597         uint_t  hal_node_num, number_of_nodes;
2598         int     new_root, new_gap_cnt;
2599 
2600         TNF_PROBE_0_DEBUG(s1394_do_bus_mgr_processing_enter,
2601             S1394_TNF_SL_BR_STACK, "");
2602 
2603         ASSERT(MUTEX_NOT_HELD(&hal->topology_tree_mutex));
2604 
2605         /* Wait for Bus Manager to be determined */
2606         /* or a Bus Reset to happen */
2607         mutex_enter(&hal->bus_mgr_node_mutex);
2608         if (hal->bus_mgr_node == -1)
2609                 cv_wait(&hal->bus_mgr_node_cv, &hal->bus_mgr_node_mutex);
2610 
2611         /* Check if a BUS RESET has come while we've been waiting */
2612         mutex_enter(&hal->br_thread_mutex);
2613         if (hal->br_thread_ev_type & (BR_THR_CFGROM_SCAN | BR_THR_GO_AWAY)) {
2614 
2615                 mutex_exit(&hal->br_thread_mutex);
2616                 mutex_exit(&hal->bus_mgr_node_mutex);
2617 
2618                 TNF_PROBE_0_DEBUG(s1394_do_bus_mgr_processing_exit,
2619                     S1394_TNF_SL_BR_STACK, "");
2620                 return (1);
2621         }
2622         mutex_exit(&hal->br_thread_mutex);
2623 
2624         hal_bus_mgr_node = hal->bus_mgr_node;
2625         mutex_exit(&hal->bus_mgr_node_mutex);
2626 
2627         if (s1394_lock_tree(hal) != DDI_SUCCESS) {
2628                 return (1);
2629         }
2630         hal_node_num = IEEE1394_NODE_NUM(hal->node_id);
2631         IRM_node_num = hal->IRM_node;
2632         number_of_nodes = hal->number_of_nodes;
2633 
2634         ret = 0;
2635 
2636         /* If we are the bus_mgr or if there is no bus_mgr */
2637         /* the IRM and there is > 1 nodes on the bus */
2638         if ((number_of_nodes > 1) &&
2639             ((hal_bus_mgr_node == (int)hal_node_num) ||
2640                 ((hal_bus_mgr_node == S1394_INVALID_NODE_NUM) &&
2641                     (IRM_node_num == (int)hal_node_num)))) {
2642 
2643                 IRM_flags = 0;
2644 
2645                 /* Make sure the root node is cycle master capable */
2646                 if (!s1394_cycle_master_capable(hal)) {
2647                         /* Make the local node root */
2648                         new_root = hal_node_num;
2649                         IRM_flags = IRM_flags | ROOT_HOLDOFF;
2650 
2651                         /* If setting root, then optimize gap_count */
2652                         new_gap_cnt = hal->optimum_gap_count;
2653                         IRM_flags = IRM_flags | GAP_COUNT;
2654 
2655                 } else {
2656                         /* Make sure root's ROOT_HOLDOFF bit is set */
2657                         new_root = (number_of_nodes - 1);
2658                         IRM_flags = IRM_flags | ROOT_HOLDOFF;
2659                 }
2660                 if (hal->gap_count > hal->optimum_gap_count) {
2661                         /* Set the gap_count to optimum */
2662                         new_gap_cnt = hal->optimum_gap_count;
2663                         IRM_flags = IRM_flags | GAP_COUNT;
2664 
2665                 }
2666 
2667                 s1394_unlock_tree(hal);
2668 
2669                 if (IRM_flags) {
2670                         ret = s1394_do_phy_config_pkt(hal, new_root,
2671                             new_gap_cnt, IRM_flags);
2672                 }
2673                 TNF_PROBE_0_DEBUG(s1394_do_bus_mgr_processing_exit,
2674                     S1394_TNF_SL_BR_STACK, "");
2675                 return (ret);
2676         }
2677 
2678         s1394_unlock_tree(hal);
2679 
2680         TNF_PROBE_0_DEBUG(s1394_do_bus_mgr_processing_exit,
2681             S1394_TNF_SL_BR_STACK, "");
2682         return (ret);
2683 }
2684 
2685 /*
2686  * s1394_bus_mgr_timers_stop()
2687  *    Cancels bus manager timeouts
2688  */
2689 /*ARGSUSED*/
2690 static void
2691 s1394_bus_mgr_timers_stop(s1394_hal_t *hal, timeout_id_t *bus_mgr_query_tid,
2692     timeout_id_t *bus_mgr_tid)
2693 {
2694         TNF_PROBE_0_DEBUG(s1394_bus_mgr_timers_stop_enter,
2695             S1394_TNF_SL_BR_STACK, "");
2696 
2697         /* Cancel the Bus Mgr timeouts (if necessary) */
2698         if (*bus_mgr_tid != 0) {
2699                 (void) untimeout(*bus_mgr_tid);
2700                 *bus_mgr_tid = 0;
2701         }
2702         if (*bus_mgr_query_tid != 0) {
2703                 (void) untimeout(*bus_mgr_query_tid);
2704                 *bus_mgr_query_tid = 0;
2705         }
2706 
2707         TNF_PROBE_0_DEBUG(s1394_bus_mgr_timers_stop_exit,
2708             S1394_TNF_SL_BR_STACK, "");
2709 }
2710 
2711 /*
2712  * s1394_bus_mgr_timers_start()
2713  *    Starts bus manager timeouts if the hal is IRM capable.
2714  */
2715 static void
2716 s1394_bus_mgr_timers_start(s1394_hal_t *hal, timeout_id_t *bus_mgr_query_tid,
2717     timeout_id_t *bus_mgr_tid)
2718 {
2719         boolean_t incumbant;
2720         uint_t    hal_node_num;
2721         int       IRM_node_num;
2722 
2723         TNF_PROBE_0_DEBUG(s1394_bus_mgr_timers_start_enter,
2724             S1394_TNF_SL_BR_STACK, "");
2725 
2726         mutex_enter(&hal->topology_tree_mutex);
2727 
2728         IRM_node_num = hal->IRM_node;
2729         hal_node_num = hal->node_id;
2730 
2731         mutex_enter(&hal->bus_mgr_node_mutex);
2732         incumbant = hal->incumbent_bus_mgr;
2733         mutex_exit(&hal->bus_mgr_node_mutex);
2734 
2735         /* If we are IRM capable, then do bus_mgr stuff... */
2736         if (hal->halinfo.bus_capabilities & IEEE1394_BIB_IRMC_MASK) {
2737                 /*
2738                  * If we are the IRM, then wait 625ms
2739                  * before checking BUS_MANAGER_ID register
2740                  */
2741                 if (IRM_node_num == IEEE1394_NODE_NUM(hal_node_num)) {
2742 
2743                         TNF_PROBE_0_DEBUG(s1394_bus_mgr_timers_625ms,
2744                             S1394_TNF_SL_BR_STACK, "");
2745 
2746                         mutex_exit(&hal->topology_tree_mutex);
2747 
2748                         /* Wait 625ms, then check bus manager */
2749                         *bus_mgr_query_tid = timeout(s1394_become_bus_mgr,
2750                             hal, drv_usectohz(IEEE1394_BM_IRM_TIMEOUT));
2751 
2752                         mutex_enter(&hal->topology_tree_mutex);
2753                 }
2754 
2755                 /* If there is an IRM on the bus */
2756                 if (IRM_node_num != -1) {
2757                         if ((incumbant == B_TRUE) &&
2758                             (hal->abdicate_bus_mgr_bit == 0)) {
2759                                 mutex_exit(&hal->topology_tree_mutex);
2760 
2761                                 /* Try to become bus manager */
2762                                 s1394_become_bus_mgr(hal);
2763 
2764                                 mutex_enter(&hal->topology_tree_mutex);
2765                         } else {
2766                                 hal->abdicate_bus_mgr_bit = 0;
2767 
2768                                 TNF_PROBE_0_DEBUG(s1394_bus_mgr_timers_125ms,
2769                                     S1394_TNF_SL_BR_STACK, "");
2770 
2771                                 mutex_exit(&hal->topology_tree_mutex);
2772 
2773                                 /* Wait 125ms, then try to become bus manager */
2774                                 *bus_mgr_tid = timeout(s1394_become_bus_mgr,
2775                                     hal, drv_usectohz(
2776                                         IEEE1394_BM_INCUMBENT_TIMEOUT));
2777 
2778                                 mutex_enter(&hal->topology_tree_mutex);
2779                         }
2780                 } else {
2781                         mutex_enter(&hal->bus_mgr_node_mutex);
2782                         hal->incumbent_bus_mgr = B_FALSE;
2783                         mutex_exit(&hal->bus_mgr_node_mutex);
2784                 }
2785         }
2786 
2787         mutex_exit(&hal->topology_tree_mutex);
2788 
2789         TNF_PROBE_0_DEBUG(s1394_bus_mgr_timers_start_exit,
2790             S1394_TNF_SL_BR_STACK, "");
2791 }
2792 
2793 /*
2794  * s1394_get_maxpayload()
2795  *    is used to determine a device's maximum payload size.  That is to
2796  *    say, the largest packet that can be transmitted or received by the
2797  *    the target device given the current topological (speed) constraints
2798  *    and the constraints specified in the local host's and remote device's
2799  *    Config ROM (max_rec).  Caller must hold the topology_tree_mutex and
2800  *    the target_list_rwlock as an RW_READER (at least).
2801  */
2802 /*ARGSUSED*/
2803 void
2804 s1394_get_maxpayload(s1394_target_t *target, uint_t *dev_max_payload,
2805     uint_t *current_max_payload)
2806 {
2807         s1394_hal_t *hal;
2808         uint32_t bus_capabilities;
2809         uint32_t from_node;
2810         uint32_t to_node;
2811         uint_t local_max_rec;
2812         uint_t local_max_blk;
2813         uint_t max_rec;
2814         uint_t max_blk;
2815         uint_t curr_speed;
2816         uint_t speed_max_blk;
2817         uint_t temp;
2818 
2819         TNF_PROBE_0_DEBUG(s1394_get_maxpayload_enter,
2820             S1394_TNF_SL_HOTPLUG_STACK, "");
2821 
2822         /* Find the HAL this target resides on */
2823         hal = target->on_hal;
2824 
2825         /* Make sure we're holding the topology_tree_mutex */
2826         ASSERT(MUTEX_HELD(&hal->topology_tree_mutex));
2827 
2828         /* Set dev_max_payload to local (HAL's) size */
2829         bus_capabilities = target->on_hal->halinfo.bus_capabilities;
2830         local_max_rec = (bus_capabilities & IEEE1394_BIB_MAXREC_MASK) >>
2831             IEEE1394_BIB_MAXREC_SHIFT;
2832         if ((local_max_rec > 0) && (local_max_rec < 14)) {
2833                 local_max_blk = 1 << (local_max_rec + 1);
2834         } else {
2835                 /* These are either unspecified or reserved */
2836                 local_max_blk = 4;
2837         }
2838 
2839         /* Is this target on a node? */
2840         if ((target->target_state & S1394_TARG_GONE) == 0 &&
2841             (target->on_node != NULL)) {
2842                 ASSERT(target->on_node->cfgrom != NULL);
2843 
2844                 bus_capabilities =
2845                     target->on_node->cfgrom[IEEE1212_NODE_CAP_QUAD];
2846                 max_rec = (bus_capabilities & IEEE1394_BIB_MAXREC_MASK) >>
2847                     IEEE1394_BIB_MAXREC_SHIFT;
2848 
2849                 if ((max_rec > 0) && (max_rec < 14)) {
2850                         max_blk = 1 << (max_rec + 1);
2851                 } else {
2852                         /* These are either unspecified or reserved */
2853                         max_blk = 4;
2854                 }
2855                 (*dev_max_payload) = max_blk;
2856 
2857                 from_node = IEEE1394_NODE_NUM(target->on_hal->node_id);
2858                 to_node = (target->on_node->node_num);
2859 
2860                 /* Speed is to be filled in from speed map */
2861                 curr_speed = (uint_t)s1394_speed_map_get(target->on_hal,
2862                     from_node, to_node);
2863                 speed_max_blk = 512 << curr_speed;
2864                 temp = (local_max_blk < max_blk) ? local_max_blk : max_blk;
2865                 (*current_max_payload) = (temp < speed_max_blk) ? temp :
2866                     speed_max_blk;
2867         } else {
2868                 /* Set dev_max_payload to local (HAL's) size */
2869                 (*dev_max_payload) = local_max_blk;
2870                 (*current_max_payload) = local_max_blk;
2871         }
2872 
2873         TNF_PROBE_0_DEBUG(s1394_get_maxpayload_exit,
2874             S1394_TNF_SL_HOTPLUG_STACK, "");
2875 }
2876 
2877 /*
2878  * s1394_cycle_master_capable()
2879  *    is used to determine whether or not the current root node on the
2880  *    1394 bus has its CMC-bit set in it Config ROM.  If not, then it
2881  *    is not capable of being cycle master and a new root node must be
2882  *    selected.
2883  */
2884 static int
2885 s1394_cycle_master_capable(s1394_hal_t *hal)
2886 {
2887         s1394_node_t    *root;
2888         int             cycle_master_capable;
2889         uint_t          hal_node_num;
2890 
2891         TNF_PROBE_0_DEBUG(s1394_cycle_master_capable_enter,
2892             S1394_TNF_SL_HOTPLUG_STACK, "");
2893 
2894         ASSERT(MUTEX_HELD(&hal->topology_tree_mutex));
2895 
2896         hal_node_num = IEEE1394_NODE_NUM(hal->node_id);
2897 
2898         /* Get a pointer to the root node */
2899         root = s1394_topology_tree_get_root_node(hal);
2900 
2901         /* Ignore, if we are already root */
2902         if (root == &hal->topology_tree[hal_node_num]) {
2903                 TNF_PROBE_2_DEBUG(s1394_cmstr_capable_hal,
2904                     S1394_TNF_SL_HOTPLUG_STACK, "", tnf_int,
2905                     node_num, hal_node_num, tnf_int, ret, 1);
2906                 return (1);
2907         }
2908 
2909         /*
2910          * We want to pick a new root if link is off or we don't have
2911          * valid config rom
2912          */
2913         if (LINK_ACTIVE(root) == B_FALSE || root->cfgrom == NULL ||
2914             CFGROM_BIB_READ(root) == 0) {
2915 
2916                 TNF_PROBE_4_DEBUG(s1394_cmstr_capable_not_hal,
2917                     S1394_TNF_SL_HOTPLUG_STACK, "", tnf_int,
2918                     root, root->node_num, tnf_int, link_active,
2919                     LINK_ACTIVE(root), tnf_opaque, cfgrom, root->cfgrom,
2920                     tnf_int, bib, CFGROM_BIB_READ(root));
2921 
2922                 return (0);
2923         }
2924 
2925         /* Check the Cycle Master bit in the Bus Info Block */
2926         cycle_master_capable = root->cfgrom[IEEE1212_NODE_CAP_QUAD] &
2927             IEEE1394_BIB_CMC_MASK;
2928 
2929         if (cycle_master_capable) {
2930                 TNF_PROBE_1_DEBUG(s1394_cmstr_capable_root,
2931                     S1394_TNF_SL_HOTPLUG_STACK, "", tnf_int,
2932                     root, root->node_num);
2933                 return (1);
2934         } else {
2935                 TNF_PROBE_1(s1394_cmstr_not_capable_root,
2936                     S1394_TNF_SL_HOTPLUG_STACK, "", tnf_int,
2937                     root, root->node_num);
2938                 return (0);
2939         }
2940 }
2941 
2942 /*
2943  * s1394_do_phy_config_pkt()
2944  *    is called by s1394_do_bus_mgr_processing() to setup and send out
2945  *    a PHY configuration packet onto the 1394 bus.  Depending on the
2946  *    values in IRM_flags, the gap_count and root_holdoff bits on the
2947  *    bus will be affected by this packet.
2948  *
2949  *    NOTE: we overload DDI_FAILURE return value to mean jump back to
2950  *    the start of bus reset processing.
2951  */
2952 static int
2953 s1394_do_phy_config_pkt(s1394_hal_t *hal, int new_root, int new_gap_cnt,
2954     uint32_t IRM_flags)
2955 {
2956         cmd1394_cmd_t    *cmd;
2957         s1394_cmd_priv_t *s_priv;
2958         h1394_cmd_priv_t *h_priv;
2959         uint32_t         pkt_data = 0;
2960         uint32_t         gap_cnt = 0;
2961         uint32_t         root = 0;
2962         int              ret, result;
2963         uint_t           flags = 0;
2964 
2965         TNF_PROBE_0_DEBUG(s1394_do_phy_config_pkt_enter,
2966             S1394_TNF_SL_HOTPLUG_STACK, "");
2967 
2968         /* Gap count needs to be optimized */
2969         if (IRM_flags & GAP_COUNT) {
2970 
2971                 pkt_data = pkt_data | IEEE1394_PHY_CONFIG_T_BIT_MASK;
2972                 gap_cnt = ((uint32_t)new_gap_cnt) <<
2973                     IEEE1394_PHY_CONFIG_GAP_CNT_SHIFT;
2974                 gap_cnt = gap_cnt & IEEE1394_PHY_CONFIG_GAP_CNT_MASK;
2975                 pkt_data = pkt_data | gap_cnt;
2976 
2977                 (void) HAL_CALL(hal).set_gap_count(hal->halinfo.hal_private,
2978                     (uint_t)new_gap_cnt);
2979         }
2980 
2981         /* Root node needs to be changed */
2982         if (IRM_flags & ROOT_HOLDOFF) {
2983 
2984                 pkt_data = pkt_data | IEEE1394_PHY_CONFIG_R_BIT_MASK;
2985                 root = ((uint32_t)new_root) <<
2986                     IEEE1394_PHY_CONFIG_ROOT_HOLD_SHIFT;
2987                 root = root & IEEE1394_PHY_CONFIG_ROOT_HOLD_MASK;
2988                 pkt_data = pkt_data | root;
2989 
2990                 (void) HAL_CALL(hal).set_root_holdoff_bit(
2991                     hal->halinfo.hal_private);
2992         }
2993 
2994 
2995         if (IRM_flags) {
2996                 if (s1394_alloc_cmd(hal, flags, &cmd) != DDI_SUCCESS) {
2997                         TNF_PROBE_1_DEBUG(s1394_do_phy_config_pkt_error,
2998                             S1394_TNF_SL_HOTPLUG_STACK, "", tnf_string, msg,
2999                             "Unable to allocate PHY config packet");
3000                         TNF_PROBE_0_DEBUG(s1394_do_phy_config_pkt_exit,
3001                             S1394_TNF_SL_HOTPLUG_STACK, "");
3002                         return (0);
3003                 }
3004 
3005                 if (s1394_lock_tree(hal) != DDI_SUCCESS) {
3006                         /* lock tree failure indicates a bus gen change */
3007                         (void) s1394_free_cmd(hal, (cmd1394_cmd_t **)&cmd);
3008                         TNF_PROBE_0_DEBUG(s1394_do_phy_config_pkt_exit,
3009                             S1394_TNF_SL_HOTPLUG_STACK, "");
3010                         return (1);
3011                 }
3012 
3013                 /* Setup the callback routine */
3014                 cmd->completion_callback  = s1394_phy_config_callback;
3015                 cmd->cmd_callback_arg          = (void *)(uintptr_t)IRM_flags;
3016                 cmd->bus_generation    = hal->generation_count;
3017                 cmd->cmd_options       = CMD1394_OVERRIDE_ADDR;
3018                 cmd->cmd_type                  = CMD1394_ASYNCH_WR_QUAD;
3019                 cmd->cmd_u.q.quadlet_data = pkt_data;
3020 
3021                 /* Get the Services Layer private area */
3022                 s_priv = S1394_GET_CMD_PRIV(cmd);
3023 
3024                 /* Get a pointer to the HAL private struct */
3025                 h_priv = (h1394_cmd_priv_t *)&s_priv->hal_cmd_private;
3026 
3027                 s_priv->sent_by_target       = (s1394_target_t *)NULL;
3028                 s_priv->sent_on_hal  = (s1394_hal_t *)hal;
3029 
3030                 h_priv->bus_generation       = cmd->bus_generation;
3031 
3032                 /* Speed must be IEEE1394_S100 on PHY config packets */
3033                 s_priv->hal_cmd_private.speed = IEEE1394_S100;
3034 
3035                 /* Mark command as being used */
3036                 s_priv->cmd_in_use = B_TRUE;
3037 
3038                 s1394_unlock_tree(hal);
3039 
3040                 /* Put command on the HAL's outstanding request Q */
3041                 s1394_insert_q_asynch_cmd(hal, cmd);
3042 
3043                 ret = HAL_CALL(hal).send_phy_configuration_packet(
3044                     hal->halinfo.hal_private, (cmd1394_cmd_t *)cmd,
3045                     (h1394_cmd_priv_t *)&s_priv->hal_cmd_private, &result);
3046 
3047                 if (ret != DDI_SUCCESS) {
3048                         TNF_PROBE_2_DEBUG(s1394_do_phy_config_pkt_error,
3049                             S1394_TNF_SL_HOTPLUG_STACK, "", tnf_string, msg,
3050                             "Unable to send PHY config packet",
3051                             tnf_int, result, result);
3052 
3053                         (void) s1394_free_cmd(hal, (cmd1394_cmd_t **)&cmd);
3054 
3055                         TNF_PROBE_0_DEBUG(s1394_do_phy_config_pkt_exit,
3056                             S1394_TNF_SL_HOTPLUG_STACK, "");
3057                         return (0);
3058 
3059                 } else {
3060                         /*
3061                          * There will be a bus reset only if GAP_COUNT changed
3062                          */
3063                         if (IRM_flags & GAP_COUNT) {
3064                                 return (1);
3065                         }
3066                 }
3067         }
3068 
3069         TNF_PROBE_0_DEBUG(s1394_do_phy_config_pkt_exit,
3070             S1394_TNF_SL_HOTPLUG_STACK, "");
3071         return (0);
3072 }
3073 
3074 /*
3075  * s1394_phy_config_callback()
3076  *    is the callback called after the PHY configuration packet has been
3077  *    sent out onto the 1394 bus.  Depending on the values in IRM_flags,
3078  *    (specifically if the gap_count has been changed) this routine may
3079  *    initiate a bus reset.
3080  */
3081 static void
3082 s1394_phy_config_callback(cmd1394_cmd_t *cmd)
3083 {
3084         s1394_cmd_priv_t *s_priv;
3085         s1394_hal_t *hal;
3086         uint32_t IRM_flags;
3087 
3088         TNF_PROBE_0_DEBUG(s1394_phy_config_callback_enter,
3089             S1394_TNF_SL_HOTPLUG_STACK, "");
3090 
3091         /* Get the Services Layer private area */
3092         s_priv = S1394_GET_CMD_PRIV(cmd);
3093 
3094         hal = (s1394_hal_t *)s_priv->sent_on_hal;
3095 
3096         IRM_flags = (uint32_t)(uintptr_t)cmd->cmd_callback_arg;
3097 
3098         if (cmd->cmd_result != CMD1394_CMDSUCCESS) {
3099                 TNF_PROBE_2_DEBUG(s1394_do_phy_config_pkt_error,
3100                     S1394_TNF_SL_HOTPLUG_STACK, "", tnf_string, msg,
3101                     "Error sending PHY config packet",
3102                     tnf_int, result, cmd->cmd_result);
3103                 (void) s1394_free_cmd(hal, &cmd);
3104         } else {
3105                 (void) s1394_free_cmd(hal, &cmd);
3106 
3107                 /* Only need a bus reset if we changed GAP_COUNT */
3108                 if (IRM_flags & GAP_COUNT) {
3109                         s1394_initiate_hal_reset(hal, NON_CRITICAL);
3110                 }
3111         }
3112 
3113         TNF_PROBE_0_DEBUG(s1394_phy_config_callback_exit,
3114             S1394_TNF_SL_HOTPLUG_STACK, "");
3115 }
3116 
3117 /*
3118  * s1394_lock_tree()
3119  *    Attempts to lock the topology tree. Returns DDI_FAILURE if generations
3120  *    changed or if the services layer signals the bus reset thread to go
3121  *    away. Otherwise, returns DDI_SUCCESS.
3122  */
3123 int
3124 s1394_lock_tree(s1394_hal_t *hal)
3125 {
3126         int     circular;
3127 
3128         ASSERT(MUTEX_NOT_HELD(&hal->br_thread_mutex));
3129         ASSERT(MUTEX_NOT_HELD(&hal->topology_tree_mutex));
3130 
3131         TNF_PROBE_0_DEBUG(s1394_lock_tree_enter, S1394_TNF_SL_HOTPLUG_STACK,
3132             "");
3133 
3134         mutex_enter(&hal->br_thread_mutex);
3135         ndi_devi_enter(hal->halinfo.dip, &circular);
3136         mutex_enter(&hal->topology_tree_mutex);
3137 
3138         if ((hal->br_thread_ev_type & BR_THR_GO_AWAY) != 0) {
3139                 TNF_PROBE_2(s1394_lock_tree_go_away,
3140                     S1394_TNF_SL_HOTPLUG_STACK, "",
3141                     tnf_int, hal_generation, hal->generation_count,
3142                     tnf_int, br_thread_gen, hal->br_cfgrom_read_gen);
3143                 TNF_PROBE_0_DEBUG(s1394_lock_tree_exit,
3144                     S1394_TNF_SL_HOTPLUG_STACK, "");
3145                 mutex_exit(&hal->br_thread_mutex);
3146                 mutex_exit(&hal->topology_tree_mutex);
3147                 ndi_devi_exit(hal->halinfo.dip, circular);
3148                 return (DDI_FAILURE);
3149         } else if (hal->br_cfgrom_read_gen != hal->generation_count) {
3150                 TNF_PROBE_2(s1394_lock_tree_gen_changed,
3151                     S1394_TNF_SL_HOTPLUG_STACK, "",
3152                     tnf_int, hal_generation, hal->generation_count,
3153                     tnf_int, br_thread_gen, hal->br_cfgrom_read_gen);
3154 
3155                 TNF_PROBE_0_DEBUG(s1394_lock_tree_exit,
3156                     S1394_TNF_SL_HOTPLUG_STACK, "");
3157                 mutex_exit(&hal->br_thread_mutex);
3158                 mutex_exit(&hal->topology_tree_mutex);
3159                 ndi_devi_exit(hal->halinfo.dip, circular);
3160                 return (DDI_FAILURE);
3161         }
3162 
3163         mutex_exit(&hal->br_thread_mutex);
3164 
3165         TNF_PROBE_0_DEBUG(s1394_lock_tree_exit, S1394_TNF_SL_HOTPLUG_STACK, "");
3166 
3167         return (DDI_SUCCESS);
3168 }
3169 
3170 /*
3171  * s1394_unlock_tree()
3172  *    Unlocks the topology tree
3173  */
3174 void
3175 s1394_unlock_tree(s1394_hal_t *hal)
3176 {
3177         TNF_PROBE_0_DEBUG(s1394_unlock_tree_enter, S1394_TNF_SL_HOTPLUG_STACK,
3178             "");
3179 
3180         ASSERT(MUTEX_HELD(&hal->topology_tree_mutex));
3181         mutex_exit(&hal->topology_tree_mutex);
3182         ndi_devi_exit(hal->halinfo.dip, 0);
3183 
3184         TNF_PROBE_0_DEBUG(s1394_unlock_tree_exit, S1394_TNF_SL_HOTPLUG_STACK,
3185             "");
3186 }
3187 
3188 /*
3189  * s1394_calc_next_quad()
3190  *    figures out the next quadlet to read. This maintains a stack of
3191  *    directories in the node. When the first quad of a directory (the
3192  *    first directory would be the root directory) is read, it is pushed on
3193  *    the this stack. When the directory is all read, it scans the directory
3194  *    looking for indirect entries. If any indirect directory entry is found,
3195  *    it is pushed on stack and that directory is read. If we are done dealing
3196  *    with all entries in the current dir, the directory is popped off the
3197  *    stack. If the stack is empty, we are back at the root directory level
3198  *    and essentially read the entire directory hierarchy.
3199  *    Returns 0 is more quads to read, else returns non-zero.
3200  */
3201 static int
3202 s1394_calc_next_quad(s1394_hal_t *hal, s1394_node_t *node, uint32_t quadlet,
3203     uint32_t *nextquadp)
3204 {
3205         uint32_t data, type, key, value, *ptr;
3206 
3207         ASSERT(MUTEX_HELD(&hal->topology_tree_mutex));
3208 
3209         TNF_PROBE_4_DEBUG(s1394_calc_next_quad_enter,
3210             S1394_TNF_SL_HOTPLUG_STACK, "", tnf_uint, node_num, node->node_num,
3211             tnf_uint, quadlet, quadlet, tnf_int, cfgrom_size, node->cfgrom_size,
3212             tnf_uint, hal_gen, hal->generation_count);
3213 
3214         if (((quadlet + 1) >= node->cfgrom_size) ||
3215             (CFGROM_SIZE_IS_CRCSIZE(node) == B_TRUE && (quadlet + 1) >=
3216                 node->cfgrom_valid_size)) {
3217                 TNF_PROBE_0_DEBUG(s1394_calc_next_quad_exit,
3218                     S1394_TNF_SL_HOTPLUG_STACK, "");
3219                 return (1);
3220         }
3221 
3222         if (s1394_turn_off_dir_stack != 0 || CFGROM_DIR_STACK_OFF(node) ==
3223             B_TRUE) {
3224                 quadlet++;
3225                 *nextquadp = quadlet;
3226                 TNF_PROBE_3_DEBUG(s1394_calc_next_quad_exit,
3227                     S1394_TNF_SL_HOTPLUG_STACK, "", tnf_string, msg,
3228                     "dir stack turned off", tnf_uint, quadlet, quadlet,
3229                     tnf_opaque, cfgrom, node->cfgrom);
3230                 return (0);
3231         }
3232 
3233         data = node->cfgrom[quadlet];
3234 
3235         if (quadlet == IEEE1212_ROOT_DIR_QUAD) {
3236                 node->dir_stack_top = -1;
3237                 node->expected_dir_quad = quadlet;
3238                 node->expected_type = IEEE1212_IMMEDIATE_TYPE;
3239         }
3240 
3241         CFGROM_TYPE_KEY_VALUE(data, type, key, value);
3242 
3243         /*
3244          * check to make sure we are looking at a dir. If the config rom
3245          * is broken, then revert to normal scanning of the config rom
3246          */
3247         if (node->expected_dir_quad == quadlet) {
3248                 if (type != 0 || key != 0) {
3249                         TNF_PROBE_3_DEBUG(s1394_calc_next_quad,
3250                             S1394_TNF_SL_HOTPLUG_ERROR, "", tnf_string, msg,
3251                             "bad directory turning off stack", tnf_uint,
3252                             quadlet, quadlet, tnf_uint, data, data);
3253                         SET_CFGROM_DIR_STACK_OFF(node);
3254                         quadlet = IEEE1212_ROOT_DIR_QUAD;
3255                 } else {
3256                         node->cur_dir_start = quadlet;
3257                         node->cur_dir_size = IEEE1212_DIR_LEN(data);
3258                         node->expected_dir_quad = 0;
3259                         /* get the next quad */
3260                         quadlet++;
3261                 }
3262         } else {
3263                 /*
3264                  * If we read all quads in cur dir and the cur dir is not
3265                  * a leaf, scan for offsets (if the directory's CRC checks
3266                  * out OK). If we have a directory or a leaf, we save the
3267                  * current location on the stack and start reading that
3268                  * directory. So, we will end up with a depth first read of
3269                  * the entire config rom. If we are done with the current
3270                  * directory, pop it off the stack and continue the scanning
3271                  * as appropriate.
3272                  */
3273                 if (quadlet == node->cur_dir_start + node->cur_dir_size) {
3274 
3275                         int i, top;
3276                         boolean_t done_with_cur_dir = B_FALSE;
3277 
3278                         if (node->expected_type == IEEE1212_LEAF_TYPE) {
3279                                 node->expected_type = IEEE1212_IMMEDIATE_TYPE;
3280                                 done_with_cur_dir = B_TRUE;
3281                                 TNF_PROBE_2_DEBUG(s1394_calc_next_quad,
3282                                     S1394_TNF_SL_HOTPLUG_STACK, "",
3283                                     tnf_string, msg, "done with a leaf",
3284                                     tnf_uint, quadlet, quadlet);
3285                                 goto donewithcurdir;
3286                         }
3287 
3288                         ptr = &node->cfgrom[node->cur_dir_start];
3289                         CFGROM_TYPE_KEY_VALUE(*ptr, type, key, value);
3290 
3291                         /*
3292                          * If CRC for this directory is invalid, turn off
3293                          * dir stack and start re-reading from root dir.
3294                          * This wastes the work done thus far, but CRC
3295                          * errors in directories should be rather rare.
3296                          * if s1394_crcsz_is_cfgsz is set, then set
3297                          * cfgrom_valid_size to the len specfied as crc len
3298                          * in quadlet 0.
3299                          */
3300                         if (s1394_valid_dir(hal, node, key, ptr) == B_FALSE) {
3301                                 SET_CFGROM_DIR_STACK_OFF(node);
3302                                 if (s1394_crcsz_is_cfgsz != 0) {
3303                                         SET_CFGROM_SIZE_IS_CRCSIZE(node);
3304                                         node->cfgrom_valid_size =
3305                                             ((node->cfgrom[0] >>
3306                                             IEEE1394_CFG_ROM_CRC_LEN_SHIFT) &
3307                                             IEEE1394_CFG_ROM_CRC_LEN_MASK);
3308                                         TNF_PROBE_2(s1394_calc_next_quad,
3309                                             S1394_TNF_SL_HOTPLUG_ERROR, "",
3310                                             tnf_string, msg, "crc sz is cfg sz",
3311                                             tnf_uint, size,
3312                                             node->cfgrom_valid_size);
3313                                 }
3314                                 TNF_PROBE_2_DEBUG(s1394_calc_next_quad_exit,
3315                                     S1394_TNF_SL_HOTPLUG_STACK, "", tnf_string,
3316                                     msg, "crc error", tnf_uint, quadlet,
3317                                     quadlet);
3318                                 *nextquadp = IEEE1212_ROOT_DIR_QUAD;
3319                                 return (0);
3320                         }
3321                         i = node->cur_dir_start + 1;
3322                 rescan:
3323                         for (done_with_cur_dir = B_FALSE; i <=
3324                             node->cur_dir_start + node->cur_dir_size; i++) {
3325                                 data = node->cfgrom[i];
3326                                 CFGROM_TYPE_KEY_VALUE(data, type, key, value);
3327                                 /* read leaf type and directory types only */
3328                                 if (type == IEEE1212_LEAF_TYPE || type ==
3329                                     IEEE1212_DIRECTORY_TYPE) {
3330 
3331                                         /*
3332                                          * push current dir on stack; if the
3333                                          * stack is overflowing, ie, too many
3334                                          * directory level nestings, turn off
3335                                          * dir stack and fall back to serial
3336                                          * scanning, starting at root dir. This
3337                                          * wastes all the work we have done
3338                                          * thus far, but more than 16 levels
3339                                          * of directories is rather odd...
3340                                          */
3341                                         top = ++node->dir_stack_top;
3342                                         if (top == S1394_DIR_STACK_SIZE) {
3343 
3344                                                 TNF_PROBE_2_DEBUG(
3345                                                     s1394_calc_next_quad_exit,
3346                                                     S1394_TNF_SL_HOTPLUG_STACK,
3347                                                     "", tnf_string, msg,
3348                                                     "dir stack overflow",
3349                                                     tnf_uint, quadlet, quadlet);
3350                                                 SET_CFGROM_DIR_STACK_OFF(node);
3351                                                 *nextquadp =
3352                                                     IEEE1212_ROOT_DIR_QUAD;
3353                                                 return (0);
3354                                         }
3355 
3356                                         TNF_PROBE_3_DEBUG(
3357                                             s1394_calc_next_quad,
3358                                             S1394_TNF_SL_HOTPLUG_STACK, "",
3359                                             tnf_string, msg, "push dir stack",
3360                                             tnf_uint, quadlet, quadlet,
3361                                             tnf_int, top, top);
3362 
3363                                         node->dir_stack[top].dir_start =
3364                                             node->cur_dir_start;
3365                                         node->dir_stack[top].dir_size =
3366                                             node->cur_dir_size;
3367                                         node->dir_stack[top].dir_next_quad =
3368                                             i + 1;
3369                                         /* and set the next quadlet to read */
3370                                         quadlet = i + value;
3371                                         node->expected_dir_quad = quadlet;
3372                                         node->expected_type = type;
3373                                         break;
3374                                 }
3375                         }
3376 
3377                 donewithcurdir:
3378 
3379                         if ((i > node->cur_dir_start + node->cur_dir_size) ||
3380                                 done_with_cur_dir == B_TRUE) {
3381 
3382                                 /*
3383                                  * all done with cur dir; pop it off the stack
3384                                  */
3385                                 if (node->dir_stack_top >= 0) {
3386                                         TNF_PROBE_3_DEBUG(
3387                                             s1394_calc_next_quad_exit,
3388                                             S1394_TNF_SL_HOTPLUG_STACK, "",
3389                                             tnf_string, msg, "pop dir stack",
3390                                             tnf_uint, quadlet, quadlet,
3391                                             tnf_int, top, node->dir_stack_top);
3392                                         top = node->dir_stack_top--;
3393                                         node->cur_dir_start =
3394                                             node->dir_stack[top].dir_start;
3395                                         node->cur_dir_size =
3396                                             node->dir_stack[top].dir_size;
3397                                         i = node->dir_stack[top].dir_next_quad;
3398                                         goto rescan;
3399                                 } else {
3400                                         /*
3401                                          * if empty stack, we are at the top
3402                                          * level; declare done.
3403                                          */
3404                                         TNF_PROBE_1_DEBUG(
3405                                             s1394_calc_next_quad_exit,
3406                                             S1394_TNF_SL_HOTPLUG_STACK, "",
3407                                             tnf_string, msg, "all done");
3408                                         return (1);
3409                                 }
3410                         }
3411                 } else {
3412                         /* get the next quadlet */
3413                         quadlet++;
3414                 }
3415         }
3416         *nextquadp = quadlet;
3417 
3418         TNF_PROBE_1_DEBUG(s1394_calc_next_quad_exit, S1394_TNF_SL_HOTPLUG_STACK,
3419             "", tnf_uint, next_quad, quadlet);
3420 
3421         return (0);
3422 }