5255 uts shouldn't open-code ISP2
[illumos-gate.git] / usr / src / uts / common / io / 1394 / s1394_dev_disc.c
blobec5c77d48b05df8799090ece659220ac8cd3d8cc
1 /*
2 * CDDL HEADER START
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.
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
20 * CDDL HEADER END
23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
30 * s1394_dev_disc.c
31 * 1394 Services Layer Device Discovery Routines
32 * This file contains the bus reset thread code, bus manager routines and
33 * various routines that are used to implement remote Config ROM reading.
35 * FUTURE:
36 * Rescan the bus if invalid nodes are seen.
37 * Investigate taskq for reading phase2 config rom reads.
38 * If we are reading the entire bus info blk, we should attempt
39 * a block read and fallback to quad reads if this fails.
42 #include <sys/conf.h>
43 #include <sys/sysmacros.h>
44 #include <sys/ddi.h>
45 #include <sys/sunddi.h>
46 #include <sys/cmn_err.h>
47 #include <sys/sunndi.h>
48 #include <sys/modctl.h>
49 #include <sys/ddi_impldefs.h>
50 #include <sys/types.h>
51 #include <sys/kmem.h>
52 #include <sys/kstat.h>
53 #include <sys/varargs.h>
55 #include <sys/tnf_probe.h>
57 #include <sys/1394/t1394.h>
58 #include <sys/1394/s1394.h>
59 #include <sys/1394/h1394.h>
60 #include <sys/1394/ieee1394.h>
61 #include <sys/1394/ieee1212.h>
63 /* hcmd_ret_t */
64 typedef enum {
65 S1394_HCMD_INVALID,
66 S1394_HCMD_NODE_DONE,
67 S1394_HCMD_NODE_EXPECT_MORE,
68 S1394_HCMD_LOCK_FAILED
69 } hcmd_ret_t;
71 #define QUAD_TO_CFGROM_ADDR(b, n, q, addr) { \
72 uint64_t bl = (b); \
73 uint64_t nl = (n); \
74 addr = ((bl) << IEEE1394_ADDR_BUS_ID_SHIFT) | \
75 ((nl) << IEEE1394_ADDR_PHY_ID_SHIFT); \
76 addr += IEEE1394_CONFIG_ROM_ADDR + ((q) << 2); \
79 #define CFGROM_READ_PAUSE(d) \
80 ((s1394_cfgrom_read_delay_ms == 0) ? (void) 0 : \
81 delay(drv_usectohz((d) * 1000)))
83 #define BUMP_CFGROM_READ_DELAY(n) \
84 (n)->cfgrom_read_delay += s1394_cfgrom_read_delay_incr
86 #define CFGROM_GET_READ_DELAY(n, d) \
87 ((d) = (n)->cfgrom_read_delay)
89 #define SETUP_QUAD_READ(n, reset_fails, quadlet, cnt) \
90 { \
91 int i = (reset_fails); \
92 if (i != 0) { \
93 (n)->cfgrom_read_fails = 0; \
94 (n)->cfgrom_read_delay = (uchar_t)s1394_cfgrom_read_delay_ms; \
95 } \
96 (n)->cfgrom_quad_to_read = (quadlet); \
97 (n)->cfgrom_quad_read_cnt = (cnt); \
100 static void s1394_wait_for_events(s1394_hal_t *hal, int firsttime);
102 static int s1394_wait_for_cfgrom_callbacks(s1394_hal_t *hal, uint_t wait_gen,
103 hcmd_ret_t(*handle_cmd_fn)(s1394_hal_t *hal, cmd1394_cmd_t *cmd));
105 static void s1394_flush_cmplq(s1394_hal_t *hal);
107 static void s1394_br_thread_exit(s1394_hal_t *hal);
109 static void s1394_target_bus_reset_notifies(s1394_hal_t *hal,
110 t1394_localinfo_t *localinfo);
112 static int s1394_alloc_cfgrom(s1394_hal_t *hal, s1394_node_t *node,
113 s1394_status_t *status);
115 static int s1394_cfgrom_scan_phase1(s1394_hal_t *hal);
117 static hcmd_ret_t s1394_br_thread_handle_cmd_phase1(s1394_hal_t *hal,
118 cmd1394_cmd_t *cmd);
120 static int s1394_cfgrom_scan_phase2(s1394_hal_t *hal);
122 static hcmd_ret_t s1394_br_thread_handle_cmd_phase2(s1394_hal_t *hal,
123 cmd1394_cmd_t *cmd);
125 static int s1394_read_config_quadlet(s1394_hal_t *hal, cmd1394_cmd_t *cmd,
126 s1394_status_t *status);
128 static void s1394_cfgrom_read_callback(cmd1394_cmd_t *cmd);
130 static void s1394_get_quad_info(cmd1394_cmd_t *cmd, uint32_t *node_num,
131 uint32_t *quadlet, uint32_t *data);
133 static int s1394_match_GUID(s1394_hal_t *hal, s1394_node_t *nnode);
135 static int s1394_match_all_GUIDs(s1394_hal_t *hal);
137 static void s1394_become_bus_mgr(void *arg);
139 static void s1394_become_bus_mgr_callback(cmd1394_cmd_t *cmd);
141 static int s1394_bus_mgr_processing(s1394_hal_t *hal);
143 static int s1394_do_bus_mgr_processing(s1394_hal_t *hal);
145 static void s1394_bus_mgr_timers_stop(s1394_hal_t *hal,
146 timeout_id_t *bus_mgr_query_tid, timeout_id_t *bus_mgr_tid);
148 static void s1394_bus_mgr_timers_start(s1394_hal_t *hal,
149 timeout_id_t *bus_mgr_query_tid, timeout_id_t *bus_mgr_tid);
151 static int s1394_cycle_master_capable(s1394_hal_t *hal);
153 static int s1394_do_phy_config_pkt(s1394_hal_t *hal, int new_root,
154 int new_gap_cnt, uint32_t IRM_flags);
156 static void s1394_phy_config_callback(cmd1394_cmd_t *cmd);
158 static int s1394_calc_next_quad(s1394_hal_t *hal, s1394_node_t *node,
159 uint32_t quadlet, uint32_t *nextquadp);
161 static int s1394_cfgrom_read_retry_cnt = 3; /* 1 + 3 retries */
162 static int s1394_cfgrom_read_delay_ms = 20; /* start with 20ms */
163 static int s1394_cfgrom_read_delay_incr = 10; /* 10ms increments */
164 static int s1394_enable_crc_validation = 0;
165 static int s1394_turn_off_dir_stack = 0;
166 static int s1394_crcsz_is_cfgsz = 0;
167 static int s1394_enable_rio_pass1_workarounds = 0;
170 * s1394_br_thread()
171 * is the bus reset thread. Its sole purpose is to read/reread config roms
172 * as appropriate and do bus reset time things (bus manager processing,
173 * isoch resource reallocation etc.).
175 void
176 s1394_br_thread(s1394_hal_t *hal)
178 TNF_PROBE_0_DEBUG(s1394_br_thread_enter, S1394_TNF_SL_HOTPLUG_STACK,
179 "");
181 ASSERT(MUTEX_NOT_HELD(&hal->topology_tree_mutex));
183 /* Initialize the Bus Mgr timers */
184 hal->bus_mgr_timeout_id = 0;
185 hal->bus_mgr_query_timeout_id = 0;
187 /* Initialize the cmpletion Q */
188 mutex_enter(&hal->br_cmplq_mutex);
189 hal->br_cmplq_head = hal->br_cmplq_tail = NULL;
190 mutex_exit(&hal->br_cmplq_mutex);
192 s1394_wait_for_events(hal, 1);
194 for (;;) {
195 ASSERT(MUTEX_NOT_HELD(&hal->topology_tree_mutex));
197 TNF_PROBE_0_DEBUG(s1394_br_thread_wait,
198 S1394_TNF_SL_HOTPLUG_STACK, "");
200 s1394_wait_for_events(hal, 0);
202 ASSERT(MUTEX_NOT_HELD(&hal->topology_tree_mutex));
204 TNF_PROBE_1_DEBUG(s1394_br_thread_restart,
205 S1394_TNF_SL_HOTPLUG_STACK, "",
206 tnf_int, hal_instance, ddi_get_instance(hal->halinfo.dip));
208 /* stop bus manager timeouts, if needed */
209 s1394_bus_mgr_timers_stop(hal, &hal->bus_mgr_query_timeout_id,
210 &hal->bus_mgr_timeout_id);
212 s1394_flush_cmplq(hal);
214 /* start timers for checking bus manager, if needed */
215 s1394_bus_mgr_timers_start(hal, &hal->bus_mgr_query_timeout_id,
216 &hal->bus_mgr_timeout_id);
218 /* Try to reallocate all isoch resources */
219 s1394_isoch_rsrc_realloc(hal);
221 if (s1394_cfgrom_scan_phase1(hal) != DDI_SUCCESS) {
222 TNF_PROBE_0_DEBUG(br_thread_phase1_restart,
223 S1394_TNF_SL_HOTPLUG_STACK, "");
224 continue;
227 TNF_PROBE_1_DEBUG(s1394_br_thread_phase1_done,
228 S1394_TNF_SL_HOTPLUG_STACK, "",
229 tnf_int, hal_instance, ddi_get_instance(hal->halinfo.dip));
231 if (s1394_bus_mgr_processing(hal) != DDI_SUCCESS) {
232 TNF_PROBE_0_DEBUG(br_thread_bus_mgr_restart,
233 S1394_TNF_SL_HOTPLUG_STACK, "");
234 continue;
237 TNF_PROBE_1_DEBUG(s1394_br_thread_bus_mgr_proc_done,
238 S1394_TNF_SL_HOTPLUG_STACK, "",
239 tnf_int, hal_instance, ddi_get_instance(hal->halinfo.dip));
241 ASSERT(MUTEX_NOT_HELD(&hal->topology_tree_mutex));
243 if (s1394_cfgrom_scan_phase2(hal) != DDI_SUCCESS) {
244 TNF_PROBE_0_DEBUG(br_thread_phase2_restart,
245 S1394_TNF_SL_HOTPLUG_STACK, "");
246 continue;
249 TNF_PROBE_1_DEBUG(s1394_br_thread_done,
250 S1394_TNF_SL_HOTPLUG_STACK, "",
251 tnf_int, hal_instance, ddi_get_instance(hal->halinfo.dip));
253 ASSERT(MUTEX_NOT_HELD(&hal->topology_tree_mutex));
258 * s1394_wait_for_events()
259 * blocks waiting for a cv_signal on the bus reset condition variable.
260 * Used by the bus reset thread for synchronizing with the bus reset/
261 * self id interrupt callback from the hal. Does CPR initialization
262 * first time it is called. If services layer sees a valid self id
263 * buffer, it builds the topology tree and signals the bus reset thread
264 * to read the config roms as appropriate (indicated by BR_THR_CFGROM_SCAN).
265 * If the services layer wishes to kill the bus reset thread, it signals
266 * this by signaling a BR_THR_GO_AWAY event.
268 static void
269 s1394_wait_for_events(s1394_hal_t *hal, int firsttime)
271 uint_t event;
273 TNF_PROBE_0_DEBUG(s1394_wait_for_events_enter,
274 S1394_TNF_SL_HOTPLUG_STACK, "");
276 ASSERT(MUTEX_NOT_HELD(&hal->br_thread_mutex));
277 ASSERT(MUTEX_NOT_HELD(&hal->topology_tree_mutex));
279 if (firsttime)
280 CALLB_CPR_INIT(&hal->hal_cprinfo, &hal->br_thread_mutex,
281 callb_generic_cpr, "s1394_br_thread");
283 /* Check and wait for a BUS RESET */
284 mutex_enter(&hal->br_thread_mutex);
285 while ((event = hal->br_thread_ev_type) == 0) {
286 CALLB_CPR_SAFE_BEGIN(&hal->hal_cprinfo);
287 cv_wait(&hal->br_thread_cv, &hal->br_thread_mutex);
288 CALLB_CPR_SAFE_END(&hal->hal_cprinfo, &hal->br_thread_mutex);
291 if (event & BR_THR_GO_AWAY) {
292 TNF_PROBE_1(s1394_wait_for_events, S1394_TNF_SL_HOTPLUG_STACK,
293 "", tnf_string, msg, "Go away set");
294 s1394_br_thread_exit(hal);
295 TNF_PROBE_0_DEBUG(s1394_wait_for_events_exit,
296 S1394_TNF_SL_HOTPLUG_STACK, "");
297 /*NOTREACHED*/
298 return;
301 if (firsttime) {
302 TNF_PROBE_0_DEBUG(s1394_wait_for_events_exit,
303 S1394_TNF_SL_HOTPLUG_STACK, "");
304 mutex_exit(&hal->br_thread_mutex);
305 return;
308 mutex_enter(&hal->topology_tree_mutex);
309 if (event & BR_THR_CFGROM_SCAN) {
310 TNF_PROBE_2_DEBUG(s1394_wait_for_events_scan,
311 S1394_TNF_SL_HOTPLUG_STACK, "",
312 tnf_int, br_thread_gen, hal->br_cfgrom_read_gen,
313 tnf_int, hal_generation, hal->generation_count);
315 hal->br_cfgrom_read_gen = hal->generation_count;
317 hal->br_thread_ev_type &= ~BR_THR_CFGROM_SCAN;
318 mutex_exit(&hal->topology_tree_mutex);
319 mutex_exit(&hal->br_thread_mutex);
321 TNF_PROBE_0_DEBUG(s1394_wait_for_events_exit,
322 S1394_TNF_SL_HOTPLUG_STACK, "");
326 * s1394_wait_for_cfgrom_callbacks()
327 * Waits for completed config rom reads. Takes each completion off the
328 * completion queue and passes it to the "completion handler" function
329 * that was passed in as an argument. Further processing of the completion
330 * queue depends on the return status of the completion handler. If there
331 * is a bus reset while waiting for completions or if the services layer
332 * signals BR_THR_GO_AWAY, quits waiting for completions and returns
333 * non-zero. Also returns non-zero if completion handler returns
334 * S1394_HCMD_LOCK_FAILED. Returns 0 if config roms for all nodes have
335 * been dealt with.
337 static int
338 s1394_wait_for_cfgrom_callbacks(s1394_hal_t *hal, uint_t wait_gen,
339 hcmd_ret_t(*handle_cmd_fn)(s1394_hal_t *hal, cmd1394_cmd_t *cmd))
341 cmd1394_cmd_t *cmd;
342 s1394_cmd_priv_t *s_priv;
343 int ret, done = 0;
344 hcmd_ret_t cmdret;
346 ASSERT(MUTEX_NOT_HELD(&hal->topology_tree_mutex));
348 TNF_PROBE_1_DEBUG(s1394_wait_for_cfgrom_callbacks_enter,
349 S1394_TNF_SL_HOTPLUG_STACK, "", tnf_uint, wait_gen, wait_gen);
351 ret = DDI_SUCCESS;
353 while (!done) {
354 mutex_enter(&hal->br_cmplq_mutex);
355 mutex_enter(&hal->topology_tree_mutex);
356 while (wait_gen == hal->generation_count &&
357 (hal->br_thread_ev_type & BR_THR_GO_AWAY) == 0 &&
358 hal->br_cmplq_head == NULL) {
359 mutex_exit(&hal->topology_tree_mutex);
360 cv_wait(&hal->br_cmplq_cv, &hal->br_cmplq_mutex);
361 mutex_enter(&hal->topology_tree_mutex);
363 ASSERT(MUTEX_HELD(&hal->topology_tree_mutex));
364 if (wait_gen != hal->generation_count ||
365 (hal->br_thread_ev_type & BR_THR_GO_AWAY) != 0) {
367 #if !defined(NPROBE) && defined(TNF_DEBUG)
368 int hal_gen = hal->generation_count;
369 #endif
371 mutex_exit(&hal->topology_tree_mutex);
372 mutex_exit(&hal->br_cmplq_mutex);
373 s1394_flush_cmplq(hal);
374 TNF_PROBE_1_DEBUG(s1394_wait_for_cfgrom_callbacks_exit,
375 S1394_TNF_SL_HOTPLUG_STACK, "", tnf_int, hal_gen,
376 hal_gen);
377 return (DDI_FAILURE);
379 mutex_exit(&hal->topology_tree_mutex);
381 if ((cmd = hal->br_cmplq_head) != NULL) {
382 s_priv = S1394_GET_CMD_PRIV(cmd);
384 hal->br_cmplq_head = s_priv->cmd_priv_next;
386 if (cmd == hal->br_cmplq_tail)
387 hal->br_cmplq_tail = NULL;
388 mutex_exit(&hal->br_cmplq_mutex);
390 if (cmd != NULL) {
391 if (cmd->bus_generation != wait_gen) {
392 TNF_PROBE_3(
393 s1394_wait_for_cfgrom_callbacks,
394 S1394_TNF_SL_HOTPLUG_STACK, "",
395 tnf_string, msg, "command gen != wait_gen",
396 tnf_uint, cmd_gen, cmd->bus_generation,
397 tnf_uint, wait_gen, wait_gen);
398 (void) s1394_free_cmd(hal, &cmd);
399 continue;
401 cmdret = (*handle_cmd_fn)(hal, cmd);
402 TNF_PROBE_2_DEBUG(s1394_wait_for_cfgrom_callbacks,
403 S1394_TNF_SL_HOTPLUG_STACK, "",
404 tnf_opaque, cmd, cmd, tnf_int, cmdret, cmdret);
405 ASSERT(cmdret != S1394_HCMD_INVALID);
406 if (cmdret == S1394_HCMD_LOCK_FAILED) {
407 /* flush completion queue */
408 ret = DDI_FAILURE;
409 s1394_flush_cmplq(hal);
410 break;
411 } else if (cmdret == S1394_HCMD_NODE_DONE) {
412 if (--hal->cfgroms_being_read == 0) {
413 /* All done */
414 break;
416 } else {
417 ASSERT(cmdret == S1394_HCMD_NODE_EXPECT_MORE);
418 done = 0;
423 TNF_PROBE_0_DEBUG(s1394_wait_for_cfgrom_callbacks_exit,
424 S1394_TNF_SL_HOTPLUG_STACK, "");
426 return (ret);
430 * s1394_flush_cmplq()
431 * Frees all cmds on the completion queue.
433 static void
434 s1394_flush_cmplq(s1394_hal_t *hal)
436 s1394_cmd_priv_t *s_priv;
437 cmd1394_cmd_t *cmd, *tcmd;
439 ASSERT(MUTEX_NOT_HELD(&hal->topology_tree_mutex));
441 TNF_PROBE_0_DEBUG(s1394_flush_cmplq_enter, S1394_TNF_SL_HOTPLUG_STACK,
442 "");
444 cmd = NULL;
446 do {
447 mutex_enter(&hal->br_cmplq_mutex);
448 cmd = hal->br_cmplq_head;
449 hal->br_cmplq_head = hal->br_cmplq_tail = NULL;
450 mutex_exit(&hal->br_cmplq_mutex);
452 while (cmd != NULL) {
453 s_priv = S1394_GET_CMD_PRIV(cmd);
455 tcmd = s_priv->cmd_priv_next;
456 TNF_PROBE_2_DEBUG(s1394_flush_cmplq,
457 S1394_TNF_SL_HOTPLUG_STACK, "", tnf_opaque, cmd,
458 cmd, tnf_uint, cmd_gen, cmd->bus_generation);
459 (void) s1394_free_cmd(hal, &cmd);
460 cmd = tcmd;
463 mutex_enter(&hal->br_cmplq_mutex);
464 cmd = hal->br_cmplq_head;
465 mutex_exit(&hal->br_cmplq_mutex);
467 } while (cmd != NULL);
469 TNF_PROBE_0_DEBUG(s1394_flush_cmplq_exit, S1394_TNF_SL_HOTPLUG_STACK,
470 "");
475 * s1394_br_thread_exit()
476 * Flushes the completion queue and calls thread_exit() (which effectively
477 * kills the bus reset thread).
479 static void
480 s1394_br_thread_exit(s1394_hal_t *hal)
482 ASSERT(MUTEX_HELD(&hal->br_thread_mutex));
483 ASSERT(MUTEX_NOT_HELD(&hal->topology_tree_mutex));
484 TNF_PROBE_0(s1394_br_thread_exit_enter, S1394_TNF_SL_HOTPLUG_STACK, "");
485 s1394_flush_cmplq(hal);
486 #ifndef __lock_lint
487 CALLB_CPR_EXIT(&hal->hal_cprinfo);
488 #endif
489 hal->br_thread_ev_type &= ~BR_THR_GO_AWAY;
490 thread_exit();
491 /*NOTREACHED*/
492 TNF_PROBE_0(s1394_br_thread_exit_enter, S1394_TNF_SL_HOTPLUG_STACK, "");
496 * s1394_target_bus_reset_notifies()
497 * tells the ndi event framework to invoke any callbacks registered for
498 * "bus reset event".
500 static void
501 s1394_target_bus_reset_notifies(s1394_hal_t *hal, t1394_localinfo_t *localinfo)
503 ddi_eventcookie_t cookie;
505 ASSERT(MUTEX_NOT_HELD(&hal->topology_tree_mutex));
507 TNF_PROBE_2_DEBUG(s1394_target_bus_reset_notifies_enter,
508 S1394_TNF_SL_HOTPLUG_STACK, "", tnf_uint, bus_gen,
509 localinfo->bus_generation, tnf_uint, node_id,
510 localinfo->local_nodeID);
512 if (ndi_event_retrieve_cookie(hal->hal_ndi_event_hdl, NULL,
513 DDI_DEVI_BUS_RESET_EVENT, &cookie, NDI_EVENT_NOPASS) ==
514 NDI_SUCCESS) {
515 (void) ndi_event_run_callbacks(hal->hal_ndi_event_hdl, NULL,
516 cookie, localinfo);
518 TNF_PROBE_0_DEBUG(s1394_target_bus_reset_notifies_exit,
519 S1394_TNF_SL_HOTPLUG_STACK, "");
523 * s1394_alloc_cfgrom()
524 * Allocates config rom for the node. Sets CFGROM_NEW_ALLOC bit in the
525 * node cfgrom state. Drops topology_tree_mutex around the calls to
526 * kmem_zalloc(). If re-locking fails, returns DDI_FAILURE, else returns
527 * DDI_SUCCESS.
529 static int
530 s1394_alloc_cfgrom(s1394_hal_t *hal, s1394_node_t *node, s1394_status_t *status)
532 uint32_t *cfgrom;
534 ASSERT(MUTEX_HELD(&hal->topology_tree_mutex));
536 TNF_PROBE_0_DEBUG(s1394_alloc_cfgrom_enter, S1394_TNF_SL_HOTPLUG_STACK,
537 "");
539 *status = S1394_NOSTATUS;
542 * if cfgrom is non-NULL, this has to be generation changed
543 * case (where we allocate cfgrom again to reread the cfgrom)
545 ASSERT(node->cfgrom == NULL || (node->cfgrom != NULL &&
546 CFGROM_GEN_CHANGED(node) == B_TRUE));
549 * if node matched, either cfgrom has to be NULL or link should be
550 * off in the last matched node or config rom generations changed.
552 ASSERT(NODE_MATCHED(node) == B_FALSE || (NODE_MATCHED(node) == B_TRUE &&
553 (node->cfgrom == NULL || LINK_ACTIVE(node->old_node) == B_FALSE) ||
554 CFGROM_GEN_CHANGED(node) == B_TRUE));
556 s1394_unlock_tree(hal);
557 cfgrom = (uint32_t *)kmem_zalloc(IEEE1394_CONFIG_ROM_SZ, KM_SLEEP);
558 if (s1394_lock_tree(hal) != DDI_SUCCESS) {
559 kmem_free(cfgrom, IEEE1394_CONFIG_ROM_SZ);
560 *status |= S1394_LOCK_FAILED;
561 TNF_PROBE_1(s1394_alloc_cfgrom, S1394_TNF_SL_HOTPLUG_ERROR,
562 "", tnf_string, msg, "cannot relock the tree");
563 TNF_PROBE_0_DEBUG(s1394_alloc_cfgrom_exit,
564 S1394_TNF_SL_HOTPLUG_STACK, "");
565 return (DDI_FAILURE);
567 node->cfgrom = cfgrom;
568 node->cfgrom_size = IEEE1394_CONFIG_ROM_QUAD_SZ;
569 SET_CFGROM_NEW_ALLOC(node);
570 ASSERT(MUTEX_HELD(&hal->topology_tree_mutex));
571 TNF_PROBE_3(s1394_alloc_cfgrom_exit, S1394_TNF_SL_HOTPLUG_STACK,
572 "cfgrom alloc", tnf_uint, hal_gen, hal->generation_count, tnf_uint,
573 node_num, node->node_num, tnf_opaque, cfgrom, cfgrom);
574 return (DDI_SUCCESS);
578 * s1394_free_cfgrom()
579 * Marks the config rom invalid and frees up the config based on otpions.
581 void
582 s1394_free_cfgrom(s1394_hal_t *hal, s1394_node_t *node,
583 s1394_free_cfgrom_t options)
585 ASSERT(MUTEX_HELD(&hal->topology_tree_mutex));
586 ASSERT(node->cfgrom != NULL);
588 TNF_PROBE_0_DEBUG(s1394_free_cfgrom_enter, S1394_TNF_SL_HOTPLUG_STACK,
589 "");
591 if (options == S1394_FREE_CFGROM_BOTH) {
593 * free in both old and new trees; will be called with
594 * new node.
596 s1394_node_t *onode = node->old_node;
598 if (NODE_MATCHED(node) == B_TRUE && onode->cfgrom != NULL)
599 ASSERT(onode->cfgrom == node->cfgrom);
601 TNF_PROBE_4(s1394_free_cfgrom_both,
602 S1394_TNF_SL_HOTPLUG_STACK, "cfgrom free", tnf_uint,
603 hal_gen, hal->generation_count, tnf_int, node_num,
604 node->node_num, tnf_opaque, old_cfgrom, onode->cfgrom,
605 tnf_opaque, cfgrom, node->cfgrom);
607 if (onode != NULL && onode->cfgrom != NULL && onode->cfgrom !=
608 node->cfgrom)
609 kmem_free(onode->cfgrom, IEEE1394_CONFIG_ROM_SZ);
611 kmem_free(node->cfgrom, IEEE1394_CONFIG_ROM_SZ);
612 onode->cfgrom = NULL;
613 node->cfgrom = NULL;
615 CLEAR_CFGROM_STATE(onode);
616 CLEAR_CFGROM_STATE(node);
618 } else if (options == S1394_FREE_CFGROM_NEW) {
620 TNF_PROBE_2(s1394_free_cfgrom_new,
621 S1394_TNF_SL_HOTPLUG_STACK, "cfgrom free",
622 tnf_int, node_num, node->node_num,
623 tnf_opaque, cfgrom, node->cfgrom);
625 ASSERT(CFGROM_NEW_ALLOC(node) == B_TRUE);
626 kmem_free(node->cfgrom, IEEE1394_CONFIG_ROM_SZ);
627 CLEAR_CFGROM_NEW_ALLOC(node);
628 node->cfgrom = NULL;
629 CLEAR_CFGROM_STATE(node);
631 } else if (options == S1394_FREE_CFGROM_OLD) {
633 /* freeing in old tree */
634 TNF_PROBE_2_DEBUG(s1394_free_cfgrom_old,
635 S1394_TNF_SL_HOTPLUG_STACK, "cfgrom free",
636 tnf_int, node_num, node->node_num,
637 tnf_opaque, cfgrom, node->cfgrom);
638 kmem_free(node->cfgrom, IEEE1394_CONFIG_ROM_SZ);
639 node->cfgrom = NULL;
640 CLEAR_CFGROM_STATE(node);
643 TNF_PROBE_0_DEBUG(s1394_free_cfgrom_exit, S1394_TNF_SL_HOTPLUG_STACK,
644 "");
648 * s1394_copy_cfgrom()
649 * Copies config rom info from "from" node to "to" node. Clears
650 * CFGROM_NEW_ALLOC bit in cfgrom state in bothe nodes. (CFGROM_NEW_ALLOC
651 * acts as a reference count. If set, only the node in the current tree
652 * has a pointer to it; if clear, both the node in the current tree as
653 * well as the corresponding node in the old tree point to the same memory).
655 void
656 s1394_copy_cfgrom(s1394_node_t *to, s1394_node_t *from)
658 TNF_PROBE_3_DEBUG(s1394_copy_cfgrom_enter, S1394_TNF_SL_HOTPLUG_STACK,
659 "", tnf_int, to_node, to->node_num, tnf_int,
660 from_node, from->node_num, tnf_opaque, from_cfgrom, from->cfgrom);
662 ASSERT(to->cfgrom == NULL);
664 to->cfgrom = from->cfgrom;
665 to->cfgrom_state = from->cfgrom_state;
666 to->cfgrom_valid_size = from->cfgrom_valid_size;
667 to->cfgrom_size = from->cfgrom_size;
668 to->node_state = from->node_state;
670 bcopy(from->dir_stack, to->dir_stack,
671 offsetof(s1394_node_t, cfgrom_quad_to_read) -
672 offsetof(s1394_node_t, dir_stack));
674 to->cfgrom_quad_to_read = from->cfgrom_quad_to_read;
676 CLEAR_CFGROM_NEW_ALLOC(to);
677 CLEAR_CFGROM_NEW_ALLOC(from);
680 * old link off, new link on => handled in s1394_cfgrom_scan_phase1
681 * old link on, new link off => handled in s1394_process_old_tree
683 if (LINK_ACTIVE(from) == B_FALSE) {
685 * if last time around, link was off, there wouldn't
686 * have been config rom allocated.
688 ASSERT(from->cfgrom == NULL);
689 TNF_PROBE_0_DEBUG(s1394_copy_cfgrom_exit,
690 S1394_TNF_SL_HOTPLUG_STACK, "");
691 return;
692 } else {
693 s1394_selfid_pkt_t *selfid_pkt = to->selfid_packet;
695 if (IEEE1394_SELFID_ISLINKON(selfid_pkt))
696 SET_LINK_ACTIVE(to);
699 TNF_PROBE_0_DEBUG(s1394_copy_cfgrom_exit,
700 S1394_TNF_SL_HOTPLUG_STACK, "");
704 * s1394_read_bus_info_blk()
705 * Attempts to kick off reading IEEE1212_NODE_CAP_QUAD quad or quad 0.
706 * Increments cfgroms_being_read by 1. Returns DDI_SUCCESS command was
707 * issued, else sets status to the failure reason and returns DDI_FAILURE.
709 static int
710 s1394_read_bus_info_blk(s1394_hal_t *hal, s1394_node_t *node,
711 s1394_status_t *status)
713 uint32_t quadlet;
714 cmd1394_cmd_t *cmd;
715 uchar_t node_num;
717 ASSERT(MUTEX_HELD(&hal->topology_tree_mutex));
718 ASSERT(LINK_ACTIVE(node) == B_TRUE);
720 node_num = node->node_num;
722 TNF_PROBE_2_DEBUG(s1394_read_bus_info_blk_enter,
723 S1394_TNF_SL_HOTPLUG_STACK, "", tnf_uint, hal_gen,
724 hal->generation_count, tnf_int, node_num, node_num);
727 * drop the topology lock around command allocation. Return failure
728 * if either command allocation fails or cannot reacquire the lock
730 s1394_unlock_tree(hal);
731 *status = S1394_NOSTATUS;
733 if (s1394_alloc_cmd(hal, 0, &cmd) != DDI_SUCCESS) {
734 TNF_PROBE_1(s1394_read_bus_info_blk, S1394_TNF_SL_HOTPLUG_ERROR,
735 "", tnf_string, msg, "command allocation failed");
736 *status |= S1394_CMD_ALLOC_FAILED;
738 if (s1394_lock_tree(hal) != DDI_SUCCESS) {
739 *status |= S1394_LOCK_FAILED;
740 TNF_PROBE_1(s1394_read_bus_info_blk, S1394_TNF_SL_HOTPLUG_ERROR,
741 "", tnf_string, msg, "unable to relock the tree");
742 /* free the cmd allocated above */
743 if (((*status) & S1394_CMD_ALLOC_FAILED) != 0)
744 (void) s1394_free_cmd(hal, (cmd1394_cmd_t **)&cmd);
746 if (((*status) & (S1394_CMD_ALLOC_FAILED | S1394_LOCK_FAILED)) != 0) {
747 TNF_PROBE_0_DEBUG(s1394_read_bus_info_blk_exit,
748 S1394_TNF_SL_HOTPLUG_STACK, "");
749 return (DDI_FAILURE);
752 /* allocate cfgrom if needed */
753 if (node->cfgrom == NULL && s1394_alloc_cfgrom(hal, node, status) !=
754 DDI_SUCCESS) {
755 ASSERT(((*status) & S1394_LOCK_FAILED) != 0);
756 (void) s1394_free_cmd(hal, (cmd1394_cmd_t **)&cmd);
757 ASSERT(MUTEX_NOT_HELD(&hal->topology_tree_mutex));
758 TNF_PROBE_1(s1394_read_bus_info_blk, S1394_TNF_SL_HOTPLUG_ERROR,
759 "", tnf_string, msg, "config rom allocation failed");
760 TNF_PROBE_0_DEBUG(s1394_read_bus_info_blk_exit,
761 S1394_TNF_SL_HOTPLUG_STACK, "");
762 return (DDI_FAILURE);
766 * if this is a matched node, read quad 2 (node capabilities) to
767 * see if the generation count changed.
769 quadlet = CFGROM_BIB_READ(node) ? IEEE1212_NODE_CAP_QUAD : 0;
772 * read bus info block at 100Mbit. This will help us with the cases
773 * where LINK is slower than PHY; s1394 uses PHY speed till speed map
774 * is updated.
776 cmd->completion_callback = s1394_cfgrom_read_callback;
777 cmd->bus_generation = hal->generation_count;
778 cmd->cmd_options = (CMD1394_CANCEL_ON_BUS_RESET |
779 CMD1394_OVERRIDE_ADDR | CMD1394_OVERRIDE_SPEED);
780 cmd->cmd_speed = IEEE1394_S100;
781 cmd->cmd_type = CMD1394_ASYNCH_RD_QUAD;
783 QUAD_TO_CFGROM_ADDR(IEEE1394_LOCAL_BUS, node_num,
784 quadlet, cmd->cmd_addr);
786 TNF_PROBE_3_DEBUG(s1394_read_bus_info_blk,
787 S1394_TNF_SL_HOTPLUG_STACK, "", tnf_uint, hal_gen,
788 hal->generation_count, tnf_int, node_num, node_num, tnf_uint,
789 quadlet, quadlet);
791 TNF_PROBE_5_DEBUG(s1394_read_bus_info_blk,
792 S1394_TNF_SL_HOTPLUG_STACK, "", tnf_int,
793 node_num, node_num, tnf_int, parsed, CFGROM_PARSED(node), tnf_int,
794 matched, NODE_MATCHED(node), tnf_int, visited,
795 NODE_VISITED(node), tnf_int, generation_changed,
796 CFGROM_GEN_CHANGED(node));
798 SETUP_QUAD_READ(node, 1, quadlet, 1);
799 if (s1394_read_config_quadlet(hal, cmd, status) != DDI_SUCCESS) {
800 TNF_PROBE_1(s1394_read_bus_info_blk, S1394_TNF_SL_HOTPLUG_ERROR,
801 "", tnf_string, msg, "Unable to start read");
802 /* free the command if it wasn't handed over to the HAL */
803 if (((*status) & S1394_CMD_INFLIGHT) == 0) {
804 (void) s1394_free_cmd(hal, (cmd1394_cmd_t **)&cmd);
806 if (((*status) & S1394_LOCK_FAILED) != 0) {
807 ASSERT(MUTEX_NOT_HELD(&hal->topology_tree_mutex));
809 TNF_PROBE_0_DEBUG(s1394_read_bus_info_blk_exit,
810 S1394_TNF_SL_HOTPLUG_STACK, "");
811 return (DDI_FAILURE);
814 hal->cfgroms_being_read++;
815 ASSERT(MUTEX_HELD(&hal->topology_tree_mutex));
817 TNF_PROBE_1_DEBUG(s1394_read_bus_info_blk_exit,
818 S1394_TNF_SL_HOTPLUG_STACK, "", tnf_int, cfgrom_read_cnt,
819 hal->cfgroms_being_read);
821 return (DDI_SUCCESS);
825 * s1394_read_rest_of_cfgrom()
826 * Attempts to start reading node->cfgrom_quad_to_read quadlet. Increments
827 * cfgroms_being_read by 1 and returns DDI_SUCCESS if command was issued,
828 * else sets status to the failure reason and returns DDI_FAILURE.
831 s1394_read_rest_of_cfgrom(s1394_hal_t *hal, s1394_node_t *node,
832 s1394_status_t *status)
834 cmd1394_cmd_t *cmd;
835 uchar_t node_num = node->node_num;
837 ASSERT(MUTEX_HELD(&hal->topology_tree_mutex));
838 ASSERT(LINK_ACTIVE(node) == B_TRUE);
840 TNF_PROBE_2_DEBUG(s1394_read_rest_of_cfgrom_enter,
841 S1394_TNF_SL_HOTPLUG_STACK, "", tnf_uint, hal_gen,
842 hal->generation_count, tnf_int, node_num, node_num);
845 * drop the topology lock around command allocation. Return failure
846 * if either command allocation fails or cannot reacquire the lock
848 s1394_unlock_tree(hal);
849 *status = S1394_NOSTATUS;
851 if (s1394_alloc_cmd(hal, 0, &cmd) != DDI_SUCCESS) {
852 *status |= S1394_CMD_ALLOC_FAILED;
853 TNF_PROBE_1(s1394_read_rest_of_cfgrom,
854 S1394_TNF_SL_HOTPLUG_ERROR, "", tnf_string, msg,
855 "command allocation failed");
857 if (s1394_lock_tree(hal) != DDI_SUCCESS) {
858 *status |= S1394_LOCK_FAILED;
859 /* free if we allocated a cmd above */
860 if (((*status) & S1394_CMD_ALLOC_FAILED) == 0)
861 (void) s1394_free_cmd(hal, (cmd1394_cmd_t **)&cmd);
862 TNF_PROBE_1(s1394_read_rest_of_cfgrom,
863 S1394_TNF_SL_HOTPLUG_ERROR, "", tnf_string, msg,
864 "unable to relock the tree");
866 if (((*status) & (S1394_CMD_ALLOC_FAILED | S1394_LOCK_FAILED)) != 0) {
867 TNF_PROBE_0_DEBUG(s1394_read_rest_of_cfgrom_exit,
868 S1394_TNF_SL_HOTPLUG_STACK, "");
869 return (DDI_FAILURE);
872 cmd->completion_callback = s1394_cfgrom_read_callback;
873 cmd->bus_generation = hal->generation_count;
874 cmd->cmd_options = (CMD1394_CANCEL_ON_BUS_RESET |
875 CMD1394_OVERRIDE_ADDR);
876 cmd->cmd_type = CMD1394_ASYNCH_RD_QUAD;
878 TNF_PROBE_2_DEBUG(s1394_read_rest_of_cfgrom, S1394_TNF_SL_HOTPLUG_STACK,
879 "", tnf_uint, hal_gen, hal->generation_count, tnf_int, node_num,
880 node->node_num);
882 QUAD_TO_CFGROM_ADDR(IEEE1394_LOCAL_BUS, node_num,
883 node->cfgrom_quad_to_read, cmd->cmd_addr);
884 SETUP_QUAD_READ(node, 1, node->cfgrom_quad_to_read, 1);
885 if (s1394_read_config_quadlet(hal, cmd, status) != DDI_SUCCESS) {
886 TNF_PROBE_1(s1394_read_rest_of_cfgrom_exit,
887 S1394_TNF_SL_HOTPLUG_ERROR, "", tnf_string, msg,
888 "unable to start read");
889 /* free the command if it wasn't handed over to the HAL */
890 if (((*status) & S1394_CMD_INFLIGHT) == 0) {
891 (void) s1394_free_cmd(hal, (cmd1394_cmd_t **)&cmd);
893 if (((*status) & S1394_LOCK_FAILED) != 0) {
894 ASSERT(MUTEX_NOT_HELD(&hal->topology_tree_mutex));
896 TNF_PROBE_0_DEBUG(s1394_read_rest_of_cfgrom_exit,
897 S1394_TNF_SL_HOTPLUG_STACK, "");
898 return (DDI_FAILURE);
901 hal->cfgroms_being_read++;
902 ASSERT(MUTEX_HELD(&hal->topology_tree_mutex));
904 TNF_PROBE_1_DEBUG(s1394_read_rest_of_cfgrom_exit,
905 S1394_TNF_SL_HOTPLUG_STACK, "", tnf_int, cfgrom_read_cnt,
906 hal->cfgroms_being_read);
908 return (DDI_SUCCESS);
912 * s1394_cfgrom_scan_phase1()
913 * Attempts to read bus info blocks for nodes as needed. Returns DDI_FAILURE
914 * if bus reset generations changed (as indicated by s1394_lock_tree()
915 * return status) or if any of the callees return failure, else returns
916 * DDI_SUCCESS.
918 static int
919 s1394_cfgrom_scan_phase1(s1394_hal_t *hal)
921 uint32_t number_of_nodes;
922 int ret;
923 int node;
924 int wait_in_gen;
925 int wait_for_cbs;
926 uint_t hal_node_num;
927 uint_t hal_node_num_old;
928 s1394_node_t *nnode, *onode;
929 s1394_selfid_pkt_t *selfid_pkt;
930 s1394_status_t status;
932 TNF_PROBE_0_DEBUG(s1394_cfgrom_scan_phase1_enter,
933 S1394_TNF_SL_HOTPLUG_STACK, "");
935 ASSERT(MUTEX_NOT_HELD(&hal->topology_tree_mutex));
937 if (s1394_lock_tree(hal) != DDI_SUCCESS) {
938 TNF_PROBE_0_DEBUG(s1394_cfgrom_scan_phase1_exit,
939 S1394_TNF_SL_HOTPLUG_STACK, "");
940 return (DDI_FAILURE);
942 wait_for_cbs = 0;
943 number_of_nodes = hal->number_of_nodes;
944 hal->cfgroms_being_read = 0;
945 hal_node_num = IEEE1394_NODE_NUM(hal->node_id);
946 hal_node_num_old = IEEE1394_NODE_NUM(hal->old_node_id);
947 s1394_unlock_tree(hal);
949 ret = DDI_SUCCESS;
951 /* Send requests for all new node config ROM 0 */
952 for (node = 0; node < number_of_nodes; node++) {
954 status = S1394_UNKNOWN;
956 if (s1394_lock_tree(hal) != DDI_SUCCESS) {
957 status = S1394_LOCK_FAILED;
958 break;
961 nnode = &hal->topology_tree[node];
962 onode = nnode->old_node;
963 /* if node matched, onode should be non NULL */
964 ASSERT(NODE_MATCHED(nnode) == B_FALSE || (NODE_MATCHED(nnode) ==
965 B_TRUE && onode != NULL));
968 * Read bus info block if it is a brand new node (MATCHED is 0)
969 * or if matched but link was off in previous generations or
970 * or if matched but had invalid cfgrom in last generation
971 * or if matched but config rom generation > 1 (this is to
972 * check if config rom generation changed between bus resets).
974 if ((node != hal_node_num) &&
975 ((NODE_MATCHED(nnode) == B_FALSE) ||
976 (NODE_MATCHED(nnode) == B_TRUE && LINK_ACTIVE(onode) ==
977 B_FALSE) || (NODE_MATCHED(nnode) == B_TRUE &&
978 (onode->cfgrom == NULL || CFGROM_VALID(onode) ==
979 B_FALSE)) || (NODE_MATCHED(nnode) == B_TRUE &&
980 nnode->cfgrom != NULL && CONFIG_ROM_GEN(nnode->cfgrom) >
981 1))) {
983 SET_NODE_VISITED(nnode);
984 selfid_pkt = nnode->selfid_packet;
985 if (IEEE1394_SELFID_ISLINKON(selfid_pkt)) {
987 SET_LINK_ACTIVE(nnode);
989 status = S1394_UNKNOWN;
991 if (s1394_read_bus_info_blk(hal, nnode,
992 &status) != DDI_SUCCESS) {
993 if ((status & S1394_LOCK_FAILED) != 0)
994 break;
995 } else {
996 wait_for_cbs++;
997 wait_in_gen = hal->br_cfgrom_read_gen;
999 } else {
1001 * Special case: if link was active last
1002 * time around, this should be treated as
1003 * node going away.
1005 CLEAR_LINK_ACTIVE(nnode);
1006 if (NODE_MATCHED(nnode) == B_TRUE &&
1007 LINK_ACTIVE(onode) == B_TRUE) {
1008 CLEAR_CFGROM_STATE(nnode);
1009 TNF_PROBE_3(s1394_cfgrom_scan_phase1,
1010 S1394_TNF_SL_HOTPLUG_ERROR,
1011 "", tnf_string, msg,
1012 "link lost power", tnf_int, node,
1013 node, tnf_int, onode,
1014 onode->node_num);
1017 } else {
1018 if (node == hal_node_num) {
1019 onode = &hal->old_tree[hal_node_num_old];
1020 /* Set up the local matched nodes */
1021 if (onode) {
1022 nnode->old_node = onode;
1023 SET_NODE_MATCHED(nnode);
1024 SET_NODE_MATCHED(onode);
1025 s1394_copy_cfgrom(nnode, onode);
1029 s1394_unlock_tree(hal);
1032 ASSERT(MUTEX_NOT_HELD(&hal->topology_tree_mutex));
1034 if ((status & S1394_LOCK_FAILED) != 0) {
1035 TNF_PROBE_1(s1394_cfrom_scan_phase1_exit,
1036 S1394_TNF_SL_HOTPLUG_STACK, "",
1037 tnf_string, msg, "Generations changed");
1038 return (DDI_FAILURE);
1042 * If we started any reads, wait for completion callbacks
1044 if (wait_for_cbs != 0) {
1045 ret = s1394_wait_for_cfgrom_callbacks(hal, wait_in_gen,
1046 s1394_br_thread_handle_cmd_phase1);
1049 ASSERT(MUTEX_NOT_HELD(&hal->topology_tree_mutex));
1051 TNF_PROBE_0_DEBUG(s1394_cfrom_scan_phase1_exit,
1052 S1394_TNF_SL_HOTPLUG_STACK, "");
1054 return (ret);
1058 * s1394_br_thread_handle_cmd_phase1()
1059 * Process the cmd completion for phase 1 config rom reads. If we
1060 * successfully read IEEE1212_NODE_CAP_QUAD quadlet and config rom gen
1061 * did not change, move targets hanging off the old node to the current
1062 * node. If config rom generations change, alloc new config rom and start
1063 * re-reading the new config rom. If all of bus info block is read (as
1064 * required), mark the node as CFGROM_BIB_READ. If config rom read fails
1065 * retry if not too many failures. Topology tree mutex is dropped and
1066 * reacquired in this routine. If reacquiring fails, returns
1067 * S1394_HCMD_LOCK_FAILED. If the entire bus info block is read, returns
1068 * S1394_HCMD_NODE_DONE, else returns S1394_HCMD_NODE_EXPECT_MORE (to
1069 * indicate not done with the node yet).
1071 * If we cannot read any of the quadlets in the bus info block, cfgrom
1072 * is marked invalid in this generation (a side effect of calling
1073 * s1394_free_cfgrom()). We free cfgrom in this routine only if the failure
1074 * is not due to bus generations changing.
1076 static hcmd_ret_t
1077 s1394_br_thread_handle_cmd_phase1(s1394_hal_t *hal, cmd1394_cmd_t *cmd)
1079 s1394_target_t *t;
1080 s1394_node_t *node, *onode;
1081 uint32_t node_num, quadlet, data;
1082 int freecmd, done, locked;
1083 hcmd_ret_t cmdret;
1084 uchar_t readdelay;
1085 s1394_status_t status;
1087 s1394_get_quad_info(cmd, &node_num, &quadlet, &data);
1088 ASSERT(quadlet == 0 || quadlet < IEEE1394_BIB_QUAD_SZ);
1090 TNF_PROBE_0_DEBUG(s1394_br_thread_handle_cmd_phase1_enter,
1091 S1394_TNF_SL_HOTPLUG_STACK, "");
1093 cmdret = S1394_HCMD_NODE_EXPECT_MORE;
1095 locked = 1;
1096 freecmd = 1;
1098 if (s1394_lock_tree(hal) != DDI_SUCCESS) {
1099 TNF_PROBE_1(s1394_br_thread_handle_cmd_phase1,
1100 S1394_TNF_SL_HOTPLUG_STACK, "", tnf_string, msg,
1101 "unable to lock tree");
1102 locked = 0;
1103 goto bail;
1106 node = &hal->topology_tree[node_num];
1108 if (cmd->cmd_result == CMD1394_CMDSUCCESS) {
1110 int reread = 0;
1112 done = 0;
1114 if (quadlet == IEEE1212_NODE_CAP_QUAD &&
1115 CFGROM_BIB_READ(node)) {
1117 int cur_gen = ((data & IEEE1394_BIB_GEN_MASK) >>
1118 IEEE1394_BIB_GEN_SHIFT);
1121 * node->old_node can be NULL if this is a new node &
1122 * we are doing a rescan
1124 onode = node->old_node;
1125 if (CONFIG_ROM_GEN(node->cfgrom) == cur_gen) {
1127 if (CFGROM_PARSED(node) == B_TRUE) {
1128 rw_enter(&hal->target_list_rwlock,
1129 RW_WRITER);
1130 /* Update the target list, if any */
1131 if (onode != NULL &&
1132 (t = onode->target_list) != NULL) {
1133 node->target_list = t;
1134 while (t != NULL) {
1135 t->on_node = node;
1136 t = t->target_sibling;
1139 rw_exit(&hal->target_list_rwlock);
1141 SET_NODE_MATCHED(node);
1142 if (onode)
1143 SET_NODE_MATCHED(onode);
1144 node->cfgrom_quad_to_read =
1145 IEEE1394_BIB_QUAD_SZ;
1146 done++;
1147 } else {
1149 TNF_PROBE_4(s1394_br_thread_handle_cmd_phase1,
1150 S1394_TNF_SL_HOTPLUG_STACK, "", tnf_string,
1151 msg, "config rom generation changed",
1152 tnf_int, node_num, node_num,
1153 tnf_int, cur_gen, cur_gen, tnf_int, old_gen,
1154 CONFIG_ROM_GEN(node->cfgrom));
1156 SET_CFGROM_GEN_CHANGED(node);
1157 if (onode != NULL)
1158 SET_CFGROM_GEN_CHANGED(onode);
1160 * Reset BIB_READ flag and start reading entire
1161 * config rom.
1163 CLEAR_CFGROM_BIB_READ(node);
1164 reread = 1;
1167 * if generations changed, allocate cfgrom for
1168 * the new generation. s1394_match_GUID() will
1169 * free up the cfgrom from the old generation.
1171 if (s1394_alloc_cfgrom(hal, node, &status) !=
1172 DDI_SUCCESS) {
1173 ASSERT((status & S1394_LOCK_FAILED) !=
1175 ASSERT(MUTEX_NOT_HELD(&hal->
1176 topology_tree_mutex));
1177 locked = 0;
1178 /* we failed to relock the tree */
1179 goto bail;
1185 * we end up here if we don't have bus_info_blk for this
1186 * node or if config rom generation changed.
1190 * Pass1 Rio bug workaround. Due to this bug, if we read
1191 * past quadlet 5 of the config rom, the PCI bus gets wedged.
1192 * Avoid the hang by not reading past quadlet 5.
1193 * We identify a remote Rio by the node vendor id part of
1194 * quad 3 (which is == SUNW == S1394_SUNW_OUI (0x80020)).
1196 if (s1394_enable_rio_pass1_workarounds != 0) {
1197 if ((quadlet == 3) && ((data >> 8) == S1394_SUNW_OUI)) {
1198 node->cfgrom_size = IEEE1394_BIB_QUAD_SZ;
1199 node->cfgrom_valid_size = IEEE1394_BIB_QUAD_SZ;
1203 if (!done) {
1205 if (reread)
1206 quadlet = 0;
1207 else
1208 node->cfgrom[quadlet++] = data;
1210 /* if we don't have the entire bus_info_blk... */
1211 if (quadlet < IEEE1394_BIB_QUAD_SZ) {
1213 CFGROM_GET_READ_DELAY(node, readdelay);
1214 SETUP_QUAD_READ(node, 1, quadlet, 1);
1215 s1394_unlock_tree(hal);
1216 CFGROM_READ_PAUSE(readdelay);
1217 /* get next quadlet */
1218 if (s1394_lock_tree(hal) != DDI_SUCCESS) {
1219 TNF_PROBE_3(
1220 s1394_br_thread_handle_cmd_phase1,
1221 S1394_TNF_SL_HOTPLUG_STACK, "",
1222 tnf_string, msg,
1223 "unable to relock tree", tnf_uint,
1224 node_num, node_num, tnf_int,
1225 quad_to_read, quadlet);
1226 locked = 0;
1227 } else if (s1394_read_config_quadlet(hal, cmd,
1228 &status) != DDI_SUCCESS) {
1230 * Failed to get going. If command was
1231 * successfully handed over to the HAL,
1232 * don't free it (it will get freed
1233 * later in the callback).
1235 TNF_PROBE_3(
1236 s1394_br_thread_handle_cmd_phase1,
1237 S1394_TNF_SL_HOTPLUG_STACK, "",
1238 tnf_string, msg,
1239 "unable to read", tnf_uint,
1240 node_num, node_num, tnf_int,
1241 quad_to_read, quadlet);
1242 if ((status & S1394_CMD_INFLIGHT) !=
1243 0) {
1244 freecmd = 0;
1246 if ((status & S1394_LOCK_FAILED) != 0) {
1247 locked = 0;
1248 } else {
1249 if (CFGROM_NEW_ALLOC(node) ==
1250 B_TRUE) {
1251 s1394_free_cfgrom(hal,
1252 node,
1253 S1394_FREE_CFGROM_NEW);
1254 } else {
1255 CLEAR_CFGROM_STATE(
1256 node);
1259 done++;
1260 } else {
1261 freecmd = 0;
1263 } else {
1264 /* got all of bus_info_blk */
1265 SET_CFGROM_BIB_READ(node);
1266 if (node->cfgrom_size == IEEE1394_BIB_QUAD_SZ)
1267 SET_CFGROM_ALL_READ(node);
1268 node->cfgrom_quad_to_read = quadlet;
1269 done++;
1270 TNF_PROBE_3_DEBUG(
1271 s1394_br_thread_handle_cmd_phase1,
1272 S1394_TNF_SL_HOTPLUG_STACK,
1273 "", tnf_string, msg, "read bus info blk",
1274 tnf_int, node_num, node->node_num,
1275 tnf_opaque, cfgrom, node->cfgrom);
1278 } else {
1279 done = 1;
1280 node->cfgrom_read_fails++;
1281 BUMP_CFGROM_READ_DELAY(node);
1283 /* retry if not too many failures */
1284 if (node->cfgrom_read_fails < s1394_cfgrom_read_retry_cnt) {
1285 CFGROM_GET_READ_DELAY(node, readdelay);
1286 SETUP_QUAD_READ(node, 0, quadlet, 1);
1287 s1394_unlock_tree(hal);
1288 CFGROM_READ_PAUSE(readdelay);
1289 if (s1394_lock_tree(hal) != DDI_SUCCESS) {
1290 TNF_PROBE_3(
1291 s1394_br_thread_handle_cmd_phase1,
1292 S1394_TNF_SL_HOTPLUG_ERROR, "",
1293 tnf_string, msg,
1294 "unable to relock tree", tnf_uint,
1295 node_num, node_num, tnf_int,
1296 quad_to_read, quadlet);
1297 locked = 0;
1298 } else if (s1394_read_config_quadlet(hal, cmd,
1299 &status) != DDI_SUCCESS) {
1301 * Failed to get going. If command was
1302 * successfully handed over to the HAL,
1303 * don't free it (it will get freed
1304 * later in the callback).
1306 TNF_PROBE_3(
1307 s1394_br_thread_handle_cmd_phase1,
1308 S1394_TNF_SL_HOTPLUG_ERROR, "", tnf_string,
1309 msg, "unable to re-read", tnf_uint,
1310 node_num, node_num, tnf_int, quad_to_read,
1311 quadlet);
1312 if ((status & S1394_CMD_INFLIGHT) != 0) {
1313 freecmd = 0;
1315 if ((status & S1394_LOCK_FAILED) != 0) {
1316 locked = 0;
1317 } else {
1318 if (CFGROM_NEW_ALLOC(node) == B_TRUE) {
1319 s1394_free_cfgrom(hal, node,
1320 S1394_FREE_CFGROM_NEW);
1321 } else {
1322 CLEAR_CFGROM_STATE(node);
1325 } else {
1326 done = 0;
1327 freecmd = 0;
1329 } else {
1330 TNF_PROBE_4(s1394_br_thread_handle_cmd_phase1,
1331 S1394_TNF_SL_HOTPLUG_STACK, "", tnf_string, msg,
1332 "retries exceeded", tnf_int, node_num, node_num,
1333 tnf_int, quadlet, quadlet, tnf_opaque, cfgrom,
1334 node->cfgrom);
1335 if (CFGROM_NEW_ALLOC(node) == B_TRUE) {
1336 s1394_free_cfgrom(hal, node,
1337 S1394_FREE_CFGROM_NEW);
1338 } else {
1339 CLEAR_CFGROM_STATE(node);
1343 bail:
1344 if (freecmd) {
1345 (void) s1394_free_cmd(hal, &cmd);
1348 if (done) {
1349 cmdret = S1394_HCMD_NODE_DONE;
1350 TNF_PROBE_2_DEBUG(s1394_br_thread_handle_cmd_phase1,
1351 S1394_TNF_SL_HOTPLUG_STACK, "", tnf_string, msg,
1352 "done with node", tnf_int, node_num, node_num);
1355 /* if we are bailing out because locking failed, locked == 0 */
1356 if (locked == 0)
1357 cmdret = S1394_HCMD_LOCK_FAILED;
1358 else
1359 s1394_unlock_tree(hal);
1361 TNF_PROBE_0_DEBUG(s1394_br_thread_handle_cmd_phase1_exit,
1362 S1394_TNF_SL_HOTPLUG_STACK, "");
1364 return (cmdret);
1368 * s1394_cfgrom_scan_phase2()
1369 * Handles phase 2 of bus reset processing. Matches GUIDs between old
1370 * and new topology trees to identify which node moved where. Processes
1371 * the old topology tree (involves offlining any nodes that got unplugged
1372 * between the last generation and the current generation). Updates speed
1373 * map, sets up physical AR request filer and does isoch resource
1374 * realloc failure notification and bus reset notifications. Then resends
1375 * any commands that were issued by targets while the reset was being
1376 * processed. Finally, the current topology tree is processed. This involves
1377 * reading config rom past the bus info block for new nodes and parsing
1378 * the config rom, creating a devinfo for each unit directory found in the
1379 * config rom.
1380 * Returns DDI_FAILURE if there was bus reset during any of the function
1381 * calls (as indicated by lock failures) or if any of the routines callees
1382 * return failure, else returns DDI_SUCCESS.
1384 static int
1385 s1394_cfgrom_scan_phase2(s1394_hal_t *hal)
1387 int ret;
1388 uint_t wait_gen;
1389 int wait_for_cbs = 0;
1390 t1394_localinfo_t localinfo;
1392 ASSERT(MUTEX_NOT_HELD(&hal->topology_tree_mutex));
1394 TNF_PROBE_0_DEBUG(s1394_cfgrom_scan_phase2_enter,
1395 S1394_TNF_SL_HOTPLUG_STACK, "");
1397 if (s1394_lock_tree(hal) != DDI_SUCCESS) {
1398 TNF_PROBE_0_DEBUG(s1394_cfgrom_scan_phase2_exit,
1399 S1394_TNF_SL_HOTPLUG_STACK, "");
1400 return (DDI_FAILURE);
1403 if (s1394_match_all_GUIDs(hal) == DDI_SUCCESS) {
1404 s1394_unlock_tree(hal);
1407 if (s1394_process_old_tree(hal) != DDI_SUCCESS) {
1408 ASSERT(MUTEX_NOT_HELD(&hal->topology_tree_mutex));
1409 TNF_PROBE_1(s1394_cfgrom_scan_phase2,
1410 S1394_TNF_SL_HOTPLUG_ERROR, "", tnf_string, msg,
1411 "non-success return from process_old_tree");
1412 TNF_PROBE_0_DEBUG(s1394_cfgrom_scan_phase2_exit,
1413 S1394_TNF_SL_HOTPLUG_STACK, "");
1414 return (DDI_FAILURE);
1417 if (s1394_lock_tree(hal) != DDI_SUCCESS) {
1418 TNF_PROBE_1(s1394_cfgrom_scan_phase2,
1419 S1394_TNF_SL_HOTPLUG_ERROR, "", tnf_string, msg,
1420 "unable to relock the tree");
1421 TNF_PROBE_0_DEBUG(s1394_cfgrom_scan_phase2_exit,
1422 S1394_TNF_SL_HOTPLUG_STACK, "");
1423 return (DDI_FAILURE);
1426 s1394_update_speed_map_link_speeds(hal);
1427 s1394_unlock_tree(hal);
1429 /* Setup physical AR request filters */
1430 s1394_physical_arreq_setup_all(hal);
1432 /* Notify targets of isoch resource realloc failures */
1433 s1394_isoch_rsrc_realloc_notify(hal);
1435 /* Notify targets of the end of bus reset processing */
1436 if (s1394_lock_tree(hal) != DDI_SUCCESS) {
1437 TNF_PROBE_1(s1394_cfgrom_scan_phase2,
1438 S1394_TNF_SL_HOTPLUG_ERROR, "", tnf_string, msg,
1439 "unable to relock the tree after isoch notify");
1440 TNF_PROBE_0_DEBUG(s1394_cfgrom_scan_phase2_exit,
1441 S1394_TNF_SL_HOTPLUG_STACK, "");
1442 return (DDI_FAILURE);
1445 localinfo.bus_generation = hal->generation_count;
1446 localinfo.local_nodeID = hal->node_id;
1448 s1394_unlock_tree(hal);
1449 s1394_target_bus_reset_notifies(hal, &localinfo);
1450 if (s1394_lock_tree(hal) != DDI_SUCCESS) {
1451 TNF_PROBE_1(s1394_cfgrom_scan_phase2,
1452 S1394_TNF_SL_HOTPLUG_ERROR, "", tnf_string, msg,
1453 "unable to relock the tree after reset notify");
1454 TNF_PROBE_0_DEBUG(s1394_cfgrom_scan_phase2_exit,
1455 S1394_TNF_SL_HOTPLUG_STACK, "");
1456 return (DDI_FAILURE);
1459 /* Set HAL state to normal */
1460 if (hal->disable_requests_bit == 0)
1461 hal->hal_state = S1394_HAL_NORMAL;
1462 else
1463 hal->hal_state = S1394_HAL_DREQ;
1465 s1394_unlock_tree(hal);
1467 /* Flush the pending Q */
1468 s1394_resend_pending_cmds(hal);
1470 if (s1394_process_topology_tree(hal, &wait_for_cbs, &wait_gen)) {
1471 TNF_PROBE_1(s1394_cfgrom_scan_phase2,
1472 S1394_TNF_SL_HOTPLUG_ERROR, "", tnf_string, msg,
1473 "non-success return from process_topology_tree");
1474 TNF_PROBE_0_DEBUG(s1394_cfgrom_scan_phase2_exit,
1475 S1394_TNF_SL_HOTPLUG_STACK, "");
1476 ASSERT(MUTEX_NOT_HELD(&hal->topology_tree_mutex));
1477 return (DDI_FAILURE);
1480 if (s1394_lock_tree(hal) != DDI_SUCCESS) {
1481 TNF_PROBE_1(s1394_cfgrom_scan_phase2,
1482 S1394_TNF_SL_HOTPLUG_ERROR, "", tnf_string, msg,
1483 "unable to relock after processing topology tree");
1484 TNF_PROBE_0_DEBUG(s1394_cfgrom_scan_phase2_exit,
1485 S1394_TNF_SL_HOTPLUG_STACK, "");
1486 return (DDI_FAILURE);
1489 s1394_print_node_info(hal);
1491 s1394_unlock_tree(hal);
1493 ASSERT(MUTEX_NOT_HELD(&hal->topology_tree_mutex));
1495 ret = DDI_SUCCESS;
1498 * If we started any reads, wait for completion callbacks
1500 if (wait_for_cbs != 0) {
1501 ret = s1394_wait_for_cfgrom_callbacks(hal, wait_gen,
1502 s1394_br_thread_handle_cmd_phase2);
1504 TNF_PROBE_2_DEBUG(s1394_cfgrom_scan_phase2,
1505 S1394_TNF_SL_HOTPLUG_STACK, "", tnf_string, msg,
1506 "returned from waiting for cfgrom callbacks", tnf_int, ret,
1507 ret);
1510 ASSERT(MUTEX_NOT_HELD(&hal->topology_tree_mutex));
1512 TNF_PROBE_0_DEBUG(s1394_cfgrom_scan_phase2_exit,
1513 S1394_TNF_SL_HOTPLUG_STACK, "");
1515 return (ret);
1519 * s1394_br_thread_handle_cmd_phase2()
1520 * Process the cmd completion for phase 2 config rom reads. If all the
1521 * needed quads are read, validates the config rom; if config rom is
1522 * invalid (crc failures), frees the config rom, else marks the config rom
1523 * valid and calls s1394_update_devinfo_tree() to parse the config rom.
1524 * If need to get more quadlets, attempts to kick off the read and returns
1525 * S1394_HCMD_NODE_EXPECT_MORE if successfully started the read. If a bus
1526 * reset is seen while in this routine, returns S1394_HCMD_LOCK_FAILED. If
1527 * done with the node (with or withoug crc errors), returns
1528 * S1394_HCMD_NODE_DONE, else returns S1394_HCMD_NODE_EXPECT_MORE (to
1529 * indicate not done with the node yet).
1531 static hcmd_ret_t
1532 s1394_br_thread_handle_cmd_phase2(s1394_hal_t *hal, cmd1394_cmd_t *cmd)
1534 s1394_node_t *node;
1535 uint32_t node_num, quadlet, data;
1536 int update_devinfo, locked, freecmd, done;
1537 hcmd_ret_t cmdret;
1538 uchar_t readdelay;
1539 s1394_status_t status;
1541 TNF_PROBE_0_DEBUG(s1394_br_thread_handle_cmd_phase2_enter,
1542 S1394_TNF_SL_HOTPLUG_STACK, "");
1545 * we end up here if this is a brand new node or if it is a known node
1546 * but the config ROM changed (and triggered a re-read).
1548 s1394_get_quad_info(cmd, &node_num, &quadlet, &data);
1549 ASSERT(quadlet == IEEE1394_BIB_QUAD_SZ || quadlet <
1550 IEEE1394_CONFIG_ROM_QUAD_SZ);
1552 locked = freecmd = done = 1;
1553 cmdret = S1394_HCMD_NODE_EXPECT_MORE;
1555 update_devinfo = 0;
1557 if (s1394_lock_tree(hal) != DDI_SUCCESS) {
1558 TNF_PROBE_3(s1394_br_thread_handle_cmd_phase2,
1559 S1394_TNF_SL_HOTPLUG_ERROR, "", tnf_string, msg,
1560 "unable to lock tree", tnf_int, node_num, node_num,
1561 tnf_int, quadlet, quadlet);
1562 locked = 0;
1563 goto bail;
1566 node = &hal->topology_tree[node_num];
1568 if (cmd->cmd_result == CMD1394_CMDSUCCESS) {
1570 ASSERT(CFGROM_BIB_READ(node) == B_TRUE);
1572 node->cfgrom[quadlet] = data;
1574 if (s1394_calc_next_quad(hal, node, quadlet, &quadlet) != 0) {
1576 * Done with this node. Mark config rom valid and
1577 * update the devinfo tree for this node.
1579 TNF_PROBE_4_DEBUG(s1394_br_thread_handle_cmd_phase2,
1580 S1394_TNF_SL_HOTPLUG_STACK, "", tnf_string, msg,
1581 "all read", tnf_int, node_num, node->node_num,
1582 tnf_opaque, cfgrom, node->cfgrom, tnf_int, quadlet,
1583 quadlet);
1585 node->cfgrom_valid_size = quadlet + 1;
1586 if (s1394_valid_cfgrom(hal, node) == B_TRUE) {
1587 SET_CFGROM_ALL_READ(node);
1588 update_devinfo++;
1589 } else {
1590 s1394_free_cfgrom(hal, node,
1591 S1394_FREE_CFGROM_BOTH);
1593 } else {
1594 CFGROM_GET_READ_DELAY(node, readdelay);
1595 SETUP_QUAD_READ(node, 1, quadlet, 1);
1596 s1394_unlock_tree(hal);
1597 CFGROM_READ_PAUSE(readdelay);
1598 if (s1394_lock_tree(hal) != DDI_SUCCESS) {
1599 locked = 0;
1600 TNF_PROBE_3(s1394_br_thread_handle_cmd_phase2,
1601 S1394_TNF_SL_HOTPLUG_ERROR, "", tnf_string,
1602 msg, "unable to relock the tree",
1603 tnf_int, node_num, node->node_num,
1604 tnf_int, quadlet, quadlet);
1605 } else if (s1394_read_config_quadlet(hal, cmd,
1606 &status) != DDI_SUCCESS) {
1607 /* give up on this guy */
1608 TNF_PROBE_3(s1394_br_thread_handle_cmd_phase2,
1609 S1394_TNF_SL_HOTPLUG_ERROR, "", tnf_string,
1610 msg, "cannot start quadlet read", tnf_int,
1611 node_num, node_num, tnf_int, quadlet,
1612 quadlet);
1614 if ((status & S1394_CMD_INFLIGHT) != 0) {
1615 freecmd = 0;
1617 if ((status & S1394_LOCK_FAILED) != 0) {
1618 locked = 0;
1619 } else {
1620 node->cfgrom_valid_size = quadlet;
1621 if (s1394_valid_cfgrom(hal, node) ==
1622 B_TRUE) {
1623 SET_CFGROM_ALL_READ(node);
1624 update_devinfo++;
1625 } else {
1626 s1394_free_cfgrom(hal, node,
1627 S1394_FREE_CFGROM_BOTH);
1630 } else {
1631 /* successfully started next read */
1632 done = 0;
1633 freecmd = 0;
1636 } else {
1637 node->cfgrom_read_fails++;
1638 BUMP_CFGROM_READ_DELAY(node);
1640 /* retry if not too many failures */
1641 if (node->cfgrom_read_fails < s1394_cfgrom_read_retry_cnt) {
1642 CFGROM_GET_READ_DELAY(node, readdelay);
1643 s1394_unlock_tree(hal);
1644 SETUP_QUAD_READ(node, 0, quadlet, 1);
1645 CFGROM_READ_PAUSE(readdelay);
1646 if (s1394_lock_tree(hal) != DDI_SUCCESS) {
1647 locked = 0;
1648 TNF_PROBE_3(s1394_br_thread_handle_cmd_phase2,
1649 S1394_TNF_SL_HOTPLUG_ERROR, "", tnf_string,
1650 msg, "unable to relock for reread",
1651 tnf_int, node_num, node->node_num,
1652 tnf_int, quadlet, quadlet);
1653 } else if (s1394_read_config_quadlet(hal, cmd,
1654 &status) != DDI_SUCCESS) {
1655 if ((status & S1394_CMD_INFLIGHT) != 0) {
1656 freecmd = 0;
1658 if ((status & S1394_LOCK_FAILED) != 0) {
1659 locked = 0;
1660 } else {
1661 /* stop further reads */
1662 TNF_PROBE_4(
1663 s1394_br_thread_handle_cmd_phase2,
1664 S1394_TNF_SL_HOTPLUG_ERROR, "",
1665 tnf_string, msg, "unable to retry",
1666 tnf_int, node_num, node->node_num,
1667 tnf_int, quadlet, quadlet,
1668 tnf_opaque, cfgrom, node->cfgrom);
1669 node->cfgrom_valid_size = quadlet + 1;
1670 if (s1394_valid_cfgrom(hal, node) ==
1671 B_TRUE) {
1672 SET_CFGROM_ALL_READ(node);
1673 update_devinfo++;
1674 } else {
1675 s1394_free_cfgrom(hal, node,
1676 S1394_FREE_CFGROM_BOTH);
1679 } else {
1680 /* successfully started next read */
1681 done = 0;
1682 freecmd = 0;
1684 } else {
1686 TNF_PROBE_4(s1394_br_thread_handle_cmd_phase2,
1687 S1394_TNF_SL_HOTPLUG_ERROR, "", tnf_string, msg,
1688 "retries exceeded", tnf_int, node_num, node_num,
1689 tnf_int, quadlet, quadlet, tnf_opaque, cfgrom,
1690 node->cfgrom);
1692 node->cfgrom_valid_size = quadlet + 1;
1693 if (s1394_valid_cfgrom(hal, node) == B_TRUE) {
1694 SET_CFGROM_ALL_READ(node);
1695 update_devinfo++;
1696 } else {
1697 s1394_free_cfgrom(hal, node,
1698 S1394_FREE_CFGROM_BOTH);
1702 bail:
1703 if (freecmd) {
1704 (void) s1394_free_cmd(hal, &cmd);
1707 if (done) {
1708 cmdret = S1394_HCMD_NODE_DONE;
1709 TNF_PROBE_2_DEBUG(s1394_br_thread_handle_cmd_phase2,
1710 S1394_TNF_SL_HOTPLUG_STACK, "", tnf_string, msg,
1711 "done with a node", tnf_int, node_num, node_num);
1714 if (update_devinfo) {
1715 ASSERT(locked);
1717 * s1394_update_devinfo_tree() drops and reacquires the
1718 * topology_tree_mutex. If tree lock fails, it returns
1719 * a DDI_FAILURE. Set locked to 0 so in this case so that
1720 * we will return S1394_HCMD_LOCK_FAILED below
1722 if (s1394_update_devinfo_tree(hal, node) != DDI_SUCCESS) {
1723 ASSERT(MUTEX_NOT_HELD(&hal->topology_tree_mutex));
1724 locked = 0;
1725 TNF_PROBE_2(s1394_br_thread_handle_cmd_phase2,
1726 S1394_TNF_SL_HOTPLUG_ERROR, "", tnf_string, msg,
1727 "update devinfo returned failure", tnf_int,
1728 node_num, node_num);
1732 /* if we are bailing out because locking failed, locked == 0 */
1733 if (locked == 0)
1734 cmdret = S1394_HCMD_LOCK_FAILED;
1735 else
1736 s1394_unlock_tree(hal);
1738 TNF_PROBE_1_DEBUG(s1394_br_thread_handle_cmd_phase2_exit,
1739 S1394_TNF_SL_HOTPLUG_STACK, "", tnf_int, cmdret, (int)cmdret);
1741 return (cmdret);
1745 * s1394_read_config_quadlet()
1746 * Starts the reads of a config quadlet (deduced cmd_addr). Returns
1747 * DDI_SUCCESS if the read was started with no errors, else DDI_FAILURE
1748 * is returned, with status indicating the reason for the failure(s).
1750 static int
1751 s1394_read_config_quadlet(s1394_hal_t *hal, cmd1394_cmd_t *cmd,
1752 s1394_status_t *status)
1754 s1394_node_t *node;
1755 int ret, err, node_num, quadlet;
1757 ASSERT(MUTEX_HELD(&hal->topology_tree_mutex));
1758 node_num = IEEE1394_ADDR_PHY_ID(cmd->cmd_addr);
1759 node = &hal->topology_tree[node_num];
1760 quadlet = node->cfgrom_quad_to_read;
1762 TNF_PROBE_2_DEBUG(s1394_read_config_quadlet_enter,
1763 S1394_TNF_SL_HOTPLUG_STACK, "", tnf_uint, node_num, node_num,
1764 tnf_uint, quadlet, quadlet);
1766 /* Calculate the 64-bit address */
1767 QUAD_TO_CFGROM_ADDR(IEEE1394_LOCAL_BUS, node_num, quadlet,
1768 cmd->cmd_addr);
1770 *status = S1394_NOSTATUS;
1772 ret = s1394_setup_asynch_command(hal, NULL, cmd, S1394_CMD_READ, &err);
1774 if (ret != DDI_SUCCESS) {
1775 *status |= S1394_UNKNOWN;
1776 ASSERT(MUTEX_HELD(&hal->topology_tree_mutex));
1777 TNF_PROBE_3(s1394_read_config_quadlet,
1778 S1394_TNF_SL_HOTPLUG_ERROR, "", tnf_string, msg,
1779 "failure from setup asynch command", tnf_uint, node_num,
1780 node_num, tnf_uint, quadlet, quadlet);
1781 TNF_PROBE_0_DEBUG(s1394_read_config_quadlet_exit,
1782 S1394_TNF_SL_HOTPLUG_STACK, "");
1783 return (DDI_FAILURE);
1786 s1394_unlock_tree(hal);
1787 ret = DDI_SUCCESS;
1788 /* Send the command out */
1789 if (s1394_xfer_asynch_command(hal, cmd, &err) == DDI_SUCCESS) {
1790 /* Callers can expect a callback now */
1791 *status |= S1394_CMD_INFLIGHT;
1792 } else {
1794 s1394_cmd_priv_t *s_priv;
1796 TNF_PROBE_3(s1394_read_config_quadlet,
1797 S1394_TNF_SL_HOTPLUG_ERROR, "", tnf_string, msg,
1798 "failure from xfer asynch command",
1799 tnf_int, quadlet, quadlet, tnf_int, node_num, node_num);
1801 /* Remove from queue */
1802 s1394_remove_q_asynch_cmd(hal, cmd);
1803 s_priv = S1394_GET_CMD_PRIV(cmd);
1805 s_priv->cmd_in_use = B_FALSE;
1807 *status |= S1394_XFER_FAILED;
1808 ret = DDI_FAILURE;
1811 if (s1394_lock_tree(hal) != DDI_SUCCESS) {
1812 *status |= S1394_LOCK_FAILED;
1813 ret = DDI_FAILURE;
1814 TNF_PROBE_1(s1394_read_config_quadlet,
1815 S1394_TNF_SL_HOTPLUG_ERROR, "", tnf_string, msg,
1816 "unable to relock the tree");
1819 TNF_PROBE_0_DEBUG(s1394_read_config_quadlet_exit,
1820 S1394_TNF_SL_HOTPLUG_STACK, "");
1822 return (ret);
1826 * s1394_cfgrom_read_callback()
1827 * callback routine for config rom reads. Frees the command if it failed
1828 * due to bus reset else appends the command to the completion queue
1829 * and signals the completion queue cv.
1831 static void
1832 s1394_cfgrom_read_callback(cmd1394_cmd_t *cmd)
1834 cmd1394_cmd_t *tcmd;
1835 s1394_cmd_priv_t *s_priv;
1836 s1394_hal_t *hal;
1838 #if defined(DEBUG)
1839 uint32_t node_num, quadlet, data;
1840 #endif
1842 TNF_PROBE_0_DEBUG(s1394_cfgrom_read_callback_enter,
1843 S1394_TNF_SL_HOTPLUG_STACK, "");
1845 /* Get the Services Layer private area */
1846 s_priv = S1394_GET_CMD_PRIV(cmd);
1848 hal = (s1394_hal_t *)s_priv->sent_on_hal;
1850 #if defined(DEBUG)
1852 s1394_get_quad_info(cmd, &node_num, &quadlet, &data);
1854 TNF_PROBE_5_DEBUG(s1394_cfgrom_read_callback,
1855 S1394_TNF_SL_HOTPLUG_STACK, "", tnf_uint, gen, cmd->bus_generation,
1856 tnf_int, quadlet, quadlet,
1857 tnf_int, node_num, node_num,
1858 tnf_int, data, data, tnf_int, result, cmd->cmd_result);
1859 #endif
1861 if (cmd->cmd_result == CMD1394_EBUSRESET) {
1862 (void) s1394_free_cmd(hal, (cmd1394_cmd_t **)&cmd);
1863 } else {
1864 mutex_enter(&hal->br_cmplq_mutex);
1866 /* Put the command on completion queue */
1867 s_priv->cmd_priv_next = NULL;
1868 if ((tcmd = hal->br_cmplq_tail) != NULL) {
1869 s_priv = S1394_GET_CMD_PRIV(tcmd);
1871 s_priv->cmd_priv_next = cmd;
1874 hal->br_cmplq_tail = cmd;
1876 if (hal->br_cmplq_head == NULL)
1877 hal->br_cmplq_head = cmd;
1879 cv_signal(&hal->br_cmplq_cv);
1880 mutex_exit(&hal->br_cmplq_mutex);
1883 TNF_PROBE_0_DEBUG(s1394_cfgrom_read_callback_exit,
1884 S1394_TNF_SL_HOTPLUG_STACK, "");
1888 * s1394_cfgrom_parse_unit_dir()
1889 * Parses the unit directory passed in and returns reg[2...5] of reg
1890 * property (see 1275 binding for reg property defintion). Currently,
1891 * returns 0 for all the values since none of the existing devices implement
1892 * this and future devices, per P1212r, need a binding change.
1894 /* ARGSUSED */
1895 void
1896 s1394_cfgrom_parse_unit_dir(uint32_t *unit_dir, uint32_t *addr_hi,
1897 uint32_t *addr_lo, uint32_t *size_hi, uint32_t *size_lo)
1899 TNF_PROBE_0_DEBUG(s1394_cfgrom_parse_unit_dir_enter,
1900 S1394_TNF_SL_HOTPLUG_STACK, "");
1901 *addr_hi = *addr_lo = *size_hi = *size_lo = 0;
1902 TNF_PROBE_0_DEBUG(s1394_cfgrom_parse_unit_dir_exit,
1903 S1394_TNF_SL_HOTPLUG_STACK, "");
1907 * s1394_get_quad_info()
1908 * Helper routine that picks apart the various fields of a 1394 address
1910 static void
1911 s1394_get_quad_info(cmd1394_cmd_t *cmd, uint32_t *node_num, uint32_t *quadlet,
1912 uint32_t *data)
1914 uint64_t addr;
1916 TNF_PROBE_0_DEBUG(s1394_get_quad_info_enter,
1917 S1394_TNF_SL_HOTPLUG_STACK, "");
1919 addr = cmd->cmd_addr;
1920 *node_num = IEEE1394_ADDR_PHY_ID(addr);
1921 *quadlet = ((addr & IEEE1394_ADDR_OFFSET_MASK) -
1922 IEEE1394_CONFIG_ROM_ADDR);
1923 *quadlet = (*quadlet >> 2);
1924 *data = T1394_DATA32(cmd->cmd_u.q.quadlet_data);
1926 TNF_PROBE_0_DEBUG(s1394_get_quad_info_exit,
1927 S1394_TNF_SL_HOTPLUG_STACK, "");
1931 * s1394_match_GUID()
1932 * attempts to match nnode (which is in the current topology tree) with
1933 * a node in the old topology tree by comparing GUIDs. If a match is found
1934 * the old_node field of the current node and cur_node field of the old
1935 * are set point to each other. Also, this routine makes both the nodes
1936 * point at the same config rom. If unable to relock the tree, returns
1937 * DDI_FAILURE, else returns DDI_SUCCESS.
1939 static int
1940 s1394_match_GUID(s1394_hal_t *hal, s1394_node_t *nnode)
1942 int old_node;
1943 int gen_changed;
1944 uint32_t old_a, old_b;
1945 uint32_t new_a, new_b;
1946 s1394_node_t *onode;
1947 s1394_target_t *t;
1948 int ret = DDI_SUCCESS;
1950 TNF_PROBE_0_DEBUG(s1394_match_GUID_enter, S1394_TNF_SL_HOTPLUG_STACK,
1951 "");
1953 ASSERT(nnode->cfgrom != NULL);
1954 ASSERT(CFGROM_BIB_READ(nnode));
1956 new_a = nnode->node_guid_hi;
1957 new_b = nnode->node_guid_lo;
1959 for (old_node = 0; old_node < hal->old_number_of_nodes; old_node++) {
1961 onode = &hal->old_tree[old_node];
1962 if (onode->cfgrom == NULL || CFGROM_BIB_READ(onode) == B_FALSE)
1963 continue;
1965 old_a = onode->node_guid_hi;
1966 old_b = onode->node_guid_lo;
1968 if ((old_a == new_a) && (old_b == new_b)) {
1970 if (NODE_MATCHED(onode) == B_TRUE) {
1971 TNF_PROBE_4(s1394_match_GUID_duplicate,
1972 S1394_TNF_SL_HOTPLUG_ERROR, "",
1973 tnf_uint, guid_hi, old_a,
1974 tnf_uint, guid_lo, old_b,
1975 tnf_uint, old_node_num, old_node,
1976 tnf_uint, node_num, nnode->node_num);
1977 cmn_err(CE_NOTE, "!Duplicate GUIDs: %08x%08x",
1978 old_a, old_b);
1979 /* offline the new node that last matched */
1980 ret = s1394_offline_node(hal, onode->cur_node);
1981 /* and make the current new node invalid */
1982 ASSERT(CFGROM_NEW_ALLOC(nnode) == B_TRUE);
1983 s1394_free_cfgrom(hal, nnode,
1984 S1394_FREE_CFGROM_NEW);
1985 break;
1989 * If there is indeed a cfgrom gen change,
1990 * CFGROM_GEN_CHANGED() will be set iff we are matching
1991 * tree nodes. Otherwise, CONFIG_ROM_GEN(old) !=
1992 * CONFIG_ROM_GEN(new).
1994 if (CFGROM_GEN_CHANGED(nnode) == B_TRUE ||
1995 (CONFIG_ROM_GEN(onode->cfgrom) !=
1996 CONFIG_ROM_GEN(nnode->cfgrom))) {
1997 gen_changed = 1;
1998 TNF_PROBE_4_DEBUG(s1394_match_GUID_gen_change,
1999 S1394_TNF_SL_HOTPLUG_STACK, "",
2000 tnf_opaque, old_cfgrom, onode->cfgrom,
2001 tnf_int, old_gen,
2002 CONFIG_ROM_GEN(onode->cfgrom), tnf_opaque,
2003 cfgrom, nnode->cfgrom, tnf_int, new_gen,
2004 CONFIG_ROM_GEN(nnode->cfgrom));
2005 } else {
2006 gen_changed = 0;
2009 onode->cur_node = nnode;
2010 nnode->old_node = onode;
2011 nnode->node_state = onode->node_state;
2012 SET_NODE_VISITED(onode);
2013 SET_NODE_MATCHED(onode);
2014 SET_NODE_MATCHED(nnode);
2016 * If generations changed, need to offline any targets
2017 * hanging off the old node, prior to freeing up old
2018 * cfgrom. If the generations didn't change, we can
2019 * free up the new config rom and copy all info from
2020 * the old node (this helps in picking up further
2021 * reads from where the last generation left off).
2023 if (gen_changed == 1) {
2024 if (s1394_offline_node(hal, onode)) {
2025 ret = DDI_FAILURE;
2026 break;
2028 TNF_PROBE_2(s1394_match_GUID_gen_freecfg,
2029 S1394_TNF_SL_HOTPLUG_STACK, "",
2030 tnf_opaque, old_cfgrom, onode->cfgrom,
2031 tnf_opaque, new_cfgrom, nnode->cfgrom);
2032 s1394_free_cfgrom(hal, onode,
2033 S1394_FREE_CFGROM_OLD);
2034 CLEAR_CFGROM_PARSED(nnode);
2035 CLEAR_CFGROM_NEW_ALLOC(nnode);
2036 CLEAR_CFGROM_NEW_ALLOC(onode);
2037 onode->cfgrom = nnode->cfgrom;
2038 /* done */
2039 break;
2043 * Free up cfgrom memory in the new_node and
2044 * point it at the same config rom as the old one.
2046 if (onode->cfgrom != nnode->cfgrom) {
2048 TNF_PROBE_5_DEBUG(s1394_match_GUID,
2049 S1394_TNF_SL_HOTPLUG_STACK, "",
2050 tnf_int, node_num, nnode->node_num,
2051 tnf_opaque, cfgrom, nnode->cfgrom,
2052 tnf_int, old_node_num, old_node,
2053 tnf_opaque, old_cfgrom, onode->cfgrom,
2054 tnf_uint, cfgrom_state,
2055 nnode->cfgrom_state);
2057 ASSERT(CFGROM_NEW_ALLOC(nnode) == B_TRUE);
2058 s1394_free_cfgrom(hal, nnode,
2059 S1394_FREE_CFGROM_NEW);
2061 nnode->cfgrom = onode->cfgrom;
2062 nnode->cfgrom_state = onode->cfgrom_state;
2063 nnode->cfgrom_valid_size = onode->cfgrom_valid_size;
2064 nnode->cfgrom_size = onode->cfgrom_size;
2065 nnode->cfgrom_quad_to_read = onode->cfgrom_quad_to_read;
2066 bcopy(onode->dir_stack, nnode->dir_stack,
2067 offsetof(s1394_node_t, cfgrom_quad_to_read) -
2068 offsetof(s1394_node_t, dir_stack));
2069 CLEAR_CFGROM_NEW_ALLOC(nnode);
2070 CLEAR_CFGROM_NEW_ALLOC(onode);
2072 if (CFGROM_PARSED(nnode) == B_TRUE) {
2073 rw_enter(&hal->target_list_rwlock, RW_WRITER);
2074 /* Update the target list */
2075 if ((t = onode->target_list) != NULL) {
2076 nnode->target_list = t;
2077 while (t != NULL) {
2078 t->on_node = nnode;
2079 t = t->target_sibling;
2082 rw_exit(&hal->target_list_rwlock);
2084 break;
2088 TNF_PROBE_0_DEBUG(s1394_match_GUID_exit, S1394_TNF_SL_HOTPLUG_STACK,
2089 "");
2091 return (ret);
2095 * s1394_match_all_GUIDs()
2096 * attempt to match each node in the current topology tree with the a
2097 * node in the old topology tree. If unable to relock the tree, returns
2098 * DDI_FAILURE, else returns DDI_SUCCESS.
2100 static int
2101 s1394_match_all_GUIDs(s1394_hal_t *hal)
2103 int node;
2104 int ret = DDI_SUCCESS;
2105 s1394_node_t *nnode;
2107 TNF_PROBE_0_DEBUG(s1394_match_all_GUIDs_enter,
2108 S1394_TNF_SL_HOTPLUG_STACK, "");
2110 ASSERT(MUTEX_HELD(&hal->topology_tree_mutex));
2112 for (node = 0; node < hal->number_of_nodes; node++) {
2113 nnode = &hal->topology_tree[node];
2114 if (LINK_ACTIVE(nnode) == B_FALSE || CFGROM_BIB_READ(nnode) ==
2115 B_FALSE)
2116 continue;
2117 if (NODE_MATCHED(nnode)) {
2119 * Skip if node matched. If config rom generations
2120 * changed, we want to call s1394_match_GUID() even
2121 * if the nodes matched.
2123 int gen_changed;
2124 s1394_node_t *onode = nnode->old_node;
2126 gen_changed = (onode && onode->cfgrom &&
2127 CONFIG_ROM_GEN(onode->cfgrom) != CONFIG_ROM_GEN(
2128 nnode->cfgrom)) ? 1 : 0;
2130 if (CFGROM_GEN_CHANGED(nnode) == 0 && gen_changed == 0)
2131 continue;
2134 if (s1394_match_GUID(hal, nnode) == DDI_FAILURE) {
2135 ret = DDI_FAILURE;
2139 TNF_PROBE_0_DEBUG(s1394_match_all_GUIDs_exit,
2140 S1394_TNF_SL_HOTPLUG_STACK, "");
2142 return (ret);
2146 * s1394_valid_cfgrom()
2147 * Performs crc check on the config rom. Returns B_TRUE if config rom has
2148 * good CRC else returns B_FALSE.
2150 /* ARGSUSED */
2151 boolean_t
2152 s1394_valid_cfgrom(s1394_hal_t *hal, s1394_node_t *node)
2154 uint32_t crc_len, crc_value, CRC, CRC_old, quad0;
2156 TNF_PROBE_0_DEBUG(s1394_valid_cfgrom_enter, S1394_TNF_SL_HOTPLUG_STACK,
2157 "");
2159 ASSERT(MUTEX_HELD(&hal->topology_tree_mutex));
2160 ASSERT(node->cfgrom);
2162 if (s1394_enable_crc_validation == 0) {
2163 TNF_PROBE_1_DEBUG(s1394_valid_cfgrom_exit,
2164 S1394_TNF_SL_HOTPLUG_STACK, "", tnf_string, msg,
2165 "validation turned off");
2166 return (B_TRUE);
2169 quad0 = node->cfgrom[0];
2170 crc_len = (quad0 >> IEEE1394_CFG_ROM_CRC_LEN_SHIFT) &
2171 IEEE1394_CFG_ROM_CRC_LEN_MASK;
2172 crc_value = quad0 & IEEE1394_CFG_ROM_CRC_VALUE_MASK;
2174 if (node->cfgrom_valid_size < crc_len + 1) {
2175 TNF_PROBE_4(s1394_valid_cfgrom_not_enough,
2176 S1394_TNF_SL_HOTPLUG_ERROR, "",
2177 tnf_uint, node_guid_hi, node->node_guid_hi,
2178 tnf_uint, node_guid_lo, node->node_guid_lo,
2179 tnf_uint, crc_len, crc_len,
2180 tnf_uint, valid_size, node->cfgrom_valid_size);
2181 TNF_PROBE_0_DEBUG(s1394_valid_cfgrom_exit,
2182 S1394_TNF_SL_HOTPLUG_STACK, "");
2183 return (B_FALSE);
2186 CRC = s1394_CRC16(&node->cfgrom[1], crc_len);
2188 if (CRC != crc_value) {
2189 CRC_old = s1394_CRC16_old(&node->cfgrom[1], crc_len);
2190 if (CRC_old == crc_value) {
2191 TNF_PROBE_4_DEBUG(s1394_valid_cfgrom_busted_crc,
2192 S1394_TNF_SL_HOTPLUG_ERROR, "",
2193 tnf_uint, node_guid_hi, node->node_guid_hi,
2194 tnf_uint, node_guid_lo, node->node_guid_lo,
2195 tnf_uint, node_num, node->node_num,
2196 tnf_uint, crc_len, crc_len);
2197 TNF_PROBE_0_DEBUG(s1394_valid_cfgrom_exit,
2198 S1394_TNF_SL_HOTPLUG_STACK, "");
2199 return (B_TRUE);
2202 cmn_err(CE_NOTE,
2203 "!Bad CRC in config rom (node's GUID %08x%08x)",
2204 node->node_guid_hi, node->node_guid_lo);
2206 TNF_PROBE_5(s1394_valid_cfgrom_bad_crc,
2207 S1394_TNF_SL_HOTPLUG_ERROR, "",
2208 tnf_uint, node_guid_hi, node->node_guid_hi,
2209 tnf_uint, node_guid_lo, node->node_guid_lo,
2210 tnf_uint, crc_len, crc_len,
2211 tnf_uint, crc, crc_value, tnf_uint, crc_computed, CRC);
2212 TNF_PROBE_0_DEBUG(s1394_valid_cfgrom_exit,
2213 S1394_TNF_SL_HOTPLUG_STACK, "");
2214 return (B_FALSE);
2217 TNF_PROBE_3_DEBUG(s1394_valid_cfgrom_exit, S1394_TNF_SL_HOTPLUG_STACK,
2218 "", tnf_uint, node_num, node->node_num, tnf_uint, crc_len, crc_len,
2219 tnf_uint, crc, crc_value);
2221 return (B_TRUE);
2225 * s1394_valid_dir()
2226 * Performs crc check on a directory. Returns B_TRUE if dir has good CRC
2227 * else returns B_FALSE.
2229 /*ARGSUSED*/
2230 boolean_t
2231 s1394_valid_dir(s1394_hal_t *hal, s1394_node_t *node,
2232 uint32_t key, uint32_t *dir)
2234 uint32_t dir_len, crc_value, CRC, CRC_old, quad0;
2236 TNF_PROBE_0_DEBUG(s1394_valid_dir_enter, S1394_TNF_SL_HOTPLUG_STACK,
2237 "");
2240 * Ideally, we would like to do crc validations for the entire cfgrom
2241 * as well as the individual directories. However, we have seen devices
2242 * that have valid directories but busted cfgrom crc and devices that
2243 * have bad crcs in directories as well as for the entire cfgrom. This
2244 * is sad, but unfortunately, real world!
2246 if (s1394_enable_crc_validation == 0) {
2247 TNF_PROBE_1_DEBUG(s1394_valid_dir_exit,
2248 S1394_TNF_SL_HOTPLUG_STACK, "", tnf_string, msg,
2249 "validation turned off");
2250 return (B_TRUE);
2253 quad0 = dir[0];
2255 dir_len = IEEE1212_DIR_LEN(quad0);
2256 crc_value = IEEE1212_DIR_CRC(quad0);
2258 ASSERT(MUTEX_HELD(&hal->topology_tree_mutex));
2260 CRC = s1394_CRC16(&dir[1], dir_len);
2262 if (CRC != crc_value) {
2263 CRC_old = s1394_CRC16_old(&dir[1], dir_len);
2264 if (CRC_old == crc_value) {
2265 TNF_PROBE_5_DEBUG(s1394_valid_dir_crc_old,
2266 S1394_TNF_SL_HOTPLUG_STACK, "",
2267 tnf_uint, node_guid_hi, node->node_guid_hi,
2268 tnf_uint, node_guid_lo, node->node_guid_lo,
2269 tnf_uint, node_num, node->node_num,
2270 tnf_uint, key, key, tnf_uint, dir_len, dir_len);
2271 TNF_PROBE_0_DEBUG(s1394_valid_dir_exit,
2272 S1394_TNF_SL_HOTPLUG_STACK, "");
2273 return (B_TRUE);
2276 TNF_PROBE_5(s1394_valid_dir_bad_crc,
2277 S1394_TNF_SL_HOTPLUG_STACK, "",
2278 tnf_uint, node_guid_hi, node->node_guid_hi,
2279 tnf_uint, node_guid_lo, node->node_guid_lo,
2280 tnf_uint, node_num, node->node_num,
2281 tnf_uint, key, key, tnf_uint, dir_len, dir_len);
2283 TNF_PROBE_0_DEBUG(s1394_valid_dir_exit,
2284 S1394_TNF_SL_HOTPLUG_STACK, "");
2285 return (B_FALSE);
2288 TNF_PROBE_4_DEBUG(s1394_valid_dir,
2289 S1394_TNF_SL_HOTPLUG_STACK, "",
2290 tnf_uint, node_guid_hi, node->node_guid_hi,
2291 tnf_uint, node_guid_lo, node->node_guid_lo,
2292 tnf_uint, node_num, node->node_num, tnf_uint, key, key);
2294 return (B_TRUE);
2298 * s1394_become_bus_mgr()
2299 * is a callback from a timeout() setup by the main br_thread. After
2300 * a bus reset, depending on the Bus Manager's incumbancy and the state
2301 * of its abdicate bit, a timer of a certain length is set. After this
2302 * time expires, the local host may attempt to become the Bus Manager.
2303 * This is done by sending a request to the current IRM on the bus. The
2304 * IRM holds the BUS_MANAGER_ID register. Depending on whether or not
2305 * the local host is already the IRM, we will send a request onto the
2306 * 1394 bus or call into the HAL.
2308 static void
2309 s1394_become_bus_mgr(void *arg)
2311 s1394_hal_t *hal;
2312 s1394_cmd_priv_t *s_priv;
2313 cmd1394_cmd_t *cmd;
2314 uint64_t Bus_Mgr_ID_addr;
2315 uint32_t hal_node_num;
2316 uint32_t old_value;
2317 uint32_t generation;
2318 uint_t curr_bus_mgr;
2319 uint_t bm_node;
2320 uint_t IRM_node;
2321 int err;
2322 int ret;
2324 TNF_PROBE_0_DEBUG(s1394_become_bus_mgr_enter, S1394_TNF_SL_BR_STACK,
2325 "");
2327 hal = (s1394_hal_t *)arg;
2329 /* Lock the topology tree */
2330 mutex_enter(&hal->topology_tree_mutex);
2332 hal_node_num = IEEE1394_NODE_NUM(hal->node_id);
2333 generation = hal->generation_count;
2334 IRM_node = hal->IRM_node;
2336 mutex_enter(&hal->bus_mgr_node_mutex);
2337 bm_node = hal->bus_mgr_node;
2338 mutex_exit(&hal->bus_mgr_node_mutex);
2340 /* Unlock the topology tree */
2341 mutex_exit(&hal->topology_tree_mutex);
2343 /* Make sure we aren't already the Bus Manager */
2344 if (bm_node != -1) {
2345 TNF_PROBE_0_DEBUG(s1394_become_bus_mgr_exit,
2346 S1394_TNF_SL_BR_STACK, "");
2347 return;
2350 /* Send compare-swap to BUS_MANAGER_ID */
2351 /* register on the Isoch Rsrc Mgr */
2352 if (IRM_node == hal_node_num) {
2353 /* Local */
2354 ret = HAL_CALL(hal).csr_cswap32(hal->halinfo.hal_private,
2355 generation, (IEEE1394_SCSR_BUSMGR_ID &
2356 IEEE1394_CSR_OFFSET_MASK), S1394_INVALID_NODE_NUM,
2357 hal_node_num, &old_value);
2358 if (ret != DDI_SUCCESS) {
2359 TNF_PROBE_1(s1394_become_bus_mgr_error,
2360 S1394_TNF_SL_BR_ERROR, "", tnf_string, msg,
2361 "Error in cswap32");
2362 TNF_PROBE_0_DEBUG(s1394_become_bus_mgr_exit,
2363 S1394_TNF_SL_BR_STACK, "");
2364 return;
2366 curr_bus_mgr = IEEE1394_NODE_NUM(old_value);
2368 mutex_enter(&hal->bus_mgr_node_mutex);
2369 if ((curr_bus_mgr == S1394_INVALID_NODE_NUM) ||
2370 (curr_bus_mgr == hal_node_num)) {
2371 hal->bus_mgr_node = hal_node_num;
2372 hal->incumbent_bus_mgr = B_TRUE;
2373 } else {
2374 hal->bus_mgr_node = curr_bus_mgr;
2375 hal->incumbent_bus_mgr = B_FALSE;
2377 cv_signal(&hal->bus_mgr_node_cv);
2378 mutex_exit(&hal->bus_mgr_node_mutex);
2380 } else {
2381 /* Remote */
2382 if (s1394_alloc_cmd(hal, T1394_ALLOC_CMD_NOSLEEP, &cmd) !=
2383 DDI_SUCCESS) {
2384 TNF_PROBE_1(s1394_become_bus_mgr_error,
2385 S1394_TNF_SL_BR_ERROR, "", tnf_string, msg,
2386 "Error in s1394_alloc_cmd()");
2387 TNF_PROBE_0_DEBUG(s1394_become_bus_mgr_exit,
2388 S1394_TNF_SL_BR_STACK, "");
2389 return;
2392 cmd->cmd_options = (CMD1394_CANCEL_ON_BUS_RESET |
2393 CMD1394_OVERRIDE_ADDR);
2394 cmd->cmd_type = CMD1394_ASYNCH_LOCK_32;
2395 cmd->completion_callback = s1394_become_bus_mgr_callback;
2396 Bus_Mgr_ID_addr = (IEEE1394_ADDR_BUS_ID_MASK |
2397 IEEE1394_SCSR_BUSMGR_ID) |
2398 (((uint64_t)hal->IRM_node) << IEEE1394_ADDR_PHY_ID_SHIFT);
2399 cmd->cmd_addr = Bus_Mgr_ID_addr;
2400 cmd->bus_generation = generation;
2401 cmd->cmd_u.l32.arg_value = T1394_DATA32(
2402 S1394_INVALID_NODE_NUM);
2403 cmd->cmd_u.l32.data_value = T1394_DATA32(hal_node_num);
2404 cmd->cmd_u.l32.num_retries = 0;
2405 cmd->cmd_u.l32.lock_type = CMD1394_LOCK_COMPARE_SWAP;
2407 /* Get the Services Layer private area */
2408 s_priv = S1394_GET_CMD_PRIV(cmd);
2410 /* Lock the topology tree */
2411 mutex_enter(&hal->topology_tree_mutex);
2413 ret = s1394_setup_asynch_command(hal, NULL, cmd,
2414 S1394_CMD_LOCK, &err);
2416 /* Unlock the topology tree */
2417 mutex_exit(&hal->topology_tree_mutex);
2419 /* Command has now been put onto the queue! */
2420 if (ret != DDI_SUCCESS) {
2421 /* Need to free the command */
2422 (void) s1394_free_cmd(hal, (cmd1394_cmd_t **)&cmd);
2423 TNF_PROBE_1(s1394_become_bus_mgr_error,
2424 S1394_TNF_SL_BR_ERROR, "", tnf_string, msg,
2425 "Error in s1394_setup_asynch_command()");
2426 TNF_PROBE_0_DEBUG(s1394_become_bus_mgr_exit,
2427 S1394_TNF_SL_BR_STACK, "");
2428 return;
2431 /* Send the command out */
2432 ret = s1394_xfer_asynch_command(hal, cmd, &err);
2434 if (ret != DDI_SUCCESS) {
2435 /* Remove cmd outstanding request Q */
2436 s1394_remove_q_asynch_cmd(hal, cmd);
2438 s_priv->cmd_in_use = B_FALSE;
2440 mutex_enter(&hal->bus_mgr_node_mutex);
2442 /* Don't know who the bus_mgr is */
2443 hal->bus_mgr_node = S1394_INVALID_NODE_NUM;
2444 hal->incumbent_bus_mgr = B_FALSE;
2446 cv_signal(&hal->bus_mgr_node_cv);
2447 mutex_exit(&hal->bus_mgr_node_mutex);
2449 /* Need to free the command */
2450 (void) s1394_free_cmd(hal, (cmd1394_cmd_t **)&cmd);
2454 TNF_PROBE_0_DEBUG(s1394_become_bus_mgr_exit, S1394_TNF_SL_BR_STACK,
2455 "");
2459 * s1394_become_bus_mgr_callback()
2460 * is the callback used by s1394_become_bus_mgr() when it is necessary
2461 * to send the Bus Manager request to a remote IRM. After the completion
2462 * of the compare-swap request, this routine looks at the "old_value"
2463 * in the request to determine whether or not it has become the Bus
2464 * Manager for the current generation. It sets the bus_mgr_node and
2465 * incumbent_bus_mgr fields to their appropriate values.
2467 static void
2468 s1394_become_bus_mgr_callback(cmd1394_cmd_t *cmd)
2470 s1394_cmd_priv_t *s_priv;
2471 s1394_hal_t *hal;
2472 uint32_t hal_node_num;
2473 uint32_t temp;
2474 uint_t curr_bus_mgr;
2476 TNF_PROBE_0_DEBUG(s1394_become_bus_mgr_callback_enter,
2477 S1394_TNF_SL_BR_STACK, "");
2479 /* Get the Services Layer private area */
2480 s_priv = S1394_GET_CMD_PRIV(cmd);
2482 hal = (s1394_hal_t *)s_priv->sent_on_hal;
2484 /* Lock the topology tree */
2485 mutex_enter(&hal->topology_tree_mutex);
2487 hal_node_num = IEEE1394_NODE_NUM(hal->node_id);
2489 /* Was the command successful? */
2490 if (cmd->cmd_result == CMD1394_CMDSUCCESS) {
2491 temp = T1394_DATA32(cmd->cmd_u.l32.old_value);
2492 curr_bus_mgr = IEEE1394_NODE_NUM(temp);
2493 mutex_enter(&hal->bus_mgr_node_mutex);
2494 if ((curr_bus_mgr == S1394_INVALID_NODE_NUM) ||
2495 (curr_bus_mgr == hal_node_num)) {
2497 hal->bus_mgr_node = hal_node_num;
2498 hal->incumbent_bus_mgr = B_TRUE;
2500 } else {
2501 hal->bus_mgr_node = curr_bus_mgr;
2502 hal->incumbent_bus_mgr = B_FALSE;
2504 cv_signal(&hal->bus_mgr_node_cv);
2505 mutex_exit(&hal->bus_mgr_node_mutex);
2507 } else {
2508 TNF_PROBE_2(s1394_become_bus_mgr_callback_error,
2509 S1394_TNF_SL_BR_ERROR, "", tnf_string, msg,
2510 "Error while attempting to become bus manager",
2511 tnf_uint, status, cmd->cmd_result);
2513 mutex_enter(&hal->bus_mgr_node_mutex);
2515 /* Don't know who the bus_mgr is */
2516 hal->bus_mgr_node = S1394_INVALID_NODE_NUM;
2517 hal->incumbent_bus_mgr = B_FALSE;
2519 cv_signal(&hal->bus_mgr_node_cv);
2520 mutex_exit(&hal->bus_mgr_node_mutex);
2523 /* Need to free the command */
2524 (void) s1394_free_cmd(hal, (cmd1394_cmd_t **)&cmd);
2526 /* Unlock the topology tree */
2527 mutex_exit(&hal->topology_tree_mutex);
2529 TNF_PROBE_0_DEBUG(s1394_become_bus_mgr_callback_exit,
2530 S1394_TNF_SL_BR_STACK, "");
2534 * s1394_bus_mgr_processing()
2535 * is called following "phase1" completion of reading Bus_Info_Blocks.
2536 * Its purpose is to determine whether the local node is capable of
2537 * becoming the Bus Manager (has the IRMC bit set) and if so to call
2538 * the s1394_do_bus_mgr_processing() routine.
2539 * NOTE: we overload DDI_FAILURE return value to mean jump back to
2540 * the start of bus reset processing.
2542 static int
2543 s1394_bus_mgr_processing(s1394_hal_t *hal)
2545 int ret;
2546 int IRM_node_num;
2548 TNF_PROBE_0_DEBUG(s1394_bus_mgr_processing_enter,
2549 S1394_TNF_SL_BR_STACK, "");
2551 ASSERT(MUTEX_NOT_HELD(&hal->topology_tree_mutex));
2553 if (s1394_lock_tree(hal) != DDI_SUCCESS) {
2554 return (DDI_FAILURE);
2556 IRM_node_num = hal->IRM_node;
2557 s1394_unlock_tree(hal);
2559 ret = DDI_SUCCESS;
2561 /* If we are IRM capable, then do bus_mgr stuff... */
2562 if (hal->halinfo.bus_capabilities & IEEE1394_BIB_IRMC_MASK) {
2563 /* If there is an IRM, then do bus_mgr stuff */
2564 if (IRM_node_num != -1) {
2565 if (s1394_do_bus_mgr_processing(hal))
2566 ret = DDI_FAILURE;
2570 ASSERT(MUTEX_NOT_HELD(&hal->topology_tree_mutex));
2572 TNF_PROBE_0_DEBUG(s1394_bus_mgr_processing_exit,
2573 S1394_TNF_SL_BR_STACK, "");
2574 return (ret);
2578 * s1394_do_bus_mgr_processing()
2579 * is used to perform those operations expected of the Bus Manager.
2580 * After being called, s1394_do_bus_mgr_processing() looks at the value
2581 * in bus_mgr_node and waits if it is -1 (Bus Manager has not been
2582 * chosen yet). Then, if there is more than one node on the 1394 bus,
2583 * and we are either the Bus Manager or (if there is no Bus Manager)
2584 * the IRM, it optimizes the gap_count and/or sets the cycle master's
2585 * root holdoff bit (to ensure that the cycle master is/stays root).
2587 * NOTE: we overload DDI_FAILURE return value to mean jump back to
2588 * the start of bus reset processing.
2590 static int
2591 s1394_do_bus_mgr_processing(s1394_hal_t *hal)
2593 int ret;
2594 int IRM_flags, hal_bus_mgr_node;
2595 int IRM_node_num;
2596 uint_t hal_node_num, number_of_nodes;
2597 int new_root, new_gap_cnt;
2599 TNF_PROBE_0_DEBUG(s1394_do_bus_mgr_processing_enter,
2600 S1394_TNF_SL_BR_STACK, "");
2602 ASSERT(MUTEX_NOT_HELD(&hal->topology_tree_mutex));
2604 /* Wait for Bus Manager to be determined */
2605 /* or a Bus Reset to happen */
2606 mutex_enter(&hal->bus_mgr_node_mutex);
2607 if (hal->bus_mgr_node == -1)
2608 cv_wait(&hal->bus_mgr_node_cv, &hal->bus_mgr_node_mutex);
2610 /* Check if a BUS RESET has come while we've been waiting */
2611 mutex_enter(&hal->br_thread_mutex);
2612 if (hal->br_thread_ev_type & (BR_THR_CFGROM_SCAN | BR_THR_GO_AWAY)) {
2614 mutex_exit(&hal->br_thread_mutex);
2615 mutex_exit(&hal->bus_mgr_node_mutex);
2617 TNF_PROBE_0_DEBUG(s1394_do_bus_mgr_processing_exit,
2618 S1394_TNF_SL_BR_STACK, "");
2619 return (1);
2621 mutex_exit(&hal->br_thread_mutex);
2623 hal_bus_mgr_node = hal->bus_mgr_node;
2624 mutex_exit(&hal->bus_mgr_node_mutex);
2626 if (s1394_lock_tree(hal) != DDI_SUCCESS) {
2627 return (1);
2629 hal_node_num = IEEE1394_NODE_NUM(hal->node_id);
2630 IRM_node_num = hal->IRM_node;
2631 number_of_nodes = hal->number_of_nodes;
2633 ret = 0;
2635 /* If we are the bus_mgr or if there is no bus_mgr */
2636 /* the IRM and there is > 1 nodes on the bus */
2637 if ((number_of_nodes > 1) &&
2638 ((hal_bus_mgr_node == (int)hal_node_num) ||
2639 ((hal_bus_mgr_node == S1394_INVALID_NODE_NUM) &&
2640 (IRM_node_num == (int)hal_node_num)))) {
2642 IRM_flags = 0;
2644 /* Make sure the root node is cycle master capable */
2645 if (!s1394_cycle_master_capable(hal)) {
2646 /* Make the local node root */
2647 new_root = hal_node_num;
2648 IRM_flags = IRM_flags | ROOT_HOLDOFF;
2650 /* If setting root, then optimize gap_count */
2651 new_gap_cnt = hal->optimum_gap_count;
2652 IRM_flags = IRM_flags | GAP_COUNT;
2654 } else {
2655 /* Make sure root's ROOT_HOLDOFF bit is set */
2656 new_root = (number_of_nodes - 1);
2657 IRM_flags = IRM_flags | ROOT_HOLDOFF;
2659 if (hal->gap_count > hal->optimum_gap_count) {
2660 /* Set the gap_count to optimum */
2661 new_gap_cnt = hal->optimum_gap_count;
2662 IRM_flags = IRM_flags | GAP_COUNT;
2666 s1394_unlock_tree(hal);
2668 if (IRM_flags) {
2669 ret = s1394_do_phy_config_pkt(hal, new_root,
2670 new_gap_cnt, IRM_flags);
2672 TNF_PROBE_0_DEBUG(s1394_do_bus_mgr_processing_exit,
2673 S1394_TNF_SL_BR_STACK, "");
2674 return (ret);
2677 s1394_unlock_tree(hal);
2679 TNF_PROBE_0_DEBUG(s1394_do_bus_mgr_processing_exit,
2680 S1394_TNF_SL_BR_STACK, "");
2681 return (ret);
2685 * s1394_bus_mgr_timers_stop()
2686 * Cancels bus manager timeouts
2688 /*ARGSUSED*/
2689 static void
2690 s1394_bus_mgr_timers_stop(s1394_hal_t *hal, timeout_id_t *bus_mgr_query_tid,
2691 timeout_id_t *bus_mgr_tid)
2693 TNF_PROBE_0_DEBUG(s1394_bus_mgr_timers_stop_enter,
2694 S1394_TNF_SL_BR_STACK, "");
2696 /* Cancel the Bus Mgr timeouts (if necessary) */
2697 if (*bus_mgr_tid != 0) {
2698 (void) untimeout(*bus_mgr_tid);
2699 *bus_mgr_tid = 0;
2701 if (*bus_mgr_query_tid != 0) {
2702 (void) untimeout(*bus_mgr_query_tid);
2703 *bus_mgr_query_tid = 0;
2706 TNF_PROBE_0_DEBUG(s1394_bus_mgr_timers_stop_exit,
2707 S1394_TNF_SL_BR_STACK, "");
2711 * s1394_bus_mgr_timers_start()
2712 * Starts bus manager timeouts if the hal is IRM capable.
2714 static void
2715 s1394_bus_mgr_timers_start(s1394_hal_t *hal, timeout_id_t *bus_mgr_query_tid,
2716 timeout_id_t *bus_mgr_tid)
2718 boolean_t incumbant;
2719 uint_t hal_node_num;
2720 int IRM_node_num;
2722 TNF_PROBE_0_DEBUG(s1394_bus_mgr_timers_start_enter,
2723 S1394_TNF_SL_BR_STACK, "");
2725 mutex_enter(&hal->topology_tree_mutex);
2727 IRM_node_num = hal->IRM_node;
2728 hal_node_num = hal->node_id;
2730 mutex_enter(&hal->bus_mgr_node_mutex);
2731 incumbant = hal->incumbent_bus_mgr;
2732 mutex_exit(&hal->bus_mgr_node_mutex);
2734 /* If we are IRM capable, then do bus_mgr stuff... */
2735 if (hal->halinfo.bus_capabilities & IEEE1394_BIB_IRMC_MASK) {
2737 * If we are the IRM, then wait 625ms
2738 * before checking BUS_MANAGER_ID register
2740 if (IRM_node_num == IEEE1394_NODE_NUM(hal_node_num)) {
2742 TNF_PROBE_0_DEBUG(s1394_bus_mgr_timers_625ms,
2743 S1394_TNF_SL_BR_STACK, "");
2745 mutex_exit(&hal->topology_tree_mutex);
2747 /* Wait 625ms, then check bus manager */
2748 *bus_mgr_query_tid = timeout(s1394_become_bus_mgr,
2749 hal, drv_usectohz(IEEE1394_BM_IRM_TIMEOUT));
2751 mutex_enter(&hal->topology_tree_mutex);
2754 /* If there is an IRM on the bus */
2755 if (IRM_node_num != -1) {
2756 if ((incumbant == B_TRUE) &&
2757 (hal->abdicate_bus_mgr_bit == 0)) {
2758 mutex_exit(&hal->topology_tree_mutex);
2760 /* Try to become bus manager */
2761 s1394_become_bus_mgr(hal);
2763 mutex_enter(&hal->topology_tree_mutex);
2764 } else {
2765 hal->abdicate_bus_mgr_bit = 0;
2767 TNF_PROBE_0_DEBUG(s1394_bus_mgr_timers_125ms,
2768 S1394_TNF_SL_BR_STACK, "");
2770 mutex_exit(&hal->topology_tree_mutex);
2772 /* Wait 125ms, then try to become bus manager */
2773 *bus_mgr_tid = timeout(s1394_become_bus_mgr,
2774 hal, drv_usectohz(
2775 IEEE1394_BM_INCUMBENT_TIMEOUT));
2777 mutex_enter(&hal->topology_tree_mutex);
2779 } else {
2780 mutex_enter(&hal->bus_mgr_node_mutex);
2781 hal->incumbent_bus_mgr = B_FALSE;
2782 mutex_exit(&hal->bus_mgr_node_mutex);
2786 mutex_exit(&hal->topology_tree_mutex);
2788 TNF_PROBE_0_DEBUG(s1394_bus_mgr_timers_start_exit,
2789 S1394_TNF_SL_BR_STACK, "");
2793 * s1394_get_maxpayload()
2794 * is used to determine a device's maximum payload size. That is to
2795 * say, the largest packet that can be transmitted or received by the
2796 * the target device given the current topological (speed) constraints
2797 * and the constraints specified in the local host's and remote device's
2798 * Config ROM (max_rec). Caller must hold the topology_tree_mutex and
2799 * the target_list_rwlock as an RW_READER (at least).
2801 /*ARGSUSED*/
2802 void
2803 s1394_get_maxpayload(s1394_target_t *target, uint_t *dev_max_payload,
2804 uint_t *current_max_payload)
2806 s1394_hal_t *hal;
2807 uint32_t bus_capabilities;
2808 uint32_t from_node;
2809 uint32_t to_node;
2810 uint_t local_max_rec;
2811 uint_t local_max_blk;
2812 uint_t max_rec;
2813 uint_t max_blk;
2814 uint_t curr_speed;
2815 uint_t speed_max_blk;
2816 uint_t temp;
2818 TNF_PROBE_0_DEBUG(s1394_get_maxpayload_enter,
2819 S1394_TNF_SL_HOTPLUG_STACK, "");
2821 /* Find the HAL this target resides on */
2822 hal = target->on_hal;
2824 /* Make sure we're holding the topology_tree_mutex */
2825 ASSERT(MUTEX_HELD(&hal->topology_tree_mutex));
2827 /* Set dev_max_payload to local (HAL's) size */
2828 bus_capabilities = target->on_hal->halinfo.bus_capabilities;
2829 local_max_rec = (bus_capabilities & IEEE1394_BIB_MAXREC_MASK) >>
2830 IEEE1394_BIB_MAXREC_SHIFT;
2831 if ((local_max_rec > 0) && (local_max_rec < 14)) {
2832 local_max_blk = 1 << (local_max_rec + 1);
2833 } else {
2834 /* These are either unspecified or reserved */
2835 local_max_blk = 4;
2838 /* Is this target on a node? */
2839 if ((target->target_state & S1394_TARG_GONE) == 0 &&
2840 (target->on_node != NULL)) {
2841 ASSERT(target->on_node->cfgrom != NULL);
2843 bus_capabilities =
2844 target->on_node->cfgrom[IEEE1212_NODE_CAP_QUAD];
2845 max_rec = (bus_capabilities & IEEE1394_BIB_MAXREC_MASK) >>
2846 IEEE1394_BIB_MAXREC_SHIFT;
2848 if ((max_rec > 0) && (max_rec < 14)) {
2849 max_blk = 1 << (max_rec + 1);
2850 } else {
2851 /* These are either unspecified or reserved */
2852 max_blk = 4;
2854 (*dev_max_payload) = max_blk;
2856 from_node = IEEE1394_NODE_NUM(target->on_hal->node_id);
2857 to_node = (target->on_node->node_num);
2859 /* Speed is to be filled in from speed map */
2860 curr_speed = (uint_t)s1394_speed_map_get(target->on_hal,
2861 from_node, to_node);
2862 speed_max_blk = 512 << curr_speed;
2863 temp = (local_max_blk < max_blk) ? local_max_blk : max_blk;
2864 (*current_max_payload) = (temp < speed_max_blk) ? temp :
2865 speed_max_blk;
2866 } else {
2867 /* Set dev_max_payload to local (HAL's) size */
2868 (*dev_max_payload) = local_max_blk;
2869 (*current_max_payload) = local_max_blk;
2872 TNF_PROBE_0_DEBUG(s1394_get_maxpayload_exit,
2873 S1394_TNF_SL_HOTPLUG_STACK, "");
2877 * s1394_cycle_master_capable()
2878 * is used to determine whether or not the current root node on the
2879 * 1394 bus has its CMC-bit set in it Config ROM. If not, then it
2880 * is not capable of being cycle master and a new root node must be
2881 * selected.
2883 static int
2884 s1394_cycle_master_capable(s1394_hal_t *hal)
2886 s1394_node_t *root;
2887 int cycle_master_capable;
2888 uint_t hal_node_num;
2890 TNF_PROBE_0_DEBUG(s1394_cycle_master_capable_enter,
2891 S1394_TNF_SL_HOTPLUG_STACK, "");
2893 ASSERT(MUTEX_HELD(&hal->topology_tree_mutex));
2895 hal_node_num = IEEE1394_NODE_NUM(hal->node_id);
2897 /* Get a pointer to the root node */
2898 root = s1394_topology_tree_get_root_node(hal);
2900 /* Ignore, if we are already root */
2901 if (root == &hal->topology_tree[hal_node_num]) {
2902 TNF_PROBE_2_DEBUG(s1394_cmstr_capable_hal,
2903 S1394_TNF_SL_HOTPLUG_STACK, "", tnf_int,
2904 node_num, hal_node_num, tnf_int, ret, 1);
2905 return (1);
2909 * We want to pick a new root if link is off or we don't have
2910 * valid config rom
2912 if (LINK_ACTIVE(root) == B_FALSE || root->cfgrom == NULL ||
2913 CFGROM_BIB_READ(root) == 0) {
2915 TNF_PROBE_4_DEBUG(s1394_cmstr_capable_not_hal,
2916 S1394_TNF_SL_HOTPLUG_STACK, "", tnf_int,
2917 root, root->node_num, tnf_int, link_active,
2918 LINK_ACTIVE(root), tnf_opaque, cfgrom, root->cfgrom,
2919 tnf_int, bib, CFGROM_BIB_READ(root));
2921 return (0);
2924 /* Check the Cycle Master bit in the Bus Info Block */
2925 cycle_master_capable = root->cfgrom[IEEE1212_NODE_CAP_QUAD] &
2926 IEEE1394_BIB_CMC_MASK;
2928 if (cycle_master_capable) {
2929 TNF_PROBE_1_DEBUG(s1394_cmstr_capable_root,
2930 S1394_TNF_SL_HOTPLUG_STACK, "", tnf_int,
2931 root, root->node_num);
2932 return (1);
2933 } else {
2934 TNF_PROBE_1(s1394_cmstr_not_capable_root,
2935 S1394_TNF_SL_HOTPLUG_STACK, "", tnf_int,
2936 root, root->node_num);
2937 return (0);
2942 * s1394_do_phy_config_pkt()
2943 * is called by s1394_do_bus_mgr_processing() to setup and send out
2944 * a PHY configuration packet onto the 1394 bus. Depending on the
2945 * values in IRM_flags, the gap_count and root_holdoff bits on the
2946 * bus will be affected by this packet.
2948 * NOTE: we overload DDI_FAILURE return value to mean jump back to
2949 * the start of bus reset processing.
2951 static int
2952 s1394_do_phy_config_pkt(s1394_hal_t *hal, int new_root, int new_gap_cnt,
2953 uint32_t IRM_flags)
2955 cmd1394_cmd_t *cmd;
2956 s1394_cmd_priv_t *s_priv;
2957 h1394_cmd_priv_t *h_priv;
2958 uint32_t pkt_data = 0;
2959 uint32_t gap_cnt = 0;
2960 uint32_t root = 0;
2961 int ret, result;
2962 uint_t flags = 0;
2964 TNF_PROBE_0_DEBUG(s1394_do_phy_config_pkt_enter,
2965 S1394_TNF_SL_HOTPLUG_STACK, "");
2967 /* Gap count needs to be optimized */
2968 if (IRM_flags & GAP_COUNT) {
2970 pkt_data = pkt_data | IEEE1394_PHY_CONFIG_T_BIT_MASK;
2971 gap_cnt = ((uint32_t)new_gap_cnt) <<
2972 IEEE1394_PHY_CONFIG_GAP_CNT_SHIFT;
2973 gap_cnt = gap_cnt & IEEE1394_PHY_CONFIG_GAP_CNT_MASK;
2974 pkt_data = pkt_data | gap_cnt;
2976 (void) HAL_CALL(hal).set_gap_count(hal->halinfo.hal_private,
2977 (uint_t)new_gap_cnt);
2980 /* Root node needs to be changed */
2981 if (IRM_flags & ROOT_HOLDOFF) {
2983 pkt_data = pkt_data | IEEE1394_PHY_CONFIG_R_BIT_MASK;
2984 root = ((uint32_t)new_root) <<
2985 IEEE1394_PHY_CONFIG_ROOT_HOLD_SHIFT;
2986 root = root & IEEE1394_PHY_CONFIG_ROOT_HOLD_MASK;
2987 pkt_data = pkt_data | root;
2989 (void) HAL_CALL(hal).set_root_holdoff_bit(
2990 hal->halinfo.hal_private);
2994 if (IRM_flags) {
2995 if (s1394_alloc_cmd(hal, flags, &cmd) != DDI_SUCCESS) {
2996 TNF_PROBE_1_DEBUG(s1394_do_phy_config_pkt_error,
2997 S1394_TNF_SL_HOTPLUG_STACK, "", tnf_string, msg,
2998 "Unable to allocate PHY config packet");
2999 TNF_PROBE_0_DEBUG(s1394_do_phy_config_pkt_exit,
3000 S1394_TNF_SL_HOTPLUG_STACK, "");
3001 return (0);
3004 if (s1394_lock_tree(hal) != DDI_SUCCESS) {
3005 /* lock tree failure indicates a bus gen change */
3006 (void) s1394_free_cmd(hal, (cmd1394_cmd_t **)&cmd);
3007 TNF_PROBE_0_DEBUG(s1394_do_phy_config_pkt_exit,
3008 S1394_TNF_SL_HOTPLUG_STACK, "");
3009 return (1);
3012 /* Setup the callback routine */
3013 cmd->completion_callback = s1394_phy_config_callback;
3014 cmd->cmd_callback_arg = (void *)(uintptr_t)IRM_flags;
3015 cmd->bus_generation = hal->generation_count;
3016 cmd->cmd_options = CMD1394_OVERRIDE_ADDR;
3017 cmd->cmd_type = CMD1394_ASYNCH_WR_QUAD;
3018 cmd->cmd_u.q.quadlet_data = pkt_data;
3020 /* Get the Services Layer private area */
3021 s_priv = S1394_GET_CMD_PRIV(cmd);
3023 /* Get a pointer to the HAL private struct */
3024 h_priv = (h1394_cmd_priv_t *)&s_priv->hal_cmd_private;
3026 s_priv->sent_by_target = (s1394_target_t *)NULL;
3027 s_priv->sent_on_hal = (s1394_hal_t *)hal;
3029 h_priv->bus_generation = cmd->bus_generation;
3031 /* Speed must be IEEE1394_S100 on PHY config packets */
3032 s_priv->hal_cmd_private.speed = IEEE1394_S100;
3034 /* Mark command as being used */
3035 s_priv->cmd_in_use = B_TRUE;
3037 s1394_unlock_tree(hal);
3039 /* Put command on the HAL's outstanding request Q */
3040 s1394_insert_q_asynch_cmd(hal, cmd);
3042 ret = HAL_CALL(hal).send_phy_configuration_packet(
3043 hal->halinfo.hal_private, (cmd1394_cmd_t *)cmd,
3044 (h1394_cmd_priv_t *)&s_priv->hal_cmd_private, &result);
3046 if (ret != DDI_SUCCESS) {
3047 TNF_PROBE_2_DEBUG(s1394_do_phy_config_pkt_error,
3048 S1394_TNF_SL_HOTPLUG_STACK, "", tnf_string, msg,
3049 "Unable to send PHY config packet",
3050 tnf_int, result, result);
3052 (void) s1394_free_cmd(hal, (cmd1394_cmd_t **)&cmd);
3054 TNF_PROBE_0_DEBUG(s1394_do_phy_config_pkt_exit,
3055 S1394_TNF_SL_HOTPLUG_STACK, "");
3056 return (0);
3058 } else {
3060 * There will be a bus reset only if GAP_COUNT changed
3062 if (IRM_flags & GAP_COUNT) {
3063 return (1);
3068 TNF_PROBE_0_DEBUG(s1394_do_phy_config_pkt_exit,
3069 S1394_TNF_SL_HOTPLUG_STACK, "");
3070 return (0);
3074 * s1394_phy_config_callback()
3075 * is the callback called after the PHY configuration packet has been
3076 * sent out onto the 1394 bus. Depending on the values in IRM_flags,
3077 * (specifically if the gap_count has been changed) this routine may
3078 * initiate a bus reset.
3080 static void
3081 s1394_phy_config_callback(cmd1394_cmd_t *cmd)
3083 s1394_cmd_priv_t *s_priv;
3084 s1394_hal_t *hal;
3085 uint32_t IRM_flags;
3087 TNF_PROBE_0_DEBUG(s1394_phy_config_callback_enter,
3088 S1394_TNF_SL_HOTPLUG_STACK, "");
3090 /* Get the Services Layer private area */
3091 s_priv = S1394_GET_CMD_PRIV(cmd);
3093 hal = (s1394_hal_t *)s_priv->sent_on_hal;
3095 IRM_flags = (uint32_t)(uintptr_t)cmd->cmd_callback_arg;
3097 if (cmd->cmd_result != CMD1394_CMDSUCCESS) {
3098 TNF_PROBE_2_DEBUG(s1394_do_phy_config_pkt_error,
3099 S1394_TNF_SL_HOTPLUG_STACK, "", tnf_string, msg,
3100 "Error sending PHY config packet",
3101 tnf_int, result, cmd->cmd_result);
3102 (void) s1394_free_cmd(hal, &cmd);
3103 } else {
3104 (void) s1394_free_cmd(hal, &cmd);
3106 /* Only need a bus reset if we changed GAP_COUNT */
3107 if (IRM_flags & GAP_COUNT) {
3108 s1394_initiate_hal_reset(hal, NON_CRITICAL);
3112 TNF_PROBE_0_DEBUG(s1394_phy_config_callback_exit,
3113 S1394_TNF_SL_HOTPLUG_STACK, "");
3117 * s1394_lock_tree()
3118 * Attempts to lock the topology tree. Returns DDI_FAILURE if generations
3119 * changed or if the services layer signals the bus reset thread to go
3120 * away. Otherwise, returns DDI_SUCCESS.
3123 s1394_lock_tree(s1394_hal_t *hal)
3125 int circular;
3127 ASSERT(MUTEX_NOT_HELD(&hal->br_thread_mutex));
3128 ASSERT(MUTEX_NOT_HELD(&hal->topology_tree_mutex));
3130 TNF_PROBE_0_DEBUG(s1394_lock_tree_enter, S1394_TNF_SL_HOTPLUG_STACK,
3131 "");
3133 mutex_enter(&hal->br_thread_mutex);
3134 ndi_devi_enter(hal->halinfo.dip, &circular);
3135 mutex_enter(&hal->topology_tree_mutex);
3137 if ((hal->br_thread_ev_type & BR_THR_GO_AWAY) != 0) {
3138 TNF_PROBE_2(s1394_lock_tree_go_away,
3139 S1394_TNF_SL_HOTPLUG_STACK, "",
3140 tnf_int, hal_generation, hal->generation_count,
3141 tnf_int, br_thread_gen, hal->br_cfgrom_read_gen);
3142 TNF_PROBE_0_DEBUG(s1394_lock_tree_exit,
3143 S1394_TNF_SL_HOTPLUG_STACK, "");
3144 mutex_exit(&hal->br_thread_mutex);
3145 mutex_exit(&hal->topology_tree_mutex);
3146 ndi_devi_exit(hal->halinfo.dip, circular);
3147 return (DDI_FAILURE);
3148 } else if (hal->br_cfgrom_read_gen != hal->generation_count) {
3149 TNF_PROBE_2(s1394_lock_tree_gen_changed,
3150 S1394_TNF_SL_HOTPLUG_STACK, "",
3151 tnf_int, hal_generation, hal->generation_count,
3152 tnf_int, br_thread_gen, hal->br_cfgrom_read_gen);
3154 TNF_PROBE_0_DEBUG(s1394_lock_tree_exit,
3155 S1394_TNF_SL_HOTPLUG_STACK, "");
3156 mutex_exit(&hal->br_thread_mutex);
3157 mutex_exit(&hal->topology_tree_mutex);
3158 ndi_devi_exit(hal->halinfo.dip, circular);
3159 return (DDI_FAILURE);
3162 mutex_exit(&hal->br_thread_mutex);
3164 TNF_PROBE_0_DEBUG(s1394_lock_tree_exit, S1394_TNF_SL_HOTPLUG_STACK, "");
3166 return (DDI_SUCCESS);
3170 * s1394_unlock_tree()
3171 * Unlocks the topology tree
3173 void
3174 s1394_unlock_tree(s1394_hal_t *hal)
3176 TNF_PROBE_0_DEBUG(s1394_unlock_tree_enter, S1394_TNF_SL_HOTPLUG_STACK,
3177 "");
3179 ASSERT(MUTEX_HELD(&hal->topology_tree_mutex));
3180 mutex_exit(&hal->topology_tree_mutex);
3181 ndi_devi_exit(hal->halinfo.dip, 0);
3183 TNF_PROBE_0_DEBUG(s1394_unlock_tree_exit, S1394_TNF_SL_HOTPLUG_STACK,
3184 "");
3188 * s1394_calc_next_quad()
3189 * figures out the next quadlet to read. This maintains a stack of
3190 * directories in the node. When the first quad of a directory (the
3191 * first directory would be the root directory) is read, it is pushed on
3192 * the this stack. When the directory is all read, it scans the directory
3193 * looking for indirect entries. If any indirect directory entry is found,
3194 * it is pushed on stack and that directory is read. If we are done dealing
3195 * with all entries in the current dir, the directory is popped off the
3196 * stack. If the stack is empty, we are back at the root directory level
3197 * and essentially read the entire directory hierarchy.
3198 * Returns 0 is more quads to read, else returns non-zero.
3200 static int
3201 s1394_calc_next_quad(s1394_hal_t *hal, s1394_node_t *node, uint32_t quadlet,
3202 uint32_t *nextquadp)
3204 uint32_t data, type, key, value, *ptr;
3206 ASSERT(MUTEX_HELD(&hal->topology_tree_mutex));
3208 TNF_PROBE_4_DEBUG(s1394_calc_next_quad_enter,
3209 S1394_TNF_SL_HOTPLUG_STACK, "", tnf_uint, node_num, node->node_num,
3210 tnf_uint, quadlet, quadlet, tnf_int, cfgrom_size, node->cfgrom_size,
3211 tnf_uint, hal_gen, hal->generation_count);
3213 if (((quadlet + 1) >= node->cfgrom_size) ||
3214 (CFGROM_SIZE_IS_CRCSIZE(node) == B_TRUE && (quadlet + 1) >=
3215 node->cfgrom_valid_size)) {
3216 TNF_PROBE_0_DEBUG(s1394_calc_next_quad_exit,
3217 S1394_TNF_SL_HOTPLUG_STACK, "");
3218 return (1);
3221 if (s1394_turn_off_dir_stack != 0 || CFGROM_DIR_STACK_OFF(node) ==
3222 B_TRUE) {
3223 quadlet++;
3224 *nextquadp = quadlet;
3225 TNF_PROBE_3_DEBUG(s1394_calc_next_quad_exit,
3226 S1394_TNF_SL_HOTPLUG_STACK, "", tnf_string, msg,
3227 "dir stack turned off", tnf_uint, quadlet, quadlet,
3228 tnf_opaque, cfgrom, node->cfgrom);
3229 return (0);
3232 data = node->cfgrom[quadlet];
3234 if (quadlet == IEEE1212_ROOT_DIR_QUAD) {
3235 node->dir_stack_top = -1;
3236 node->expected_dir_quad = quadlet;
3237 node->expected_type = IEEE1212_IMMEDIATE_TYPE;
3240 CFGROM_TYPE_KEY_VALUE(data, type, key, value);
3243 * check to make sure we are looking at a dir. If the config rom
3244 * is broken, then revert to normal scanning of the config rom
3246 if (node->expected_dir_quad == quadlet) {
3247 if (type != 0 || key != 0) {
3248 TNF_PROBE_3_DEBUG(s1394_calc_next_quad,
3249 S1394_TNF_SL_HOTPLUG_ERROR, "", tnf_string, msg,
3250 "bad directory turning off stack", tnf_uint,
3251 quadlet, quadlet, tnf_uint, data, data);
3252 SET_CFGROM_DIR_STACK_OFF(node);
3253 quadlet = IEEE1212_ROOT_DIR_QUAD;
3254 } else {
3255 node->cur_dir_start = quadlet;
3256 node->cur_dir_size = IEEE1212_DIR_LEN(data);
3257 node->expected_dir_quad = 0;
3258 /* get the next quad */
3259 quadlet++;
3261 } else {
3263 * If we read all quads in cur dir and the cur dir is not
3264 * a leaf, scan for offsets (if the directory's CRC checks
3265 * out OK). If we have a directory or a leaf, we save the
3266 * current location on the stack and start reading that
3267 * directory. So, we will end up with a depth first read of
3268 * the entire config rom. If we are done with the current
3269 * directory, pop it off the stack and continue the scanning
3270 * as appropriate.
3272 if (quadlet == node->cur_dir_start + node->cur_dir_size) {
3274 int i, top;
3275 boolean_t done_with_cur_dir = B_FALSE;
3277 if (node->expected_type == IEEE1212_LEAF_TYPE) {
3278 node->expected_type = IEEE1212_IMMEDIATE_TYPE;
3279 done_with_cur_dir = B_TRUE;
3280 TNF_PROBE_2_DEBUG(s1394_calc_next_quad,
3281 S1394_TNF_SL_HOTPLUG_STACK, "",
3282 tnf_string, msg, "done with a leaf",
3283 tnf_uint, quadlet, quadlet);
3284 goto donewithcurdir;
3287 ptr = &node->cfgrom[node->cur_dir_start];
3288 CFGROM_TYPE_KEY_VALUE(*ptr, type, key, value);
3291 * If CRC for this directory is invalid, turn off
3292 * dir stack and start re-reading from root dir.
3293 * This wastes the work done thus far, but CRC
3294 * errors in directories should be rather rare.
3295 * if s1394_crcsz_is_cfgsz is set, then set
3296 * cfgrom_valid_size to the len specfied as crc len
3297 * in quadlet 0.
3299 if (s1394_valid_dir(hal, node, key, ptr) == B_FALSE) {
3300 SET_CFGROM_DIR_STACK_OFF(node);
3301 if (s1394_crcsz_is_cfgsz != 0) {
3302 SET_CFGROM_SIZE_IS_CRCSIZE(node);
3303 node->cfgrom_valid_size =
3304 ((node->cfgrom[0] >>
3305 IEEE1394_CFG_ROM_CRC_LEN_SHIFT) &
3306 IEEE1394_CFG_ROM_CRC_LEN_MASK);
3307 TNF_PROBE_2(s1394_calc_next_quad,
3308 S1394_TNF_SL_HOTPLUG_ERROR, "",
3309 tnf_string, msg, "crc sz is cfg sz",
3310 tnf_uint, size,
3311 node->cfgrom_valid_size);
3313 TNF_PROBE_2_DEBUG(s1394_calc_next_quad_exit,
3314 S1394_TNF_SL_HOTPLUG_STACK, "", tnf_string,
3315 msg, "crc error", tnf_uint, quadlet,
3316 quadlet);
3317 *nextquadp = IEEE1212_ROOT_DIR_QUAD;
3318 return (0);
3320 i = node->cur_dir_start + 1;
3321 rescan:
3322 for (done_with_cur_dir = B_FALSE; i <=
3323 node->cur_dir_start + node->cur_dir_size; i++) {
3324 data = node->cfgrom[i];
3325 CFGROM_TYPE_KEY_VALUE(data, type, key, value);
3326 /* read leaf type and directory types only */
3327 if (type == IEEE1212_LEAF_TYPE || type ==
3328 IEEE1212_DIRECTORY_TYPE) {
3331 * push current dir on stack; if the
3332 * stack is overflowing, ie, too many
3333 * directory level nestings, turn off
3334 * dir stack and fall back to serial
3335 * scanning, starting at root dir. This
3336 * wastes all the work we have done
3337 * thus far, but more than 16 levels
3338 * of directories is rather odd...
3340 top = ++node->dir_stack_top;
3341 if (top == S1394_DIR_STACK_SIZE) {
3343 TNF_PROBE_2_DEBUG(
3344 s1394_calc_next_quad_exit,
3345 S1394_TNF_SL_HOTPLUG_STACK,
3346 "", tnf_string, msg,
3347 "dir stack overflow",
3348 tnf_uint, quadlet, quadlet);
3349 SET_CFGROM_DIR_STACK_OFF(node);
3350 *nextquadp =
3351 IEEE1212_ROOT_DIR_QUAD;
3352 return (0);
3355 TNF_PROBE_3_DEBUG(
3356 s1394_calc_next_quad,
3357 S1394_TNF_SL_HOTPLUG_STACK, "",
3358 tnf_string, msg, "push dir stack",
3359 tnf_uint, quadlet, quadlet,
3360 tnf_int, top, top);
3362 node->dir_stack[top].dir_start =
3363 node->cur_dir_start;
3364 node->dir_stack[top].dir_size =
3365 node->cur_dir_size;
3366 node->dir_stack[top].dir_next_quad =
3367 i + 1;
3368 /* and set the next quadlet to read */
3369 quadlet = i + value;
3370 node->expected_dir_quad = quadlet;
3371 node->expected_type = type;
3372 break;
3376 donewithcurdir:
3378 if ((i > node->cur_dir_start + node->cur_dir_size) ||
3379 done_with_cur_dir == B_TRUE) {
3382 * all done with cur dir; pop it off the stack
3384 if (node->dir_stack_top >= 0) {
3385 TNF_PROBE_3_DEBUG(
3386 s1394_calc_next_quad_exit,
3387 S1394_TNF_SL_HOTPLUG_STACK, "",
3388 tnf_string, msg, "pop dir stack",
3389 tnf_uint, quadlet, quadlet,
3390 tnf_int, top, node->dir_stack_top);
3391 top = node->dir_stack_top--;
3392 node->cur_dir_start =
3393 node->dir_stack[top].dir_start;
3394 node->cur_dir_size =
3395 node->dir_stack[top].dir_size;
3396 i = node->dir_stack[top].dir_next_quad;
3397 goto rescan;
3398 } else {
3400 * if empty stack, we are at the top
3401 * level; declare done.
3403 TNF_PROBE_1_DEBUG(
3404 s1394_calc_next_quad_exit,
3405 S1394_TNF_SL_HOTPLUG_STACK, "",
3406 tnf_string, msg, "all done");
3407 return (1);
3410 } else {
3411 /* get the next quadlet */
3412 quadlet++;
3415 *nextquadp = quadlet;
3417 TNF_PROBE_1_DEBUG(s1394_calc_next_quad_exit, S1394_TNF_SL_HOTPLUG_STACK,
3418 "", tnf_uint, next_quad, quadlet);
3420 return (0);