1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 /* 30 * s1394_asynch.c 31 * 1394 Services Layer Asynchronous Communications Routines 32 * These routines handle all of the tasks relating to asynch commands 33 */ 34 35 #include <sys/conf.h> 36 #include <sys/ddi.h> 37 #include <sys/sunddi.h> 38 #include <sys/cmn_err.h> 39 #include <sys/types.h> 40 #include <sys/kmem.h> 41 #include <sys/tnf_probe.h> 42 43 #include <sys/1394/t1394.h> 44 #include <sys/1394/s1394.h> 45 #include <sys/1394/h1394.h> 46 #include <sys/1394/ieee1394.h> 47 #include <sys/1394/ieee1212.h> 48 49 static void s1394_handle_lock(cmd1394_cmd_t *cmd); 50 51 static cmd1394_cmd_t *s1394_pending_q_remove(s1394_hal_t *hal); 52 53 static boolean_t s1394_process_pending_q(s1394_hal_t *hal); 54 55 static boolean_t s1394_pending_q_helper(s1394_hal_t *hal, cmd1394_cmd_t *cmd); 56 57 static int s1394_process_split_lock(cmd1394_cmd_t *cmd, 58 cmd1394_cmd_t *target_cmd); 59 60 static int s1394_finish_split_lock(cmd1394_cmd_t *cmd, 61 cmd1394_cmd_t *target_cmd); 62 63 /* 64 * s1394_alloc_cmd() 65 * is used to allocate a command for a target or for a HAL. 66 */ 67 int 68 s1394_alloc_cmd(s1394_hal_t *hal, uint_t flags, cmd1394_cmd_t **cmdp) 69 { 70 s1394_cmd_priv_t *s_priv; 71 void *hal_overhead; 72 uint_t cmd_size; 73 int alloc_sleep; 74 75 TNF_PROBE_0_DEBUG(s1394_alloc_cmd_enter, S1394_TNF_SL_STACK, ""); 76 77 alloc_sleep = (flags & T1394_ALLOC_CMD_NOSLEEP) ? KM_NOSLEEP : KM_SLEEP; 78 79 if ((alloc_sleep == KM_SLEEP) && 80 (curthread->t_flag == T_INTR_THREAD)) { 81 TNF_PROBE_1(s1394_alloc_cmd_error, S1394_TNF_SL_ATREQ_ERROR, 82 "", tnf_string, msg, "Tried to sleep in intr context"); 83 TNF_PROBE_0_DEBUG(s1394_alloc_cmd_exit, 84 S1394_TNF_SL_ATREQ_STACK, ""); 85 ASSERT(alloc_sleep != KM_SLEEP); /* fail */ 86 return (DDI_FAILURE); 87 } 88 89 /* either FCP command or response, but not both */ 90 if ((flags & 91 (T1394_ALLOC_CMD_FCP_COMMAND | T1394_ALLOC_CMD_FCP_RESPONSE)) == 92 (T1394_ALLOC_CMD_FCP_COMMAND | T1394_ALLOC_CMD_FCP_RESPONSE)) { 93 TNF_PROBE_1(s1394_alloc_cmd_error, S1394_TNF_SL_ATREQ_ERROR, 94 "", tnf_string, msg, "Both FCP cmd and resp flags"); 95 TNF_PROBE_0_DEBUG(s1394_alloc_cmd_exit, 96 S1394_TNF_SL_ATREQ_STACK, ""); 97 return (DDI_FAILURE); 98 } 99 100 *cmdp = kmem_cache_alloc(hal->hal_kmem_cachep, alloc_sleep); 101 if (*cmdp == NULL) { 102 TNF_PROBE_0_DEBUG(s1394_alloc_cmd_exit, 103 S1394_TNF_SL_STACK, ""); 104 return (DDI_FAILURE); 105 } 106 cmd_size = sizeof (cmd1394_cmd_t) + 107 sizeof (s1394_cmd_priv_t) + hal->halinfo.hal_overhead; 108 bzero((void *)*cmdp, cmd_size); 109 110 (*cmdp)->cmd_version = T1394_VERSION_V1; 111 (*cmdp)->cmd_result = CMD1394_NOSTATUS; 112 113 /* Get the Services Layer private area */ 114 s_priv = S1394_GET_CMD_PRIV(*cmdp); 115 116 /* Set extension type */ 117 if (flags & T1394_ALLOC_CMD_FCP_COMMAND) { 118 s1394_fa_init_cmd(s_priv, S1394_FA_TYPE_FCP_CTL); 119 } else if (flags & T1394_ALLOC_CMD_FCP_RESPONSE) { 120 s1394_fa_init_cmd(s_priv, S1394_FA_TYPE_FCP_TGT); 121 } 122 123 /* Set up the hal_overhead ptr in the hal_cmd_private */ 124 hal_overhead = (uchar_t *)s_priv + sizeof (s1394_cmd_priv_t); 125 s_priv->hal_cmd_private.hal_overhead = (void *)hal_overhead; 126 127 TNF_PROBE_1_DEBUG(s1394_alloc_cmd, S1394_TNF_SL_STACK, "", 128 tnf_opaque, cmd, *cmdp); 129 130 /* kstats - number of cmd allocs */ 131 hal->hal_kstats->cmd_alloc++; 132 133 TNF_PROBE_0_DEBUG(s1394_alloc_cmd_exit, S1394_TNF_SL_STACK, ""); 134 return (DDI_SUCCESS); 135 } 136 137 /* 138 * s1394_free_cmd() 139 * is used to free a command that had been previously allocated by 140 * s1394_alloc_cmd(). 141 */ 142 int 143 s1394_free_cmd(s1394_hal_t *hal, cmd1394_cmd_t **cmdp) 144 { 145 s1394_cmd_priv_t *s_priv; 146 147 TNF_PROBE_0_DEBUG(s1394_free_cmd_enter, S1394_TNF_SL_STACK, ""); 148 149 /* Get the Services Layer private area */ 150 s_priv = S1394_GET_CMD_PRIV(*cmdp); 151 152 /* Check that command isn't in use */ 153 if (s_priv->cmd_in_use == B_TRUE) { 154 TNF_PROBE_1(s1394_free_cmd_error, S1394_TNF_SL_ERROR, "", 155 tnf_string, msg, "Attempted to free an in-use command"); 156 TNF_PROBE_0_DEBUG(s1394_free_cmd_exit, S1394_TNF_SL_STACK, ""); 157 ASSERT(s_priv->cmd_in_use == B_FALSE); 158 return (DDI_FAILURE); 159 } 160 TNF_PROBE_1_DEBUG(s1394_free_cmd, S1394_TNF_SL_STACK, "", 161 tnf_opaque, cmd, *cmdp); 162 163 /* kstats - number of cmd allocs */ 164 kmem_cache_free(hal->hal_kmem_cachep, *cmdp); 165 166 /* Command pointer is set to NULL before returning */ 167 *cmdp = NULL; 168 169 /* kstats - number of cmd frees */ 170 hal->hal_kstats->cmd_free++; 171 172 TNF_PROBE_0_DEBUG(s1394_free_cmd_exit, S1394_TNF_SL_STACK, ""); 173 return (DDI_SUCCESS); 174 } 175 176 /* 177 * s1394_xfer_asynch_command() 178 * is used to send an asynch command down to the HAL. Based upon the type 179 * of command that is being sent, the appropriate HAL function is called. 180 * Command failures are handled be returning an error and/or shutting down 181 * the HAL, depending on the severity of the error. 182 */ 183 int 184 s1394_xfer_asynch_command(s1394_hal_t *hal, cmd1394_cmd_t *cmd, int *err) 185 { 186 s1394_cmd_priv_t *s_priv; 187 h1394_cmd_priv_t *h_priv; 188 s1394_hal_state_t state; 189 dev_info_t *dip; 190 int result_from_hal; 191 int ret; 192 193 TNF_PROBE_0_DEBUG(s1394_xfer_asynch_command_enter, 194 S1394_TNF_SL_ATREQ_STACK, ""); 195 196 ASSERT(MUTEX_NOT_HELD(&hal->topology_tree_mutex)); 197 198 mutex_enter(&hal->topology_tree_mutex); 199 state = hal->hal_state; 200 if (((state != S1394_HAL_NORMAL) && (state != S1394_HAL_RESET)) || 201 (hal->disable_requests_bit == 1)) { 202 *err = s1394_HAL_asynch_error(hal, cmd, state); 203 mutex_exit(&hal->topology_tree_mutex); 204 TNF_PROBE_0_DEBUG(s1394_xfer_asynch_command_exit, 205 S1394_TNF_SL_ATREQ_STACK, ""); 206 return (DDI_FAILURE); 207 } 208 mutex_exit(&hal->topology_tree_mutex); 209 210 /* Get the Services Layer private area */ 211 s_priv = S1394_GET_CMD_PRIV(cmd); 212 213 /* Get a pointer to the HAL private struct */ 214 h_priv = (h1394_cmd_priv_t *)&s_priv->hal_cmd_private; 215 216 /* kstats - number of AT requests sent */ 217 switch (cmd->cmd_type) { 218 case CMD1394_ASYNCH_RD_QUAD: 219 hal->hal_kstats->atreq_quad_rd++; 220 break; 221 222 case CMD1394_ASYNCH_RD_BLOCK: 223 hal->hal_kstats->atreq_blk_rd++; 224 break; 225 226 case CMD1394_ASYNCH_WR_QUAD: 227 hal->hal_kstats->atreq_quad_wr++; 228 break; 229 230 case CMD1394_ASYNCH_WR_BLOCK: 231 hal->hal_kstats->atreq_blk_wr++; 232 hal->hal_kstats->atreq_blk_wr_size += h_priv->mblk.length; 233 break; 234 235 case CMD1394_ASYNCH_LOCK_32: 236 hal->hal_kstats->atreq_lock32++; 237 break; 238 239 case CMD1394_ASYNCH_LOCK_64: 240 hal->hal_kstats->atreq_lock64++; 241 break; 242 } 243 244 switch (s_priv->cmd_priv_xfer_type) { 245 /* Call the HAL's read entry point */ 246 case S1394_CMD_READ: 247 ret = HAL_CALL(hal).read(hal->halinfo.hal_private, 248 (cmd1394_cmd_t *)cmd, 249 (h1394_cmd_priv_t *)&s_priv->hal_cmd_private, 250 &result_from_hal); 251 break; 252 253 /* Call the HAL's write entry point */ 254 case S1394_CMD_WRITE: 255 ret = HAL_CALL(hal).write(hal->halinfo.hal_private, 256 (cmd1394_cmd_t *)cmd, 257 (h1394_cmd_priv_t *)&s_priv->hal_cmd_private, 258 &result_from_hal); 259 break; 260 261 /* Call the HAL's lock entry point */ 262 case S1394_CMD_LOCK: 263 ret = HAL_CALL(hal).lock(hal->halinfo.hal_private, 264 (cmd1394_cmd_t *)cmd, 265 (h1394_cmd_priv_t *)&s_priv->hal_cmd_private, 266 &result_from_hal); 267 break; 268 269 default: 270 *err = CMD1394_EUNKNOWN_ERROR; 271 272 TNF_PROBE_1(s1394_xfer_asynch_command_error, 273 S1394_TNF_SL_ATREQ_ERROR, "", tnf_string, msg, 274 "Invalid command type specified"); 275 TNF_PROBE_0_DEBUG(s1394_xfer_asynch_command_exit, 276 S1394_TNF_SL_ATREQ_STACK, ""); 277 return (DDI_FAILURE); 278 } 279 280 TNF_PROBE_0_DEBUG(s1394_xfer_asynch_command_return_from_HAL, 281 S1394_TNF_SL_ATREQ_STACK, ""); 282 283 if (ret == DDI_FAILURE) { 284 switch (result_from_hal) { 285 case H1394_STATUS_EMPTY_TLABEL: 286 /* Out of TLABELs - Unable to send AT req */ 287 *err = CMD1394_ENO_ATREQ; 288 break; 289 290 case H1394_STATUS_INVALID_BUSGEN: 291 /* Out of TLABELs - Unable to send AT req */ 292 *err = CMD1394_ESTALE_GENERATION; 293 break; 294 295 case H1394_STATUS_NOMORE_SPACE: 296 /* No more space on HAL's HW queue */ 297 *err = CMD1394_ENO_ATREQ; 298 break; 299 300 case H1394_STATUS_INTERNAL_ERROR: 301 dip = hal->halinfo.dip; 302 303 /* An unexpected error in the HAL */ 304 cmn_err(CE_WARN, HALT_ERROR_MESSAGE, 305 ddi_node_name(dip), ddi_get_instance(dip)); 306 307 /* Disable the HAL */ 308 s1394_hal_shutdown(hal, B_TRUE); 309 310 *err = CMD1394_EFATAL_ERROR; 311 break; 312 313 default: 314 dip = hal->halinfo.dip; 315 316 /* An unexpected error in the HAL */ 317 cmn_err(CE_WARN, HALT_ERROR_MESSAGE, 318 ddi_node_name(dip), ddi_get_instance(dip)); 319 320 /* Disable the HAL */ 321 s1394_hal_shutdown(hal, B_TRUE); 322 323 *err = CMD1394_EFATAL_ERROR; 324 break; 325 } 326 327 TNF_PROBE_2_DEBUG(s1394_xfer_asynch_command_exit, 328 S1394_TNF_SL_ATREQ_STACK, "", 329 tnf_int, result_from_hal, result_from_hal, 330 tnf_int, err, *err); 331 return (DDI_FAILURE); 332 } 333 334 /* No errors, return success */ 335 *err = CMD1394_NOSTATUS; 336 337 TNF_PROBE_0_DEBUG(s1394_xfer_asynch_command_exit, 338 S1394_TNF_SL_ATREQ_STACK, ""); 339 return (DDI_SUCCESS); 340 } 341 342 /* 343 * s1394_setup_asynch_command() 344 * is used to setup an asynch command to be sent down to the HAL and out 345 * onto the bus. This function handles setting up the destination address 346 * (if necessary), speed, max_payload, putting the command onto the 347 * outstanding Q list, and any other things that must be done prior to 348 * calling the HAL. 349 */ 350 int 351 s1394_setup_asynch_command(s1394_hal_t *hal, s1394_target_t *target, 352 cmd1394_cmd_t *cmd, uint32_t xfer_type, int *err) 353 { 354 s1394_cmd_priv_t *s_priv; 355 h1394_cmd_priv_t *h_priv; 356 uint64_t node; 357 uint32_t from_node; 358 uint32_t to_node; 359 uint32_t bus_capabilities; 360 uint_t current_max_payload; 361 uint_t max_rec; 362 uint_t max_blk; 363 364 TNF_PROBE_0_DEBUG(s1394_setup_asynch_command_enter, 365 S1394_TNF_SL_ATREQ_STACK, ""); 366 367 ASSERT(MUTEX_HELD(&hal->topology_tree_mutex)); 368 369 switch (cmd->cmd_type) { 370 case CMD1394_ASYNCH_RD_QUAD: 371 case CMD1394_ASYNCH_WR_QUAD: 372 case CMD1394_ASYNCH_RD_BLOCK: 373 case CMD1394_ASYNCH_WR_BLOCK: 374 case CMD1394_ASYNCH_LOCK_32: 375 case CMD1394_ASYNCH_LOCK_64: 376 break; 377 378 default: 379 *err = CMD1394_EINVALID_COMMAND; 380 TNF_PROBE_1(s1394_setup_asynch_command_error, 381 S1394_TNF_SL_ATREQ_ERROR, "", tnf_string, msg, 382 "Invalid command type specified"); 383 TNF_PROBE_0_DEBUG(s1394_setup_asynch_command_exit, 384 S1394_TNF_SL_ATREQ_STACK, ""); 385 return (DDI_FAILURE); 386 } 387 388 /* Check for potential address roll-over */ 389 if (s1394_address_rollover(cmd) != B_FALSE) { 390 *err = CMD1394_EADDRESS_ERROR; 391 TNF_PROBE_0_DEBUG(s1394_setup_asynch_command_exit, 392 S1394_TNF_SL_ATREQ_STACK, ""); 393 return (DDI_FAILURE); 394 } 395 396 /* Get the Services Layer private area */ 397 s_priv = S1394_GET_CMD_PRIV(cmd); 398 399 /* Set up who sent command on which hal */ 400 s_priv->sent_by_target = (s1394_target_t *)target; 401 s_priv->sent_on_hal = (s1394_hal_t *)hal; 402 403 /* Set up command transfer type */ 404 s_priv->cmd_priv_xfer_type = xfer_type; 405 406 if (cmd->cmd_options & CMD1394_OVERRIDE_ADDR) { 407 /* Compare the current generation from the HAL struct */ 408 /* to the one given by the target */ 409 410 /* Speed is to be filled in from speed map */ 411 from_node = IEEE1394_NODE_NUM(hal->node_id); 412 to_node = IEEE1394_ADDR_PHY_ID(cmd->cmd_addr); 413 414 if (cmd->bus_generation != hal->generation_count) { 415 *err = CMD1394_ESTALE_GENERATION; 416 TNF_PROBE_0_DEBUG(s1394_setup_asynch_command_exit, 417 S1394_TNF_SL_ATREQ_STACK, ""); 418 return (DDI_FAILURE); 419 } 420 421 } else { 422 /* Set the generation */ 423 cmd->bus_generation = hal->generation_count; 424 425 /* If not OVERRIDE_ADDR, then target may not be NULL */ 426 ASSERT(target != NULL); 427 428 rw_enter(&hal->target_list_rwlock, RW_READER); 429 430 if ((target->target_state & S1394_TARG_GONE) != 0 || 431 target->on_node == NULL) { 432 rw_exit(&hal->target_list_rwlock); 433 *err = CMD1394_EDEVICE_REMOVED; 434 TNF_PROBE_0_DEBUG(s1394_setup_asynch_command_exit, 435 S1394_TNF_SL_ATREQ_STACK, ""); 436 return (DDI_FAILURE); 437 } 438 439 ASSERT((target->target_state & S1394_TARG_GONE) == 0); 440 node = target->on_node->node_num; 441 rw_exit(&hal->target_list_rwlock); 442 443 /* Mask in the top 16-bits */ 444 cmd->cmd_addr = (cmd->cmd_addr & IEEE1394_ADDR_OFFSET_MASK); 445 cmd->cmd_addr = (cmd->cmd_addr | 446 (node << IEEE1394_ADDR_PHY_ID_SHIFT)); 447 cmd->cmd_addr = (cmd->cmd_addr | IEEE1394_ADDR_BUS_ID_MASK); 448 449 /* Speed is to be filled in from speed map */ 450 from_node = IEEE1394_NODE_NUM(hal->node_id); 451 to_node = (uint32_t)node; 452 } 453 454 /* Get a pointer to the HAL private struct */ 455 h_priv = (h1394_cmd_priv_t *)&s_priv->hal_cmd_private; 456 457 /* Copy the generation into the HAL's private field */ 458 h_priv->bus_generation = cmd->bus_generation; 459 460 /* Fill in the nodeID */ 461 cmd->nodeID = (cmd->cmd_addr & IEEE1394_ADDR_NODE_ID_MASK) >> 462 IEEE1394_ADDR_NODE_ID_SHIFT; 463 464 if (cmd->cmd_options & CMD1394_OVERRIDE_SPEED) { 465 if (cmd->cmd_speed > IEEE1394_S400) { 466 *err = CMD1394_EINVALID_COMMAND; 467 TNF_PROBE_0_DEBUG(s1394_setup_asynch_command_exit, 468 S1394_TNF_SL_ATREQ_STACK, ""); 469 return (DDI_FAILURE); 470 471 } else { 472 s_priv->hal_cmd_private.speed = (int)cmd->cmd_speed; 473 } 474 475 } else { 476 /* Speed is to be filled in from speed map */ 477 s_priv->hal_cmd_private.speed = (int)s1394_speed_map_get(hal, 478 from_node, to_node); 479 } 480 481 /* Is it a block request? */ 482 if ((cmd->cmd_type == CMD1394_ASYNCH_RD_BLOCK) || 483 (cmd->cmd_type == CMD1394_ASYNCH_WR_BLOCK)) { 484 485 if (cmd->cmd_u.b.data_block == NULL) { 486 *err = CMD1394_ENULL_MBLK; 487 TNF_PROBE_0_DEBUG(s1394_setup_asynch_command_exit, 488 S1394_TNF_SL_ATREQ_STACK, ""); 489 return (DDI_FAILURE); 490 } 491 492 /* Also need to check for MBLK_TOO_SMALL */ 493 if (s1394_mblk_too_small(cmd) != B_FALSE) { 494 *err = CMD1394_EMBLK_TOO_SMALL; 495 TNF_PROBE_0_DEBUG(s1394_setup_asynch_command_exit, 496 S1394_TNF_SL_ATREQ_STACK, ""); 497 return (DDI_FAILURE); 498 } 499 500 /* Initialize bytes_transferred to zero */ 501 cmd->cmd_u.b.bytes_transferred = 0; 502 503 /* Handle the MAX_PAYLOAD size */ 504 if (cmd->cmd_options & CMD1394_OVERRIDE_ADDR) { 505 506 current_max_payload = 512 << 507 (s_priv->hal_cmd_private.speed); 508 if (hal->topology_tree[to_node].cfgrom) { 509 bus_capabilities = 510 hal->topology_tree[to_node].cfgrom[ 511 IEEE1212_NODE_CAP_QUAD]; 512 max_rec = (bus_capabilities & 513 IEEE1394_BIB_MAXREC_MASK) >> 514 IEEE1394_BIB_MAXREC_SHIFT; 515 } else { 516 max_rec = 0; 517 } 518 519 if ((max_rec > 0) && (max_rec < 14)) { 520 max_blk = 1 << (max_rec + 1); 521 522 } else { 523 /* These are either unspecified or reserved */ 524 max_blk = 4; 525 } 526 if (max_blk < current_max_payload) 527 current_max_payload = max_blk; 528 529 } else { 530 rw_enter(&hal->target_list_rwlock, RW_READER); 531 current_max_payload = target->current_max_payload; 532 rw_exit(&hal->target_list_rwlock); 533 } 534 535 if (cmd->cmd_options & CMD1394_OVERRIDE_MAX_PAYLOAD) { 536 if (current_max_payload > cmd->cmd_u.b.max_payload) 537 current_max_payload = cmd->cmd_u.b.max_payload; 538 } 539 540 h_priv->mblk.curr_mblk = cmd->cmd_u.b.data_block; 541 542 if (cmd->cmd_type == CMD1394_ASYNCH_WR_BLOCK) { 543 h_priv->mblk.curr_offset = 544 cmd->cmd_u.b.data_block->b_rptr; 545 } else { 546 h_priv->mblk.curr_offset = 547 cmd->cmd_u.b.data_block->b_wptr; 548 } 549 550 if (cmd->cmd_u.b.blk_length > current_max_payload) { 551 h_priv->mblk.length = current_max_payload; 552 s_priv->data_remaining = cmd->cmd_u.b.blk_length; 553 554 } else { 555 h_priv->mblk.length = cmd->cmd_u.b.blk_length; 556 s_priv->data_remaining = cmd->cmd_u.b.blk_length; 557 } 558 } 559 560 /* Mark command as being used */ 561 s_priv->cmd_in_use = B_TRUE; 562 563 /* Put command on the HAL's outstanding request Q */ 564 s1394_insert_q_asynch_cmd(hal, cmd); 565 566 TNF_PROBE_0_DEBUG(s1394_setup_asynch_command_exit, 567 S1394_TNF_SL_ATREQ_STACK, ""); 568 return (DDI_SUCCESS); 569 } 570 571 /* 572 * s1394_insert_q_asynch_cmd() 573 * is used to insert a given command structure onto a HAL's outstanding 574 * asynch queue. 575 */ 576 void 577 s1394_insert_q_asynch_cmd(s1394_hal_t *hal, cmd1394_cmd_t *cmd) 578 { 579 s1394_cmd_priv_t *s_priv; 580 s1394_cmd_priv_t *c_priv; 581 cmd1394_cmd_t *temp_cmd; 582 583 TNF_PROBE_0_DEBUG(s1394_insert_q_asynch_cmd_enter, 584 S1394_TNF_SL_ATREQ_STACK, ""); 585 586 mutex_enter(&hal->outstanding_q_mutex); 587 588 /* Get the Services Layer private area */ 589 s_priv = S1394_GET_CMD_PRIV(cmd); 590 591 /* Is the outstanding request queue empty? */ 592 if ((hal->outstanding_q_head == NULL) && 593 (hal->outstanding_q_tail == NULL)) { 594 595 hal->outstanding_q_head = (cmd1394_cmd_t *)cmd; 596 hal->outstanding_q_tail = (cmd1394_cmd_t *)cmd; 597 s_priv->cmd_priv_next = (cmd1394_cmd_t *)NULL; 598 s_priv->cmd_priv_prev = (cmd1394_cmd_t *)NULL; 599 600 } else { 601 s_priv->cmd_priv_next = hal->outstanding_q_head; 602 s_priv->cmd_priv_prev = (cmd1394_cmd_t *)NULL; 603 604 temp_cmd = (cmd1394_cmd_t *)hal->outstanding_q_head; 605 c_priv = (s1394_cmd_priv_t *)((uchar_t *)temp_cmd + 606 sizeof (cmd1394_cmd_t)); 607 c_priv->cmd_priv_prev = (cmd1394_cmd_t *)cmd; 608 609 hal->outstanding_q_head = (cmd1394_cmd_t *)cmd; 610 } 611 612 mutex_exit(&hal->outstanding_q_mutex); 613 614 TNF_PROBE_0_DEBUG(s1394_insert_q_asynch_cmd_exit, 615 S1394_TNF_SL_ATREQ_STACK, ""); 616 } 617 618 /* 619 * s1394_remove_q_asynch_cmd() 620 * is used to remove a given command structure from a HAL's outstanding 621 * asynch queue. 622 */ 623 void 624 s1394_remove_q_asynch_cmd(s1394_hal_t *hal, cmd1394_cmd_t *cmd) 625 { 626 s1394_cmd_priv_t *s_priv; 627 s1394_cmd_priv_t *c_priv; 628 cmd1394_cmd_t *prev_cmd; 629 cmd1394_cmd_t *next_cmd; 630 631 TNF_PROBE_0_DEBUG(s1394_remove_q_asynch_cmd_enter, 632 S1394_TNF_SL_ATREQ_STACK, ""); 633 634 mutex_enter(&hal->outstanding_q_mutex); 635 636 /* Get the Services Layer private area */ 637 s_priv = S1394_GET_CMD_PRIV(cmd); 638 639 prev_cmd = (cmd1394_cmd_t *)s_priv->cmd_priv_prev; 640 next_cmd = (cmd1394_cmd_t *)s_priv->cmd_priv_next; 641 642 s_priv->cmd_priv_prev = (cmd1394_cmd_t *)NULL; 643 s_priv->cmd_priv_next = (cmd1394_cmd_t *)NULL; 644 645 if (prev_cmd != NULL) { 646 c_priv = (s1394_cmd_priv_t *)((uchar_t *)prev_cmd + 647 sizeof (cmd1394_cmd_t)); 648 c_priv->cmd_priv_next = (cmd1394_cmd_t *)next_cmd; 649 650 } else { 651 if (hal->outstanding_q_head == (cmd1394_cmd_t *)cmd) 652 hal->outstanding_q_head = (cmd1394_cmd_t *)next_cmd; 653 } 654 655 if (next_cmd != NULL) { 656 c_priv = (s1394_cmd_priv_t *)((uchar_t *)next_cmd + 657 sizeof (cmd1394_cmd_t)); 658 c_priv->cmd_priv_prev = (cmd1394_cmd_t *)prev_cmd; 659 660 } else { 661 if (hal->outstanding_q_tail == (cmd1394_cmd_t *)cmd) 662 hal->outstanding_q_tail = (cmd1394_cmd_t *)prev_cmd; 663 } 664 665 mutex_exit(&hal->outstanding_q_mutex); 666 667 TNF_PROBE_0_DEBUG(s1394_remove_q_asynch_cmd_exit, 668 S1394_TNF_SL_ATREQ_STACK, ""); 669 } 670 671 /* 672 * s1394_atreq_cmd_complete() 673 * is called by h1394_cmd_is_complete() when an AT request has completed. 674 * Based upon a command's completion status, s1394_atreq_cmd_complete() 675 * determines whether to call the target (or unblock), put the command onto 676 * the pending Q to be sent out later, or to resend the command 677 * (multi-part command). 678 */ 679 void 680 s1394_atreq_cmd_complete(s1394_hal_t *hal, cmd1394_cmd_t *req, int status) 681 { 682 s1394_cmd_priv_t *s_priv; 683 h1394_cmd_priv_t *h_priv; 684 dev_info_t *dip; 685 int ret; 686 int cmd_result; 687 int err; 688 689 TNF_PROBE_0_DEBUG(s1394_atreq_cmd_complete_enter, 690 S1394_TNF_SL_ATREQ_STACK, ""); 691 692 /* Get the Services Layer private area */ 693 s_priv = S1394_GET_CMD_PRIV(req); 694 695 /* If not an ack_complete... */ 696 if (status != H1394_CMD_SUCCESS) { 697 /* kstats - number of failure AT responses */ 698 switch (req->cmd_type) { 699 case CMD1394_ASYNCH_RD_QUAD: 700 hal->hal_kstats->atresp_quad_rd_fail++; 701 break; 702 703 case CMD1394_ASYNCH_RD_BLOCK: 704 hal->hal_kstats->atresp_blk_rd_fail++; 705 break; 706 707 case CMD1394_ASYNCH_WR_QUAD: 708 hal->hal_kstats->atresp_quad_wr_fail++; 709 break; 710 711 case CMD1394_ASYNCH_WR_BLOCK: 712 hal->hal_kstats->atresp_blk_wr_fail++; 713 break; 714 715 case CMD1394_ASYNCH_LOCK_32: 716 hal->hal_kstats->atresp_lock32_fail++; 717 break; 718 719 case CMD1394_ASYNCH_LOCK_64: 720 hal->hal_kstats->atresp_lock64_fail++; 721 break; 722 } 723 724 725 switch (status) { 726 /* evt_missing_ack */ 727 case H1394_CMD_ETIMEOUT: 728 cmd_result = CMD1394_ETIMEOUT; 729 break; 730 731 /* evt_flushed */ 732 case H1394_CMD_EBUSRESET: 733 /* Move request to pending Q if cancel on */ 734 /* reset is not set */ 735 if (req->cmd_options & CMD1394_CANCEL_ON_BUS_RESET) { 736 cmd_result = CMD1394_EBUSRESET; 737 break; 738 } 739 s1394_remove_q_asynch_cmd(hal, req); 740 s1394_pending_q_insert(hal, req, S1394_PENDING_Q_REAR); 741 TNF_PROBE_0_DEBUG(s1394_atreq_cmd_complete_exit, 742 S1394_TNF_SL_ATREQ_STACK, ""); 743 return; 744 745 /* ack_busy_X */ 746 /* ack_busy_A */ 747 /* ack_busy_B */ 748 case H1394_CMD_EDEVICE_BUSY: 749 cmd_result = CMD1394_EDEVICE_BUSY; 750 break; 751 752 /* ack_data_error */ 753 case H1394_CMD_EDATA_ERROR: 754 cmd_result = CMD1394_EDATA_ERROR; 755 break; 756 757 /* ack_type_error */ 758 case H1394_CMD_ETYPE_ERROR: 759 cmd_result = CMD1394_ETYPE_ERROR; 760 break; 761 762 /* resp_address_error */ 763 /* ack_address_error */ 764 case H1394_CMD_EADDR_ERROR: 765 cmd_result = CMD1394_EADDRESS_ERROR; 766 break; 767 768 /* resp_conflict_error */ 769 /* ack_conflict_error */ 770 case H1394_CMD_ERSRC_CONFLICT: 771 cmd_result = CMD1394_ERSRC_CONFLICT; 772 break; 773 774 /* ack_tardy */ 775 case H1394_CMD_EDEVICE_POWERUP: 776 cmd_result = CMD1394_EDEVICE_BUSY; 777 break; 778 779 /* device errors (bad tcodes, ACKs, etc...) */ 780 case H1394_CMD_EDEVICE_ERROR: 781 cmd_result = CMD1394_EDEVICE_ERROR; 782 break; 783 784 /* Unknown error type */ 785 case H1394_CMD_EUNKNOWN_ERROR: 786 cmd_result = CMD1394_EUNKNOWN_ERROR; 787 break; 788 789 /* Unrecognized error */ 790 default: 791 dip = hal->halinfo.dip; 792 793 /* An unexpected error in the HAL */ 794 cmn_err(CE_WARN, HALT_ERROR_MESSAGE, 795 ddi_node_name(dip), ddi_get_instance(dip)); 796 797 /* Disable the HAL */ 798 s1394_hal_shutdown(hal, B_TRUE); 799 800 TNF_PROBE_2(s1394_atreq_cmd_complete_error, 801 S1394_TNF_SL_ATREQ_ERROR, "", tnf_string, msg, 802 "Unrecognized cmd status code", 803 tnf_int, status, status); 804 TNF_PROBE_0_DEBUG(s1394_atreq_cmd_complete_exit, 805 S1394_TNF_SL_ATREQ_STACK, ""); 806 return; 807 } 808 809 /* Remove command from the HAL's outstanding request Q */ 810 s1394_remove_q_asynch_cmd(hal, req); 811 812 s_priv->cmd_in_use = B_FALSE; 813 814 req->cmd_result = cmd_result; 815 816 /* Is this a blocking command? */ 817 if (req->cmd_options & CMD1394_BLOCKING) { 818 /* Unblock the waiting command */ 819 mutex_enter(&s_priv->blocking_mutex); 820 s_priv->blocking_flag = B_TRUE; 821 cv_signal(&s_priv->blocking_cv); 822 mutex_exit(&s_priv->blocking_mutex); 823 824 TNF_PROBE_0_DEBUG(s1394_atreq_cmd_complete_exit, 825 S1394_TNF_SL_ATREQ_STACK, ""); 826 return; 827 } 828 829 /* Call the target's completion_callback() */ 830 if (req->completion_callback != NULL) { 831 TNF_PROBE_0_DEBUG(s1394_atreq_cmd_complete_do_callback, 832 S1394_TNF_SL_ATREQ_STACK, ""); 833 req->completion_callback(req); 834 } 835 836 TNF_PROBE_0_DEBUG(s1394_atreq_cmd_complete_exit, 837 S1394_TNF_SL_ATREQ_STACK, ""); 838 return; 839 } 840 841 /* Successful unless otherwise modified */ 842 err = CMD1394_CMDSUCCESS; 843 844 if ((req->cmd_type == CMD1394_ASYNCH_RD_BLOCK) || 845 (req->cmd_type == CMD1394_ASYNCH_WR_BLOCK)) { 846 847 /* Get a pointer to the HAL private struct */ 848 h_priv = (h1394_cmd_priv_t *)&s_priv->hal_cmd_private; 849 850 /* Update data_remaining */ 851 s_priv->data_remaining -= h_priv->mblk.length; 852 853 /* Increment bytes_transferred */ 854 req->cmd_u.b.bytes_transferred += h_priv->mblk.length; 855 856 if (req->cmd_type == CMD1394_ASYNCH_RD_BLOCK) 857 hal->hal_kstats->atreq_blk_rd_size += 858 h_priv->mblk.length; 859 860 /* Is there still more to send? */ 861 if (s_priv->data_remaining > 0) { 862 863 /* Setup the new mblk and offset */ 864 h_priv->mblk.curr_mblk = h_priv->mblk.next_mblk; 865 h_priv->mblk.curr_offset = h_priv->mblk.next_offset; 866 867 /* Update destination address */ 868 if (!(req->cmd_options & 869 CMD1394_DISABLE_ADDR_INCREMENT)) { 870 req->cmd_addr += h_priv->mblk.length; 871 } 872 873 /* 874 * Use the current MAX_PAYLOAD size. This value 875 * doesn't need to be recalculated because we must 876 * be in the same generation on the bus, else we 877 * would have seen a bus reset error. 878 */ 879 if (s_priv->data_remaining < h_priv->mblk.length) { 880 h_priv->mblk.length = s_priv->data_remaining; 881 } 882 883 /* Send command out again */ 884 ret = s1394_xfer_asynch_command(hal, req, &err); 885 886 if (ret == DDI_SUCCESS) { 887 TNF_PROBE_0_DEBUG(s1394_atreq_cmd_complete_exit, 888 S1394_TNF_SL_ATREQ_STACK, ""); 889 return; 890 891 } else if (err == CMD1394_ESTALE_GENERATION) { 892 /* Remove cmd from outstanding request Q */ 893 s1394_remove_q_asynch_cmd(hal, req); 894 s1394_pending_q_insert(hal, req, 895 S1394_PENDING_Q_REAR); 896 897 TNF_PROBE_0_DEBUG(s1394_atreq_cmd_complete_exit, 898 S1394_TNF_SL_ATREQ_STACK, ""); 899 return; 900 } 901 } 902 } 903 904 /* Remove command from the HAL's outstanding request Q */ 905 s1394_remove_q_asynch_cmd(hal, req); 906 907 s_priv->cmd_in_use = B_FALSE; 908 909 /* Set status */ 910 req->cmd_result = err; 911 912 /* Is this a blocking command? */ 913 if (req->cmd_options & CMD1394_BLOCKING) { 914 /* Unblock the waiting command */ 915 mutex_enter(&s_priv->blocking_mutex); 916 s_priv->blocking_flag = B_TRUE; 917 cv_signal(&s_priv->blocking_cv); 918 mutex_exit(&s_priv->blocking_mutex); 919 920 TNF_PROBE_0_DEBUG(s1394_atreq_cmd_complete_exit, 921 S1394_TNF_SL_ATREQ_STACK, ""); 922 return; 923 } 924 925 /* Set status and call completion_callback() */ 926 if (req->completion_callback != NULL) { 927 928 TNF_PROBE_0_DEBUG(s1394_atreq_cmd_complete_do_callback, 929 S1394_TNF_SL_ATREQ_STACK, ""); 930 931 req->completion_callback(req); 932 933 TNF_PROBE_0_DEBUG(s1394_atreq_cmd_complete_exit, 934 S1394_TNF_SL_ATREQ_STACK, ""); 935 return; 936 } 937 938 TNF_PROBE_0_DEBUG(s1394_atreq_cmd_complete_exit, 939 S1394_TNF_SL_ATREQ_STACK, ""); 940 } 941 942 /* 943 * s1394_atresp_cmd_complete() 944 * is similar to s1394_atreq_cmd_complete(). It is also called by 945 * h1394_cmd_is_complete(), but when an AT response has completed. 946 * Again, based upon the command's completion status, 947 * s1394_atresp_cmd_complete() determines whether to call the target or 948 * to simply cleanup the command and return. 949 */ 950 void 951 s1394_atresp_cmd_complete(s1394_hal_t *hal, cmd1394_cmd_t *resp, int status) 952 { 953 s1394_cmd_priv_t *s_priv; 954 h1394_cmd_priv_t *h_priv; 955 dev_info_t *dip; 956 boolean_t valid_addr_blk; 957 int target_status; 958 959 TNF_PROBE_0_DEBUG(s1394_atresp_cmd_complete_enter, 960 S1394_TNF_SL_ATRESP_STACK, ""); 961 962 target_status = CMD1394_CMDSUCCESS; 963 964 /* If not an ack_complete */ 965 if (status != H1394_CMD_SUCCESS) { 966 switch (status) { 967 /* evt_missing_ack */ 968 case H1394_CMD_ETIMEOUT: 969 target_status = CMD1394_ETIMEOUT; 970 break; 971 972 /* evt_flushed */ 973 case H1394_CMD_EBUSRESET: 974 target_status = CMD1394_EBUSRESET; 975 break; 976 977 /* ack_busy_X */ 978 /* ack_busy_A */ 979 /* ack_busy_B */ 980 case H1394_CMD_EDEVICE_BUSY: 981 target_status = CMD1394_EDEVICE_BUSY; 982 break; 983 984 /* ack_data_error */ 985 case H1394_CMD_EDATA_ERROR: 986 target_status = CMD1394_EDATA_ERROR; 987 break; 988 989 /* ack_type_error */ 990 case H1394_CMD_ETYPE_ERROR: 991 target_status = CMD1394_ETYPE_ERROR; 992 break; 993 994 /* ack_address_error */ 995 case H1394_CMD_EADDR_ERROR: 996 target_status = CMD1394_EADDRESS_ERROR; 997 break; 998 999 /* ack_conflict_error */ 1000 case H1394_CMD_ERSRC_CONFLICT: 1001 target_status = CMD1394_ERSRC_CONFLICT; 1002 break; 1003 1004 /* ack_tardy */ 1005 case H1394_CMD_EDEVICE_POWERUP: 1006 target_status = CMD1394_EDEVICE_BUSY; 1007 break; 1008 1009 /* device errors (bad tcodes, ACKs, etc...) */ 1010 case H1394_CMD_EDEVICE_ERROR: 1011 target_status = CMD1394_EDEVICE_ERROR; 1012 break; 1013 1014 /* Unknown error type */ 1015 case H1394_CMD_EUNKNOWN_ERROR: 1016 target_status = CMD1394_EUNKNOWN_ERROR; 1017 break; 1018 1019 /* Unrecognized error */ 1020 default: 1021 dip = hal->halinfo.dip; 1022 1023 /* An unexpected error in the HAL */ 1024 cmn_err(CE_WARN, HALT_ERROR_MESSAGE, 1025 ddi_node_name(dip), ddi_get_instance(dip)); 1026 1027 /* Disable the HAL */ 1028 s1394_hal_shutdown(hal, B_TRUE); 1029 1030 TNF_PROBE_2(s1394_atresp_cmd_complete_error, 1031 S1394_TNF_SL_ATRESP_ERROR, "", tnf_string, msg, 1032 "Unrecognized cmd status code", 1033 tnf_int, status, status); 1034 TNF_PROBE_0_DEBUG(s1394_atresp_cmd_complete_exit, 1035 S1394_TNF_SL_ATRESP_STACK, ""); 1036 return; 1037 } 1038 } 1039 1040 /* Get the Services Layer private area */ 1041 s_priv = S1394_GET_CMD_PRIV(resp); 1042 1043 /* Get a pointer to the HAL private struct */ 1044 h_priv = (h1394_cmd_priv_t *)&s_priv->hal_cmd_private; 1045 1046 valid_addr_blk = s_priv->arreq_valid_addr; 1047 1048 if (valid_addr_blk == B_TRUE) { 1049 /* Set the command status */ 1050 resp->cmd_result = target_status; 1051 1052 switch (s_priv->cmd_priv_xfer_type) { 1053 case S1394_CMD_READ: 1054 case S1394_CMD_WRITE: 1055 case S1394_CMD_LOCK: 1056 if (resp->completion_callback != NULL) { 1057 TNF_PROBE_0_DEBUG( 1058 s1394_atresp_cmd_complete_do_callback, 1059 S1394_TNF_SL_ATRESP_STACK, ""); 1060 resp->completion_callback(resp); 1061 } 1062 break; 1063 1064 default: 1065 dip = hal->halinfo.dip; 1066 1067 /* An unexpected error in the HAL */ 1068 cmn_err(CE_WARN, HALT_ERROR_MESSAGE, 1069 ddi_node_name(dip), ddi_get_instance(dip)); 1070 1071 /* Disable the HAL */ 1072 s1394_hal_shutdown(hal, B_TRUE); 1073 1074 TNF_PROBE_1(s1394_atresp_cmd_complete_error, 1075 S1394_TNF_SL_ATRESP_ERROR, "", tnf_string, msg, 1076 "Unrecognized transfer type"); 1077 TNF_PROBE_0_DEBUG(s1394_atresp_cmd_complete_exit, 1078 S1394_TNF_SL_ATRESP_STACK, ""); 1079 return; 1080 } 1081 } 1082 1083 TNF_PROBE_0_DEBUG(s1394_atresp_cmd_complete_call_hal_cmplt, 1084 S1394_TNF_SL_ATRESP_STACK, ""); 1085 1086 /* Free the command - Pass it back to the HAL */ 1087 HAL_CALL(hal).response_complete(hal->halinfo.hal_private, resp, h_priv); 1088 1089 TNF_PROBE_1_DEBUG(s1394_atresp_cmd_complete_exit, 1090 S1394_TNF_SL_ATRESP_STACK, "", tnf_int, status, target_status); 1091 } 1092 1093 /* 1094 * s1394_send_response() 1095 * is used to send a response to an AR request. Depending on whether the 1096 * request was a broadcast request, a write to posted write address space, 1097 * or some other request, either a response packet is sent, or the command 1098 * is returned to the HAL. A return value of DDI_SUCCESS means that the 1099 * command has been handled correctly. It was either successfully sent to 1100 * the HAL, or, if it was posted_write of broadcast, it was freed up. A 1101 * return value of DDI_FAILURE indicates either a serious error, in which 1102 * case the HAL is shutdown, or a failure returned by the HAL, in which 1103 * case the command is freed up and notice of the failure is returned. 1104 */ 1105 int 1106 s1394_send_response(s1394_hal_t *hal, cmd1394_cmd_t *resp) 1107 { 1108 s1394_cmd_priv_t *s_priv; 1109 h1394_cmd_priv_t *h_priv; 1110 dev_info_t *dip; 1111 int ret; 1112 int result; 1113 1114 TNF_PROBE_0_DEBUG(s1394_send_response_enter, S1394_TNF_SL_ATRESP_STACK, 1115 ""); 1116 1117 /* Get the Services Layer private area */ 1118 s_priv = S1394_GET_CMD_PRIV(resp); 1119 1120 /* Get a pointer to the HAL private struct */ 1121 h_priv = (h1394_cmd_priv_t *)&s_priv->hal_cmd_private; 1122 1123 /* 1124 * If request was broadcast or a write request to a posted write 1125 * address, don't send a response 1126 */ 1127 if ((resp->broadcast == 1) || ((s_priv->posted_write == B_TRUE) && 1128 ((resp->cmd_result == CMD1394_ASYNCH_WR_QUAD) || 1129 (resp->cmd_result == CMD1394_ASYNCH_WR_BLOCK)))) { 1130 1131 TNF_PROBE_0_DEBUG(s1394_send_response_call_hal_cmplt, 1132 S1394_TNF_SL_ATRESP_STACK, ""); 1133 1134 /* Free the command - Pass it back to the HAL */ 1135 HAL_CALL(hal).response_complete(hal->halinfo.hal_private, 1136 resp, h_priv); 1137 1138 TNF_PROBE_0_DEBUG(s1394_send_response_exit, 1139 S1394_TNF_SL_ATRESP_STACK, ""); 1140 return (DDI_SUCCESS); 1141 } 1142 1143 TNF_PROBE_0_DEBUG(s1394_send_response_call_hal_resp, 1144 S1394_TNF_SL_ATRESP_STACK, ""); 1145 1146 /* kstats - number of failure responses sent */ 1147 if (resp->cmd_result != IEEE1394_RESP_COMPLETE) { 1148 switch (resp->cmd_type) { 1149 case CMD1394_ASYNCH_RD_QUAD: 1150 hal->hal_kstats->arresp_quad_rd_fail++; 1151 break; 1152 1153 case CMD1394_ASYNCH_RD_BLOCK: 1154 hal->hal_kstats->arresp_blk_rd_fail++; 1155 break; 1156 1157 case CMD1394_ASYNCH_WR_QUAD: 1158 hal->hal_kstats->arresp_quad_wr_fail++; 1159 break; 1160 1161 case CMD1394_ASYNCH_WR_BLOCK: 1162 hal->hal_kstats->arresp_blk_wr_fail++; 1163 break; 1164 1165 case CMD1394_ASYNCH_LOCK_32: 1166 hal->hal_kstats->arresp_lock32_fail++; 1167 break; 1168 1169 case CMD1394_ASYNCH_LOCK_64: 1170 hal->hal_kstats->arresp_lock64_fail++; 1171 break; 1172 } 1173 } else { 1174 if (resp->cmd_type == CMD1394_ASYNCH_RD_BLOCK) 1175 hal->hal_kstats->arreq_blk_rd_size += 1176 resp->cmd_u.b.blk_length; 1177 } 1178 1179 if (resp->cmd_type == CMD1394_ASYNCH_RD_BLOCK) { 1180 h_priv->mblk.curr_mblk = resp->cmd_u.b.data_block; 1181 h_priv->mblk.curr_offset = resp->cmd_u.b.data_block->b_rptr; 1182 h_priv->mblk.length = resp->cmd_u.b.blk_length; 1183 } 1184 1185 switch (s_priv->cmd_priv_xfer_type) { 1186 case S1394_CMD_READ: 1187 ret = HAL_CALL(hal).read_response(hal->halinfo.hal_private, 1188 resp, h_priv, &result); 1189 break; 1190 1191 case S1394_CMD_WRITE: 1192 ret = HAL_CALL(hal).write_response(hal->halinfo.hal_private, 1193 resp, h_priv, &result); 1194 break; 1195 1196 case S1394_CMD_LOCK: 1197 ret = HAL_CALL(hal).lock_response(hal->halinfo.hal_private, 1198 resp, h_priv, &result); 1199 break; 1200 1201 default: 1202 dip = hal->halinfo.dip; 1203 1204 /* An unexpected error in the HAL */ 1205 cmn_err(CE_WARN, HALT_ERROR_MESSAGE, 1206 ddi_node_name(dip), ddi_get_instance(dip)); 1207 1208 /* Disable the HAL */ 1209 s1394_hal_shutdown(hal, B_TRUE); 1210 1211 TNF_PROBE_1(s1394_send_response_error, 1212 S1394_TNF_SL_ATRESP_ERROR, "", tnf_string, msg, 1213 "Unrecognized transfer type"); 1214 TNF_PROBE_0_DEBUG(s1394_send_response_exit, 1215 S1394_TNF_SL_ATRESP_STACK, ""); 1216 return (DDI_FAILURE); 1217 } 1218 1219 /* Unable to send a response */ 1220 if (ret != DDI_SUCCESS) { 1221 if (result == H1394_STATUS_INVALID_BUSGEN) { 1222 TNF_PROBE_1(s1394_send_response_error, 1223 S1394_TNF_SL_ATRESP_ERROR, "", tnf_string, msg, 1224 "Invalid generation in response"); 1225 } else if (result == H1394_STATUS_NOMORE_SPACE) { 1226 TNF_PROBE_1(s1394_send_response_error, 1227 S1394_TNF_SL_ATRESP_ERROR, "", tnf_string, msg, 1228 "No more space on AT response queue"); 1229 } else { 1230 TNF_PROBE_1(s1394_send_response_error, 1231 S1394_TNF_SL_ATRESP_ERROR, "", tnf_string, msg, 1232 "Unknown problem in s1394_send_response"); 1233 } 1234 TNF_PROBE_0_DEBUG(s1394_send_response_call_hal_cmplt, 1235 S1394_TNF_SL_ATRESP_STACK, ""); 1236 1237 /* Free the command - Pass it back to the HAL */ 1238 HAL_CALL(hal).response_complete(hal->halinfo.hal_private, 1239 resp, h_priv); 1240 1241 TNF_PROBE_0_DEBUG(s1394_send_response_exit, 1242 S1394_TNF_SL_ATRESP_STACK, ""); 1243 return (DDI_FAILURE); 1244 } 1245 1246 TNF_PROBE_0_DEBUG(s1394_send_response_exit, S1394_TNF_SL_ATRESP_STACK, 1247 ""); 1248 return (DDI_SUCCESS); 1249 } 1250 1251 /* 1252 * s1394_compare_swap() 1253 * is used by t1394_lock() to send a lock request. Any of the lock 1254 * requests specified explicitly by the 1394 spec will pass thru here, 1255 * i.e compare-swap, mask-swap, etc. 1256 */ 1257 int 1258 s1394_compare_swap(s1394_hal_t *hal, s1394_target_t *target, cmd1394_cmd_t *cmd) 1259 { 1260 s1394_cmd_priv_t *s_priv; 1261 s1394_hal_state_t state; 1262 int err; 1263 int ret; 1264 1265 TNF_PROBE_0_DEBUG(s1394_compare_swap_enter, S1394_TNF_SL_ATREQ_STACK, 1266 ""); 1267 1268 ASSERT(MUTEX_NOT_HELD(&hal->topology_tree_mutex)); 1269 1270 /* Lock the topology tree - protect from bus reset */ 1271 mutex_enter(&hal->topology_tree_mutex); 1272 1273 ret = s1394_setup_asynch_command(hal, target, cmd, S1394_CMD_LOCK, 1274 &err); 1275 1276 /* Unlock the topology tree */ 1277 mutex_exit(&hal->topology_tree_mutex); 1278 1279 /* Get the Services Layer private area */ 1280 s_priv = S1394_GET_CMD_PRIV(cmd); 1281 1282 /* Command has now been put onto the queue! */ 1283 if (ret != DDI_SUCCESS) { 1284 /* Copy error code into result */ 1285 cmd->cmd_result = err; 1286 1287 TNF_PROBE_0(s1394_compare_swap_error_in_setup_asynch, 1288 S1394_TNF_SL_ATREQ_ERROR, ""); 1289 TNF_PROBE_0_DEBUG(s1394_compare_swap_exit, 1290 S1394_TNF_SL_ATREQ_STACK, ""); 1291 return (DDI_FAILURE); 1292 } 1293 1294 mutex_enter(&hal->topology_tree_mutex); 1295 state = hal->hal_state; 1296 /* If this command was sent during a bus reset, */ 1297 /* then put it onto the pending Q. */ 1298 if (state == S1394_HAL_RESET) { 1299 /* Remove cmd from outstanding request Q */ 1300 s1394_remove_q_asynch_cmd(hal, cmd); 1301 1302 /* Are we on the bus reset event stack? */ 1303 if (s1394_on_br_thread(hal) == B_TRUE) { 1304 /* Blocking commands are not allowed */ 1305 if (cmd->cmd_options & CMD1394_BLOCKING) { 1306 mutex_exit(&hal->topology_tree_mutex); 1307 1308 s_priv->cmd_in_use = B_FALSE; 1309 1310 cmd->cmd_result = CMD1394_EINVALID_CONTEXT; 1311 1312 TNF_PROBE_1(s1394_compare_swap_error, 1313 S1394_TNF_SL_ATREQ_ERROR, "", tnf_string, 1314 msg, "CMD1394_BLOCKING in bus reset ctxt"); 1315 TNF_PROBE_0_DEBUG(s1394_compare_swap_exit, 1316 S1394_TNF_SL_ATREQ_STACK, ""); 1317 return (DDI_FAILURE); 1318 } 1319 } 1320 1321 s1394_pending_q_insert(hal, cmd, S1394_PENDING_Q_FRONT); 1322 mutex_exit(&hal->topology_tree_mutex); 1323 1324 /* Block (if necessary) */ 1325 s1394_block_on_asynch_cmd(cmd); 1326 1327 TNF_PROBE_0_DEBUG(t1394_write_exit, S1394_TNF_SL_ATREQ_STACK, 1328 ""); 1329 return (DDI_SUCCESS); 1330 } 1331 mutex_exit(&hal->topology_tree_mutex); 1332 1333 /* Send the command out */ 1334 ret = s1394_xfer_asynch_command(hal, cmd, &err); 1335 1336 if (ret != DDI_SUCCESS) { 1337 if (err == CMD1394_ESTALE_GENERATION) { 1338 /* Remove cmd from outstanding request Q */ 1339 s1394_remove_q_asynch_cmd(hal, cmd); 1340 s1394_pending_q_insert(hal, cmd, S1394_PENDING_Q_FRONT); 1341 1342 /* Block (if necessary) */ 1343 s1394_block_on_asynch_cmd(cmd); 1344 1345 TNF_PROBE_0_DEBUG(s1394_compare_swap_exit, 1346 S1394_TNF_SL_ATREQ_STACK, ""); 1347 return (DDI_SUCCESS); 1348 1349 } else { 1350 /* Remove cmd from outstanding request Q */ 1351 s1394_remove_q_asynch_cmd(hal, cmd); 1352 1353 s_priv->cmd_in_use = B_FALSE; 1354 1355 /* Copy error code into result */ 1356 cmd->cmd_result = err; 1357 1358 TNF_PROBE_0(s1394_compare_swap_error_in_xfer, 1359 S1394_TNF_SL_ATREQ_ERROR, ""); 1360 TNF_PROBE_0_DEBUG(s1394_compare_swap_exit, 1361 S1394_TNF_SL_ATREQ_STACK, ""); 1362 return (DDI_FAILURE); 1363 } 1364 } else { 1365 /* Block (if necessary) */ 1366 s1394_block_on_asynch_cmd(cmd); 1367 1368 TNF_PROBE_0_DEBUG(s1394_compare_swap_exit, 1369 S1394_TNF_SL_ATREQ_STACK, ""); 1370 return (DDI_SUCCESS); 1371 } 1372 } 1373 1374 /* 1375 * s1394_split_lock_req() 1376 * is also used by t1394_lock() to send a lock request. The difference 1377 * is that s1394_split_lock_req() is used to send the software supported 1378 * lock types, i.e. bit_and, bit_or, etc. These lock requests require 1379 * more than one transaction, typically compare-swap's. 1380 */ 1381 int 1382 s1394_split_lock_req(s1394_hal_t *hal, s1394_target_t *target, 1383 cmd1394_cmd_t *cmd) 1384 { 1385 s1394_cmd_priv_t *s_priv; 1386 cmd1394_cmd_t *tmp_cmd; 1387 1388 TNF_PROBE_0_DEBUG(s1394_split_lock_req_enter, 1389 S1394_TNF_SL_ATREQ_STACK, ""); 1390 1391 /* Allocate a temporary command */ 1392 if (s1394_alloc_cmd(hal, T1394_ALLOC_CMD_NOSLEEP, &tmp_cmd) != 1393 DDI_SUCCESS) { 1394 cmd->cmd_result = CMD1394_EUNKNOWN_ERROR; 1395 1396 TNF_PROBE_0(s1394_split_lock_req_error_alloc_cmd, 1397 S1394_TNF_SL_ATREQ_ERROR, ""); 1398 TNF_PROBE_0_DEBUG(s1394_split_lock_req_exit, 1399 S1394_TNF_SL_ATREQ_STACK, ""); 1400 return (DDI_FAILURE); 1401 } 1402 1403 /* Get the Services Layer private area */ 1404 s_priv = S1394_GET_CMD_PRIV(tmp_cmd); 1405 1406 tmp_cmd->completion_callback = s1394_handle_lock; 1407 tmp_cmd->cmd_callback_arg = (opaque_t)cmd; 1408 tmp_cmd->cmd_type = cmd->cmd_type; 1409 tmp_cmd->cmd_addr = cmd->cmd_addr; 1410 tmp_cmd->cmd_options = cmd->cmd_options; 1411 tmp_cmd->bus_generation = cmd->bus_generation; 1412 1413 /* The temporary command can not block */ 1414 tmp_cmd->cmd_options = tmp_cmd->cmd_options & ~CMD1394_BLOCKING; 1415 1416 /* Setup compare-swap with data_value == arg_value (read) */ 1417 if (tmp_cmd->cmd_type == CMD1394_ASYNCH_LOCK_32) { 1418 tmp_cmd->cmd_u.l32.data_value = 0; 1419 tmp_cmd->cmd_u.l32.arg_value = 0; 1420 tmp_cmd->cmd_u.l32.lock_type = CMD1394_LOCK_COMPARE_SWAP; 1421 s_priv->temp_num_retries = cmd->cmd_u.l32.num_retries; 1422 } else { 1423 tmp_cmd->cmd_u.l64.data_value = 0; 1424 tmp_cmd->cmd_u.l64.arg_value = 0; 1425 tmp_cmd->cmd_u.l64.lock_type = CMD1394_LOCK_COMPARE_SWAP; 1426 s_priv->temp_num_retries = cmd->cmd_u.l64.num_retries; 1427 } 1428 1429 /* Initialize lock_req_step */ 1430 s_priv->lock_req_step = 0; 1431 1432 /* Get the Services Layer private area for the target cmd */ 1433 s_priv = S1394_GET_CMD_PRIV(cmd); 1434 1435 s_priv->cmd_in_use = B_TRUE; 1436 1437 /* Send the request */ 1438 if (s1394_compare_swap(hal, target, tmp_cmd) != DDI_SUCCESS) { 1439 s_priv->cmd_in_use = B_FALSE; 1440 1441 /* Free the temporary command */ 1442 if (s1394_free_cmd(hal, &tmp_cmd) != DDI_SUCCESS) 1443 cmd->cmd_result = CMD1394_EUNKNOWN_ERROR; 1444 1445 TNF_PROBE_0_DEBUG(s1394_split_lock_req_exit, 1446 S1394_TNF_SL_ATREQ_STACK, ""); 1447 return (DDI_FAILURE); 1448 } 1449 1450 /* Block (if necessary) */ 1451 s1394_block_on_asynch_cmd(cmd); 1452 1453 TNF_PROBE_0_DEBUG(s1394_split_lock_req_exit, 1454 S1394_TNF_SL_ATREQ_STACK, ""); 1455 return (DDI_SUCCESS); 1456 } 1457 1458 /* 1459 * s1394_handle_lock() 1460 * is the callback for s1394_split_lock_req(). It does all of the real 1461 * work. Based on the specific lock type all necessary manipulation is 1462 * performed and another compare swap is sent out. If the transaction 1463 * is unsuccessful, it is retried. 1464 */ 1465 static void 1466 s1394_handle_lock(cmd1394_cmd_t *cmd) 1467 { 1468 s1394_hal_t *to_hal; 1469 s1394_target_t *target; 1470 s1394_cmd_priv_t *s_priv; 1471 cmd1394_cmd_t *target_cmd; 1472 uint32_t lock_req_step; 1473 int tcmd_result; 1474 int ret; 1475 1476 1477 TNF_PROBE_0_DEBUG(s1394_handle_lock_enter, S1394_TNF_SL_ATREQ_STACK, 1478 ""); 1479 1480 /* Get the Services Layer private area */ 1481 s_priv = S1394_GET_CMD_PRIV(cmd); 1482 1483 lock_req_step = s_priv->lock_req_step; 1484 1485 /* Get the target's command */ 1486 target_cmd = (cmd1394_cmd_t *)cmd->cmd_callback_arg; 1487 1488 /* Get the destination of the command */ 1489 to_hal = s_priv->sent_on_hal; 1490 1491 lock_req_step_0: 1492 /* Is this step 0 completing? */ 1493 if (lock_req_step == 0) { 1494 /* Was the request successful? */ 1495 if (cmd->cmd_result == CMD1394_CMDSUCCESS) { 1496 /* Do any math, bit ops, or byte-swapping necessary */ 1497 ret = s1394_process_split_lock(cmd, target_cmd); 1498 1499 if (ret != DDI_SUCCESS) { 1500 tcmd_result = target_cmd->cmd_result; 1501 goto lock_req_done; 1502 } 1503 1504 s_priv->lock_req_step = 1; 1505 1506 target = s_priv->sent_by_target; 1507 1508 if (s1394_compare_swap(to_hal, target, cmd) != 1509 DDI_SUCCESS) { 1510 tcmd_result = cmd->cmd_result; 1511 goto lock_req_done; 1512 } else { 1513 TNF_PROBE_0_DEBUG(s1394_handle_lock_exit, 1514 S1394_TNF_SL_ATREQ_STACK, ""); 1515 return; 1516 } 1517 } else { 1518 /* Command failed for some reason */ 1519 tcmd_result = cmd->cmd_result; 1520 goto lock_req_done; 1521 } 1522 } else { /* lock_req_step == 1 */ 1523 /* Was the request successful? */ 1524 if (cmd->cmd_result == CMD1394_CMDSUCCESS) { 1525 /* Do whatever's necessary to finish up the lock */ 1526 ret = s1394_finish_split_lock(cmd, target_cmd); 1527 1528 if (ret != DDI_SUCCESS) { 1529 lock_req_step = 0; 1530 goto lock_req_step_0; 1531 } else { 1532 tcmd_result = cmd->cmd_result; 1533 goto lock_req_done; 1534 } 1535 } else { 1536 /* Command failed for some reason */ 1537 tcmd_result = cmd->cmd_result; 1538 goto lock_req_done; 1539 } 1540 } 1541 1542 lock_req_done: 1543 if (s1394_free_cmd(to_hal, &cmd) != DDI_SUCCESS) { 1544 TNF_PROBE_0(s1394_handle_lock_error_in_freecmd, 1545 S1394_TNF_SL_ATREQ_ERROR, ""); 1546 } 1547 1548 /* Get the Services Layer private area */ 1549 s_priv = S1394_GET_CMD_PRIV(target_cmd); 1550 1551 s_priv->cmd_in_use = B_FALSE; 1552 1553 target_cmd->cmd_result = tcmd_result; 1554 1555 /* Is this a blocking command? */ 1556 if (target_cmd->cmd_options & CMD1394_BLOCKING) { 1557 /* Unblock the waiting command */ 1558 mutex_enter(&s_priv->blocking_mutex); 1559 s_priv->blocking_flag = B_TRUE; 1560 cv_signal(&s_priv->blocking_cv); 1561 mutex_exit(&s_priv->blocking_mutex); 1562 1563 TNF_PROBE_0_DEBUG(s1394_handle_lock_exit, 1564 S1394_TNF_SL_ATREQ_STACK, ""); 1565 return; 1566 } 1567 1568 /* Call the target's completion_callback() */ 1569 if (target_cmd->completion_callback != NULL) 1570 target_cmd->completion_callback(target_cmd); 1571 1572 TNF_PROBE_0_DEBUG(s1394_handle_lock_exit, 1573 S1394_TNF_SL_ATREQ_STACK, ""); 1574 } 1575 1576 /* 1577 * s1394_pending_q_insert() 1578 * is used to insert a given command structure onto a HAL's pending queue 1579 * for later processing (after the bus reset). All commands returned by 1580 * the HAL, are inserted onto the rear of the list (first priority), and 1581 * all other commands (from targets during bus reset) are put onto the front. 1582 */ 1583 void 1584 s1394_pending_q_insert(s1394_hal_t *hal, cmd1394_cmd_t *cmd, uint_t flags) 1585 { 1586 cmd1394_cmd_t *temp_cmd; 1587 s1394_cmd_priv_t *s_priv; 1588 s1394_cmd_priv_t *c_priv; 1589 1590 TNF_PROBE_0_DEBUG(s1394_pending_q_insert_enter, 1591 S1394_TNF_SL_ATREQ_STACK, ""); 1592 1593 mutex_enter(&hal->pending_q_mutex); 1594 1595 /* Get the Services Layer private area */ 1596 s_priv = S1394_GET_CMD_PRIV(cmd); 1597 1598 /* Is the outstanding request queue empty? */ 1599 if ((hal->pending_q_head == NULL) && (hal->pending_q_tail == NULL)) { 1600 1601 hal->pending_q_head = (cmd1394_cmd_t *)cmd; 1602 hal->pending_q_tail = (cmd1394_cmd_t *)cmd; 1603 s_priv->cmd_priv_next = (cmd1394_cmd_t *)NULL; 1604 s_priv->cmd_priv_prev = (cmd1394_cmd_t *)NULL; 1605 1606 } else if (flags == S1394_PENDING_Q_FRONT) { 1607 s_priv->cmd_priv_next = hal->pending_q_head; 1608 s_priv->cmd_priv_prev = (cmd1394_cmd_t *)NULL; 1609 1610 temp_cmd = (cmd1394_cmd_t *)hal->pending_q_head; 1611 c_priv = (s1394_cmd_priv_t *)((uchar_t *)temp_cmd + 1612 sizeof (cmd1394_cmd_t)); 1613 c_priv->cmd_priv_prev = (cmd1394_cmd_t *)cmd; 1614 1615 hal->pending_q_head = (cmd1394_cmd_t *)cmd; 1616 1617 } else { 1618 s_priv->cmd_priv_prev = hal->pending_q_tail; 1619 s_priv->cmd_priv_next = (cmd1394_cmd_t *)NULL; 1620 1621 temp_cmd = (cmd1394_cmd_t *)hal->pending_q_tail; 1622 c_priv = (s1394_cmd_priv_t *)((uchar_t *)temp_cmd + 1623 sizeof (cmd1394_cmd_t)); 1624 c_priv->cmd_priv_next = (cmd1394_cmd_t *)cmd; 1625 1626 hal->pending_q_tail = (cmd1394_cmd_t *)cmd; 1627 } 1628 1629 mutex_exit(&hal->pending_q_mutex); 1630 1631 /* kstats - number of pending Q insertions */ 1632 hal->hal_kstats->pending_q_insert++; 1633 1634 TNF_PROBE_0_DEBUG(s1394_pending_q_insert_exit, 1635 S1394_TNF_SL_ATREQ_STACK, ""); 1636 } 1637 1638 /* 1639 * s1394_pending_q_remove() 1640 * is used to remove a command structure from a HAL's pending queue for 1641 * processing. 1642 */ 1643 static cmd1394_cmd_t * 1644 s1394_pending_q_remove(s1394_hal_t *hal) 1645 { 1646 s1394_cmd_priv_t *s_priv; 1647 s1394_cmd_priv_t *c_priv; 1648 cmd1394_cmd_t *cmd; 1649 cmd1394_cmd_t *prev_cmd; 1650 1651 TNF_PROBE_0_DEBUG(s1394_pending_q_remove_enter, 1652 S1394_TNF_SL_ATREQ_STACK, ""); 1653 1654 mutex_enter(&hal->pending_q_mutex); 1655 1656 cmd = (cmd1394_cmd_t *)hal->pending_q_tail; 1657 if (cmd == NULL) { 1658 mutex_exit(&hal->pending_q_mutex); 1659 TNF_PROBE_0_DEBUG(s1394_pending_q_remove_exit, 1660 S1394_TNF_SL_ATREQ_STACK, ""); 1661 return (NULL); 1662 } 1663 1664 /* Get the Services Layer private area */ 1665 s_priv = S1394_GET_CMD_PRIV(cmd); 1666 1667 prev_cmd = (cmd1394_cmd_t *)s_priv->cmd_priv_prev; 1668 1669 s_priv->cmd_priv_prev = (cmd1394_cmd_t *)NULL; 1670 s_priv->cmd_priv_next = (cmd1394_cmd_t *)NULL; 1671 1672 if (prev_cmd != NULL) { 1673 c_priv = (s1394_cmd_priv_t *)((uchar_t *)prev_cmd + 1674 sizeof (cmd1394_cmd_t)); 1675 c_priv->cmd_priv_next = (cmd1394_cmd_t *)NULL; 1676 1677 } else { 1678 hal->pending_q_head = (cmd1394_cmd_t *)NULL; 1679 } 1680 hal->pending_q_tail = (cmd1394_cmd_t *)prev_cmd; 1681 1682 mutex_exit(&hal->pending_q_mutex); 1683 1684 TNF_PROBE_0_DEBUG(s1394_pending_q_remove_exit, 1685 S1394_TNF_SL_ATREQ_STACK, ""); 1686 return (cmd); 1687 } 1688 1689 /* 1690 * s1394_resend_pending_cmds() 1691 * is called when the pending queue is to be flushed. After most of the 1692 * bus reset processing is completed, the pending commands are sent/resent. 1693 */ 1694 void 1695 s1394_resend_pending_cmds(s1394_hal_t *hal) 1696 { 1697 int done; 1698 1699 TNF_PROBE_0_DEBUG(s1394_resend_pending_cmds_enter, 1700 S1394_TNF_SL_BR_STACK, ""); 1701 1702 ASSERT(MUTEX_NOT_HELD(&hal->topology_tree_mutex)); 1703 1704 do { 1705 done = s1394_process_pending_q(hal); 1706 } while (done == B_FALSE); 1707 1708 ASSERT(MUTEX_NOT_HELD(&hal->topology_tree_mutex)); 1709 1710 TNF_PROBE_0_DEBUG(s1394_resend_pending_cmds_exit, 1711 S1394_TNF_SL_BR_STACK, ""); 1712 } 1713 1714 /* 1715 * s1394_process_pending_q() 1716 * is called to send/resend the commands on the pending queue. All command 1717 * handling can be done here, including notifying the target of failed 1718 * commands, etc. If it is necessary to recompute the address, speed, 1719 * or max_payload for a command, that can be done here too. And if there 1720 * is no reason not to continue sending commands from the pending queue, 1721 * then a B_FALSE is returned, else B_TRUE is returned. 1722 */ 1723 static boolean_t 1724 s1394_process_pending_q(s1394_hal_t *hal) 1725 { 1726 s1394_cmd_priv_t *s_priv; 1727 h1394_cmd_priv_t *h_priv; 1728 s1394_target_t *target; 1729 cmd1394_cmd_t *cmd; 1730 uint64_t node; 1731 uint32_t from_node; 1732 uint32_t to_node; 1733 uint_t current_max_payload; 1734 int ret; 1735 1736 TNF_PROBE_0_DEBUG(s1394_process_pending_q_enter, 1737 S1394_TNF_SL_BR_STACK, ""); 1738 1739 ASSERT(MUTEX_NOT_HELD(&hal->topology_tree_mutex)); 1740 1741 /* Pull a command from the Pending Q */ 1742 cmd = s1394_pending_q_remove(hal); 1743 1744 if (cmd == NULL) { 1745 TNF_PROBE_0_DEBUG(s1394_process_pending_q_exit, 1746 S1394_TNF_SL_BR_STACK, ""); 1747 return (B_TRUE); 1748 } 1749 1750 /* Get the Services Layer private area */ 1751 s_priv = S1394_GET_CMD_PRIV(cmd); 1752 1753 /* Get a pointer to the HAL private struct */ 1754 h_priv = (h1394_cmd_priv_t *)&s_priv->hal_cmd_private; 1755 1756 if ((cmd->cmd_options & CMD1394_OVERRIDE_ADDR) || 1757 (cmd->cmd_options & CMD1394_CANCEL_ON_BUS_RESET)) { 1758 if (h_priv->bus_generation == hal->generation_count) { 1759 ret = s1394_pending_q_helper(hal, cmd); 1760 return (ret); 1761 } else { 1762 1763 s_priv->cmd_in_use = B_FALSE; 1764 1765 cmd->cmd_result = CMD1394_EBUSRESET; 1766 1767 /* Is this a blocking command? */ 1768 if (cmd->cmd_options & CMD1394_BLOCKING) { 1769 /* Unblock the waiting command */ 1770 mutex_enter(&s_priv->blocking_mutex); 1771 s_priv->blocking_flag = B_TRUE; 1772 cv_signal(&s_priv->blocking_cv); 1773 mutex_exit(&s_priv->blocking_mutex); 1774 1775 TNF_PROBE_0_DEBUG(s1394_process_pending_q_exit, 1776 S1394_TNF_SL_BR_STACK, ""); 1777 return (B_FALSE); 1778 } 1779 1780 /* Call the target's completion_callback() */ 1781 if (cmd->completion_callback != NULL) { 1782 cmd->completion_callback(cmd); 1783 } 1784 1785 TNF_PROBE_0_DEBUG(s1394_process_pending_q_exit, 1786 S1394_TNF_SL_BR_STACK, ""); 1787 return (B_FALSE); 1788 } 1789 } else { 1790 if (h_priv->bus_generation == hal->generation_count) { 1791 ret = s1394_pending_q_helper(hal, cmd); 1792 return (ret); 1793 } else { 1794 /* Make sure we can get the topology_tree_mutex */ 1795 if (s1394_lock_tree(hal) != DDI_SUCCESS) 1796 return (B_TRUE); 1797 1798 /* Set the generation */ 1799 cmd->bus_generation = hal->generation_count; 1800 1801 /* Copy the generation into the HAL's private field */ 1802 h_priv->bus_generation = cmd->bus_generation; 1803 1804 target = s_priv->sent_by_target; 1805 1806 /* If not OVERRIDE_ADDR, then target may not be NULL */ 1807 ASSERT(target != NULL); 1808 1809 rw_enter(&hal->target_list_rwlock, RW_READER); 1810 1811 if (((target->target_state & S1394_TARG_GONE) == 0) && 1812 (target->on_node != NULL)) { 1813 node = target->on_node->node_num; 1814 rw_exit(&hal->target_list_rwlock); 1815 } else { 1816 rw_exit(&hal->target_list_rwlock); 1817 1818 s_priv->cmd_in_use = B_FALSE; 1819 1820 cmd->cmd_result = CMD1394_EDEVICE_REMOVED; 1821 1822 /* Is this a blocking command? */ 1823 if (cmd->cmd_options & CMD1394_BLOCKING) { 1824 s1394_unlock_tree(hal); 1825 1826 /* Unblock the waiting command */ 1827 mutex_enter(&s_priv->blocking_mutex); 1828 s_priv->blocking_flag = B_TRUE; 1829 cv_signal(&s_priv->blocking_cv); 1830 mutex_exit(&s_priv->blocking_mutex); 1831 1832 TNF_PROBE_0_DEBUG( 1833 s1394_process_pending_q_exit, 1834 S1394_TNF_SL_BR_STACK, 1835 ""); 1836 return (B_FALSE); 1837 } 1838 1839 /* Call the target's completion_callback() */ 1840 if (cmd->completion_callback != NULL) { 1841 s1394_unlock_tree(hal); 1842 cmd->completion_callback(cmd); 1843 TNF_PROBE_0_DEBUG( 1844 s1394_process_pending_q_exit, 1845 S1394_TNF_SL_BR_STACK, ""); 1846 return (B_FALSE); 1847 } else { 1848 s1394_unlock_tree(hal); 1849 TNF_PROBE_0_DEBUG( 1850 s1394_process_pending_q_exit, 1851 S1394_TNF_SL_BR_STACK, ""); 1852 return (B_FALSE); 1853 } 1854 } 1855 1856 /* Mask in the top 16-bits */ 1857 cmd->cmd_addr = cmd->cmd_addr & 1858 IEEE1394_ADDR_OFFSET_MASK; 1859 cmd->cmd_addr = cmd->cmd_addr | 1860 (node << IEEE1394_ADDR_PHY_ID_SHIFT); 1861 cmd->cmd_addr = cmd->cmd_addr | 1862 IEEE1394_ADDR_BUS_ID_MASK; 1863 1864 /* Speed is to be filled in from speed map */ 1865 from_node = IEEE1394_NODE_NUM(hal->node_id); 1866 to_node = (uint32_t)node; 1867 1868 /* Fill in the nodeID */ 1869 cmd->nodeID = 1870 (cmd->cmd_addr & IEEE1394_ADDR_NODE_ID_MASK) >> 1871 IEEE1394_ADDR_NODE_ID_SHIFT; 1872 1873 if (cmd->cmd_options & CMD1394_OVERRIDE_SPEED) { 1874 s_priv->hal_cmd_private.speed = 1875 (int)cmd->cmd_speed; 1876 } else { 1877 /* Speed is to be filled in from speed map */ 1878 s_priv->hal_cmd_private.speed = 1879 (int)s1394_speed_map_get(hal, from_node, 1880 to_node); 1881 } 1882 1883 /* Is it a block request? */ 1884 if ((cmd->cmd_type == CMD1394_ASYNCH_RD_BLOCK) || 1885 (cmd->cmd_type == CMD1394_ASYNCH_WR_BLOCK)) { 1886 1887 /* Get a pointer to the HAL private struct */ 1888 h_priv = (h1394_cmd_priv_t *)&s_priv-> 1889 hal_cmd_private; 1890 1891 /* Handle the MAX_PAYLOAD size */ 1892 if (s_priv->sent_by_target != NULL) { 1893 current_max_payload = 1894 s_priv->sent_by_target-> 1895 current_max_payload; 1896 } else { 1897 current_max_payload = 4; 1898 } 1899 if (cmd->cmd_options & 1900 CMD1394_OVERRIDE_MAX_PAYLOAD) { 1901 if (current_max_payload > 1902 cmd->cmd_u.b.max_payload) 1903 current_max_payload = 1904 cmd->cmd_u.b.max_payload; 1905 } 1906 if (s_priv->data_remaining < 1907 current_max_payload) { 1908 h_priv->mblk.length = 1909 s_priv->data_remaining; 1910 } else { 1911 h_priv->mblk.length = 1912 current_max_payload; 1913 } 1914 } 1915 s1394_unlock_tree(hal); 1916 ret = s1394_pending_q_helper(hal, cmd); 1917 TNF_PROBE_0_DEBUG(s1394_process_pending_q_exit, 1918 S1394_TNF_SL_BR_STACK, ""); 1919 return (ret); 1920 } 1921 } 1922 } 1923 1924 /* 1925 * s1394_pending_q_helper() 1926 * is a "helper" function for s1394_process_pending_q(). It attempts to 1927 * resend commands, handling error conditions whenever necessary. 1928 */ 1929 static boolean_t 1930 s1394_pending_q_helper(s1394_hal_t *hal, cmd1394_cmd_t *cmd) 1931 { 1932 s1394_cmd_priv_t *s_priv; 1933 int err; 1934 int ret; 1935 1936 TNF_PROBE_0_DEBUG(s1394_pending_q_helper_enter, 1937 S1394_TNF_SL_BR_STACK, ""); 1938 1939 ASSERT(MUTEX_NOT_HELD(&hal->topology_tree_mutex)); 1940 1941 /* Get the Services Layer private area */ 1942 s_priv = S1394_GET_CMD_PRIV(cmd); 1943 1944 /* Put cmd on outstanding request Q */ 1945 s1394_insert_q_asynch_cmd(hal, cmd); 1946 1947 /* Send command out again */ 1948 ret = s1394_xfer_asynch_command(hal, cmd, &err); 1949 1950 if (ret != DDI_SUCCESS) { 1951 if (err == CMD1394_ESTALE_GENERATION) { 1952 /* Remove cmd outstanding req Q */ 1953 s1394_remove_q_asynch_cmd(hal, cmd); 1954 s1394_pending_q_insert(hal, cmd, S1394_PENDING_Q_FRONT); 1955 1956 TNF_PROBE_0_DEBUG(s1394_pending_q_helper_exit, 1957 S1394_TNF_SL_BR_STACK, ""); 1958 return (B_TRUE); 1959 } else { 1960 /* Remove cmd from outstanding request Q */ 1961 s1394_remove_q_asynch_cmd(hal, cmd); 1962 1963 s_priv->cmd_in_use = B_FALSE; 1964 1965 cmd->cmd_result = err; 1966 1967 /* Is this a blocking command? */ 1968 if (cmd->cmd_options & CMD1394_BLOCKING) { 1969 /* Unblock waiting command */ 1970 mutex_enter(&s_priv->blocking_mutex); 1971 s_priv->blocking_flag = B_TRUE; 1972 cv_signal(&s_priv->blocking_cv); 1973 mutex_exit(&s_priv->blocking_mutex); 1974 1975 TNF_PROBE_0_DEBUG(s1394_pending_q_helper_exit, 1976 S1394_TNF_SL_BR_STACK, ""); 1977 return (B_FALSE); 1978 } 1979 1980 /* Call target completion_callback() */ 1981 if (cmd->completion_callback != NULL) { 1982 cmd->completion_callback(cmd); 1983 TNF_PROBE_0_DEBUG(s1394_pending_q_helper_exit, 1984 S1394_TNF_SL_BR_STACK, ""); 1985 return (B_FALSE); 1986 } else { 1987 TNF_PROBE_0_DEBUG(s1394_pending_q_helper_exit, 1988 S1394_TNF_SL_BR_STACK, ""); 1989 return (B_FALSE); 1990 } 1991 } 1992 } 1993 1994 TNF_PROBE_0_DEBUG(s1394_pending_q_helper_exit, 1995 S1394_TNF_SL_BR_STACK, ""); 1996 return (B_FALSE); 1997 } 1998 1999 /* 2000 * s1394_process_split_lock() 2001 * is a "helper" function for the s1394_handle_lock() callback. Its 2002 * job is to perform whatever manipulation is required for the given 2003 * request. 2004 */ 2005 static int 2006 s1394_process_split_lock(cmd1394_cmd_t *cmd, cmd1394_cmd_t *target_cmd) 2007 { 2008 uint64_t new_value64; 2009 uint64_t data_value64; 2010 uint64_t arg_value64; 2011 uint64_t old_value64; 2012 uint64_t temp_value64; 2013 uint32_t new_value32; 2014 uint32_t data_value32; 2015 uint32_t arg_value32; 2016 uint32_t old_value32; 2017 uint32_t temp_value32; 2018 2019 TNF_PROBE_0_DEBUG(s1394_process_split_lock_enter, 2020 S1394_TNF_SL_ATREQ_STACK, ""); 2021 2022 if (cmd->cmd_type == CMD1394_ASYNCH_LOCK_32) { 2023 old_value32 = cmd->cmd_u.l32.old_value; 2024 data_value32 = target_cmd->cmd_u.l32.data_value; 2025 arg_value32 = target_cmd->cmd_u.l32.arg_value; 2026 2027 /* Lock type specific */ 2028 switch (target_cmd->cmd_u.l32.lock_type) { 2029 case CMD1394_LOCK_BIT_AND: 2030 new_value32 = old_value32 & data_value32; 2031 break; 2032 2033 case CMD1394_LOCK_BIT_OR: 2034 new_value32 = old_value32 | data_value32; 2035 break; 2036 2037 case CMD1394_LOCK_BIT_XOR: 2038 new_value32 = old_value32 ^ data_value32; 2039 break; 2040 2041 case CMD1394_LOCK_INCREMENT: 2042 old_value32 = T1394_DATA32(old_value32); 2043 new_value32 = old_value32 + 1; 2044 new_value32 = T1394_DATA32(new_value32); 2045 old_value32 = T1394_DATA32(old_value32); 2046 break; 2047 2048 case CMD1394_LOCK_DECREMENT: 2049 old_value32 = T1394_DATA32(old_value32); 2050 new_value32 = old_value32 - 1; 2051 new_value32 = T1394_DATA32(new_value32); 2052 old_value32 = T1394_DATA32(old_value32); 2053 break; 2054 2055 case CMD1394_LOCK_ADD: 2056 old_value32 = T1394_DATA32(old_value32); 2057 new_value32 = old_value32 + data_value32; 2058 new_value32 = T1394_DATA32(new_value32); 2059 old_value32 = T1394_DATA32(old_value32); 2060 break; 2061 2062 case CMD1394_LOCK_SUBTRACT: 2063 old_value32 = T1394_DATA32(old_value32); 2064 new_value32 = old_value32 - data_value32; 2065 new_value32 = T1394_DATA32(new_value32); 2066 old_value32 = T1394_DATA32(old_value32); 2067 break; 2068 2069 case CMD1394_LOCK_THRESH_ADD: 2070 old_value32 = T1394_DATA32(old_value32); 2071 temp_value32 = (old_value32 + data_value32); 2072 if ((temp_value32 >= old_value32) && 2073 (temp_value32 <= arg_value32)) { 2074 new_value32 = T1394_DATA32(temp_value32); 2075 old_value32 = T1394_DATA32(old_value32); 2076 } else { 2077 /* Failed threshold add */ 2078 target_cmd->cmd_u.l32.old_value = 2079 T1394_DATA32(cmd->cmd_u.l32.old_value); 2080 target_cmd->cmd_result = CMD1394_CMDSUCCESS; 2081 TNF_PROBE_0_DEBUG( 2082 s1394_process_split_lock_exit, 2083 S1394_TNF_SL_ATREQ_STACK, ""); 2084 return (DDI_FAILURE); 2085 } 2086 break; 2087 2088 case CMD1394_LOCK_THRESH_SUBTRACT: 2089 old_value32 = T1394_DATA32(old_value32); 2090 temp_value32 = (old_value32 - data_value32); 2091 if ((old_value32 >= data_value32) && 2092 (temp_value32 >= arg_value32)) { 2093 new_value32 = T1394_DATA32(temp_value32); 2094 old_value32 = T1394_DATA32(old_value32); 2095 } else { 2096 /* Failed threshold subtract */ 2097 target_cmd->cmd_u.l32.old_value = 2098 T1394_DATA32(cmd->cmd_u.l32.old_value); 2099 target_cmd->cmd_result = CMD1394_CMDSUCCESS; 2100 TNF_PROBE_0_DEBUG( 2101 s1394_process_split_lock_exit, 2102 S1394_TNF_SL_ATREQ_STACK, ""); 2103 return (DDI_FAILURE); 2104 } 2105 break; 2106 2107 case CMD1394_LOCK_CLIP_ADD: 2108 old_value32 = T1394_DATA32(old_value32); 2109 temp_value32 = (old_value32 + data_value32); 2110 if ((temp_value32 < old_value32) || 2111 (temp_value32 > arg_value32)) 2112 new_value32 = T1394_DATA32(arg_value32); 2113 else 2114 new_value32 = T1394_DATA32(temp_value32); 2115 old_value32 = T1394_DATA32(old_value32); 2116 break; 2117 2118 case CMD1394_LOCK_CLIP_SUBTRACT: 2119 old_value32 = T1394_DATA32(old_value32); 2120 temp_value32 = (old_value32 - data_value32); 2121 if ((data_value32 > old_value32) || 2122 (temp_value32 < arg_value32)) 2123 new_value32 = T1394_DATA32(arg_value32); 2124 else 2125 new_value32 = T1394_DATA32(temp_value32); 2126 old_value32 = T1394_DATA32(old_value32); 2127 break; 2128 } 2129 2130 /* Send compare-swap lock request */ 2131 cmd->cmd_u.l32.arg_value = old_value32; 2132 cmd->cmd_u.l32.data_value = new_value32; 2133 } else { 2134 old_value64 = cmd->cmd_u.l64.old_value; 2135 data_value64 = target_cmd->cmd_u.l64.data_value; 2136 arg_value64 = target_cmd->cmd_u.l64.arg_value; 2137 2138 /* Lock type specific */ 2139 switch (target_cmd->cmd_u.l64.lock_type) { 2140 case CMD1394_LOCK_BIT_AND: 2141 new_value64 = old_value64 & data_value64; 2142 break; 2143 2144 case CMD1394_LOCK_BIT_OR: 2145 new_value64 = old_value64 | data_value64; 2146 break; 2147 2148 case CMD1394_LOCK_BIT_XOR: 2149 new_value64 = old_value64 ^ data_value64; 2150 break; 2151 2152 case CMD1394_LOCK_INCREMENT: 2153 old_value64 = T1394_DATA64(old_value64); 2154 new_value64 = old_value64 + 1; 2155 new_value64 = T1394_DATA64(new_value64); 2156 old_value64 = T1394_DATA64(old_value64); 2157 break; 2158 2159 case CMD1394_LOCK_DECREMENT: 2160 old_value64 = T1394_DATA64(old_value64); 2161 new_value64 = old_value64 - 1; 2162 new_value64 = T1394_DATA64(new_value64); 2163 old_value64 = T1394_DATA64(old_value64); 2164 break; 2165 2166 case CMD1394_LOCK_ADD: 2167 old_value64 = T1394_DATA64(old_value64); 2168 new_value64 = old_value64 + data_value64; 2169 new_value64 = T1394_DATA64(new_value64); 2170 old_value64 = T1394_DATA64(old_value64); 2171 break; 2172 2173 case CMD1394_LOCK_SUBTRACT: 2174 old_value64 = T1394_DATA64(old_value64); 2175 new_value64 = old_value64 - data_value64; 2176 new_value64 = T1394_DATA64(new_value64); 2177 old_value64 = T1394_DATA64(old_value64); 2178 break; 2179 2180 case CMD1394_LOCK_THRESH_ADD: 2181 old_value64 = T1394_DATA64(old_value64); 2182 temp_value64 = (old_value64 + data_value64); 2183 if ((temp_value64 >= old_value64) && 2184 (temp_value64 <= arg_value64)) { 2185 new_value64 = T1394_DATA64(temp_value64); 2186 old_value64 = T1394_DATA64(old_value64); 2187 } else { 2188 /* Failed threshold add */ 2189 target_cmd->cmd_u.l64.old_value = 2190 T1394_DATA64(cmd->cmd_u.l64.old_value); 2191 target_cmd->cmd_result = CMD1394_CMDSUCCESS; 2192 TNF_PROBE_0_DEBUG( 2193 s1394_process_split_lock_exit, 2194 S1394_TNF_SL_ATREQ_STACK, ""); 2195 return (DDI_FAILURE); 2196 } 2197 break; 2198 2199 case CMD1394_LOCK_THRESH_SUBTRACT: 2200 old_value64 = T1394_DATA64(old_value64); 2201 temp_value64 = (old_value64 - data_value64); 2202 if ((old_value64 >= data_value64) && 2203 (temp_value64 >= arg_value64)) { 2204 new_value64 = T1394_DATA64(temp_value64); 2205 old_value64 = T1394_DATA64(old_value64); 2206 } else { 2207 /* Failed threshold subtract */ 2208 target_cmd->cmd_u.l64.old_value = 2209 T1394_DATA64(cmd->cmd_u.l64.old_value); 2210 target_cmd->cmd_result = CMD1394_CMDSUCCESS; 2211 TNF_PROBE_0_DEBUG( 2212 s1394_process_split_lock_exit, 2213 S1394_TNF_SL_ATREQ_STACK, ""); 2214 return (DDI_FAILURE); 2215 } 2216 break; 2217 2218 case CMD1394_LOCK_CLIP_ADD: 2219 old_value64 = T1394_DATA64(old_value64); 2220 temp_value64 = (old_value64 + data_value64); 2221 if ((temp_value64 < old_value64) || 2222 (temp_value64 > arg_value64)) 2223 new_value64 = T1394_DATA64(arg_value64); 2224 else 2225 new_value64 = T1394_DATA64(temp_value64); 2226 old_value64 = T1394_DATA64(old_value64); 2227 break; 2228 2229 case CMD1394_LOCK_CLIP_SUBTRACT: 2230 old_value64 = T1394_DATA64(old_value64); 2231 temp_value64 = (old_value64 - data_value64); 2232 if ((data_value64 > old_value64) || 2233 (temp_value64 < arg_value64)) 2234 new_value64 = T1394_DATA64(arg_value64); 2235 else 2236 new_value64 = T1394_DATA64(temp_value64); 2237 old_value64 = T1394_DATA64(old_value64); 2238 break; 2239 } 2240 2241 /* Send compare-swap lock request */ 2242 cmd->cmd_u.l64.arg_value = old_value64; 2243 cmd->cmd_u.l64.data_value = new_value64; 2244 } 2245 2246 TNF_PROBE_0_DEBUG(s1394_process_split_lock_exit, 2247 S1394_TNF_SL_ATREQ_STACK, ""); 2248 return (DDI_SUCCESS); 2249 } 2250 2251 /* 2252 * s1394_finish_split_lock() 2253 * is another "helper" function for the s1394_handle_lock() callback. 2254 * Its job is to finish up whatever lock request procesing is necessary. 2255 */ 2256 static int 2257 s1394_finish_split_lock(cmd1394_cmd_t *cmd, cmd1394_cmd_t *target_cmd) 2258 { 2259 s1394_cmd_priv_t *s_priv; 2260 uint64_t tmp_value64; 2261 uint32_t tmp_value32; 2262 2263 TNF_PROBE_0_DEBUG(s1394_finish_split_lock_enter, 2264 S1394_TNF_SL_ATREQ_STACK, ""); 2265 2266 /* Get the Services Layer private area */ 2267 s_priv = S1394_GET_CMD_PRIV(cmd); 2268 2269 if (((cmd->cmd_type == CMD1394_ASYNCH_LOCK_32) && 2270 (cmd->cmd_u.l32.old_value == cmd->cmd_u.l32.arg_value)) || 2271 ((cmd->cmd_type == CMD1394_ASYNCH_LOCK_64) && 2272 (cmd->cmd_u.l64.old_value == cmd->cmd_u.l64.arg_value))) { 2273 2274 if (cmd->cmd_type == CMD1394_ASYNCH_LOCK_32) { 2275 switch (cmd->cmd_u.l32.lock_type) { 2276 case CMD1394_LOCK_INCREMENT: 2277 case CMD1394_LOCK_DECREMENT: 2278 case CMD1394_LOCK_ADD: 2279 case CMD1394_LOCK_SUBTRACT: 2280 case CMD1394_LOCK_THRESH_ADD: 2281 case CMD1394_LOCK_THRESH_SUBTRACT: 2282 case CMD1394_LOCK_CLIP_ADD: 2283 case CMD1394_LOCK_CLIP_SUBTRACT: 2284 tmp_value32 = cmd->cmd_u.l32.old_value; 2285 tmp_value32 = T1394_DATA32(tmp_value32); 2286 target_cmd->cmd_u.l32.old_value = tmp_value32; 2287 break; 2288 default: 2289 tmp_value32 = cmd->cmd_u.l32.old_value; 2290 target_cmd->cmd_u.l32.old_value = tmp_value32; 2291 break; 2292 } 2293 } else { 2294 switch (cmd->cmd_u.l64.lock_type) { 2295 case CMD1394_LOCK_INCREMENT: 2296 case CMD1394_LOCK_DECREMENT: 2297 case CMD1394_LOCK_ADD: 2298 case CMD1394_LOCK_SUBTRACT: 2299 case CMD1394_LOCK_THRESH_ADD: 2300 case CMD1394_LOCK_THRESH_SUBTRACT: 2301 case CMD1394_LOCK_CLIP_ADD: 2302 case CMD1394_LOCK_CLIP_SUBTRACT: 2303 tmp_value64 = cmd->cmd_u.l64.old_value; 2304 tmp_value64 = T1394_DATA64(tmp_value64); 2305 target_cmd->cmd_u.l64.old_value = tmp_value64; 2306 break; 2307 default: 2308 tmp_value64 = cmd->cmd_u.l64.old_value; 2309 target_cmd->cmd_u.l64.old_value = tmp_value64; 2310 break; 2311 } 2312 } 2313 /* Set status */ 2314 target_cmd->cmd_result = CMD1394_CMDSUCCESS; 2315 TNF_PROBE_0_DEBUG(s1394_finish_split_lock_exit, 2316 S1394_TNF_SL_ATREQ_STACK, ""); 2317 return (DDI_SUCCESS); 2318 } else { 2319 if (s_priv->temp_num_retries > 0) { 2320 /* Decrement retry count */ 2321 s_priv->temp_num_retries--; 2322 2323 /* Reset lock_req_step */ 2324 s_priv->lock_req_step = 0; 2325 2326 TNF_PROBE_0_DEBUG(s1394_finish_split_lock_start_over, 2327 S1394_TNF_SL_ATREQ_STACK, ""); 2328 /* Resend... start at step 0 again */ 2329 TNF_PROBE_0_DEBUG(s1394_finish_split_lock_exit, 2330 S1394_TNF_SL_ATREQ_STACK, ""); 2331 return (DDI_FAILURE); 2332 } else { 2333 /* Failed... RETRIES_EXCEEDED */ 2334 target_cmd->cmd_result = CMD1394_ERETRIES_EXCEEDED; 2335 TNF_PROBE_0_DEBUG(s1394_finish_split_lock_exit, 2336 S1394_TNF_SL_ATREQ_STACK, ""); 2337 return (DDI_SUCCESS); 2338 } 2339 } 2340 } 2341