1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 /* 30 * h1394.c 31 * 1394 Services Layer HAL Interface 32 * Contains all of the routines that define the HAL to Services Layer 33 * interface 34 */ 35 36 #include <sys/conf.h> 37 #include <sys/ddi.h> 38 #include <sys/sunddi.h> 39 #include <sys/modctl.h> 40 #include <sys/sunndi.h> 41 #include <sys/cmn_err.h> 42 #include <sys/types.h> 43 #include <sys/kmem.h> 44 #include <sys/thread.h> 45 #include <sys/proc.h> 46 #include <sys/disp.h> 47 #include <sys/time.h> 48 #include <sys/devctl.h> 49 #include <sys/tnf_probe.h> 50 51 #include <sys/1394/t1394.h> 52 #include <sys/1394/s1394.h> 53 #include <sys/1394/h1394.h> 54 #include <sys/1394/ieee1394.h> 55 56 57 extern struct bus_ops nx1394_busops; 58 extern int nx1394_define_events(s1394_hal_t *hal); 59 extern void nx1394_undefine_events(s1394_hal_t *hal); 60 extern int s1394_ignore_invalid_gap_cnt; 61 62 /* 63 * Function: h1394_init() 64 * Input(s): modlp The structure containing all of the 65 * HAL's relevant information 66 * 67 * Output(s): 68 * 69 * Description: h1394_init() is called by the HAL's _init function and is 70 * used to set up the nexus bus ops. 71 */ 72 int 73 h1394_init(struct modlinkage *modlp) 74 { 75 struct dev_ops *devops; 76 77 TNF_PROBE_0_DEBUG(h1394_init_enter, S1394_TNF_SL_STACK, ""); 78 79 devops = ((struct modldrv *)(modlp->ml_linkage[0]))->drv_dev_ops; 80 devops->devo_bus_ops = &nx1394_busops; 81 82 TNF_PROBE_0_DEBUG(h1394_init_exit, S1394_TNF_SL_STACK, ""); 83 return (0); 84 } 85 86 /* 87 * Function: h1394_fini() 88 * Input(s): modlp The structure containing all of the 89 * HAL's relevant information 90 * 91 * Output(s): 92 * 93 * Description: h1394_fini() is called by the HAL's _fini function and is 94 * used to NULL out the nexus bus ops. 95 */ 96 void 97 h1394_fini(struct modlinkage *modlp) 98 { 99 struct dev_ops *devops; 100 101 TNF_PROBE_0_DEBUG(h1394_fini_enter, S1394_TNF_SL_STACK, ""); 102 103 devops = ((struct modldrv *)(modlp->ml_linkage[0]))->drv_dev_ops; 104 devops->devo_bus_ops = NULL; 105 106 TNF_PROBE_0_DEBUG(h1394_fini_enter, S1394_TNF_SL_STACK, ""); 107 } 108 109 /* 110 * Function: h1394_attach() 111 * Input(s): halinfo The structure containing all of the 112 * HAL's relevant information 113 * cmd The ddi_attach_cmd_t that tells us 114 * if this is a RESUME or a regular 115 * attach() call 116 * 117 * Output(s): sl_private The HAL "handle" to be used for 118 * all subsequent calls into the 119 * 1394 Software Framework 120 * 121 * Description: h1394_attach() registers the HAL with the 1394 Software 122 * Framework. It returns a HAL "handle" to be used for 123 * all subsequent calls into the 1394 Software Framework. 124 */ 125 int 126 h1394_attach(h1394_halinfo_t *halinfo, ddi_attach_cmd_t cmd, void **sl_private) 127 { 128 s1394_hal_t *hal; 129 int ret; 130 char buf[32]; 131 uint_t cmd_size; 132 133 TNF_PROBE_0_DEBUG(h1394_attach_enter, S1394_TNF_SL_STACK, ""); 134 135 ASSERT(sl_private != NULL); 136 137 /* If this is a DDI_RESUME, return success */ 138 if (cmd == DDI_RESUME) { 139 hal = (s1394_hal_t *)(*sl_private); 140 /* If we have a 1394A PHY, then reset the "contender bit" */ 141 if (hal->halinfo.phy == H1394_PHY_1394A) 142 (void) HAL_CALL(hal).set_contender_bit( 143 hal->halinfo.hal_private); 144 TNF_PROBE_0_DEBUG(h1394_attach_exit, S1394_TNF_SL_STACK, 145 ""); 146 return (DDI_SUCCESS); 147 } else if (cmd != DDI_ATTACH) { 148 TNF_PROBE_2(h1394_attach_error, S1394_TNF_SL_ERROR, "", 149 tnf_string, msg, "Invalid ddi_attach_cmd received", 150 tnf_uint, attach_cmd, (uint_t)cmd); 151 TNF_PROBE_0_DEBUG(h1394_attach_exit, S1394_TNF_SL_STACK, 152 ""); 153 return (DDI_FAILURE); 154 } 155 156 /* Allocate space for s1394_hal_t */ 157 hal = kmem_zalloc(sizeof (s1394_hal_t), KM_SLEEP); 158 159 /* Setup HAL state */ 160 hal->hal_state = S1394_HAL_INIT; 161 162 /* Copy in the halinfo struct */ 163 hal->halinfo = *halinfo; 164 165 /* Create the topology tree mutex */ 166 mutex_init(&hal->topology_tree_mutex, NULL, MUTEX_DRIVER, 167 hal->halinfo.hw_interrupt); 168 169 /* Create the Cycle Mater timer mutex */ 170 mutex_init(&hal->cm_timer_mutex, NULL, MUTEX_DRIVER, 171 hal->halinfo.hw_interrupt); 172 173 /* Initialize the Isoch CEC list */ 174 hal->isoch_cec_list_head = NULL; 175 hal->isoch_cec_list_tail = NULL; 176 mutex_init(&hal->isoch_cec_list_mutex, NULL, MUTEX_DRIVER, 177 hal->halinfo.hw_interrupt); 178 179 /* Initialize the Bus Manager node ID mutex and cv */ 180 mutex_init(&hal->bus_mgr_node_mutex, NULL, MUTEX_DRIVER, 181 hal->halinfo.hw_interrupt); 182 cv_init(&hal->bus_mgr_node_cv, NULL, CV_DRIVER, 183 hal->halinfo.hw_interrupt); 184 185 /* Initialize the Bus Manager node ID - "-1" means undetermined */ 186 hal->bus_mgr_node = -1; 187 hal->incumbent_bus_mgr = B_FALSE; 188 189 /* Initialize the Target list */ 190 hal->target_head = NULL; 191 hal->target_tail = NULL; 192 rw_init(&hal->target_list_rwlock, NULL, RW_DRIVER, 193 hal->halinfo.hw_interrupt); 194 195 /* Setup Request Q's */ 196 hal->outstanding_q_head = NULL; 197 hal->outstanding_q_tail = NULL; 198 mutex_init(&hal->outstanding_q_mutex, NULL, MUTEX_DRIVER, 199 hal->halinfo.hw_interrupt); 200 hal->pending_q_head = NULL; 201 hal->pending_q_tail = NULL; 202 mutex_init(&hal->pending_q_mutex, NULL, MUTEX_DRIVER, 203 hal->halinfo.hw_interrupt); 204 205 /* Create the kmem_cache for command allocations */ 206 (void) sprintf(buf, "hal%d_cache", ddi_get_instance(hal->halinfo.dip)); 207 cmd_size = sizeof (cmd1394_cmd_t) + sizeof (s1394_cmd_priv_t) + 208 hal->halinfo.hal_overhead; 209 210 hal->hal_kmem_cachep = kmem_cache_create(buf, cmd_size, 8, NULL, NULL, 211 NULL, NULL, NULL, 0); 212 213 /* Setup the event stuff */ 214 ret = nx1394_define_events(hal); 215 if (ret != DDI_SUCCESS) { 216 /* Clean up before leaving */ 217 s1394_cleanup_for_detach(hal, H1394_CLEANUP_LEVEL0); 218 219 TNF_PROBE_1(h1394_attach_error, S1394_TNF_SL_ERROR, "", 220 tnf_string, msg, "Unable to define attach events"); 221 TNF_PROBE_0_DEBUG(h1394_attach_exit, S1394_TNF_SL_STACK, 222 ""); 223 return (DDI_FAILURE); 224 } 225 226 /* Initialize the mutexes and cv's used by the bus reset thread */ 227 mutex_init(&hal->br_thread_mutex, NULL, MUTEX_DRIVER, 228 hal->halinfo.hw_interrupt); 229 cv_init(&hal->br_thread_cv, NULL, CV_DRIVER, hal->halinfo.hw_interrupt); 230 mutex_init(&hal->br_cmplq_mutex, NULL, MUTEX_DRIVER, 231 hal->halinfo.hw_interrupt); 232 cv_init(&hal->br_cmplq_cv, NULL, CV_DRIVER, hal->halinfo.hw_interrupt); 233 234 /* 235 * Create a bus reset thread to handle the device discovery. 236 * It should take the default stack sizes, it should run 237 * the s1394_br_thread() routine at the start, passing the 238 * HAL pointer as its argument. The thread should be put 239 * on processor p0, its state should be set to runnable, 240 * but not yet on a processor, and its scheduling priority 241 * should be the minimum level of any system class. 242 */ 243 hal->br_thread = thread_create((caddr_t)NULL, 0, s1394_br_thread, 244 hal, 0, &p0, TS_RUN, minclsyspri); 245 246 /* Until we see a bus reset this HAL has no nodes */ 247 hal->number_of_nodes = 0; 248 hal->num_bus_reset_till_fail = NUM_BR_FAIL; 249 250 /* Initialize the SelfID Info */ 251 hal->current_buffer = 0; 252 hal->selfid_buf0 = kmem_zalloc(S1394_SELFID_BUF_SIZE, KM_SLEEP); 253 hal->selfid_buf1 = kmem_zalloc(S1394_SELFID_BUF_SIZE, KM_SLEEP); 254 255 /* Initialize kstat structures */ 256 ret = s1394_kstat_init(hal); 257 if (ret != DDI_SUCCESS) { 258 /* Clean up before leaving */ 259 s1394_cleanup_for_detach(hal, H1394_CLEANUP_LEVEL3); 260 261 TNF_PROBE_1(h1394_attach_error, S1394_TNF_SL_ERROR, "", 262 tnf_string, msg, "Failure in s1394_kstat_init"); 263 TNF_PROBE_0_DEBUG(h1394_attach_exit, S1394_TNF_SL_STACK, 264 ""); 265 return (DDI_FAILURE); 266 } 267 hal->hal_kstats->guid = hal->halinfo.guid; 268 269 /* Setup the node tree pointers */ 270 hal->old_tree = &hal->last_valid_tree[0]; 271 hal->topology_tree = &hal->current_tree[0]; 272 273 /* Initialize the local Config ROM entry */ 274 ret = s1394_init_local_config_rom(hal); 275 if (ret != DDI_SUCCESS) { 276 /* Clean up before leaving */ 277 s1394_cleanup_for_detach(hal, H1394_CLEANUP_LEVEL4); 278 279 TNF_PROBE_1(h1394_attach_error, S1394_TNF_SL_ERROR, "", 280 tnf_string, msg, "Failure in s1394_init_local_config_rom"); 281 TNF_PROBE_0_DEBUG(h1394_attach_exit, S1394_TNF_SL_STACK, ""); 282 return (DDI_FAILURE); 283 } 284 285 /* Initialize 1394 Address Space */ 286 ret = s1394_init_addr_space(hal); 287 if (ret != DDI_SUCCESS) { 288 /* Clean up before leaving */ 289 s1394_cleanup_for_detach(hal, H1394_CLEANUP_LEVEL5); 290 291 TNF_PROBE_1(h1394_attach_error, S1394_TNF_SL_ERROR, "", 292 tnf_string, msg, "Invalid 1394 address space"); 293 TNF_PROBE_0_DEBUG(h1394_attach_exit, S1394_TNF_SL_STACK, 294 ""); 295 return (DDI_FAILURE); 296 } 297 298 /* Initialize FCP subsystem */ 299 ret = s1394_fcp_hal_init(hal); 300 if (ret != DDI_SUCCESS) { 301 /* Clean up before leaving */ 302 s1394_cleanup_for_detach(hal, H1394_CLEANUP_LEVEL6); 303 304 TNF_PROBE_1(h1394_attach_error, S1394_TNF_SL_ERROR, "", 305 tnf_string, msg, "FCP initialization failure"); 306 TNF_PROBE_0_DEBUG(h1394_attach_exit, S1394_TNF_SL_STACK, 307 ""); 308 return (DDI_FAILURE); 309 } 310 311 /* Initialize the IRM node ID - "-1" means invalid, undetermined */ 312 hal->IRM_node = -1; 313 314 /* If we have a 1394A PHY, then set the "contender bit" */ 315 if (hal->halinfo.phy == H1394_PHY_1394A) 316 (void) HAL_CALL(hal).set_contender_bit( 317 hal->halinfo.hal_private); 318 319 /* Add into linked list */ 320 mutex_enter(&s1394_statep->hal_list_mutex); 321 if ((s1394_statep->hal_head == NULL) && 322 (s1394_statep->hal_tail == NULL)) { 323 s1394_statep->hal_head = hal; 324 s1394_statep->hal_tail = hal; 325 } else { 326 s1394_statep->hal_tail->hal_next = hal; 327 hal->hal_prev = s1394_statep->hal_tail; 328 s1394_statep->hal_tail = hal; 329 } 330 mutex_exit(&s1394_statep->hal_list_mutex); 331 332 /* Fill in services layer private info */ 333 *sl_private = (void *)hal; 334 335 TNF_PROBE_0_DEBUG(h1394_attach_exit, S1394_TNF_SL_STACK, ""); 336 return (DDI_SUCCESS); 337 } 338 339 /* 340 * Function: h1394_detach() 341 * Input(s): sl_private The HAL "handle" returned by 342 * h1394_attach() 343 * cmd The ddi_detach_cmd_t that tells us 344 * if this is a SUSPEND or a regular 345 * detach() call 346 * 347 * Output(s): DDI_SUCCESS HAL successfully detached 348 * DDI_FAILURE HAL failed to detach 349 * 350 * Description: h1394_detach() unregisters the HAL from the 1394 Software 351 * Framework. It can be called during a SUSPEND operation or 352 * for a real detach() event. 353 */ 354 int 355 h1394_detach(void **sl_private, ddi_detach_cmd_t cmd) 356 { 357 s1394_hal_t *hal; 358 359 TNF_PROBE_0_DEBUG(h1394_detach_enter, S1394_TNF_SL_STACK, ""); 360 361 hal = (s1394_hal_t *)(*sl_private); 362 363 switch (cmd) { 364 case DDI_DETACH: 365 /* Clean up before leaving */ 366 s1394_cleanup_for_detach(hal, H1394_CLEANUP_LEVEL7); 367 /* NULL out the HAL "handle" */ 368 *sl_private = NULL; 369 break; 370 371 case DDI_SUSPEND: 372 /* Turn off any timers that might be set */ 373 s1394_destroy_timers(hal); 374 /* Set the hal_was_suspended bit */ 375 hal->hal_was_suspended = B_TRUE; 376 break; 377 378 default: 379 TNF_PROBE_2(h1394_attach_error, S1394_TNF_SL_ERROR, "", 380 tnf_string, msg, "Invalid ddi_detach_cmd_t type specified", 381 tnf_uint, detach_cmd, (uint_t)cmd); 382 TNF_PROBE_0_DEBUG(h1394_detach_exit, S1394_TNF_SL_STACK, ""); 383 return (DDI_FAILURE); 384 } 385 386 TNF_PROBE_0_DEBUG(h1394_detach_exit, S1394_TNF_SL_STACK, ""); 387 return (DDI_SUCCESS); 388 } 389 390 /* 391 * Function: h1394_alloc_cmd() 392 * Input(s): sl_private The HAL "handle" returned by 393 * h1394_attach() 394 * flags The flags parameter is described below 395 * 396 * Output(s): cmdp Pointer to the newly allocated command 397 * hal_priv_ptr Offset into the command, points to 398 * the HAL's private area 399 * 400 * Description: h1394_alloc_cmd() allocates a command for use with the 401 * h1394_read_request(), h1394_write_request(), or 402 * h1394_lock_request() interfaces of the 1394 Software Framework. 403 * By default, h1394_alloc_cmd() may sleep while allocating 404 * memory for the command structure. If this is undesirable, 405 * the HAL may set the H1394_ALLOC_CMD_NOSLEEP bit in the flags 406 * parameter. 407 */ 408 int 409 h1394_alloc_cmd(void *sl_private, uint_t flags, cmd1394_cmd_t **cmdp, 410 h1394_cmd_priv_t **hal_priv_ptr) 411 { 412 s1394_hal_t *hal; 413 s1394_cmd_priv_t *s_priv; 414 415 TNF_PROBE_0_DEBUG(h1394_alloc_cmd_enter, S1394_TNF_SL_ARREQ_STACK, 416 ""); 417 418 hal = (s1394_hal_t *)sl_private; 419 420 if (s1394_alloc_cmd(hal, flags, cmdp) != DDI_SUCCESS) { 421 TNF_PROBE_1(h1394_alloc_cmd_error, S1394_TNF_SL_ARREQ_ERROR, "", 422 tnf_string, msg, "Failed to allocate command structure"); 423 TNF_PROBE_0_DEBUG(h1394_alloc_cmd_exit, 424 S1394_TNF_SL_ARREQ_STACK, ""); 425 return (DDI_FAILURE); 426 } 427 428 /* Get the Services Layer private area */ 429 s_priv = S1394_GET_CMD_PRIV(*cmdp); 430 431 *hal_priv_ptr = &s_priv->hal_cmd_private; 432 433 TNF_PROBE_0_DEBUG(h1394_alloc_cmd_exit, S1394_TNF_SL_ARREQ_STACK, 434 ""); 435 return (DDI_SUCCESS); 436 } 437 438 /* 439 * Function: h1394_free_cmd() 440 * Input(s): sl_private The HAL "handle" returned by 441 * h1394_attach() 442 * cmdp Pointer to the command to be freed 443 * 444 * Output(s): DDI_SUCCESS HAL successfully freed command 445 * DDI_FAILURE HAL failed to free command 446 * 447 * Description: h1394_free_cmd() attempts to free a command that has previously 448 * been allocated by the HAL. It is possible for h1394_free_cmd() 449 * to fail because the command is currently in-use by the 1394 450 * Software Framework. 451 */ 452 int 453 h1394_free_cmd(void *sl_private, cmd1394_cmd_t **cmdp) 454 { 455 s1394_hal_t *hal; 456 s1394_cmd_priv_t *s_priv; 457 458 TNF_PROBE_0_DEBUG(h1394_free_cmd_enter, S1394_TNF_SL_ARREQ_STACK, 459 ""); 460 461 hal = (s1394_hal_t *)sl_private; 462 463 /* Get the Services Layer private area */ 464 s_priv = S1394_GET_CMD_PRIV(*cmdp); 465 466 /* Check that command isn't in use */ 467 if (s_priv->cmd_in_use == B_TRUE) { 468 TNF_PROBE_1(h1394_free_cmd_error, S1394_TNF_SL_ARREQ_ERROR, "", 469 tnf_string, msg, "Attempted to free an in-use command"); 470 TNF_PROBE_0_DEBUG(h1394_free_cmd_exit, S1394_TNF_SL_ARREQ_STACK, 471 ""); 472 ASSERT(s_priv->cmd_in_use == B_FALSE); 473 return (DDI_FAILURE); 474 } 475 476 kmem_cache_free(hal->hal_kmem_cachep, *cmdp); 477 478 /* Command pointer is set to NULL before returning */ 479 *cmdp = NULL; 480 481 /* kstats - number of cmds freed */ 482 hal->hal_kstats->cmd_free++; 483 484 TNF_PROBE_0_DEBUG(h1394_free_cmd_exit, S1394_TNF_SL_ARREQ_STACK, 485 ""); 486 return (DDI_SUCCESS); 487 } 488 489 /* 490 * Function: h1394_cmd_is_complete() 491 * Input(s): sl_private The HAL "handle" returned by 492 * h1394_attach() 493 * command_id Pointer to the command that has 494 * just completed 495 * cmd_type AT_RESP => AT response or ATREQ = 496 * AT request 497 * status Command's completion status 498 * 499 * Output(s): None 500 * 501 * Description: h1394_cmd_is_complete() is called by the HAL whenever an 502 * outstanding command has completed (successfully or otherwise). 503 * After determining whether it was an AT request or and AT 504 * response that we are handling, the command is dispatched to 505 * the appropriate handler in the 1394 Software Framework. 506 */ 507 void 508 h1394_cmd_is_complete(void *sl_private, cmd1394_cmd_t *command_id, 509 uint32_t cmd_type, int status) 510 { 511 s1394_hal_t *hal; 512 dev_info_t *dip; 513 514 TNF_PROBE_0_DEBUG(h1394_cmd_is_complete_enter, 515 S1394_TNF_SL_ATREQ_ATRESP_STACK, ""); 516 517 hal = (s1394_hal_t *)sl_private; 518 519 /* Is it AT_RESP or AT_REQ? */ 520 switch (cmd_type) { 521 case H1394_AT_REQ: 522 s1394_atreq_cmd_complete(hal, command_id, status); 523 break; 524 525 case H1394_AT_RESP: 526 s1394_atresp_cmd_complete(hal, command_id, status); 527 break; 528 529 default: 530 dip = hal->halinfo.dip; 531 532 /* An unexpected error in the HAL */ 533 cmn_err(CE_WARN, HALT_ERROR_MESSAGE, 534 ddi_node_name(dip), ddi_get_instance(dip)); 535 536 /* Disable the HAL */ 537 s1394_hal_shutdown(hal, B_TRUE); 538 539 TNF_PROBE_1(h1394_cmd_is_complete_error, 540 S1394_TNF_SL_ATREQ_ATRESP_ERROR, "", 541 tnf_string, msg, "Invalid command type specified"); 542 break; 543 } 544 545 TNF_PROBE_0_DEBUG(h1394_cmd_is_complete_exit, 546 S1394_TNF_SL_ATREQ_ATRESP_STACK, ""); 547 } 548 549 /* 550 * Function: h1394_bus_reset() 551 * Input(s): sl_private The HAL "handle" returned by 552 * h1394_attach() 553 * 554 * Output(s): selfid_buf_addr The pointer to a buffer into which 555 * any Self ID packets should be put 556 * 557 * Description: h1394_bus_reset() is called whenever a 1394 bus reset event 558 * is detected by the HAL. This routine simply prepares for 559 * the subsequent Self ID packets. 560 */ 561 void 562 h1394_bus_reset(void *sl_private, void **selfid_buf_addr) 563 { 564 s1394_hal_t *hal; 565 566 TNF_PROBE_0_DEBUG(h1394_bus_reset_enter, S1394_TNF_SL_BR_STACK, ""); 567 568 hal = (s1394_hal_t *)sl_private; 569 570 mutex_enter(&hal->topology_tree_mutex); 571 572 /* Update the HAL's state */ 573 if (hal->hal_state != S1394_HAL_SHUTDOWN) { 574 hal->hal_state = S1394_HAL_RESET; 575 } else { 576 mutex_exit(&hal->topology_tree_mutex); 577 return; 578 } 579 580 if (hal->initiated_bus_reset == B_TRUE) { 581 hal->initiated_bus_reset = B_FALSE; 582 if (hal->num_bus_reset_till_fail > 0) { 583 hal->num_bus_reset_till_fail--; 584 } else { 585 TNF_PROBE_2(h1394_bus_reset_error, 586 S1394_TNF_SL_BR_ERROR, "", 587 tnf_string, msg, "Bus reset fail (too many resets)", 588 tnf_uint, br_type, hal->initiated_br_reason); 589 } 590 } else { 591 hal->num_bus_reset_till_fail = NUM_BR_FAIL; 592 } 593 594 /* Reset the IRM node ID */ 595 hal->IRM_node = -1; 596 597 /* Slowest node defaults to IEEE1394_S400 */ 598 hal->slowest_node_speed = IEEE1394_S400; 599 600 /* Pick a SelfID buffer to give */ 601 if (hal->current_buffer == 0) { 602 *selfid_buf_addr = (void *)hal->selfid_buf1; 603 hal->current_buffer = 1; 604 } else { 605 *selfid_buf_addr = (void *)hal->selfid_buf0; 606 hal->current_buffer = 0; 607 } 608 609 /* Disable the CSR topology_map (temporarily) */ 610 s1394_CSR_topology_map_disable(hal); 611 612 mutex_exit(&hal->topology_tree_mutex); 613 614 /* Reset the Bus Manager node ID */ 615 mutex_enter(&hal->bus_mgr_node_mutex); 616 hal->bus_mgr_node = -1; 617 mutex_exit(&hal->bus_mgr_node_mutex); 618 619 TNF_PROBE_0_DEBUG(h1394_bus_reset_exit, S1394_TNF_SL_BR_STACK, ""); 620 } 621 622 /* 623 * Function: h1394_self_ids() 624 * Input(s): sl_private The HAL "handle" returned by 625 * h1394_attach() 626 * selfid_buf_addr Pointer to the Self ID buffer 627 * selfid_size The size of the filled part of the 628 * Self ID buffer 629 * node_id The local (host) node ID for the 630 * current generation 631 * generation_count The current generation number 632 * 633 * Output(s): None 634 * 635 * Description: h1394_self_ids() does alot of the work at bus reset. It 636 * takes the Self ID packets and parses them, builds a topology 637 * tree representation of them, calculates gap count, IRM, speed 638 * map, does any node matching that's possible, and then wakes 639 * up the br_thread. 640 */ 641 void 642 h1394_self_ids(void *sl_private, void *selfid_buf_addr, uint32_t selfid_size, 643 uint32_t node_id, uint32_t generation_count) 644 { 645 s1394_hal_t *hal; 646 int diameter; 647 uint_t gen_diff, gen_rollover; 648 boolean_t tree_copied = B_FALSE; 649 ushort_t saved_number_of_nodes; 650 651 /* 652 * NOTE: current topology tree is referred to as topology_tree 653 * and the old topology tree is referred to as old_tree. 654 * tree_valid indicates selfID buffer checked out OK and we were 655 * able to build the topology tree. 656 * tree_processed indicates we read the config ROMs as needed. 657 */ 658 TNF_PROBE_1_DEBUG(h1394_self_ids_enter, S1394_TNF_SL_BR_STACK, "", 659 tnf_uint, hal_generation, generation_count); 660 661 hal = (s1394_hal_t *)sl_private; 662 663 /* Lock the topology tree */ 664 mutex_enter(&hal->topology_tree_mutex); 665 if (hal->hal_state == S1394_HAL_SHUTDOWN) { 666 mutex_exit(&hal->topology_tree_mutex); 667 TNF_PROBE_0_DEBUG(h1394_self_ids_exit, S1394_TNF_SL_BR_STACK, 668 ""); 669 return; 670 } 671 672 /* kstats - number of selfid completes */ 673 hal->hal_kstats->selfid_complete++; 674 675 if (generation_count > hal->generation_count) { 676 gen_diff = generation_count - hal->generation_count; 677 hal->hal_kstats->bus_reset += gen_diff; 678 } else { 679 gen_diff = hal->generation_count - generation_count; 680 /* Use max_generation to determine how many bus resets */ 681 hal->hal_kstats->bus_reset += 682 (hal->halinfo.max_generation - gen_diff); 683 } 684 685 /* 686 * If the current tree has a valid topology tree (selfids 687 * checked out OK etc) and config roms read as needed, 688 * then make it the old tree before building a new one. 689 */ 690 if ((hal->topology_tree_valid == B_TRUE) && 691 (hal->topology_tree_processed == B_TRUE)) { 692 TNF_PROBE_0_DEBUG(h1394_self_ids_tree_copy, 693 S1394_TNF_SL_BR_STACK, ""); 694 /* Trees are switched after the copy completes */ 695 s1394_copy_old_tree(hal); 696 tree_copied = B_TRUE; 697 } 698 699 /* Set the new generation and node id */ 700 hal->node_id = node_id; 701 hal->generation_count = generation_count; 702 703 /* Invalidate the current topology tree */ 704 hal->topology_tree_valid = B_FALSE; 705 hal->topology_tree_processed = B_FALSE; 706 hal->cfgroms_being_read = 0; 707 708 TNF_PROBE_0_DEBUG(h1394_self_ids_parse_selfid, S1394_TNF_SL_BR_STACK, 709 ""); 710 711 /* 712 * Save the number of nodes prior to parsing the self id buffer. 713 * We need this saved value while initializing the topology tree 714 * (for non-copy case). 715 */ 716 saved_number_of_nodes = hal->number_of_nodes; 717 718 /* Parse the SelfID buffer */ 719 if (s1394_parse_selfid_buffer(hal, selfid_buf_addr, selfid_size) != 720 DDI_SUCCESS) { 721 /* Unlock the topology tree */ 722 mutex_exit(&hal->topology_tree_mutex); 723 TNF_PROBE_1(h1394_self_ids_error, S1394_TNF_SL_BR_ERROR, "", 724 tnf_string, msg, "Unable to parse selfID buffer"); 725 TNF_PROBE_0_DEBUG(h1394_self_ids_exit, S1394_TNF_SL_BR_STACK, 726 ""); 727 728 /* kstats - SelfID buffer error */ 729 hal->hal_kstats->selfid_buffer_error++; 730 return; /* Error parsing SelfIDs */ 731 } 732 733 /* Sort the SelfID packets by node number (if it's a 1995 PHY) */ 734 if (hal->halinfo.phy == H1394_PHY_1995) { 735 TNF_PROBE_0_DEBUG(h1394_self_ids_sort, S1394_TNF_SL_BR_STACK, 736 ""); 737 s1394_sort_selfids(hal); 738 } 739 740 /* 741 * Update the cycle master timer - if the timer is set and 742 * we were the root but we are not anymore, then disable it. 743 */ 744 mutex_enter(&hal->cm_timer_mutex); 745 if ((hal->cm_timer_set == B_TRUE) && 746 ((hal->old_number_of_nodes - 1) == 747 IEEE1394_NODE_NUM(hal->old_node_id)) && 748 ((hal->number_of_nodes - 1) != 749 IEEE1394_NODE_NUM(hal->node_id))) { 750 mutex_exit(&hal->cm_timer_mutex); 751 (void) untimeout(hal->cm_timer); 752 } else { 753 mutex_exit(&hal->cm_timer_mutex); 754 } 755 756 TNF_PROBE_0_DEBUG(h1394_self_ids_init_topology, S1394_TNF_SL_BR_STACK, 757 ""); 758 s1394_init_topology_tree(hal, tree_copied, saved_number_of_nodes); 759 760 /* Determine the 1394 bus gap count */ 761 hal->gap_count = s1394_get_current_gap_count(hal); 762 /* If gap counts are inconsistent, reset */ 763 if (hal->gap_count == -1) { 764 /* Unlock the topology tree */ 765 mutex_exit(&hal->topology_tree_mutex); 766 TNF_PROBE_1(h1394_self_ids_error, S1394_TNF_SL_BR_ERROR, "", 767 tnf_string, msg, "Invalid gap counts in SelfID pkts"); 768 TNF_PROBE_0_DEBUG(h1394_self_ids_exit, S1394_TNF_SL_BR_STACK, 769 ""); 770 771 /* kstats - SelfID buffer error (invalid gap counts) */ 772 hal->hal_kstats->selfid_buffer_error++; 773 774 if (s1394_ignore_invalid_gap_cnt == 1) { 775 /* Lock the topology tree again */ 776 mutex_enter(&hal->topology_tree_mutex); 777 hal->gap_count = 0x3F; 778 } else { 779 return; /* Invalid gap counts in SelfID buffer */ 780 } 781 } 782 783 TNF_PROBE_1_DEBUG(h1394_self_ids_get_gap_count, S1394_TNF_SL_BR_STACK, 784 "", tnf_uint, gap_count, hal->gap_count); 785 786 /* Determine the Isoch Resource Manager */ 787 hal->IRM_node = s1394_get_isoch_rsrc_mgr(hal); 788 789 TNF_PROBE_1_DEBUG(h1394_self_ids_IRM_node, S1394_TNF_SL_BR_STACK, "", 790 tnf_int, IRM_node, hal->IRM_node); 791 792 TNF_PROBE_0_DEBUG(h1394_self_ids_build_topology_tree, 793 S1394_TNF_SL_BR_STACK, ""); 794 795 /* Build the topology tree */ 796 if (s1394_topology_tree_build(hal) != DDI_SUCCESS) { 797 /* Unlock the topology tree */ 798 mutex_exit(&hal->topology_tree_mutex); 799 TNF_PROBE_1(h1394_self_ids_error, S1394_TNF_SL_BR_ERROR, "", 800 tnf_string, msg, "Error building the topology tree"); 801 TNF_PROBE_0_DEBUG(h1394_self_ids_exit, S1394_TNF_SL_BR_STACK, 802 ""); 803 804 /* kstats - SelfID buffer error (Invalid topology tree) */ 805 hal->hal_kstats->selfid_buffer_error++; 806 return; /* Error building topology tree from SelfIDs */ 807 } 808 809 TNF_PROBE_0_DEBUG(h1394_self_ids_topology_CSRs, S1394_TNF_SL_BR_STACK, 810 ""); 811 812 /* Update the CSR topology_map */ 813 s1394_CSR_topology_map_update(hal); 814 815 /* Calculate the diameter */ 816 diameter = s1394_topology_tree_calculate_diameter(hal); 817 818 /* Determine the optimum gap count */ 819 hal->optimum_gap_count = s1394_gap_count_optimize(diameter); 820 821 TNF_PROBE_1_DEBUG(h1394_self_ids_diameter_and_gap_count, 822 S1394_TNF_SL_BR_STACK, "", 823 tnf_uint, optimum_gap, hal->optimum_gap_count); 824 825 TNF_PROBE_0_DEBUG(h1394_self_ids_speed_map, S1394_TNF_SL_BR_STACK, ""); 826 827 /* Fill in the speed map */ 828 s1394_speed_map_fill(hal); 829 830 /* Initialize the two trees (for tree walking) */ 831 s1394_topology_tree_mark_all_unvisited(hal); 832 s1394_old_tree_mark_all_unvisited(hal); 833 s1394_old_tree_mark_all_unmatched(hal); 834 835 /* Are both trees (old and new) valid? */ 836 if ((hal->old_tree_valid == B_TRUE) && 837 (hal->topology_tree_valid == B_TRUE)) { 838 /* If HAL was in a suspended state, then do no matching */ 839 if (hal->hal_was_suspended == B_TRUE) { 840 hal->hal_was_suspended = B_FALSE; 841 } else { 842 gen_rollover = hal->halinfo.max_generation + 1; 843 /* If only one bus reset occurred, match the trees */ 844 if (((hal->old_generation_count + 1) % gen_rollover) == 845 generation_count) { 846 TNF_PROBE_0_DEBUG(h1394_self_ids_tree_matching, 847 S1394_TNF_SL_BR_STACK, ""); 848 s1394_match_tree_nodes(hal); 849 } 850 } 851 } 852 853 /* Unlock the topology tree */ 854 mutex_exit(&hal->topology_tree_mutex); 855 856 /* Wake up the bus reset processing thread */ 857 s1394_tickle_bus_reset_thread(hal); 858 859 TNF_PROBE_0_DEBUG(h1394_self_ids_exit, 860 S1394_TNF_SL_BR_STACK, ""); 861 } 862 863 /* 864 * Function: h1394_read_request() 865 * Input(s): sl_private The HAL "handle" returned by 866 * h1394_attach() 867 * req The incoming AR request 868 * 869 * Output(s): None 870 * 871 * Description: h1394_read_request() receives incoming AR requests. These 872 * asynchronous read requests are dispatched to the appropriate 873 * target (if one has registered) or are handled by the 1394 874 * Software Framework, which will send out an appropriate 875 * response. 876 */ 877 void 878 h1394_read_request(void *sl_private, cmd1394_cmd_t *req) 879 { 880 s1394_hal_t *hal; 881 s1394_cmd_priv_t *s_priv; 882 s1394_addr_space_blk_t *addr_blk; 883 dev_info_t *dip; 884 uint64_t end_of_request; 885 uint32_t offset; 886 size_t cmd_length; 887 uchar_t *bufp_addr; 888 uchar_t *begin_ptr; 889 uchar_t *end_ptr; 890 uchar_t *tmp_ptr; 891 void (*recv_read_req)(cmd1394_cmd_t *); 892 893 TNF_PROBE_0_DEBUG(h1394_read_request_enter, S1394_TNF_SL_ARREQ_STACK, 894 ""); 895 896 hal = (s1394_hal_t *)sl_private; 897 898 /* Get the Services Layer private area */ 899 s_priv = S1394_GET_CMD_PRIV(req); 900 901 s_priv->cmd_priv_xfer_type = S1394_CMD_READ; 902 903 switch (req->cmd_type) { 904 case CMD1394_ASYNCH_RD_QUAD: 905 cmd_length = IEEE1394_QUADLET; 906 hal->hal_kstats->arreq_quad_rd++; 907 break; 908 909 case CMD1394_ASYNCH_RD_BLOCK: 910 cmd_length = req->cmd_u.b.blk_length; 911 hal->hal_kstats->arreq_blk_rd++; 912 break; 913 914 default: 915 dip = hal->halinfo.dip; 916 917 /* An unexpected error in the HAL */ 918 cmn_err(CE_WARN, HALT_ERROR_MESSAGE, 919 ddi_node_name(dip), ddi_get_instance(dip)); 920 921 /* Disable the HAL */ 922 s1394_hal_shutdown(hal, B_TRUE); 923 924 TNF_PROBE_1(h1394_read_request_error, 925 S1394_TNF_SL_ARREQ_ERROR, "", 926 tnf_string, msg, "Invalid command type specified"); 927 TNF_PROBE_0_DEBUG(h1394_read_request_exit, 928 S1394_TNF_SL_ARREQ_STACK, ""); 929 return; 930 } 931 932 /* Lock the "used" tree */ 933 mutex_enter(&hal->addr_space_used_mutex); 934 935 /* Has the 1394 address been allocated? */ 936 addr_blk = s1394_used_tree_search(hal, req->cmd_addr); 937 938 TNF_PROBE_0_DEBUG(h1394_read_request_addr_search, 939 S1394_TNF_SL_ARREQ_STACK, ""); 940 941 /* If it wasn't found, it isn't owned... */ 942 if (addr_blk == NULL) { 943 /* Unlock the "used" tree */ 944 mutex_exit(&hal->addr_space_used_mutex); 945 req->cmd_result = IEEE1394_RESP_ADDRESS_ERROR; 946 (void) s1394_send_response(hal, req); 947 TNF_PROBE_0_DEBUG(h1394_read_request_exit, 948 S1394_TNF_SL_ARREQ_STACK, ""); 949 return; 950 } 951 952 /* Does the WHOLE request fit in the allocated block? */ 953 end_of_request = (req->cmd_addr + cmd_length) - 1; 954 if (end_of_request > addr_blk->addr_hi) { 955 /* Unlock the "used" tree */ 956 mutex_exit(&hal->addr_space_used_mutex); 957 req->cmd_result = IEEE1394_RESP_ADDRESS_ERROR; 958 (void) s1394_send_response(hal, req); 959 TNF_PROBE_0_DEBUG(h1394_read_request_exit, 960 S1394_TNF_SL_ARREQ_STACK, ""); 961 return; 962 } 963 964 /* Is a read request valid for this address space? */ 965 if (!(addr_blk->addr_enable & T1394_ADDR_RDENBL)) { 966 /* Unlock the "used" tree */ 967 mutex_exit(&hal->addr_space_used_mutex); 968 req->cmd_result = IEEE1394_RESP_TYPE_ERROR; 969 (void) s1394_send_response(hal, req); 970 TNF_PROBE_0_DEBUG(h1394_read_request_exit, 971 S1394_TNF_SL_ARREQ_STACK, ""); 972 return; 973 } 974 975 /* Make sure quadlet requests are quadlet-aligned */ 976 offset = req->cmd_addr - addr_blk->addr_lo; 977 if ((req->cmd_type == CMD1394_ASYNCH_RD_QUAD) && 978 ((offset & 0x3) != 0)) { 979 /* Unlock the "used" tree */ 980 mutex_exit(&hal->addr_space_used_mutex); 981 req->cmd_result = IEEE1394_RESP_TYPE_ERROR; 982 (void) s1394_send_response(hal, req); 983 TNF_PROBE_0_DEBUG(h1394_read_request_exit, 984 S1394_TNF_SL_ARREQ_STACK, ""); 985 return; 986 } 987 988 /* Fill in the backing store if necessary */ 989 if (addr_blk->kmem_bufp != NULL) { 990 offset = req->cmd_addr - addr_blk->addr_lo; 991 bufp_addr = (uchar_t *)addr_blk->kmem_bufp + offset; 992 993 switch (req->cmd_type) { 994 case CMD1394_ASYNCH_RD_QUAD: 995 bcopy((void *)bufp_addr, 996 (void *)&(req->cmd_u.q.quadlet_data), cmd_length); 997 break; 998 999 case CMD1394_ASYNCH_RD_BLOCK: 1000 begin_ptr = req->cmd_u.b.data_block->b_wptr; 1001 end_ptr = begin_ptr + cmd_length; 1002 tmp_ptr = req->cmd_u.b.data_block->b_datap->db_lim; 1003 if (end_ptr <= tmp_ptr) { 1004 bcopy((void *)bufp_addr, (void *)begin_ptr, 1005 cmd_length); 1006 /* Update b_wptr to refelect the new data */ 1007 req->cmd_u.b.data_block->b_wptr = end_ptr; 1008 } else { 1009 dip = hal->halinfo.dip; 1010 1011 /* An unexpected error in the HAL */ 1012 cmn_err(CE_WARN, HALT_ERROR_MESSAGE, 1013 ddi_node_name(dip), ddi_get_instance(dip)); 1014 1015 /* Unlock the "used" tree */ 1016 mutex_exit(&hal->addr_space_used_mutex); 1017 1018 /* Disable the HAL */ 1019 s1394_hal_shutdown(hal, B_TRUE); 1020 1021 TNF_PROBE_1(h1394_read_request_error, 1022 S1394_TNF_SL_ARREQ_ERROR, "", tnf_string, 1023 msg, "Error - mblk too small for request"); 1024 TNF_PROBE_0_DEBUG(h1394_read_request_exit, 1025 S1394_TNF_SL_ARREQ_STACK, ""); 1026 return; 1027 } 1028 break; 1029 1030 default: 1031 dip = hal->halinfo.dip; 1032 1033 /* An unexpected error in the HAL */ 1034 cmn_err(CE_WARN, HALT_ERROR_MESSAGE, 1035 ddi_node_name(dip), ddi_get_instance(dip)); 1036 1037 /* Unlock the "used" tree */ 1038 mutex_exit(&hal->addr_space_used_mutex); 1039 1040 /* Disable the HAL */ 1041 s1394_hal_shutdown(hal, B_TRUE); 1042 1043 TNF_PROBE_1(h1394_read_request_error, 1044 S1394_TNF_SL_ARREQ_ERROR, "", tnf_string, msg, 1045 "Invalid command type specified"); 1046 TNF_PROBE_0_DEBUG(h1394_read_request_exit, 1047 S1394_TNF_SL_ARREQ_STACK, ""); 1048 return; 1049 } 1050 } 1051 1052 /* Fill in the rest of the info in the request */ 1053 s_priv->arreq_valid_addr = B_TRUE; 1054 req->cmd_callback_arg = addr_blk->addr_arg; 1055 recv_read_req = addr_blk->addr_events.recv_read_request; 1056 1057 /* Unlock the "used" tree */ 1058 mutex_exit(&hal->addr_space_used_mutex); 1059 1060 /* 1061 * Add no code that modifies the command after the target 1062 * callback is called or after the response is sent to the 1063 * HAL. 1064 */ 1065 if (recv_read_req != NULL) { 1066 TNF_PROBE_0_DEBUG(h1394_read_request_do_callback, 1067 S1394_TNF_SL_ARREQ_STACK, ""); 1068 recv_read_req(req); 1069 } else { 1070 req->cmd_result = IEEE1394_RESP_COMPLETE; 1071 (void) s1394_send_response(hal, req); 1072 TNF_PROBE_0_DEBUG(h1394_read_request_exit, 1073 S1394_TNF_SL_ARREQ_STACK, ""); 1074 return; 1075 } 1076 1077 TNF_PROBE_0_DEBUG(h1394_read_request_exit, S1394_TNF_SL_ARREQ_STACK, 1078 ""); 1079 } 1080 1081 /* 1082 * Function: h1394_write_request() 1083 * Input(s): sl_private The HAL "handle" returned by 1084 * h1394_attach() 1085 * req The incoming AR request 1086 * 1087 * Output(s): None 1088 * 1089 * Description: h1394_write_request() receives incoming AR requests. These 1090 * asynchronous write requests are dispatched to the appropriate 1091 * target (if one has registered) or are handled by the 1394 1092 * Software Framework, which will send out an appropriate 1093 * response. 1094 */ 1095 void 1096 h1394_write_request(void *sl_private, cmd1394_cmd_t *req) 1097 { 1098 s1394_hal_t *hal; 1099 s1394_cmd_priv_t *s_priv; 1100 h1394_cmd_priv_t *h_priv; 1101 s1394_addr_space_blk_t *addr_blk; 1102 dev_info_t *dip; 1103 uint32_t offset; 1104 size_t cmd_length; 1105 uchar_t *bufp_addr; 1106 uchar_t *begin_ptr; 1107 uchar_t *end_ptr; 1108 uchar_t *tmp_ptr; 1109 uint64_t end_of_request; 1110 boolean_t posted_write = B_FALSE; 1111 boolean_t write_error = B_FALSE; 1112 void (*recv_write_req)(cmd1394_cmd_t *); 1113 1114 TNF_PROBE_0_DEBUG(h1394_write_request_enter, S1394_TNF_SL_ARREQ_STACK, 1115 ""); 1116 1117 hal = (s1394_hal_t *)sl_private; 1118 1119 /* Get the Services Layer private area */ 1120 s_priv = S1394_GET_CMD_PRIV(req); 1121 1122 s_priv->cmd_priv_xfer_type = S1394_CMD_WRITE; 1123 1124 switch (req->cmd_type) { 1125 case CMD1394_ASYNCH_WR_QUAD: 1126 cmd_length = IEEE1394_QUADLET; 1127 hal->hal_kstats->arreq_quad_wr++; 1128 break; 1129 1130 case CMD1394_ASYNCH_WR_BLOCK: 1131 cmd_length = req->cmd_u.b.blk_length; 1132 hal->hal_kstats->arreq_blk_wr++; 1133 hal->hal_kstats->arreq_blk_wr_size += cmd_length; 1134 break; 1135 1136 default: 1137 dip = hal->halinfo.dip; 1138 1139 /* An unexpected error in the HAL */ 1140 cmn_err(CE_WARN, HALT_ERROR_MESSAGE, 1141 ddi_node_name(dip), ddi_get_instance(dip)); 1142 1143 /* Disable the HAL */ 1144 s1394_hal_shutdown(hal, B_TRUE); 1145 1146 TNF_PROBE_1(h1394_write_request_error, 1147 S1394_TNF_SL_ARREQ_ERROR, "", tnf_string, msg, 1148 "Invalid command type specified"); 1149 TNF_PROBE_0_DEBUG(h1394_write_request_exit, 1150 S1394_TNF_SL_ARREQ_STACK, ""); 1151 return; 1152 } 1153 1154 /* Lock the "used" tree */ 1155 mutex_enter(&hal->addr_space_used_mutex); 1156 1157 /* Has the 1394 address been allocated? */ 1158 addr_blk = s1394_used_tree_search(hal, req->cmd_addr); 1159 1160 TNF_PROBE_0_DEBUG(h1394_write_request_addr_search, 1161 S1394_TNF_SL_ARREQ_STACK, ""); 1162 1163 /* Is this a posted write request? */ 1164 posted_write = s1394_is_posted_write(hal, req->cmd_addr); 1165 1166 /* If it wasn't found, it isn't owned... */ 1167 if (addr_blk == NULL) { 1168 req->cmd_result = IEEE1394_RESP_ADDRESS_ERROR; 1169 write_error = B_TRUE; 1170 goto write_error_check; 1171 } 1172 1173 /* Does the WHOLE request fit in the allocated block? */ 1174 end_of_request = (req->cmd_addr + cmd_length) - 1; 1175 if (end_of_request > addr_blk->addr_hi) { 1176 req->cmd_result = IEEE1394_RESP_ADDRESS_ERROR; 1177 write_error = B_TRUE; 1178 goto write_error_check; 1179 } 1180 1181 /* Is a write request valid for this address space? */ 1182 if (!(addr_blk->addr_enable & T1394_ADDR_WRENBL)) { 1183 req->cmd_result = IEEE1394_RESP_TYPE_ERROR; 1184 write_error = B_TRUE; 1185 goto write_error_check; 1186 } 1187 1188 /* Make sure quadlet request is quadlet aligned */ 1189 offset = req->cmd_addr - addr_blk->addr_lo; 1190 if ((req->cmd_type == CMD1394_ASYNCH_WR_QUAD) && 1191 ((offset & 0x3) != 0)) { 1192 req->cmd_result = IEEE1394_RESP_TYPE_ERROR; 1193 write_error = B_TRUE; 1194 goto write_error_check; 1195 } 1196 1197 write_error_check: 1198 /* Check if posted-write when sending error responses */ 1199 if (write_error == B_TRUE) { 1200 /* Unlock the "used" tree */ 1201 mutex_exit(&hal->addr_space_used_mutex); 1202 1203 if (posted_write == B_TRUE) { 1204 /* Get a pointer to the HAL private struct */ 1205 h_priv = (h1394_cmd_priv_t *)&s_priv->hal_cmd_private; 1206 hal->hal_kstats->arreq_posted_write_error++; 1207 /* Free the command - Pass it back to the HAL */ 1208 HAL_CALL(hal).response_complete( 1209 hal->halinfo.hal_private, req, h_priv); 1210 TNF_PROBE_0_DEBUG(h1394_write_request_exit, 1211 S1394_TNF_SL_ARREQ_STACK, ""); 1212 return; 1213 } else { 1214 (void) s1394_send_response(hal, req); 1215 TNF_PROBE_0_DEBUG(h1394_write_request_exit, 1216 S1394_TNF_SL_ARREQ_STACK, ""); 1217 return; 1218 } 1219 } 1220 1221 /* Fill in the backing store if necessary */ 1222 if (addr_blk->kmem_bufp != NULL) { 1223 offset = req->cmd_addr - addr_blk->addr_lo; 1224 bufp_addr = (uchar_t *)addr_blk->kmem_bufp + offset; 1225 switch (req->cmd_type) { 1226 case CMD1394_ASYNCH_WR_QUAD: 1227 bcopy((void *)&(req->cmd_u.q.quadlet_data), 1228 (void *)bufp_addr, cmd_length); 1229 break; 1230 1231 case CMD1394_ASYNCH_WR_BLOCK: 1232 begin_ptr = req->cmd_u.b.data_block->b_rptr; 1233 end_ptr = begin_ptr + cmd_length; 1234 tmp_ptr = req->cmd_u.b.data_block->b_wptr; 1235 if (end_ptr <= tmp_ptr) { 1236 bcopy((void *)begin_ptr, (void *)bufp_addr, 1237 cmd_length); 1238 } else { 1239 dip = hal->halinfo.dip; 1240 1241 /* An unexpected error in the HAL */ 1242 cmn_err(CE_WARN, HALT_ERROR_MESSAGE, 1243 ddi_node_name(dip), ddi_get_instance(dip)); 1244 1245 /* Unlock the "used" tree */ 1246 mutex_exit(&hal->addr_space_used_mutex); 1247 1248 /* Disable the HAL */ 1249 s1394_hal_shutdown(hal, B_TRUE); 1250 1251 TNF_PROBE_1(h1394_write_request_error, 1252 S1394_TNF_SL_ARREQ_ERROR, "", tnf_string, 1253 msg, "Error - mblk too small for request"); 1254 TNF_PROBE_0_DEBUG(h1394_write_request_exit, 1255 S1394_TNF_SL_ARREQ_STACK, ""); 1256 return; 1257 } 1258 break; 1259 1260 default: 1261 dip = hal->halinfo.dip; 1262 1263 /* An unexpected error in the HAL */ 1264 cmn_err(CE_WARN, HALT_ERROR_MESSAGE, 1265 ddi_node_name(dip), ddi_get_instance(dip)); 1266 1267 /* Unlock the "used" tree */ 1268 mutex_exit(&hal->addr_space_used_mutex); 1269 1270 /* Disable the HAL */ 1271 s1394_hal_shutdown(hal, B_TRUE); 1272 1273 TNF_PROBE_1(h1394_write_request_error, 1274 S1394_TNF_SL_ARREQ_ERROR, "", tnf_string, msg, 1275 "Invalid command type specified"); 1276 TNF_PROBE_0_DEBUG(h1394_write_request_exit, 1277 S1394_TNF_SL_ARREQ_STACK, ""); 1278 return; 1279 } 1280 } 1281 1282 /* Fill in the rest of the info in the request */ 1283 if (addr_blk->addr_type == T1394_ADDR_POSTED_WRITE) 1284 s_priv->posted_write = B_TRUE; 1285 1286 s_priv->arreq_valid_addr = B_TRUE; 1287 req->cmd_callback_arg = addr_blk->addr_arg; 1288 recv_write_req = addr_blk->addr_events.recv_write_request; 1289 1290 /* Unlock the "used" tree */ 1291 mutex_exit(&hal->addr_space_used_mutex); 1292 1293 /* 1294 * Add no code that modifies the command after the target 1295 * callback is called or after the response is sent to the 1296 * HAL. 1297 */ 1298 if (recv_write_req != NULL) { 1299 TNF_PROBE_0_DEBUG(h1394_write_request_do_callback, 1300 S1394_TNF_SL_ARREQ_STACK, ""); 1301 recv_write_req(req); 1302 } else { 1303 req->cmd_result = IEEE1394_RESP_COMPLETE; 1304 (void) s1394_send_response(hal, req); 1305 TNF_PROBE_0_DEBUG(h1394_write_request_exit, 1306 S1394_TNF_SL_ARREQ_STACK, ""); 1307 return; 1308 } 1309 1310 TNF_PROBE_0_DEBUG(h1394_write_request_exit, 1311 S1394_TNF_SL_ARREQ_STACK, ""); 1312 } 1313 1314 /* 1315 * Function: h1394_lock_request() 1316 * Input(s): sl_private The HAL "handle" returned by 1317 * h1394_attach() 1318 * req The incoming AR request 1319 * 1320 * Output(s): None 1321 * 1322 * Description: h1394_lock_request() receives incoming AR requests. These 1323 * asynchronous lock requests are dispatched to the appropriate 1324 * target (if one has registered) or are handled by the 1394 1325 * Software Framework, which will send out an appropriate 1326 * response. 1327 */ 1328 void 1329 h1394_lock_request(void *sl_private, cmd1394_cmd_t *req) 1330 { 1331 s1394_hal_t *hal; 1332 s1394_cmd_priv_t *s_priv; 1333 s1394_addr_space_blk_t *addr_blk; 1334 dev_info_t *dip; 1335 uint64_t end_of_request; 1336 uint32_t offset; 1337 uchar_t *bufp_addr; 1338 cmd1394_lock_type_t lock_type; 1339 void (*recv_lock_req)(cmd1394_cmd_t *); 1340 1341 TNF_PROBE_0_DEBUG(h1394_lock_request_enter, 1342 S1394_TNF_SL_ARREQ_STACK, ""); 1343 1344 hal = (s1394_hal_t *)sl_private; 1345 1346 /* Get the Services Layer private area */ 1347 s_priv = S1394_GET_CMD_PRIV(req); 1348 1349 s_priv->cmd_priv_xfer_type = S1394_CMD_LOCK; 1350 1351 /* Lock the "used" tree */ 1352 mutex_enter(&hal->addr_space_used_mutex); 1353 1354 /* Has the 1394 address been allocated? */ 1355 addr_blk = s1394_used_tree_search(hal, req->cmd_addr); 1356 1357 /* If it wasn't found, it isn't owned... */ 1358 if (addr_blk == NULL) { 1359 /* Unlock the "used" tree */ 1360 mutex_exit(&hal->addr_space_used_mutex); 1361 req->cmd_result = IEEE1394_RESP_ADDRESS_ERROR; 1362 (void) s1394_send_response(hal, req); 1363 TNF_PROBE_0_DEBUG(h1394_lock_request_exit, 1364 S1394_TNF_SL_ARREQ_STACK, ""); 1365 return; 1366 } 1367 1368 /* Does the WHOLE request fit in the allocated block? */ 1369 switch (req->cmd_type) { 1370 case CMD1394_ASYNCH_LOCK_32: 1371 end_of_request = (req->cmd_addr + IEEE1394_QUADLET) - 1; 1372 /* kstats - 32-bit lock request */ 1373 hal->hal_kstats->arreq_lock32++; 1374 break; 1375 1376 case CMD1394_ASYNCH_LOCK_64: 1377 end_of_request = (req->cmd_addr + IEEE1394_OCTLET) - 1; 1378 /* kstats - 64-bit lock request */ 1379 hal->hal_kstats->arreq_lock64++; 1380 break; 1381 1382 default: 1383 /* Unlock the "used" tree */ 1384 mutex_exit(&hal->addr_space_used_mutex); 1385 1386 dip = hal->halinfo.dip; 1387 1388 /* An unexpected error in the HAL */ 1389 cmn_err(CE_WARN, HALT_ERROR_MESSAGE, 1390 ddi_node_name(dip), ddi_get_instance(dip)); 1391 1392 /* Disable the HAL */ 1393 s1394_hal_shutdown(hal, B_TRUE); 1394 1395 TNF_PROBE_1(h1394_lock_request_error, 1396 S1394_TNF_SL_ARREQ_ERROR, "", tnf_string, msg, 1397 "Invalid command type specified"); 1398 TNF_PROBE_0_DEBUG(h1394_lock_request_exit, 1399 S1394_TNF_SL_ARREQ_STACK, ""); 1400 return; 1401 } 1402 1403 if (end_of_request > addr_blk->addr_hi) { 1404 /* Unlock the "used" tree */ 1405 mutex_exit(&hal->addr_space_used_mutex); 1406 req->cmd_result = IEEE1394_RESP_ADDRESS_ERROR; 1407 (void) s1394_send_response(hal, req); 1408 TNF_PROBE_0_DEBUG(h1394_lock_request_exit, 1409 S1394_TNF_SL_ARREQ_STACK, ""); 1410 return; 1411 } 1412 1413 /* Is a lock request valid for this address space? */ 1414 if (!(addr_blk->addr_enable & T1394_ADDR_LKENBL)) { 1415 /* Unlock the "used" tree */ 1416 mutex_exit(&hal->addr_space_used_mutex); 1417 req->cmd_result = IEEE1394_RESP_TYPE_ERROR; 1418 (void) s1394_send_response(hal, req); 1419 TNF_PROBE_0_DEBUG(h1394_lock_request_exit, 1420 S1394_TNF_SL_ARREQ_STACK, ""); 1421 return; 1422 } 1423 1424 /* Fill in the backing store if necessary */ 1425 if (addr_blk->kmem_bufp != NULL) { 1426 offset = req->cmd_addr - addr_blk->addr_lo; 1427 bufp_addr = (uchar_t *)addr_blk->kmem_bufp + offset; 1428 1429 if (req->cmd_type == CMD1394_ASYNCH_LOCK_32) { 1430 uint32_t old_value; 1431 uint32_t arg_value; 1432 uint32_t data_value; 1433 uint32_t new_value; 1434 1435 arg_value = req->cmd_u.l32.arg_value; 1436 data_value = req->cmd_u.l32.data_value; 1437 lock_type = req->cmd_u.l32.lock_type; 1438 bcopy((void *)bufp_addr, (void *)&old_value, 1439 IEEE1394_QUADLET); 1440 1441 switch (lock_type) { 1442 case CMD1394_LOCK_MASK_SWAP: 1443 /* Mask-Swap (see P1394A - Table 1.7) */ 1444 new_value = (data_value & arg_value) | 1445 (old_value & ~arg_value); 1446 /* Copy new_value into backing store */ 1447 bcopy((void *)&new_value, (void *)bufp_addr, 1448 IEEE1394_QUADLET); 1449 req->cmd_u.l32.old_value = old_value; 1450 break; 1451 1452 case CMD1394_LOCK_COMPARE_SWAP: 1453 /* Compare-Swap */ 1454 if (old_value == arg_value) { 1455 new_value = data_value; 1456 /* Copy new_value into backing store */ 1457 bcopy((void *)&new_value, 1458 (void *)bufp_addr, 1459 IEEE1394_QUADLET); 1460 } 1461 req->cmd_u.l32.old_value = old_value; 1462 break; 1463 1464 case CMD1394_LOCK_FETCH_ADD: 1465 /* Fetch-Add (see P1394A - Table 1.7) */ 1466 old_value = T1394_DATA32(old_value); 1467 new_value = old_value + data_value; 1468 new_value = T1394_DATA32(new_value); 1469 /* Copy new_value into backing store */ 1470 bcopy((void *)&new_value, (void *)bufp_addr, 1471 IEEE1394_QUADLET); 1472 req->cmd_u.l32.old_value = old_value; 1473 break; 1474 1475 case CMD1394_LOCK_LITTLE_ADD: 1476 /* Little-Add (see P1394A - Table 1.7) */ 1477 old_value = T1394_DATA32(old_value); 1478 new_value = old_value + data_value; 1479 new_value = T1394_DATA32(new_value); 1480 /* Copy new_value into backing store */ 1481 bcopy((void *)&new_value, (void *)bufp_addr, 1482 IEEE1394_QUADLET); 1483 req->cmd_u.l32.old_value = old_value; 1484 break; 1485 1486 case CMD1394_LOCK_BOUNDED_ADD: 1487 /* Bounded-Add (see P1394A - Table 1.7) */ 1488 old_value = T1394_DATA32(old_value); 1489 if (old_value != arg_value) { 1490 new_value = old_value + data_value; 1491 new_value = T1394_DATA32(new_value); 1492 /* Copy new_value into backing store */ 1493 bcopy((void *)&new_value, 1494 (void *)bufp_addr, 1495 IEEE1394_QUADLET); 1496 } 1497 req->cmd_u.l32.old_value = old_value; 1498 break; 1499 1500 case CMD1394_LOCK_WRAP_ADD: 1501 /* Wrap-Add (see P1394A - Table 1.7) */ 1502 old_value = T1394_DATA32(old_value); 1503 if (old_value != arg_value) { 1504 new_value = old_value + data_value; 1505 } else { 1506 new_value = data_value; 1507 } 1508 new_value = T1394_DATA32(new_value); 1509 /* Copy new_value into backing store */ 1510 bcopy((void *)&new_value, (void *)bufp_addr, 1511 IEEE1394_QUADLET); 1512 req->cmd_u.l32.old_value = old_value; 1513 break; 1514 1515 default: 1516 /* Unlock the "used" tree */ 1517 mutex_exit(&hal->addr_space_used_mutex); 1518 req->cmd_result = IEEE1394_RESP_TYPE_ERROR; 1519 (void) s1394_send_response(hal, req); 1520 TNF_PROBE_1(h1394_lock_request_error, 1521 S1394_TNF_SL_ARREQ_ERROR, "", tnf_string, 1522 msg, "Invalid lock_type"); 1523 TNF_PROBE_0_DEBUG(h1394_lock_request_exit, 1524 S1394_TNF_SL_ARREQ_STACK, ""); 1525 return; 1526 } 1527 } else { 1528 /* Handling for the 8-byte (64-bit) lock requests */ 1529 uint64_t old_value; 1530 uint64_t arg_value; 1531 uint64_t data_value; 1532 uint64_t new_value; 1533 1534 arg_value = req->cmd_u.l64.arg_value; 1535 data_value = req->cmd_u.l64.data_value; 1536 lock_type = req->cmd_u.l64.lock_type; 1537 bcopy((void *)bufp_addr, (void *)&old_value, 1538 IEEE1394_OCTLET); 1539 1540 switch (lock_type) { 1541 case CMD1394_LOCK_MASK_SWAP: 1542 /* Mask-Swap (see P1394A - Table 1.7) */ 1543 new_value = (data_value & arg_value) | 1544 (old_value & ~arg_value); 1545 /* Copy new_value into backing store */ 1546 bcopy((void *)&new_value, (void *)bufp_addr, 1547 IEEE1394_OCTLET); 1548 req->cmd_u.l64.old_value = old_value; 1549 break; 1550 1551 case CMD1394_LOCK_COMPARE_SWAP: 1552 /* Compare-Swap */ 1553 if (old_value == arg_value) { 1554 new_value = data_value; 1555 /* Copy new_value into backing store */ 1556 bcopy((void *)&new_value, 1557 (void *)bufp_addr, 1558 IEEE1394_OCTLET); 1559 } 1560 req->cmd_u.l64.old_value = old_value; 1561 break; 1562 1563 case CMD1394_LOCK_FETCH_ADD: 1564 /* Fetch-Add (see P1394A - Table 1.7) */ 1565 old_value = T1394_DATA64(old_value); 1566 new_value = old_value + data_value; 1567 new_value = T1394_DATA64(new_value); 1568 /* Copy new_value into backing store */ 1569 bcopy((void *)&new_value, (void *)bufp_addr, 1570 IEEE1394_OCTLET); 1571 req->cmd_u.l64.old_value = old_value; 1572 break; 1573 1574 case CMD1394_LOCK_LITTLE_ADD: 1575 /* Little-Add (see P1394A - Table 1.7) */ 1576 old_value = T1394_DATA64(old_value); 1577 new_value = old_value + data_value; 1578 new_value = T1394_DATA64(new_value); 1579 /* Copy new_value into backing store */ 1580 bcopy((void *)&new_value, (void *)bufp_addr, 1581 IEEE1394_OCTLET); 1582 req->cmd_u.l64.old_value = old_value; 1583 break; 1584 1585 case CMD1394_LOCK_BOUNDED_ADD: 1586 /* Bounded-Add (see P1394A - Table 1.7) */ 1587 old_value = T1394_DATA64(old_value); 1588 if (old_value != arg_value) { 1589 new_value = old_value + data_value; 1590 new_value = T1394_DATA64(new_value); 1591 /* Copy new_value into backing store */ 1592 bcopy((void *)&new_value, 1593 (void *)bufp_addr, 1594 IEEE1394_OCTLET); 1595 } 1596 req->cmd_u.l64.old_value = old_value; 1597 break; 1598 1599 case CMD1394_LOCK_WRAP_ADD: 1600 /* Wrap-Add (see P1394A - Table 1.7) */ 1601 old_value = T1394_DATA64(old_value); 1602 if (old_value != arg_value) { 1603 new_value = old_value + data_value; 1604 } else { 1605 new_value = data_value; 1606 } 1607 new_value = T1394_DATA64(new_value); 1608 /* Copy new_value into backing store */ 1609 bcopy((void *)&new_value, (void *)bufp_addr, 1610 IEEE1394_OCTLET); 1611 req->cmd_u.l64.old_value = old_value; 1612 break; 1613 1614 default: 1615 /* Unlock the "used" tree */ 1616 mutex_exit(&hal->addr_space_used_mutex); 1617 req->cmd_result = IEEE1394_RESP_TYPE_ERROR; 1618 (void) s1394_send_response(hal, req); 1619 TNF_PROBE_1(h1394_lock_request_error, 1620 S1394_TNF_SL_ARREQ_ERROR, "", tnf_string, 1621 msg, "Invalid lock_type"); 1622 TNF_PROBE_0_DEBUG(h1394_lock_request_exit, 1623 S1394_TNF_SL_ARREQ_STACK, ""); 1624 return; 1625 } 1626 } 1627 } 1628 1629 /* Fill in the rest of the info in the request */ 1630 s_priv->arreq_valid_addr = B_TRUE; 1631 req->cmd_callback_arg = addr_blk->addr_arg; 1632 recv_lock_req = addr_blk->addr_events.recv_lock_request; 1633 1634 /* Unlock the "used" tree */ 1635 mutex_exit(&hal->addr_space_used_mutex); 1636 1637 /* 1638 * Add no code that modifies the command after the target 1639 * callback is called or after the response is sent to the 1640 * HAL. 1641 */ 1642 if (recv_lock_req != NULL) { 1643 TNF_PROBE_0_DEBUG(h1394_lock_request_do_callback, 1644 S1394_TNF_SL_ARREQ_STACK, ""); 1645 recv_lock_req(req); 1646 } else { 1647 req->cmd_result = IEEE1394_RESP_COMPLETE; 1648 (void) s1394_send_response(hal, req); 1649 TNF_PROBE_0_DEBUG(h1394_lock_request_exit, 1650 S1394_TNF_SL_ARREQ_STACK, ""); 1651 return; 1652 } 1653 1654 TNF_PROBE_0_DEBUG(h1394_lock_request_exit, 1655 S1394_TNF_SL_ARREQ_STACK, ""); 1656 } 1657 1658 /* 1659 * Function: h1394_ioctl() 1660 * Input(s): sl_private The HAL "handle" returned by 1661 * h1394_attach() 1662 * cmd ioctl cmd 1663 * arg argument for the ioctl cmd 1664 * mode mode bits (see ioctl(9e)) 1665 * cred_p cred structure pointer 1666 * rval_p pointer to return value (see ioctl(9e)) 1667 * 1668 * Output(s): EINVAL if not a DEVCTL ioctl, else return value from s1394_ioctl 1669 * 1670 * Description: h1394_ioctl() implements non-HAL specific ioctls. Currently, 1671 * DEVCTL ioctls are the only generic ioctls supported. 1672 */ 1673 int 1674 h1394_ioctl(void *sl_private, int cmd, intptr_t arg, int mode, cred_t *cred_p, 1675 int *rval_p) 1676 { 1677 int status; 1678 1679 TNF_PROBE_0_DEBUG(h1394_ioctl_enter, S1394_TNF_SL_IOCTL_STACK, ""); 1680 1681 if ((cmd & DEVCTL_IOC) != DEVCTL_IOC) 1682 return (EINVAL); 1683 1684 status = s1394_ioctl((s1394_hal_t *)sl_private, cmd, arg, mode, 1685 cred_p, rval_p); 1686 1687 TNF_PROBE_1_DEBUG(h1394_ioctl_exit, S1394_TNF_SL_IOCTL_STACK, "", 1688 tnf_int, status, status); 1689 return (status); 1690 } 1691 1692 /* 1693 * Function: h1394_phy_packet() 1694 * Input(s): sl_private The HAL "handle" returned by 1695 * h1394_attach() 1696 * packet_data Pointer to a buffer of packet data 1697 * quadlet_count Length of the buffer 1698 * timestamp Timestamp indicating time of arrival 1699 * 1700 * Output(s): None 1701 * 1702 * Description: h1394_phy_packet() is not implemented currently, but would 1703 * be used to process the responses to PHY ping packets in P1394A 1704 * When one is sent out, a timestamp is given indicating its time 1705 * of departure. Comparing that old timestamp with this new 1706 * timestamp, we can determine the time of flight and can use 1707 * those times to optimize the gap count. 1708 */ 1709 /* ARGSUSED */ 1710 void 1711 h1394_phy_packet(void *sl_private, uint32_t *packet_data, uint_t quadlet_count, 1712 uint_t timestamp) 1713 { 1714 TNF_PROBE_0_DEBUG(h1394_phy_packet_enter, S1394_TNF_SL_STACK, ""); 1715 1716 /* This interface is not yet implemented */ 1717 TNF_PROBE_1_DEBUG(h1394_phy_packet, S1394_TNF_SL_STACK, "", 1718 tnf_string, msg, "h1394_phy_packet: Received"); 1719 1720 TNF_PROBE_0_DEBUG(h1394_phy_packet_exit, S1394_TNF_SL_STACK, ""); 1721 } 1722 1723 /* 1724 * Function: h1394_error_detected() 1725 * Input(s): sl_private The HAL "handle" returned by 1726 * h1394_attach() 1727 * type The type of error the HAL detected 1728 * arg Pointer to any extra information 1729 * 1730 * Output(s): None 1731 * 1732 * Description: h1394_error_detected() is used by the HAL to report errors 1733 * to the 1394 Software Framework. 1734 */ 1735 void 1736 h1394_error_detected(void *sl_private, h1394_error_t type, void *arg) 1737 { 1738 s1394_hal_t *hal; 1739 uint_t hal_node_num; 1740 uint_t IRM_node_num; 1741 1742 TNF_PROBE_0_DEBUG(h1394_error_detected_enter, S1394_TNF_SL_STACK, ""); 1743 1744 hal = (s1394_hal_t *)sl_private; 1745 1746 switch (type) { 1747 case H1394_LOCK_RESP_ERR: 1748 TNF_PROBE_1(h1394_error_detected, S1394_TNF_SL_ERROR, "", 1749 tnf_string, msg, "Lock response error"); 1750 /* If we are the IRM, then initiate a bus reset */ 1751 mutex_enter(&hal->topology_tree_mutex); 1752 hal_node_num = IEEE1394_NODE_NUM(hal->node_id); 1753 IRM_node_num = hal->IRM_node; 1754 mutex_exit(&hal->topology_tree_mutex); 1755 if (IRM_node_num == hal_node_num) 1756 s1394_initiate_hal_reset(hal, NON_CRITICAL); 1757 break; 1758 1759 case H1394_POSTED_WR_ERR: 1760 TNF_PROBE_2(h1394_error_detected, S1394_TNF_SL_ERROR, "", 1761 tnf_string, msg, "Posted write error detected", 1762 tnf_opaque, addr, ((h1394_posted_wr_err_t *)arg)->addr); 1763 break; 1764 1765 case H1394_SELF_INITIATED_SHUTDOWN: 1766 TNF_PROBE_1(h1394_error_detected, S1394_TNF_SL_ERROR, "", 1767 tnf_string, msg, "HAL self-initiated shutdown"); 1768 s1394_hal_shutdown(hal, B_FALSE); 1769 break; 1770 1771 case H1394_CYCLE_TOO_LONG: 1772 /* Set a timer to become cycle master after 1 second */ 1773 mutex_enter(&hal->cm_timer_mutex); 1774 hal->cm_timer_set = B_TRUE; 1775 mutex_exit(&hal->cm_timer_mutex); 1776 hal->cm_timer = timeout(s1394_cycle_too_long_callback, hal, 1777 drv_usectohz(CYCLE_MASTER_TIMER * 1000)); 1778 1779 TNF_PROBE_1(h1394_error_detected, S1394_TNF_SL_ERROR, "", 1780 tnf_string, msg, "Isochronous cycle too long error"); 1781 break; 1782 1783 default: 1784 TNF_PROBE_2(h1394_error_detected, S1394_TNF_SL_ERROR, "", 1785 tnf_string, msg, "Unknown error type received", 1786 tnf_uint, type, type); 1787 break; 1788 } 1789 1790 TNF_PROBE_0_DEBUG(h1394_error_detected_exit, S1394_TNF_SL_STACK, ""); 1791 } 1792