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