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