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