1 /*- 2 * Copyright (c) 2017 Broadcom. All rights reserved. 3 * The term "Broadcom" refers to Broadcom Limited and/or its subsidiaries. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright notice, 12 * this list of conditions and the following disclaimer in the documentation 13 * and/or other materials provided with the distribution. 14 * 15 * 3. Neither the name of the copyright holder nor the names of its contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 * 31 * $FreeBSD$ 32 */ 33 34 /** 35 * @file 36 * Functions to build and send ELS/CT/BLS commands and responses. 37 */ 38 39 /*! 40 @defgroup els_api ELS/BLS/CT Command and Response Functions 41 */ 42 43 #include "ocs.h" 44 #include "ocs_els.h" 45 #include "ocs_scsi.h" 46 #include "ocs_device.h" 47 48 #define ELS_IOFMT "[i:%04x t:%04x h:%04x]" 49 #define ELS_IOFMT_ARGS(els) els->init_task_tag, els->tgt_task_tag, els->hw_tag 50 51 #define node_els_trace() \ 52 do { \ 53 if (OCS_LOG_ENABLE_ELS_TRACE(ocs)) \ 54 ocs_log_info(ocs, "[%s] %-20s\n", node->display_name, __func__); \ 55 } while (0) 56 57 #define els_io_printf(els, fmt, ...) \ 58 ocs_log_debug(els->node->ocs, "[%s]" ELS_IOFMT " %-8s " fmt, els->node->display_name, ELS_IOFMT_ARGS(els), els->display_name, ##__VA_ARGS__); 59 60 static int32_t ocs_els_send(ocs_io_t *els, uint32_t reqlen, uint32_t timeout_sec, ocs_hw_srrs_cb_t cb); 61 static int32_t ocs_els_send_rsp(ocs_io_t *els, uint32_t rsplen); 62 static int32_t ocs_els_acc_cb(ocs_hw_io_t *hio, ocs_remote_node_t *rnode, uint32_t length, int32_t status, uint32_t ext_status, void *arg); 63 static ocs_io_t *ocs_bls_send_acc(ocs_io_t *io, uint32_t s_id, uint16_t ox_id, uint16_t rx_id); 64 static int32_t ocs_bls_send_acc_cb(ocs_hw_io_t *hio, ocs_remote_node_t *rnode, uint32_t length, 65 int32_t status, uint32_t ext_status, void *app); 66 static void ocs_io_transition(ocs_io_t *els, ocs_sm_function_t state, void *data); 67 static ocs_io_t *ocs_els_abort_io(ocs_io_t *els, int send_abts); 68 static void _ocs_els_io_free(void *arg); 69 static void ocs_els_delay_timer_cb(void *arg); 70 71 72 /** 73 * @ingroup els_api 74 * @brief ELS state machine transition wrapper. 75 * 76 * <h3 class="desc">Description</h3> 77 * This function is the transition wrapper for the ELS state machine. It grabs 78 * the node lock prior to making the transition to protect 79 * against multiple threads accessing a particular ELS. For example, 80 * one thread transitioning from __els_init to 81 * __ocs_els_wait_resp and another thread (tasklet) handling the 82 * completion of that ELS request. 83 * 84 * @param els Pointer to the IO context. 85 * @param state State to transition to. 86 * @param data Data to pass in with the transition. 87 * 88 * @return None. 89 */ 90 static void 91 ocs_io_transition(ocs_io_t *els, ocs_sm_function_t state, void *data) 92 { 93 /* protect ELS events with node lock */ 94 ocs_node_t *node = els->node; 95 ocs_node_lock(node); 96 ocs_sm_transition(&els->els_sm, state, data); 97 ocs_node_unlock(node); 98 } 99 100 /** 101 * @ingroup els_api 102 * @brief ELS state machine post event wrapper. 103 * 104 * <h3 class="desc">Description</h3> 105 * Post an event wrapper for the ELS state machine. This function grabs 106 * the node lock prior to posting the event. 107 * 108 * @param els Pointer to the IO context. 109 * @param evt Event to process. 110 * @param data Data to pass in with the transition. 111 * 112 * @return None. 113 */ 114 void 115 ocs_els_post_event(ocs_io_t *els, ocs_sm_event_t evt, void *data) 116 { 117 /* protect ELS events with node lock */ 118 ocs_node_t *node = els->node; 119 ocs_node_lock(node); 120 els->els_evtdepth ++; 121 ocs_sm_post_event(&els->els_sm, evt, data); 122 els->els_evtdepth --; 123 ocs_node_unlock(node); 124 if (els->els_evtdepth == 0 && els->els_req_free) { 125 ocs_els_io_free(els); 126 } 127 } 128 129 /** 130 * @ingroup els_api 131 * @brief Allocate an IO structure for an ELS IO context. 132 * 133 * <h3 class="desc">Description</h3> 134 * Allocate an IO for an ELS context. Uses OCS_ELS_RSP_LEN as response size. 135 * 136 * @param node node to associate ELS IO with 137 * @param reqlen Length of ELS request 138 * @param role Role of ELS (originator/responder) 139 * 140 * @return pointer to IO structure allocated 141 */ 142 143 ocs_io_t * 144 ocs_els_io_alloc(ocs_node_t *node, uint32_t reqlen, ocs_els_role_e role) 145 { 146 return ocs_els_io_alloc_size(node, reqlen, OCS_ELS_RSP_LEN, role); 147 } 148 149 /** 150 * @ingroup els_api 151 * @brief Allocate an IO structure for an ELS IO context. 152 * 153 * <h3 class="desc">Description</h3> 154 * Allocate an IO for an ELS context, allowing the caller to specify the size of the response. 155 * 156 * @param node node to associate ELS IO with 157 * @param reqlen Length of ELS request 158 * @param rsplen Length of ELS response 159 * @param role Role of ELS (originator/responder) 160 * 161 * @return pointer to IO structure allocated 162 */ 163 164 ocs_io_t * 165 ocs_els_io_alloc_size(ocs_node_t *node, uint32_t reqlen, uint32_t rsplen, ocs_els_role_e role) 166 { 167 168 ocs_t *ocs; 169 ocs_xport_t *xport; 170 ocs_io_t *els; 171 ocs_assert(node, NULL); 172 ocs_assert(node->ocs, NULL); 173 ocs = node->ocs; 174 ocs_assert(ocs->xport, NULL); 175 xport = ocs->xport; 176 177 ocs_lock(&node->active_ios_lock); 178 if (!node->io_alloc_enabled) { 179 ocs_log_debug(ocs, "called with io_alloc_enabled = FALSE\n"); 180 ocs_unlock(&node->active_ios_lock); 181 return NULL; 182 } 183 184 els = ocs_io_alloc(ocs); 185 if (els == NULL) { 186 ocs_atomic_add_return(&xport->io_alloc_failed_count, 1); 187 ocs_unlock(&node->active_ios_lock); 188 return NULL; 189 } 190 191 /* initialize refcount */ 192 ocs_ref_init(&els->ref, _ocs_els_io_free, els); 193 194 switch (role) { 195 case OCS_ELS_ROLE_ORIGINATOR: 196 els->cmd_ini = TRUE; 197 els->cmd_tgt = FALSE; 198 break; 199 case OCS_ELS_ROLE_RESPONDER: 200 els->cmd_ini = FALSE; 201 els->cmd_tgt = TRUE; 202 break; 203 } 204 205 /* IO should not have an associated HW IO yet. Assigned below. */ 206 if (els->hio != NULL) { 207 ocs_log_err(ocs, "assertion failed. HIO is not null\n"); 208 ocs_io_free(ocs, els); 209 ocs_unlock(&node->active_ios_lock); 210 return NULL; 211 } 212 213 /* populate generic io fields */ 214 els->ocs = ocs; 215 els->node = node; 216 217 /* set type and ELS-specific fields */ 218 els->io_type = OCS_IO_TYPE_ELS; 219 els->display_name = "pending"; 220 221 if (reqlen > OCS_ELS_REQ_LEN) { 222 ocs_log_err(ocs, "ELS command request len greater than allocated\n"); 223 ocs_io_free(ocs, els); 224 ocs_unlock(&node->active_ios_lock); 225 return NULL; 226 } 227 228 if (rsplen > OCS_ELS_GID_PT_RSP_LEN) { 229 ocs_log_err(ocs, "ELS command response len: %d " 230 "greater than allocated\n", rsplen); 231 ocs_io_free(ocs, els); 232 ocs_unlock(&node->active_ios_lock); 233 return NULL; 234 } 235 236 els->els_req.size = reqlen; 237 els->els_rsp.size = rsplen; 238 239 if (els != NULL) { 240 ocs_memset(&els->els_sm, 0, sizeof(els->els_sm)); 241 els->els_sm.app = els; 242 243 /* initialize fields */ 244 els->els_retries_remaining = OCS_FC_ELS_DEFAULT_RETRIES; 245 els->els_evtdepth = 0; 246 els->els_pend = 0; 247 els->els_active = 0; 248 249 /* add els structure to ELS IO list */ 250 ocs_list_add_tail(&node->els_io_pend_list, els); 251 els->els_pend = 1; 252 } 253 ocs_unlock(&node->active_ios_lock); 254 return els; 255 } 256 257 /** 258 * @ingroup els_api 259 * @brief Free IO structure for an ELS IO context. 260 * 261 * <h3 class="desc">Description</h3> Free IO for an ELS 262 * IO context 263 * 264 * @param els ELS IO structure for which IO is allocated 265 * 266 * @return None 267 */ 268 269 void 270 ocs_els_io_free(ocs_io_t *els) 271 { 272 ocs_ref_put(&els->ref); 273 } 274 275 /** 276 * @ingroup els_api 277 * @brief Free IO structure for an ELS IO context. 278 * 279 * <h3 class="desc">Description</h3> Free IO for an ELS 280 * IO context 281 * 282 * @param arg ELS IO structure for which IO is allocated 283 * 284 * @return None 285 */ 286 287 static void 288 _ocs_els_io_free(void *arg) 289 { 290 ocs_io_t *els = (ocs_io_t *)arg; 291 ocs_t *ocs; 292 ocs_node_t *node; 293 int send_empty_event = FALSE; 294 295 ocs_assert(els); 296 ocs_assert(els->node); 297 ocs_assert(els->node->ocs); 298 ocs = els->node->ocs; 299 300 node = els->node; 301 ocs = node->ocs; 302 303 ocs_lock(&node->active_ios_lock); 304 if (els->els_active) { 305 /* if active, remove from active list and check empty */ 306 ocs_list_remove(&node->els_io_active_list, els); 307 /* Send list empty event if the IO allocator is disabled, and the list is empty 308 * If node->io_alloc_enabled was not checked, the event would be posted continually 309 */ 310 send_empty_event = (!node->io_alloc_enabled) && ocs_list_empty(&node->els_io_active_list); 311 els->els_active = 0; 312 } else if (els->els_pend) { 313 /* if pending, remove from pending list; node shutdown isn't 314 * gated off the pending list (only the active list), so no 315 * need to check if pending list is empty 316 */ 317 ocs_list_remove(&node->els_io_pend_list, els); 318 els->els_pend = 0; 319 } else { 320 ocs_log_err(ocs, "assertion failed: niether els->els_pend nor els->active set\n"); 321 ocs_unlock(&node->active_ios_lock); 322 return; 323 } 324 325 ocs_unlock(&node->active_ios_lock); 326 327 ocs_io_free(ocs, els); 328 329 if (send_empty_event) { 330 ocs_node_post_event(node, OCS_EVT_ALL_CHILD_NODES_FREE, NULL); 331 } 332 333 ocs_scsi_check_pending(ocs); 334 } 335 336 /** 337 * @ingroup els_api 338 * @brief Make ELS IO active 339 * 340 * @param els Pointer to the IO context to make active. 341 * 342 * @return Returns 0 on success; or a negative error code value on failure. 343 */ 344 345 static void 346 ocs_els_make_active(ocs_io_t *els) 347 { 348 ocs_node_t *node = els->node; 349 350 /* move ELS from pending list to active list */ 351 ocs_lock(&node->active_ios_lock); 352 if (els->els_pend) { 353 if (els->els_active) { 354 ocs_log_err(node->ocs, "assertion failed: both els->els_pend and els->active set\n"); 355 ocs_unlock(&node->active_ios_lock); 356 return; 357 } else { 358 359 /* remove from pending list */ 360 ocs_list_remove(&node->els_io_pend_list, els); 361 els->els_pend = 0; 362 363 /* add els structure to ELS IO list */ 364 ocs_list_add_tail(&node->els_io_active_list, els); 365 els->els_active = 1; 366 } 367 } else { 368 /* must be retrying; make sure it's already active */ 369 if (!els->els_active) { 370 ocs_log_err(node->ocs, "assertion failed: niether els->els_pend nor els->active set\n"); 371 } 372 } 373 ocs_unlock(&node->active_ios_lock); 374 } 375 376 /** 377 * @ingroup els_api 378 * @brief Send the ELS command. 379 * 380 * <h3 class="desc">Description</h3> 381 * The command, given by the \c els IO context, is sent to the node that the IO was 382 * configured with, using ocs_hw_srrs_send(). Upon completion, 383 * the \c cb callback is invoked, 384 * with the application-specific argument set to the \c els IO context. 385 * 386 * @param els Pointer to the IO context. 387 * @param reqlen Byte count in the payload to send. 388 * @param timeout_sec Command timeout, in seconds (0 -> 2*R_A_TOV). 389 * @param cb Completion callback. 390 * 391 * @return Returns 0 on success; or a negative error code value on failure. 392 */ 393 394 static int32_t 395 ocs_els_send(ocs_io_t *els, uint32_t reqlen, uint32_t timeout_sec, ocs_hw_srrs_cb_t cb) 396 { 397 ocs_node_t *node = els->node; 398 399 /* update ELS request counter */ 400 node->els_req_cnt++; 401 402 /* move ELS from pending list to active list */ 403 ocs_els_make_active(els); 404 405 els->wire_len = reqlen; 406 return ocs_scsi_io_dispatch(els, cb); 407 } 408 409 /** 410 * @ingroup els_api 411 * @brief Send the ELS response. 412 * 413 * <h3 class="desc">Description</h3> 414 * The ELS response, given by the \c els IO context, is sent to the node 415 * that the IO was configured with, using ocs_hw_srrs_send(). 416 * 417 * @param els Pointer to the IO context. 418 * @param rsplen Byte count in the payload to send. 419 * 420 * @return Returns 0 on success; or a negative error value on failure. 421 */ 422 423 static int32_t 424 ocs_els_send_rsp(ocs_io_t *els, uint32_t rsplen) 425 { 426 ocs_node_t *node = els->node; 427 428 /* increment ELS completion counter */ 429 node->els_cmpl_cnt++; 430 431 /* move ELS from pending list to active list */ 432 ocs_els_make_active(els); 433 434 els->wire_len = rsplen; 435 return ocs_scsi_io_dispatch(els, ocs_els_acc_cb); 436 } 437 438 /** 439 * @ingroup els_api 440 * @brief Handle ELS IO request completions. 441 * 442 * <h3 class="desc">Description</h3> 443 * This callback is used for several ELS send operations. 444 * 445 * @param hio Pointer to the HW IO context that completed. 446 * @param rnode Pointer to the remote node. 447 * @param length Length of the returned payload data. 448 * @param status Status of the completion. 449 * @param ext_status Extended status of the completion. 450 * @param arg Application-specific argument (generally a pointer to the ELS IO context). 451 * 452 * @return Returns 0 on success; or a negative error value on failure. 453 */ 454 455 static int32_t 456 ocs_els_req_cb(ocs_hw_io_t *hio, ocs_remote_node_t *rnode, uint32_t length, int32_t status, uint32_t ext_status, void *arg) 457 { 458 ocs_io_t *els; 459 ocs_node_t *node; 460 ocs_t *ocs; 461 ocs_node_cb_t cbdata; 462 ocs_io_t *io; 463 464 ocs_assert(arg, -1); 465 io = arg; 466 els = io; 467 ocs_assert(els, -1); 468 ocs_assert(els->node, -1); 469 node = els->node; 470 ocs_assert(node->ocs, -1); 471 ocs = node->ocs; 472 473 ocs_assert(io->hio, -1); 474 ocs_assert(hio == io->hio, -1); 475 476 if (status != 0) { 477 els_io_printf(els, "status x%x ext x%x\n", status, ext_status); 478 } 479 480 /* set the response len element of els->rsp */ 481 els->els_rsp.len = length; 482 483 cbdata.status = status; 484 cbdata.ext_status = ext_status; 485 cbdata.header = NULL; 486 cbdata.els = els; 487 488 /* FW returns the number of bytes received on the link in 489 * the WCQE, not the amount placed in the buffer; use this info to 490 * check if there was an overrun. 491 */ 492 if (length > els->els_rsp.size) { 493 ocs_log_warn(ocs, "ELS response returned len=%d > buflen=%zu\n", 494 length, els->els_rsp.size); 495 ocs_els_post_event(els, OCS_EVT_SRRS_ELS_REQ_FAIL, &cbdata); 496 return 0; 497 } 498 499 /* Post event to ELS IO object */ 500 switch (status) { 501 case SLI4_FC_WCQE_STATUS_SUCCESS: 502 ocs_els_post_event(els, OCS_EVT_SRRS_ELS_REQ_OK, &cbdata); 503 break; 504 505 case SLI4_FC_WCQE_STATUS_LS_RJT: 506 ocs_els_post_event(els, OCS_EVT_SRRS_ELS_REQ_RJT, &cbdata); 507 break; 508 509 510 case SLI4_FC_WCQE_STATUS_LOCAL_REJECT: 511 switch (ext_status) { 512 case SLI4_FC_LOCAL_REJECT_SEQUENCE_TIMEOUT: 513 ocs_els_post_event(els, OCS_EVT_ELS_REQ_TIMEOUT, &cbdata); 514 break; 515 case SLI4_FC_LOCAL_REJECT_ABORT_REQUESTED: 516 ocs_els_post_event(els, OCS_EVT_ELS_REQ_ABORTED, &cbdata); 517 break; 518 default: 519 ocs_els_post_event(els, OCS_EVT_SRRS_ELS_REQ_FAIL, &cbdata); 520 break; 521 } 522 break; 523 default: 524 ocs_log_warn(ocs, "els req complete: failed status x%x, ext_status, x%x\n", status, ext_status); 525 ocs_els_post_event(els, OCS_EVT_SRRS_ELS_REQ_FAIL, &cbdata); 526 break; 527 } 528 529 return 0; 530 } 531 532 /** 533 * @ingroup els_api 534 * @brief Handle ELS IO accept/response completions. 535 * 536 * <h3 class="desc">Description</h3> 537 * This callback is used for several ELS send operations. 538 * 539 * @param hio Pointer to the HW IO context that completed. 540 * @param rnode Pointer to the remote node. 541 * @param length Length of the returned payload data. 542 * @param status Status of the completion. 543 * @param ext_status Extended status of the completion. 544 * @param arg Application-specific argument (generally a pointer to the ELS IO context). 545 * 546 * @return Returns 0 on success; or a negative error value on failure. 547 */ 548 549 static int32_t 550 ocs_els_acc_cb(ocs_hw_io_t *hio, ocs_remote_node_t *rnode, uint32_t length, int32_t status, uint32_t ext_status, void *arg) 551 { 552 ocs_io_t *els; 553 ocs_node_t *node; 554 ocs_t *ocs; 555 ocs_node_cb_t cbdata; 556 ocs_io_t *io; 557 558 ocs_assert(arg, -1); 559 io = arg; 560 els = io; 561 ocs_assert(els, -1); 562 ocs_assert(els->node, -1); 563 node = els->node; 564 ocs_assert(node->ocs, -1); 565 ocs = node->ocs; 566 567 ocs_assert(io->hio, -1); 568 ocs_assert(hio == io->hio, -1); 569 570 cbdata.status = status; 571 cbdata.ext_status = ext_status; 572 cbdata.header = NULL; 573 cbdata.els = els; 574 575 /* Post node event */ 576 switch (status) { 577 case SLI4_FC_WCQE_STATUS_SUCCESS: 578 ocs_node_post_event(node, OCS_EVT_SRRS_ELS_CMPL_OK, &cbdata); 579 break; 580 581 default: 582 ocs_log_warn(ocs, "[%s] %-8s failed status x%x, ext_status x%x\n", 583 node->display_name, els->display_name, status, ext_status); 584 ocs_log_warn(ocs, "els acc complete: failed status x%x, ext_status, x%x\n", status, ext_status); 585 ocs_node_post_event(node, OCS_EVT_SRRS_ELS_CMPL_FAIL, &cbdata); 586 break; 587 } 588 589 /* If this IO has a callback, invoke it */ 590 if (els->els_callback) { 591 (*els->els_callback)(node, &cbdata, els->els_callback_arg); 592 } 593 594 ocs_els_io_free(els); 595 596 return 0; 597 } 598 599 /** 600 * @ingroup els_api 601 * @brief Format and send a PLOGI ELS command. 602 * 603 * <h3 class="desc">Description</h3> 604 * Construct a PLOGI payload using the domain SLI port service parameters, 605 * and send to the \c node. 606 * 607 * @param node Node to which the PLOGI is sent. 608 * @param timeout_sec Command timeout, in seconds. 609 * @param retries Number of times to retry errors before reporting a failure. 610 * @param cb Callback function. 611 * @param cbarg Callback function argument. 612 * 613 * @return Returns pointer to IO object, or NULL if error. 614 */ 615 616 ocs_io_t * 617 ocs_send_plogi(ocs_node_t *node, uint32_t timeout_sec, uint32_t retries, 618 void (*cb)(ocs_node_t *node, ocs_node_cb_t *cbdata, void *arg), void *cbarg) 619 { 620 ocs_io_t *els; 621 ocs_t *ocs = node->ocs; 622 fc_plogi_payload_t *plogi; 623 624 node_els_trace(); 625 626 els = ocs_els_io_alloc(node, sizeof(*plogi), OCS_ELS_ROLE_ORIGINATOR); 627 if (els == NULL) { 628 ocs_log_err(ocs, "IO alloc failed\n"); 629 } else { 630 els->els_timeout_sec = timeout_sec; 631 els->els_retries_remaining = retries; 632 els->els_callback = cb; 633 els->els_callback_arg = cbarg; 634 els->display_name = "plogi"; 635 636 /* Build PLOGI request */ 637 plogi = els->els_req.virt; 638 639 ocs_memcpy(plogi, node->sport->service_params, sizeof(*plogi)); 640 641 plogi->command_code = FC_ELS_CMD_PLOGI; 642 plogi->resv1 = 0; 643 644 ocs_display_sparams(node->display_name, "plogi send req", 0, NULL, plogi->common_service_parameters); 645 646 els->hio_type = OCS_HW_ELS_REQ; 647 els->iparam.els.timeout = timeout_sec; 648 649 ocs_io_transition(els, __ocs_els_init, NULL); 650 651 } 652 return els; 653 } 654 655 /** 656 * @ingroup els_api 657 * @brief Format and send a FLOGI ELS command. 658 * 659 * <h3 class="desc">Description</h3> 660 * Construct an FLOGI payload, and send to the \c node. 661 * 662 * @param node Node to which the FLOGI is sent. 663 * @param timeout_sec Command timeout, in seconds. 664 * @param retries Number of times to retry errors before reporting a failure. 665 * @param cb Callback function. 666 * @param cbarg Callback function argument. 667 * 668 * @return Returns pointer to IO object, or NULL if error. 669 */ 670 671 ocs_io_t * 672 ocs_send_flogi(ocs_node_t *node, uint32_t timeout_sec, uint32_t retries, 673 els_cb_t cb, void *cbarg) 674 { 675 ocs_io_t *els; 676 ocs_t *ocs; 677 fc_plogi_payload_t *flogi; 678 679 ocs_assert(node, NULL); 680 ocs_assert(node->ocs, NULL); 681 ocs_assert(node->sport, NULL); 682 ocs = node->ocs; 683 684 node_els_trace(); 685 686 els = ocs_els_io_alloc(node, sizeof(*flogi), OCS_ELS_ROLE_ORIGINATOR); 687 if (els == NULL) { 688 ocs_log_err(ocs, "IO alloc failed\n"); 689 } else { 690 els->els_timeout_sec = timeout_sec; 691 els->els_retries_remaining = retries; 692 els->els_callback = cb; 693 els->els_callback_arg = cbarg; 694 els->display_name = "flogi"; 695 696 /* Build FLOGI request */ 697 flogi = els->els_req.virt; 698 699 ocs_memcpy(flogi, node->sport->service_params, sizeof(*flogi)); 700 flogi->command_code = FC_ELS_CMD_FLOGI; 701 flogi->resv1 = 0; 702 703 /* Priority tagging support */ 704 flogi->common_service_parameters[1] |= ocs_htobe32(1U << 23); 705 706 ocs_display_sparams(node->display_name, "flogi send req", 0, NULL, flogi->common_service_parameters); 707 708 els->hio_type = OCS_HW_ELS_REQ; 709 els->iparam.els.timeout = timeout_sec; 710 ocs_io_transition(els, __ocs_els_init, NULL); 711 } 712 return els; 713 } 714 715 /** 716 * @ingroup els_api 717 * @brief Format and send a FDISC ELS command. 718 * 719 * <h3 class="desc">Description</h3> 720 * Construct an FDISC payload, and send to the \c node. 721 * 722 * @param node Node to which the FDISC is sent. 723 * @param timeout_sec Command timeout, in seconds. 724 * @param retries Number of times to retry errors before reporting a failure. 725 * @param cb Callback function. 726 * @param cbarg Callback function argument. 727 * 728 * @return Returns pointer to IO object, or NULL if error. 729 */ 730 731 ocs_io_t * 732 ocs_send_fdisc(ocs_node_t *node, uint32_t timeout_sec, uint32_t retries, 733 els_cb_t cb, void *cbarg) 734 { 735 ocs_io_t *els; 736 ocs_t *ocs; 737 fc_plogi_payload_t *fdisc; 738 739 ocs_assert(node, NULL); 740 ocs_assert(node->ocs, NULL); 741 ocs = node->ocs; 742 743 node_els_trace(); 744 745 els = ocs_els_io_alloc(node, sizeof(*fdisc), OCS_ELS_ROLE_ORIGINATOR); 746 if (els == NULL) { 747 ocs_log_err(ocs, "IO alloc failed\n"); 748 } else { 749 els->els_timeout_sec = timeout_sec; 750 els->els_retries_remaining = retries; 751 els->els_callback = cb; 752 els->els_callback_arg = cbarg; 753 els->display_name = "fdisc"; 754 755 /* Build FDISC request */ 756 fdisc = els->els_req.virt; 757 758 ocs_memcpy(fdisc, node->sport->service_params, sizeof(*fdisc)); 759 fdisc->command_code = FC_ELS_CMD_FDISC; 760 fdisc->resv1 = 0; 761 762 ocs_display_sparams(node->display_name, "fdisc send req", 0, NULL, fdisc->common_service_parameters); 763 764 els->hio_type = OCS_HW_ELS_REQ; 765 els->iparam.els.timeout = timeout_sec; 766 ocs_io_transition(els, __ocs_els_init, NULL); 767 } 768 return els; 769 } 770 771 /** 772 * @ingroup els_api 773 * @brief Send a PRLI ELS command. 774 * 775 * <h3 class="desc">Description</h3> 776 * Construct a PRLI ELS command, and send to the \c node. 777 * 778 * @param node Node to which the PRLI is sent. 779 * @param timeout_sec Command timeout, in seconds. 780 * @param retries Number of times to retry errors before reporting a failure. 781 * @param cb Callback function. 782 * @param cbarg Callback function argument. 783 * 784 * @return Returns pointer to IO object, or NULL if error. 785 */ 786 787 ocs_io_t * 788 ocs_send_prli(ocs_node_t *node, uint32_t timeout_sec, uint32_t retries, 789 els_cb_t cb, void *cbarg) 790 { 791 ocs_t *ocs = node->ocs; 792 ocs_io_t *els; 793 fc_prli_payload_t *prli; 794 795 node_els_trace(); 796 797 els = ocs_els_io_alloc(node, sizeof(*prli), OCS_ELS_ROLE_ORIGINATOR); 798 if (els == NULL) { 799 ocs_log_err(ocs, "IO alloc failed\n"); 800 } else { 801 els->els_timeout_sec = timeout_sec; 802 els->els_retries_remaining = retries; 803 els->els_callback = cb; 804 els->els_callback_arg = cbarg; 805 els->display_name = "prli"; 806 807 /* Build PRLI request */ 808 prli = els->els_req.virt; 809 810 ocs_memset(prli, 0, sizeof(*prli)); 811 812 prli->command_code = FC_ELS_CMD_PRLI; 813 prli->page_length = 16; 814 prli->payload_length = ocs_htobe16(sizeof(fc_prli_payload_t)); 815 prli->type = FC_TYPE_FCP; 816 prli->type_ext = 0; 817 prli->flags = ocs_htobe16(FC_PRLI_ESTABLISH_IMAGE_PAIR); 818 prli->service_params = ocs_htobe16(FC_PRLI_READ_XRDY_DISABLED | 819 (node->sport->enable_ini ? FC_PRLI_INITIATOR_FUNCTION : 0) | 820 (node->sport->enable_tgt ? FC_PRLI_TARGET_FUNCTION : 0)); 821 822 /* For Tape Drive support */ 823 prli->service_params |= ocs_htobe16(FC_PRLI_CONFIRMED_COMPLETION | FC_PRLI_RETRY | 824 FC_PRLI_TASK_RETRY_ID_REQ| FC_PRLI_REC_SUPPORT); 825 826 els->hio_type = OCS_HW_ELS_REQ; 827 els->iparam.els.timeout = timeout_sec; 828 ocs_io_transition(els, __ocs_els_init, NULL); 829 } 830 831 return els; 832 } 833 834 /** 835 * @ingroup els_api 836 * @brief Send a PRLO ELS command. 837 * 838 * <h3 class="desc">Description</h3> 839 * Construct a PRLO ELS command, and send to the \c node. 840 * 841 * @param node Node to which the PRLO is sent. 842 * @param timeout_sec Command timeout, in seconds. 843 * @param retries Number of times to retry errors before reporting a failure. 844 * @param cb Callback function. 845 * @param cbarg Callback function argument. 846 * 847 * @return Returns pointer to IO object, or NULL if error. 848 */ 849 850 ocs_io_t * 851 ocs_send_prlo(ocs_node_t *node, uint32_t timeout_sec, uint32_t retries, 852 els_cb_t cb, void *cbarg) 853 { 854 ocs_t *ocs = node->ocs; 855 ocs_io_t *els; 856 fc_prlo_payload_t *prlo; 857 858 node_els_trace(); 859 860 els = ocs_els_io_alloc(node, sizeof(*prlo), OCS_ELS_ROLE_ORIGINATOR); 861 if (els == NULL) { 862 ocs_log_err(ocs, "IO alloc failed\n"); 863 } else { 864 els->els_timeout_sec = timeout_sec; 865 els->els_retries_remaining = retries; 866 els->els_callback = cb; 867 els->els_callback_arg = cbarg; 868 els->display_name = "prlo"; 869 870 /* Build PRLO request */ 871 prlo = els->els_req.virt; 872 873 ocs_memset(prlo, 0, sizeof(*prlo)); 874 prlo->command_code = FC_ELS_CMD_PRLO; 875 prlo->page_length = 16; 876 prlo->payload_length = ocs_htobe16(sizeof(fc_prlo_payload_t)); 877 prlo->type = FC_TYPE_FCP; 878 prlo->type_ext = 0; 879 880 els->hio_type = OCS_HW_ELS_REQ; 881 els->iparam.els.timeout = timeout_sec; 882 ocs_io_transition(els, __ocs_els_init, NULL); 883 } 884 return els; 885 } 886 887 /** 888 * @ingroup els_api 889 * @brief Send a LOGO ELS command. 890 * 891 * <h3 class="desc">Description</h3> 892 * Format a LOGO, and send to the \c node. 893 * 894 * @param node Node to which the LOGO is sent. 895 * @param timeout_sec Command timeout, in seconds. 896 * @param retries Number of times to retry errors before reporting a failure. 897 * @param cb Callback function. 898 * @param cbarg Callback function argument. 899 * 900 * @return Returns pointer to IO object, or NULL if error. 901 */ 902 903 ocs_io_t * 904 ocs_send_logo(ocs_node_t *node, uint32_t timeout_sec, uint32_t retries, 905 els_cb_t cb, void *cbarg) 906 { 907 ocs_io_t *els; 908 ocs_t *ocs; 909 fc_logo_payload_t *logo; 910 fc_plogi_payload_t *sparams; 911 912 913 ocs = node->ocs; 914 915 node_els_trace(); 916 917 sparams = (fc_plogi_payload_t*) node->sport->service_params; 918 919 els = ocs_els_io_alloc(node, sizeof(*logo), OCS_ELS_ROLE_ORIGINATOR); 920 if (els == NULL) { 921 ocs_log_err(ocs, "IO alloc failed\n"); 922 } else { 923 els->els_timeout_sec = timeout_sec; 924 els->els_retries_remaining = retries; 925 els->els_callback = cb; 926 els->els_callback_arg = cbarg; 927 els->display_name = "logo"; 928 929 /* Build LOGO request */ 930 931 logo = els->els_req.virt; 932 933 ocs_memset(logo, 0, sizeof(*logo)); 934 logo->command_code = FC_ELS_CMD_LOGO; 935 logo->resv1 = 0; 936 logo->port_id = fc_htobe24(node->rnode.sport->fc_id); 937 logo->port_name_hi = sparams->port_name_hi; 938 logo->port_name_lo = sparams->port_name_lo; 939 940 els->hio_type = OCS_HW_ELS_REQ; 941 els->iparam.els.timeout = timeout_sec; 942 ocs_io_transition(els, __ocs_els_init, NULL); 943 } 944 return els; 945 } 946 947 /** 948 * @ingroup els_api 949 * @brief Send an ADISC ELS command. 950 * 951 * <h3 class="desc">Description</h3> 952 * Construct an ADISC ELS command, and send to the \c node. 953 * 954 * @param node Node to which the ADISC is sent. 955 * @param timeout_sec Command timeout, in seconds. 956 * @param retries Number of times to retry errors before reporting a failure. 957 * @param cb Callback function. 958 * @param cbarg Callback function argument. 959 * 960 * @return Returns pointer to IO object, or NULL if error. 961 */ 962 963 ocs_io_t * 964 ocs_send_adisc(ocs_node_t *node, uint32_t timeout_sec, uint32_t retries, 965 els_cb_t cb, void *cbarg) 966 { 967 ocs_io_t *els; 968 ocs_t *ocs; 969 fc_adisc_payload_t *adisc; 970 fc_plogi_payload_t *sparams; 971 ocs_sport_t *sport = node->sport; 972 973 ocs = node->ocs; 974 975 node_els_trace(); 976 977 sparams = (fc_plogi_payload_t*) node->sport->service_params; 978 979 els = ocs_els_io_alloc(node, sizeof(*adisc), OCS_ELS_ROLE_ORIGINATOR); 980 if (els == NULL) { 981 ocs_log_err(ocs, "IO alloc failed\n"); 982 } else { 983 els->els_timeout_sec = timeout_sec; 984 els->els_retries_remaining = retries; 985 els->els_callback = cb; 986 els->els_callback_arg = cbarg; 987 els->display_name = "adisc"; 988 989 /* Build ADISC request */ 990 991 adisc = els->els_req.virt; 992 sparams = (fc_plogi_payload_t*) node->sport->service_params; 993 994 ocs_memset(adisc, 0, sizeof(*adisc)); 995 adisc->command_code = FC_ELS_CMD_ADISC; 996 adisc->hard_address = fc_htobe24(sport->fc_id); 997 adisc->port_name_hi = sparams->port_name_hi; 998 adisc->port_name_lo = sparams->port_name_lo; 999 adisc->node_name_hi = sparams->node_name_hi; 1000 adisc->node_name_lo = sparams->node_name_lo; 1001 adisc->port_id = fc_htobe24(node->rnode.sport->fc_id); 1002 1003 els->hio_type = OCS_HW_ELS_REQ; 1004 els->iparam.els.timeout = timeout_sec; 1005 ocs_io_transition(els, __ocs_els_init, NULL); 1006 } 1007 return els; 1008 } 1009 1010 /** 1011 * @ingroup els_api 1012 * @brief Send a PDISC ELS command. 1013 * 1014 * <h3 class="desc">Description</h3> 1015 * Construct a PDISC ELS command, and send to the \c node. 1016 * 1017 * @param node Node to which the PDISC is sent. 1018 * @param timeout_sec Command timeout, in seconds. 1019 * @param retries Number of times to retry errors before reporting a failure. 1020 * @param cb Callback function. 1021 * @param cbarg Callback function argument. 1022 * 1023 * @return Returns pointer to IO object, or NULL if error. 1024 */ 1025 1026 ocs_io_t * 1027 ocs_send_pdisc(ocs_node_t *node, uint32_t timeout_sec, uint32_t retries, 1028 els_cb_t cb, void *cbarg) 1029 { 1030 ocs_io_t *els; 1031 ocs_t *ocs = node->ocs; 1032 fc_plogi_payload_t *pdisc; 1033 1034 node_els_trace(); 1035 1036 els = ocs_els_io_alloc(node, sizeof(*pdisc), OCS_ELS_ROLE_ORIGINATOR); 1037 if (els == NULL) { 1038 ocs_log_err(ocs, "IO alloc failed\n"); 1039 } else { 1040 els->els_timeout_sec = timeout_sec; 1041 els->els_retries_remaining = retries; 1042 els->els_callback = cb; 1043 els->els_callback_arg = cbarg; 1044 els->display_name = "pdisc"; 1045 1046 pdisc = els->els_req.virt; 1047 1048 ocs_memcpy(pdisc, node->sport->service_params, sizeof(*pdisc)); 1049 1050 pdisc->command_code = FC_ELS_CMD_PDISC; 1051 pdisc->resv1 = 0; 1052 1053 els->hio_type = OCS_HW_ELS_REQ; 1054 els->iparam.els.timeout = timeout_sec; 1055 ocs_io_transition(els, __ocs_els_init, NULL); 1056 } 1057 return els; 1058 } 1059 1060 /** 1061 * @ingroup els_api 1062 * @brief Send an SCR ELS command. 1063 * 1064 * <h3 class="desc">Description</h3> 1065 * Format an SCR, and send to the \c node. 1066 * 1067 * @param node Node to which the SCR is sent. 1068 * @param timeout_sec Command timeout, in seconds. 1069 * @param retries Number of times to retry errors before reporting a failure. 1070 * @param cb Callback function 1071 * @param cbarg Callback function arg 1072 * 1073 * @return Returns pointer to IO object, or NULL if error. 1074 */ 1075 1076 ocs_io_t * 1077 ocs_send_scr(ocs_node_t *node, uint32_t timeout_sec, uint32_t retries, 1078 els_cb_t cb, void *cbarg) 1079 { 1080 ocs_io_t *els; 1081 ocs_t *ocs = node->ocs; 1082 fc_scr_payload_t *req; 1083 1084 node_els_trace(); 1085 1086 els = ocs_els_io_alloc(node, sizeof(*req), OCS_ELS_ROLE_ORIGINATOR); 1087 if (els == NULL) { 1088 ocs_log_err(ocs, "IO alloc failed\n"); 1089 } else { 1090 els->els_timeout_sec = timeout_sec; 1091 els->els_retries_remaining = retries; 1092 els->els_callback = cb; 1093 els->els_callback_arg = cbarg; 1094 els->display_name = "scr"; 1095 1096 req = els->els_req.virt; 1097 1098 ocs_memset(req, 0, sizeof(*req)); 1099 req->command_code = FC_ELS_CMD_SCR; 1100 req->function = FC_SCR_REG_FULL; 1101 1102 els->hio_type = OCS_HW_ELS_REQ; 1103 els->iparam.els.timeout = timeout_sec; 1104 ocs_io_transition(els, __ocs_els_init, NULL); 1105 } 1106 return els; 1107 } 1108 1109 /** 1110 * @ingroup els_api 1111 * @brief Send an RRQ ELS command. 1112 * 1113 * <h3 class="desc">Description</h3> 1114 * Format an RRQ, and send to the \c node. 1115 * 1116 * @param node Node to which the RRQ is sent. 1117 * @param timeout_sec Command timeout, in seconds. 1118 * @param retries Number of times to retry errors before reporting a failure. 1119 * @param cb Callback function 1120 * @param cbarg Callback function arg 1121 * 1122 * @return Returns pointer to IO object, or NULL if error. 1123 */ 1124 1125 ocs_io_t * 1126 ocs_send_rrq(ocs_node_t *node, uint32_t timeout_sec, uint32_t retries, 1127 els_cb_t cb, void *cbarg) 1128 { 1129 ocs_io_t *els; 1130 ocs_t *ocs = node->ocs; 1131 fc_scr_payload_t *req; 1132 1133 node_els_trace(); 1134 1135 els = ocs_els_io_alloc(node, sizeof(*req), OCS_ELS_ROLE_ORIGINATOR); 1136 if (els == NULL) { 1137 ocs_log_err(ocs, "IO alloc failed\n"); 1138 } else { 1139 els->els_timeout_sec = timeout_sec; 1140 els->els_retries_remaining = retries; 1141 els->els_callback = cb; 1142 els->els_callback_arg = cbarg; 1143 els->display_name = "scr"; 1144 1145 req = els->els_req.virt; 1146 1147 ocs_memset(req, 0, sizeof(*req)); 1148 req->command_code = FC_ELS_CMD_RRQ; 1149 req->function = FC_SCR_REG_FULL; 1150 1151 els->hio_type = OCS_HW_ELS_REQ; 1152 els->iparam.els.timeout = timeout_sec; 1153 ocs_io_transition(els, __ocs_els_init, NULL); 1154 } 1155 return els; 1156 } 1157 1158 /** 1159 * @ingroup els_api 1160 * @brief Send an RSCN ELS command. 1161 * 1162 * <h3 class="desc">Description</h3> 1163 * Format an RSCN, and send to the \c node. 1164 * 1165 * @param node Node to which the RRQ is sent. 1166 * @param timeout_sec Command timeout, in seconds. 1167 * @param retries Number of times to retry errors before reporting a failure. 1168 * @param port_ids Pointer to port IDs 1169 * @param port_ids_count Count of port IDs 1170 * @param cb Callback function 1171 * @param cbarg Callback function arg 1172 * 1173 * @return Returns pointer to IO object, or NULL if error. 1174 */ 1175 ocs_io_t * 1176 ocs_send_rscn(ocs_node_t *node, uint32_t timeout_sec, uint32_t retries, 1177 void *port_ids, uint32_t port_ids_count, els_cb_t cb, void *cbarg) 1178 { 1179 ocs_io_t *els; 1180 ocs_t *ocs = node->ocs; 1181 fc_rscn_payload_t *req; 1182 uint32_t payload_length = sizeof(fc_rscn_affected_port_id_page_t)*(port_ids_count - 1) + 1183 sizeof(fc_rscn_payload_t); 1184 1185 node_els_trace(); 1186 1187 els = ocs_els_io_alloc(node, payload_length, OCS_ELS_ROLE_ORIGINATOR); 1188 if (els == NULL) { 1189 ocs_log_err(ocs, "IO alloc failed\n"); 1190 } else { 1191 els->els_timeout_sec = timeout_sec; 1192 els->els_retries_remaining = retries; 1193 els->els_callback = cb; 1194 els->els_callback_arg = cbarg; 1195 els->display_name = "rscn"; 1196 1197 req = els->els_req.virt; 1198 1199 req->command_code = FC_ELS_CMD_RSCN; 1200 req->page_length = sizeof(fc_rscn_affected_port_id_page_t); 1201 req->payload_length = ocs_htobe16(sizeof(*req) + 1202 sizeof(fc_rscn_affected_port_id_page_t)*(port_ids_count-1)); 1203 1204 els->hio_type = OCS_HW_ELS_REQ; 1205 els->iparam.els.timeout = timeout_sec; 1206 1207 /* copy in the payload */ 1208 ocs_memcpy(req->port_list, port_ids, port_ids_count*sizeof(fc_rscn_affected_port_id_page_t)); 1209 1210 /* Submit the request */ 1211 ocs_io_transition(els, __ocs_els_init, NULL); 1212 } 1213 return els; 1214 } 1215 1216 /** 1217 * @brief Send an LS_RJT ELS response. 1218 * 1219 * <h3 class="desc">Description</h3> 1220 * Send an LS_RJT ELS response. 1221 * 1222 * @param io Pointer to a SCSI IO object. 1223 * @param ox_id Originator exchange ID being responded to. 1224 * @param reason_code Reason code value for LS_RJT. 1225 * @param reason_code_expl Reason code explanation value for LS_RJT. 1226 * @param vendor_unique Vendor-unique value for LS_RJT. 1227 * @param cb Callback function. 1228 * @param cbarg Callback function argument. 1229 * 1230 * @return Returns pointer to IO object, or NULL if error. 1231 */ 1232 1233 ocs_io_t * 1234 ocs_send_ls_rjt(ocs_io_t *io, uint32_t ox_id, uint32_t reason_code, uint32_t reason_code_expl, 1235 uint32_t vendor_unique, els_cb_t cb, void *cbarg) 1236 { 1237 ocs_node_t *node = io->node; 1238 int32_t rc; 1239 ocs_t *ocs = node->ocs; 1240 fc_ls_rjt_payload_t *rjt; 1241 1242 node_els_trace(); 1243 1244 io->els_callback = cb; 1245 io->els_callback_arg = cbarg; 1246 io->display_name = "ls_rjt"; 1247 io->init_task_tag = ox_id; 1248 1249 ocs_memset(&io->iparam, 0, sizeof(io->iparam)); 1250 io->iparam.els.ox_id = ox_id; 1251 1252 rjt = io->els_req.virt; 1253 ocs_memset(rjt, 0, sizeof(*rjt)); 1254 1255 rjt->command_code = FC_ELS_CMD_RJT; 1256 rjt->reason_code = reason_code; 1257 rjt->reason_code_exp = reason_code_expl; 1258 1259 io->hio_type = OCS_HW_ELS_RSP; 1260 if ((rc = ocs_els_send_rsp(io, sizeof(*rjt)))) { 1261 ocs_els_io_free(io); 1262 io = NULL; 1263 } 1264 1265 return io; 1266 } 1267 1268 /** 1269 * @ingroup els_api 1270 * @brief Send a PLOGI accept response. 1271 * 1272 * <h3 class="desc">Description</h3> 1273 * Construct a PLOGI LS_ACC, and send to the \c node, using the originator exchange ID 1274 * \c ox_id. 1275 * 1276 * @param io Pointer to a SCSI IO object. 1277 * @param ox_id Originator exchange ID being responsed to. 1278 * @param cb Callback function. 1279 * @param cbarg Callback function argument. 1280 * 1281 * @return Returns pointer to IO object, or NULL if error. 1282 */ 1283 ocs_io_t * 1284 ocs_send_plogi_acc(ocs_io_t *io, uint32_t ox_id, els_cb_t cb, void *cbarg) 1285 { 1286 ocs_node_t *node = io->node; 1287 int32_t rc; 1288 ocs_t *ocs = node->ocs; 1289 fc_plogi_payload_t *plogi; 1290 fc_plogi_payload_t *req = (fc_plogi_payload_t *)node->service_params; 1291 1292 node_els_trace(); 1293 1294 io->els_callback = cb; 1295 io->els_callback_arg = cbarg; 1296 io->display_name = "plog_acc"; 1297 io->init_task_tag = ox_id; 1298 1299 ocs_memset(&io->iparam, 0, sizeof(io->iparam)); 1300 io->iparam.els.ox_id = ox_id; 1301 1302 plogi = io->els_req.virt; 1303 1304 /* copy our port's service parameters to payload */ 1305 ocs_memcpy(plogi, node->sport->service_params, sizeof(*plogi)); 1306 plogi->command_code = FC_ELS_CMD_ACC; 1307 plogi->resv1 = 0; 1308 1309 /* Set Application header support bit if requested */ 1310 if (req->common_service_parameters[1] & ocs_htobe32(1U << 24)) { 1311 plogi->common_service_parameters[1] |= ocs_htobe32(1U << 24); 1312 } 1313 1314 /* Priority tagging support. */ 1315 if (req->common_service_parameters[1] & ocs_htobe32(1U << 23)) { 1316 plogi->common_service_parameters[1] |= ocs_htobe32(1U << 23); 1317 } 1318 1319 ocs_display_sparams(node->display_name, "plogi send resp", 0, NULL, plogi->common_service_parameters); 1320 1321 io->hio_type = OCS_HW_ELS_RSP; 1322 if ((rc = ocs_els_send_rsp(io, sizeof(*plogi)))) { 1323 ocs_els_io_free(io); 1324 io = NULL; 1325 } 1326 return io; 1327 } 1328 1329 /** 1330 * @ingroup els_api 1331 * @brief Send an FLOGI accept response for point-to-point negotiation. 1332 * 1333 * <h3 class="desc">Description</h3> 1334 * Construct an FLOGI accept response, and send to the \c node using the originator 1335 * exchange id \c ox_id. The \c s_id is used for the response frame source FC ID. 1336 * 1337 * @param io Pointer to a SCSI IO object. 1338 * @param ox_id Originator exchange ID for the response. 1339 * @param s_id Source FC ID to be used in the response frame. 1340 * @param cb Callback function. 1341 * @param cbarg Callback function argument. 1342 * 1343 * @return Returns pointer to IO object, or NULL if error. 1344 */ 1345 ocs_io_t * 1346 ocs_send_flogi_p2p_acc(ocs_io_t *io, uint32_t ox_id, uint32_t s_id, els_cb_t cb, void *cbarg) 1347 { 1348 ocs_node_t *node = io->node; 1349 int32_t rc; 1350 ocs_t *ocs = node->ocs; 1351 fc_plogi_payload_t *flogi; 1352 1353 node_els_trace(); 1354 1355 io->els_callback = cb; 1356 io->els_callback_arg = cbarg; 1357 io->display_name = "flogi_p2p_acc"; 1358 io->init_task_tag = ox_id; 1359 1360 ocs_memset(&io->iparam, 0, sizeof(io->iparam)); 1361 io->iparam.els_sid.ox_id = ox_id; 1362 io->iparam.els_sid.s_id = s_id; 1363 1364 flogi = io->els_req.virt; 1365 1366 /* copy our port's service parameters to payload */ 1367 ocs_memcpy(flogi, node->sport->service_params, sizeof(*flogi)); 1368 flogi->command_code = FC_ELS_CMD_ACC; 1369 flogi->resv1 = 0; 1370 ocs_memset(flogi->class1_service_parameters, 0, sizeof(flogi->class1_service_parameters)); 1371 ocs_memset(flogi->class2_service_parameters, 0, sizeof(flogi->class1_service_parameters)); 1372 ocs_memset(flogi->class3_service_parameters, 0, sizeof(flogi->class1_service_parameters)); 1373 ocs_memset(flogi->class4_service_parameters, 0, sizeof(flogi->class1_service_parameters)); 1374 1375 io->hio_type = OCS_HW_ELS_RSP_SID; 1376 if ((rc = ocs_els_send_rsp(io, sizeof(*flogi)))) { 1377 ocs_els_io_free(io); 1378 io = NULL; 1379 } 1380 1381 return io; 1382 } 1383 1384 ocs_io_t * 1385 ocs_send_flogi_acc(ocs_io_t *io, uint32_t ox_id, uint32_t is_fport, els_cb_t cb, void *cbarg) 1386 { 1387 ocs_node_t *node = io->node; 1388 int32_t rc; 1389 ocs_t *ocs = node->ocs; 1390 fc_plogi_payload_t *flogi; 1391 1392 node_els_trace(); 1393 1394 io->els_callback = cb; 1395 io->els_callback_arg = cbarg; 1396 io->display_name = "flogi_acc"; 1397 io->init_task_tag = ox_id; 1398 1399 ocs_memset(&io->iparam, 0, sizeof(io->iparam)); 1400 io->iparam.els_sid.ox_id = ox_id; 1401 io->iparam.els_sid.s_id = io->node->sport->fc_id; 1402 1403 flogi = io->els_req.virt; 1404 1405 /* copy our port's service parameters to payload */ 1406 ocs_memcpy(flogi, node->sport->service_params, sizeof(*flogi)); 1407 1408 /* Set F_port */ 1409 if (is_fport) { 1410 /* Set F_PORT and Multiple N_PORT_ID Assignment */ 1411 flogi->common_service_parameters[1] |= ocs_be32toh(3U << 28); 1412 } 1413 1414 flogi->command_code = FC_ELS_CMD_ACC; 1415 flogi->resv1 = 0; 1416 1417 ocs_display_sparams(node->display_name, "flogi send resp", 0, NULL, flogi->common_service_parameters); 1418 1419 ocs_memset(flogi->class1_service_parameters, 0, sizeof(flogi->class1_service_parameters)); 1420 ocs_memset(flogi->class2_service_parameters, 0, sizeof(flogi->class1_service_parameters)); 1421 ocs_memset(flogi->class3_service_parameters, 0, sizeof(flogi->class1_service_parameters)); 1422 ocs_memset(flogi->class4_service_parameters, 0, sizeof(flogi->class1_service_parameters)); 1423 1424 io->hio_type = OCS_HW_ELS_RSP_SID; 1425 if ((rc = ocs_els_send_rsp(io, sizeof(*flogi)))) { 1426 ocs_els_io_free(io); 1427 io = NULL; 1428 } 1429 1430 return io; 1431 } 1432 1433 /** 1434 * @ingroup els_api 1435 * @brief Send a PRLI accept response 1436 * 1437 * <h3 class="desc">Description</h3> 1438 * Construct a PRLI LS_ACC response, and send to the \c node, using the originator 1439 * \c ox_id exchange ID. 1440 * 1441 * @param io Pointer to a SCSI IO object. 1442 * @param ox_id Originator exchange ID. 1443 * @param cb Callback function. 1444 * @param cbarg Callback function argument. 1445 * 1446 * @return Returns pointer to IO object, or NULL if error. 1447 */ 1448 1449 ocs_io_t * 1450 ocs_send_prli_acc(ocs_io_t *io, uint32_t ox_id, uint8_t fc_type, els_cb_t cb, void *cbarg) 1451 { 1452 ocs_node_t *node = io->node; 1453 int32_t rc; 1454 ocs_t *ocs = node->ocs; 1455 fc_prli_payload_t *prli; 1456 1457 node_els_trace(); 1458 1459 io->els_callback = cb; 1460 io->els_callback_arg = cbarg; 1461 io->display_name = "prli_acc"; 1462 io->init_task_tag = ox_id; 1463 1464 ocs_memset(&io->iparam, 0, sizeof(io->iparam)); 1465 io->iparam.els.ox_id = ox_id; 1466 1467 prli = io->els_req.virt; 1468 ocs_memset(prli, 0, sizeof(*prli)); 1469 1470 prli->command_code = FC_ELS_CMD_ACC; 1471 prli->page_length = 16; 1472 prli->payload_length = ocs_htobe16(sizeof(fc_prli_payload_t)); 1473 prli->type = fc_type; 1474 prli->type_ext = 0; 1475 prli->flags = ocs_htobe16(FC_PRLI_ESTABLISH_IMAGE_PAIR | FC_PRLI_REQUEST_EXECUTED); 1476 1477 prli->service_params = ocs_htobe16(FC_PRLI_READ_XRDY_DISABLED | 1478 (node->sport->enable_ini ? FC_PRLI_INITIATOR_FUNCTION : 0) | 1479 (node->sport->enable_tgt ? FC_PRLI_TARGET_FUNCTION : 0)); 1480 1481 io->hio_type = OCS_HW_ELS_RSP; 1482 if ((rc = ocs_els_send_rsp(io, sizeof(*prli)))) { 1483 ocs_els_io_free(io); 1484 io = NULL; 1485 } 1486 1487 return io; 1488 } 1489 1490 /** 1491 * @ingroup els_api 1492 * @brief Send a PRLO accept response. 1493 * 1494 * <h3 class="desc">Description</h3> 1495 * Construct a PRLO LS_ACC response, and send to the \c node, using the originator 1496 * exchange ID \c ox_id. 1497 * 1498 * @param io Pointer to a SCSI IO object. 1499 * @param ox_id Originator exchange ID. 1500 * @param cb Callback function. 1501 * @param cbarg Callback function argument. 1502 * 1503 * @return Returns pointer to IO object, or NULL if error. 1504 */ 1505 1506 ocs_io_t * 1507 ocs_send_prlo_acc(ocs_io_t *io, uint32_t ox_id, uint8_t fc_type, els_cb_t cb, void *cbarg) 1508 { 1509 ocs_node_t *node = io->node; 1510 int32_t rc; 1511 ocs_t *ocs = node->ocs; 1512 fc_prlo_acc_payload_t *prlo_acc; 1513 1514 node_els_trace(); 1515 1516 io->els_callback = cb; 1517 io->els_callback_arg = cbarg; 1518 io->display_name = "prlo_acc"; 1519 io->init_task_tag = ox_id; 1520 1521 ocs_memset(&io->iparam, 0, sizeof(io->iparam)); 1522 io->iparam.els.ox_id = ox_id; 1523 1524 prlo_acc = io->els_req.virt; 1525 ocs_memset(prlo_acc, 0, sizeof(*prlo_acc)); 1526 1527 prlo_acc->command_code = FC_ELS_CMD_ACC; 1528 prlo_acc->page_length = 16; 1529 prlo_acc->payload_length = ocs_htobe16(sizeof(fc_prlo_acc_payload_t)); 1530 prlo_acc->type = fc_type; 1531 prlo_acc->type_ext = 0; 1532 prlo_acc->response_code = FC_PRLO_REQUEST_EXECUTED; 1533 1534 io->hio_type = OCS_HW_ELS_RSP; 1535 if ((rc = ocs_els_send_rsp(io, sizeof(*prlo_acc)))) { 1536 ocs_els_io_free(io); 1537 io = NULL; 1538 } 1539 1540 return io; 1541 } 1542 1543 /** 1544 * @ingroup els_api 1545 * @brief Send a generic LS_ACC response without a payload. 1546 * 1547 * <h3 class="desc">Description</h3> 1548 * A generic LS_ACC response is sent to the \c node using the originator exchange ID 1549 * \c ox_id. 1550 * 1551 * @param io Pointer to a SCSI IO object. 1552 * @param ox_id Originator exchange id. 1553 * @param cb Callback function. 1554 * @param cbarg Callback function argument. 1555 * 1556 * @return Returns pointer to IO object, or NULL if error. 1557 */ 1558 ocs_io_t * 1559 ocs_send_ls_acc(ocs_io_t *io, uint32_t ox_id, els_cb_t cb, void *cbarg) 1560 { 1561 ocs_node_t *node = io->node; 1562 int32_t rc; 1563 ocs_t *ocs = node->ocs; 1564 fc_acc_payload_t *acc; 1565 1566 node_els_trace(); 1567 1568 io->els_callback = cb; 1569 io->els_callback_arg = cbarg; 1570 io->display_name = "ls_acc"; 1571 io->init_task_tag = ox_id; 1572 1573 ocs_memset(&io->iparam, 0, sizeof(io->iparam)); 1574 io->iparam.els.ox_id = ox_id; 1575 1576 acc = io->els_req.virt; 1577 ocs_memset(acc, 0, sizeof(*acc)); 1578 1579 acc->command_code = FC_ELS_CMD_ACC; 1580 1581 io->hio_type = OCS_HW_ELS_RSP; 1582 if ((rc = ocs_els_send_rsp(io, sizeof(*acc)))) { 1583 ocs_els_io_free(io); 1584 io = NULL; 1585 } 1586 1587 return io; 1588 } 1589 1590 /** 1591 * @ingroup els_api 1592 * @brief Send a LOGO accept response. 1593 * 1594 * <h3 class="desc">Description</h3> 1595 * Construct a LOGO LS_ACC response, and send to the \c node, using the originator 1596 * exchange ID \c ox_id. 1597 * 1598 * @param io Pointer to a SCSI IO object. 1599 * @param ox_id Originator exchange ID. 1600 * @param cb Callback function. 1601 * @param cbarg Callback function argument. 1602 * 1603 * @return Returns pointer to IO object, or NULL if error. 1604 */ 1605 ocs_io_t * 1606 ocs_send_logo_acc(ocs_io_t *io, uint32_t ox_id, els_cb_t cb, void *cbarg) 1607 { 1608 ocs_node_t *node = io->node; 1609 int32_t rc; 1610 ocs_t *ocs = node->ocs; 1611 fc_acc_payload_t *logo; 1612 1613 node_els_trace(); 1614 1615 io->els_callback = cb; 1616 io->els_callback_arg = cbarg; 1617 io->display_name = "logo_acc"; 1618 io->init_task_tag = ox_id; 1619 1620 ocs_memset(&io->iparam, 0, sizeof(io->iparam)); 1621 io->iparam.els.ox_id = ox_id; 1622 1623 logo = io->els_req.virt; 1624 ocs_memset(logo, 0, sizeof(*logo)); 1625 1626 logo->command_code = FC_ELS_CMD_ACC; 1627 logo->resv1 = 0; 1628 1629 io->hio_type = OCS_HW_ELS_RSP; 1630 if ((rc = ocs_els_send_rsp(io, sizeof(*logo)))) { 1631 ocs_els_io_free(io); 1632 io = NULL; 1633 } 1634 1635 return io; 1636 } 1637 1638 /** 1639 * @ingroup els_api 1640 * @brief Send an ADISC accept response. 1641 * 1642 * <h3 class="desc">Description</h3> 1643 * Construct an ADISC LS__ACC, and send to the \c node, using the originator 1644 * exchange id \c ox_id. 1645 * 1646 * @param io Pointer to a SCSI IO object. 1647 * @param ox_id Originator exchange ID. 1648 * @param cb Callback function. 1649 * @param cbarg Callback function argument. 1650 * 1651 * @return Returns pointer to IO object, or NULL if error. 1652 */ 1653 1654 ocs_io_t * 1655 ocs_send_adisc_acc(ocs_io_t *io, uint32_t ox_id, els_cb_t cb, void *cbarg) 1656 { 1657 ocs_node_t *node = io->node; 1658 int32_t rc; 1659 fc_adisc_payload_t *adisc; 1660 fc_plogi_payload_t *sparams; 1661 ocs_t *ocs; 1662 1663 ocs_assert(node, NULL); 1664 ocs_assert(node->ocs, NULL); 1665 ocs = node->ocs; 1666 1667 node_els_trace(); 1668 1669 io->els_callback = cb; 1670 io->els_callback_arg = cbarg; 1671 io->display_name = "adisc_acc"; 1672 io->init_task_tag = ox_id; 1673 1674 /* Go ahead and send the ELS_ACC */ 1675 ocs_memset(&io->iparam, 0, sizeof(io->iparam)); 1676 io->iparam.els.ox_id = ox_id; 1677 1678 sparams = (fc_plogi_payload_t*) node->sport->service_params; 1679 adisc = io->els_req.virt; 1680 ocs_memset(adisc, 0, sizeof(fc_adisc_payload_t)); 1681 adisc->command_code = FC_ELS_CMD_ACC; 1682 adisc->hard_address = 0; 1683 adisc->port_name_hi = sparams->port_name_hi; 1684 adisc->port_name_lo = sparams->port_name_lo; 1685 adisc->node_name_hi = sparams->node_name_hi; 1686 adisc->node_name_lo = sparams->node_name_lo; 1687 adisc->port_id = fc_htobe24(node->rnode.sport->fc_id); 1688 1689 io->hio_type = OCS_HW_ELS_RSP; 1690 if ((rc = ocs_els_send_rsp(io, sizeof(*adisc)))) { 1691 ocs_els_io_free(io); 1692 io = NULL; 1693 } 1694 1695 return io; 1696 } 1697 1698 /** 1699 * @ingroup els_api 1700 * @brief Send a RFTID CT request. 1701 * 1702 * <h3 class="desc">Description</h3> 1703 * Construct an RFTID CT request, and send to the \c node. 1704 * 1705 * @param node Node to which the RFTID request is sent. 1706 * @param timeout_sec Time, in seconds, to wait before timing out the ELS. 1707 * @param retries Number of times to retry errors before reporting a failure. 1708 * @param cb Callback function. 1709 * @param cbarg Callback function argument. 1710 * 1711 * @return Returns pointer to IO object, or NULL if error. 1712 */ 1713 ocs_io_t * 1714 ocs_ns_send_rftid(ocs_node_t *node, uint32_t timeout_sec, uint32_t retries, 1715 els_cb_t cb, void *cbarg) 1716 { 1717 ocs_io_t *els; 1718 ocs_t *ocs = node->ocs; 1719 fcct_rftid_req_t *rftid; 1720 1721 node_els_trace(); 1722 1723 els = ocs_els_io_alloc(node, sizeof(*rftid), OCS_ELS_ROLE_ORIGINATOR); 1724 if (els == NULL) { 1725 ocs_log_err(ocs, "IO alloc failed\n"); 1726 } else { 1727 1728 els->iparam.fc_ct.r_ctl = FC_RCTL_ELS; 1729 els->iparam.fc_ct.type = FC_TYPE_GS; 1730 els->iparam.fc_ct.df_ctl = 0; 1731 els->iparam.fc_ct.timeout = timeout_sec; 1732 1733 els->els_callback = cb; 1734 els->els_callback_arg = cbarg; 1735 els->display_name = "rftid"; 1736 1737 rftid = els->els_req.virt; 1738 1739 ocs_memset(rftid, 0, sizeof(*rftid)); 1740 fcct_build_req_header(&rftid->hdr, FC_GS_NAMESERVER_RFT_ID, (OCS_ELS_RSP_LEN - sizeof(rftid->hdr))); 1741 rftid->port_id = ocs_htobe32(node->rnode.sport->fc_id); 1742 rftid->fc4_types[FC_GS_TYPE_WORD(FC_TYPE_FCP)] = ocs_htobe32(1 << FC_GS_TYPE_BIT(FC_TYPE_FCP)); 1743 1744 els->hio_type = OCS_HW_FC_CT; 1745 1746 ocs_io_transition(els, __ocs_els_init, NULL); 1747 } 1748 return els; 1749 } 1750 1751 /** 1752 * @ingroup els_api 1753 * @brief Send a RFFID CT request. 1754 * 1755 * <h3 class="desc">Description</h3> 1756 * Construct an RFFID CT request, and send to the \c node. 1757 * 1758 * @param node Node to which the RFFID request is sent. 1759 * @param timeout_sec Time, in seconds, to wait before timing out the ELS. 1760 * @param retries Number of times to retry errors before reporting a failure. 1761 * @param cb Callback function 1762 * @param cbarg Callback function argument. 1763 * 1764 * @return Returns pointer to IO object, or NULL if error. 1765 */ 1766 ocs_io_t * 1767 ocs_ns_send_rffid(ocs_node_t *node, uint32_t timeout_sec, uint32_t retries, 1768 els_cb_t cb, void *cbarg) 1769 { 1770 ocs_io_t *els; 1771 ocs_t *ocs = node->ocs; 1772 fcct_rffid_req_t *rffid; 1773 1774 node_els_trace(); 1775 1776 els = ocs_els_io_alloc(node, sizeof(*rffid), OCS_ELS_ROLE_ORIGINATOR); 1777 if (els == NULL) { 1778 ocs_log_err(ocs, "IO alloc failed\n"); 1779 } else { 1780 1781 els->iparam.fc_ct.r_ctl = FC_RCTL_ELS; 1782 els->iparam.fc_ct.type = FC_TYPE_GS; 1783 els->iparam.fc_ct.df_ctl = 0; 1784 els->iparam.fc_ct.timeout = timeout_sec; 1785 1786 els->els_callback = cb; 1787 els->els_callback_arg = cbarg; 1788 els->display_name = "rffid"; 1789 1790 rffid = els->els_req.virt; 1791 1792 ocs_memset(rffid, 0, sizeof(*rffid)); 1793 1794 fcct_build_req_header(&rffid->hdr, FC_GS_NAMESERVER_RFF_ID, (OCS_ELS_RSP_LEN - sizeof(rffid->hdr))); 1795 rffid->port_id = ocs_htobe32(node->rnode.sport->fc_id); 1796 if (node->sport->enable_ini) { 1797 rffid->fc4_feature_bits |= FC4_FEATURE_INITIATOR; 1798 } 1799 if (node->sport->enable_tgt) { 1800 rffid->fc4_feature_bits |= FC4_FEATURE_TARGET; 1801 } 1802 rffid->type = FC_TYPE_FCP; 1803 1804 els->hio_type = OCS_HW_FC_CT; 1805 1806 ocs_io_transition(els, __ocs_els_init, NULL); 1807 } 1808 return els; 1809 } 1810 1811 1812 /** 1813 * @ingroup els_api 1814 * @brief Send a GIDPT CT request. 1815 * 1816 * <h3 class="desc">Description</h3> 1817 * Construct a GIDPT CT request, and send to the \c node. 1818 * 1819 * @param node Node to which the GIDPT request is sent. 1820 * @param timeout_sec Time, in seconds, to wait before timing out the ELS. 1821 * @param retries Number of times to retry errors before reporting a failure. 1822 * @param cb Callback function. 1823 * @param cbarg Callback function argument. 1824 * 1825 * @return Returns pointer to IO object, or NULL if error. 1826 */ 1827 1828 ocs_io_t * 1829 ocs_ns_send_gidpt(ocs_node_t *node, uint32_t timeout_sec, uint32_t retries, 1830 els_cb_t cb, void *cbarg) 1831 { 1832 ocs_io_t *els; 1833 ocs_t *ocs = node->ocs; 1834 fcct_gidpt_req_t *gidpt; 1835 1836 node_els_trace(); 1837 1838 els = ocs_els_io_alloc_size(node, sizeof(*gidpt), OCS_ELS_GID_PT_RSP_LEN, OCS_ELS_ROLE_ORIGINATOR); 1839 if (els == NULL) { 1840 ocs_log_err(ocs, "IO alloc failed\n"); 1841 } else { 1842 1843 els->iparam.fc_ct.r_ctl = FC_RCTL_ELS; 1844 els->iparam.fc_ct.type = FC_TYPE_GS; 1845 els->iparam.fc_ct.df_ctl = 0; 1846 els->iparam.fc_ct.timeout = timeout_sec; 1847 1848 els->els_callback = cb; 1849 els->els_callback_arg = cbarg; 1850 els->display_name = "gidpt"; 1851 1852 gidpt = els->els_req.virt; 1853 1854 ocs_memset(gidpt, 0, sizeof(*gidpt)); 1855 fcct_build_req_header(&gidpt->hdr, FC_GS_NAMESERVER_GID_PT, (OCS_ELS_GID_PT_RSP_LEN - sizeof(gidpt->hdr)) ); 1856 gidpt->domain_id_scope = 0; 1857 gidpt->area_id_scope = 0; 1858 gidpt->port_type = 0x7f; 1859 1860 els->hio_type = OCS_HW_FC_CT; 1861 1862 ocs_io_transition(els, __ocs_els_init, NULL); 1863 } 1864 return els; 1865 } 1866 1867 /** 1868 * @ingroup els_api 1869 * @brief Send a BA_ACC given the request's FC header 1870 * 1871 * <h3 class="desc">Description</h3> 1872 * Using the S_ID/D_ID from the request's FC header, generate a BA_ACC. 1873 * 1874 * @param io Pointer to a SCSI IO object. 1875 * @param hdr Pointer to the FC header. 1876 * 1877 * @return Returns pointer to IO object, or NULL if error. 1878 */ 1879 1880 ocs_io_t * 1881 ocs_bls_send_acc_hdr(ocs_io_t *io, fc_header_t *hdr) 1882 { 1883 uint16_t ox_id = ocs_be16toh(hdr->ox_id); 1884 uint16_t rx_id = ocs_be16toh(hdr->rx_id); 1885 uint32_t d_id = fc_be24toh(hdr->d_id); 1886 1887 return ocs_bls_send_acc(io, d_id, ox_id, rx_id); 1888 } 1889 1890 /** 1891 * @ingroup els_api 1892 * @brief Send a BLS BA_ACC response. 1893 * 1894 * <h3 class="desc">Description</h3> 1895 * Construct a BLS BA_ACC response, and send to the \c node. 1896 * 1897 * @param io Pointer to a SCSI IO object. 1898 * @param s_id S_ID to use for the response. If UINT32_MAX, then use our SLI port 1899 * (sport) S_ID. 1900 * @param ox_id Originator exchange ID. 1901 * @param rx_id Responder exchange ID. 1902 * 1903 * @return Returns pointer to IO object, or NULL if error. 1904 */ 1905 1906 static ocs_io_t * 1907 ocs_bls_send_acc(ocs_io_t *io, uint32_t s_id, uint16_t ox_id, uint16_t rx_id) 1908 { 1909 ocs_node_t *node = io->node; 1910 int32_t rc; 1911 fc_ba_acc_payload_t *acc; 1912 ocs_t *ocs; 1913 1914 ocs_assert(node, NULL); 1915 ocs_assert(node->ocs, NULL); 1916 ocs = node->ocs; 1917 1918 if (node->rnode.sport->fc_id == s_id) { 1919 s_id = UINT32_MAX; 1920 } 1921 1922 /* fill out generic fields */ 1923 io->ocs = ocs; 1924 io->node = node; 1925 io->cmd_tgt = TRUE; 1926 1927 /* fill out BLS Response-specific fields */ 1928 io->io_type = OCS_IO_TYPE_BLS_RESP; 1929 io->display_name = "ba_acc"; 1930 io->hio_type = OCS_HW_BLS_ACC_SID; 1931 io->init_task_tag = ox_id; 1932 1933 /* fill out iparam fields */ 1934 ocs_memset(&io->iparam, 0, sizeof(io->iparam)); 1935 io->iparam.bls_sid.s_id = s_id; 1936 io->iparam.bls_sid.ox_id = ox_id; 1937 io->iparam.bls_sid.rx_id = rx_id; 1938 1939 acc = (void *)io->iparam.bls_sid.payload; 1940 1941 ocs_memset(io->iparam.bls_sid.payload, 0, sizeof(io->iparam.bls_sid.payload)); 1942 acc->ox_id = io->iparam.bls_sid.ox_id; 1943 acc->rx_id = io->iparam.bls_sid.rx_id; 1944 acc->high_seq_cnt = UINT16_MAX; 1945 1946 if ((rc = ocs_scsi_io_dispatch(io, ocs_bls_send_acc_cb))) { 1947 ocs_log_err(ocs, "ocs_scsi_io_dispatch() failed: %d\n", rc); 1948 ocs_scsi_io_free(io); 1949 io = NULL; 1950 } 1951 return io; 1952 } 1953 1954 /** 1955 * @brief Handle the BLS accept completion. 1956 * 1957 * <h3 class="desc">Description</h3> 1958 * Upon completion of sending a BA_ACC, this callback is invoked by the HW. 1959 * 1960 * @param hio Pointer to the HW IO object. 1961 * @param rnode Pointer to the HW remote node. 1962 * @param length Length of the response payload, in bytes. 1963 * @param status Completion status. 1964 * @param ext_status Extended completion status. 1965 * @param app Callback private argument. 1966 * 1967 * @return Returns 0 on success; or a negative error value on failure. 1968 */ 1969 1970 static int32_t 1971 ocs_bls_send_acc_cb(ocs_hw_io_t *hio, ocs_remote_node_t *rnode, uint32_t length, int32_t status, uint32_t ext_status, void *app) 1972 { 1973 ocs_io_t *io = app; 1974 1975 ocs_assert(io, -1); 1976 1977 ocs_scsi_io_free(io); 1978 return 0; 1979 } 1980 1981 /** 1982 * @brief ELS abort callback. 1983 * 1984 * <h3 class="desc">Description</h3> 1985 * This callback is invoked by the HW when an ELS IO is aborted. 1986 * 1987 * @param hio Pointer to the HW IO object. 1988 * @param rnode Pointer to the HW remote node. 1989 * @param length Length of the response payload, in bytes. 1990 * @param status Completion status. 1991 * @param ext_status Extended completion status. 1992 * @param app Callback private argument. 1993 * 1994 * @return Returns 0 on success; or a negative error value on failure. 1995 */ 1996 1997 static int32_t 1998 ocs_els_abort_cb(ocs_hw_io_t *hio, ocs_remote_node_t *rnode, uint32_t length, int32_t status, uint32_t ext_status, void *app) 1999 { 2000 ocs_io_t *els; 2001 ocs_io_t *abort_io = NULL; /* IO structure used to abort ELS */ 2002 ocs_t *ocs; 2003 2004 ocs_assert(app, -1); 2005 abort_io = app; 2006 els = abort_io->io_to_abort; 2007 ocs_assert(els->node, -1); 2008 ocs_assert(els->node->ocs, -1); 2009 2010 ocs = els->node->ocs; 2011 2012 if (status != 0) { 2013 ocs_log_warn(ocs, "status x%x ext x%x\n", status, ext_status); 2014 } 2015 2016 /* now free the abort IO */ 2017 ocs_io_free(ocs, abort_io); 2018 2019 /* send completion event to indicate abort process is complete 2020 * Note: The ELS SM will already be receiving ELS_REQ_OK/FAIL/RJT/ABORTED 2021 */ 2022 ocs_els_post_event(els, OCS_EVT_ELS_ABORT_CMPL, NULL); 2023 2024 /* done with ELS IO to abort */ 2025 ocs_ref_put(&els->ref); /* ocs_ref_get(): ocs_els_abort_io() */ 2026 return 0; 2027 } 2028 2029 /** 2030 * @brief Abort an ELS IO. 2031 * 2032 * <h3 class="desc">Description</h3> 2033 * The ELS IO is aborted by making a HW abort IO request, 2034 * optionally requesting that an ABTS is sent. 2035 * 2036 * \b Note: This function allocates a HW IO, and associates the HW IO 2037 * with the ELS IO that it is aborting. It does not associate 2038 * the HW IO with the node directly, like for ELS requests. The 2039 * abort completion is propagated up to the node once the 2040 * original WQE and the abort WQE are complete (the original WQE 2041 * completion is not propagated up to node). 2042 * 2043 * @param els Pointer to the ELS IO. 2044 * @param send_abts Boolean to indicate if hardware will automatically generate an ABTS. 2045 * 2046 * @return Returns pointer to Abort IO object, or NULL if error. 2047 */ 2048 2049 static ocs_io_t * 2050 ocs_els_abort_io(ocs_io_t *els, int send_abts) 2051 { 2052 ocs_t *ocs; 2053 ocs_xport_t *xport; 2054 int32_t rc; 2055 ocs_io_t *abort_io = NULL; 2056 2057 ocs_assert(els, NULL); 2058 ocs_assert(els->node, NULL); 2059 ocs_assert(els->node->ocs, NULL); 2060 2061 ocs = els->node->ocs; 2062 ocs_assert(ocs->xport, NULL); 2063 xport = ocs->xport; 2064 2065 /* take a reference on IO being aborted */ 2066 if ((ocs_ref_get_unless_zero(&els->ref) == 0)) { 2067 /* command no longer active */ 2068 ocs_log_debug(ocs, "els no longer active\n"); 2069 return NULL; 2070 } 2071 2072 /* allocate IO structure to send abort */ 2073 abort_io = ocs_io_alloc(ocs); 2074 if (abort_io == NULL) { 2075 ocs_atomic_add_return(&xport->io_alloc_failed_count, 1); 2076 } else { 2077 ocs_assert(abort_io->hio == NULL, NULL); 2078 2079 /* set generic fields */ 2080 abort_io->ocs = ocs; 2081 abort_io->node = els->node; 2082 abort_io->cmd_ini = TRUE; 2083 2084 /* set type and ABORT-specific fields */ 2085 abort_io->io_type = OCS_IO_TYPE_ABORT; 2086 abort_io->display_name = "abort_els"; 2087 abort_io->io_to_abort = els; 2088 abort_io->send_abts = send_abts; 2089 2090 /* now dispatch IO */ 2091 if ((rc = ocs_scsi_io_dispatch_abort(abort_io, ocs_els_abort_cb))) { 2092 ocs_log_err(ocs, "ocs_scsi_io_dispatch failed: %d\n", rc); 2093 ocs_io_free(ocs, abort_io); 2094 abort_io = NULL; 2095 } 2096 } 2097 2098 /* if something failed, put reference on ELS to abort */ 2099 if (abort_io == NULL) { 2100 ocs_ref_put(&els->ref); /* ocs_ref_get(): same function */ 2101 } 2102 return abort_io; 2103 } 2104 2105 2106 /* 2107 * ELS IO State Machine 2108 */ 2109 2110 #define std_els_state_decl(...) \ 2111 ocs_io_t *els = NULL; \ 2112 ocs_node_t *node = NULL; \ 2113 ocs_t *ocs = NULL; \ 2114 ocs_assert(ctx != NULL, NULL); \ 2115 els = ctx->app; \ 2116 ocs_assert(els != NULL, NULL); \ 2117 node = els->node; \ 2118 ocs_assert(node != NULL, NULL); \ 2119 ocs = node->ocs; \ 2120 ocs_assert(ocs != NULL, NULL); 2121 2122 #define els_sm_trace(...) \ 2123 do { \ 2124 if (OCS_LOG_ENABLE_ELS_TRACE(ocs)) \ 2125 ocs_log_info(ocs, "[%s] %-8s %-20s %-20s\n", node->display_name, els->display_name, \ 2126 __func__, ocs_sm_event_name(evt)); \ 2127 } while (0) 2128 2129 2130 /** 2131 * @brief Cleanup an ELS IO 2132 * 2133 * <h3 class="desc">Description</h3> 2134 * Cleans up an ELS IO by posting the requested event to the owning node object; 2135 * invoking the callback, if one is provided; and then freeing the 2136 * ELS IO object. 2137 * 2138 * @param els Pointer to the ELS IO. 2139 * @param node_evt Node SM event to post. 2140 * @param arg Node SM event argument. 2141 * 2142 * @return None. 2143 */ 2144 2145 void 2146 ocs_els_io_cleanup(ocs_io_t *els, ocs_sm_event_t node_evt, void *arg) 2147 { 2148 ocs_assert(els); 2149 2150 /* don't want further events that could come; e.g. abort requests 2151 * from the node state machine; thus, disable state machine 2152 */ 2153 ocs_sm_disable(&els->els_sm); 2154 ocs_node_post_event(els->node, node_evt, arg); 2155 2156 /* If this IO has a callback, invoke it */ 2157 if (els->els_callback) { 2158 (*els->els_callback)(els->node, arg, els->els_callback_arg); 2159 } 2160 els->els_req_free = 1; 2161 } 2162 2163 2164 /** 2165 * @brief Common event handler for the ELS IO state machine. 2166 * 2167 * <h3 class="desc">Description</h3> 2168 * Provide handler for events for which default actions are desired. 2169 * 2170 * @param funcname Name of the calling function (for logging). 2171 * @param ctx Remote node SM context. 2172 * @param evt Event to process. 2173 * @param arg Per event optional argument. 2174 * 2175 * @return Returns NULL. 2176 */ 2177 2178 void * 2179 __ocs_els_common(const char *funcname, ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg) 2180 { 2181 std_els_state_decl(); 2182 2183 switch(evt) { 2184 case OCS_EVT_ENTER: 2185 case OCS_EVT_REENTER: 2186 case OCS_EVT_EXIT: 2187 break; 2188 2189 /* If ELS_REQ_FAIL is not handled in state, then we'll terminate this ELS and 2190 * pass the event to the node 2191 */ 2192 case OCS_EVT_SRRS_ELS_REQ_FAIL: 2193 ocs_log_warn(els->node->ocs, "[%s] %-20s %-20s not handled - terminating ELS\n", node->display_name, funcname, 2194 ocs_sm_event_name(evt)); 2195 ocs_els_io_cleanup(els, OCS_EVT_SRRS_ELS_REQ_FAIL, arg); 2196 break; 2197 default: 2198 ocs_log_warn(els->node->ocs, "[%s] %-20s %-20s not handled\n", node->display_name, funcname, 2199 ocs_sm_event_name(evt)); 2200 break; 2201 } 2202 return NULL; 2203 } 2204 2205 /** 2206 * @brief Initial ELS IO state 2207 * 2208 * <h3 class="desc">Description</h3> 2209 * This is the initial ELS IO state. Upon entry, the requested ELS/CT is submitted to 2210 * the hardware. 2211 * 2212 * @param ctx Remote node SM context. 2213 * @param evt Event to process. 2214 * @param arg Per event optional argument. 2215 * 2216 * @return Returns NULL. 2217 */ 2218 2219 void * 2220 __ocs_els_init(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg) 2221 { 2222 int32_t rc = 0; 2223 std_els_state_decl(); 2224 2225 els_sm_trace(); 2226 2227 switch(evt) { 2228 case OCS_EVT_ENTER: { 2229 rc = ocs_els_send(els, els->els_req.size, els->els_timeout_sec, ocs_els_req_cb); 2230 if (rc) { 2231 ocs_node_cb_t cbdata; 2232 cbdata.status = cbdata.ext_status = (~0); 2233 cbdata.els = els; 2234 ocs_log_err(ocs, "ocs_els_send failed: %d\n", rc); 2235 ocs_els_io_cleanup(els, OCS_EVT_SRRS_ELS_REQ_FAIL, &cbdata); 2236 } else { 2237 ocs_io_transition(els, __ocs_els_wait_resp, NULL); 2238 } 2239 break; 2240 } 2241 default: 2242 __ocs_els_common(__func__, ctx, evt, arg); 2243 break; 2244 } 2245 2246 return NULL; 2247 } 2248 2249 /** 2250 * @brief Wait for the ELS request to complete. 2251 * 2252 * <h3 class="desc">Description</h3> 2253 * This is the ELS IO state that waits for the submitted ELS event to complete. 2254 * If an error completion event is received, the requested ELS is aborted. 2255 * 2256 * @param ctx Remote node SM context. 2257 * @param evt Event to process. 2258 * @param arg Per event optional argument. 2259 * 2260 * @return Returns NULL. 2261 */ 2262 2263 void * 2264 __ocs_els_wait_resp(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg) 2265 { 2266 ocs_io_t *io; 2267 std_els_state_decl(); 2268 2269 els_sm_trace(); 2270 2271 switch(evt) { 2272 case OCS_EVT_SRRS_ELS_REQ_OK: { 2273 ocs_els_io_cleanup(els, OCS_EVT_SRRS_ELS_REQ_OK, arg); 2274 break; 2275 } 2276 2277 case OCS_EVT_SRRS_ELS_REQ_FAIL: { 2278 ocs_els_io_cleanup(els, OCS_EVT_SRRS_ELS_REQ_FAIL, arg); 2279 break; 2280 } 2281 2282 case OCS_EVT_ELS_REQ_TIMEOUT: { 2283 els_io_printf(els, "Timed out, retry (%d tries remaining)\n", 2284 els->els_retries_remaining-1); 2285 ocs_io_transition(els, __ocs_els_retry, NULL); 2286 break; 2287 } 2288 2289 case OCS_EVT_SRRS_ELS_REQ_RJT: { 2290 ocs_node_cb_t *cbdata = arg; 2291 uint32_t reason_code = (cbdata->ext_status >> 16) & 0xff; 2292 2293 /* delay and retry if reason code is Logical Busy */ 2294 switch (reason_code) { 2295 case FC_REASON_LOGICAL_BUSY: 2296 els->node->els_req_cnt--; 2297 els_io_printf(els, "LS_RJT Logical Busy response, delay and retry\n"); 2298 ocs_io_transition(els, __ocs_els_delay_retry, NULL); 2299 break; 2300 default: 2301 ocs_els_io_cleanup(els, evt, arg); 2302 break; 2303 } 2304 break; 2305 } 2306 2307 case OCS_EVT_ABORT_ELS: { 2308 /* request to abort this ELS without an ABTS */ 2309 els_io_printf(els, "ELS abort requested\n"); 2310 els->els_retries_remaining = 0; /* Set retries to zero, we are done */ 2311 io = ocs_els_abort_io(els, FALSE); 2312 if (io == NULL) { 2313 ocs_log_err(ocs, "ocs_els_send failed\n"); 2314 ocs_els_io_cleanup(els, OCS_EVT_SRRS_ELS_REQ_FAIL, arg); 2315 } else { 2316 ocs_io_transition(els, __ocs_els_aborting, NULL); 2317 } 2318 break; 2319 } 2320 2321 default: 2322 __ocs_els_common(__func__, ctx, evt, arg); 2323 break; 2324 } 2325 return NULL; 2326 } 2327 2328 /** 2329 * @brief Wait for the ELS IO abort request to complete, and retry the ELS. 2330 * 2331 * <h3 class="desc">Description</h3> 2332 * This state is entered when waiting for an abort of an ELS 2333 * request to complete so the request can be retried. 2334 * 2335 * @param ctx Remote node SM context. 2336 * @param evt Event to process. 2337 * @param arg Per event optional argument. 2338 * 2339 * @return Returns NULL. 2340 */ 2341 2342 void * 2343 __ocs_els_retry(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg) 2344 { 2345 int32_t rc = 0; 2346 std_els_state_decl(); 2347 2348 els_sm_trace(); 2349 2350 switch(evt) { 2351 case OCS_EVT_ENTER: { 2352 /* handle event for ABORT_XRI WQE 2353 * once abort is complete, retry if retries left; 2354 * don't need to wait for OCS_EVT_SRRS_ELS_REQ_* event because we got 2355 * by receiving OCS_EVT_ELS_REQ_TIMEOUT 2356 */ 2357 ocs_node_cb_t node_cbdata; 2358 node_cbdata.status = node_cbdata.ext_status = (~0); 2359 node_cbdata.els = els; 2360 if (els->els_retries_remaining && --els->els_retries_remaining) { 2361 /* Use a different XRI for the retry (would like a new oxid), 2362 * so free the HW IO (dispatch will allocate a new one). It's an 2363 * optimization to only free the HW IO here and not the ocs_io_t; 2364 * Freeing the ocs_io_t object would require copying all the necessary 2365 * info from the old ocs_io_t object to the * new one; and allocating 2366 * a new ocs_io_t could fail. 2367 */ 2368 ocs_assert(els->hio, NULL); 2369 ocs_hw_io_free(&ocs->hw, els->hio); 2370 els->hio = NULL; 2371 2372 /* result isn't propagated up to node sm, need to decrement req cnt */ 2373 ocs_assert(els->node->els_req_cnt, NULL); 2374 els->node->els_req_cnt--; 2375 rc = ocs_els_send(els, els->els_req.size, els->els_timeout_sec, ocs_els_req_cb); 2376 if (rc) { 2377 ocs_log_err(ocs, "ocs_els_send failed: %d\n", rc); 2378 ocs_els_io_cleanup(els, OCS_EVT_SRRS_ELS_REQ_FAIL, &node_cbdata); 2379 } 2380 ocs_io_transition(els, __ocs_els_wait_resp, NULL); 2381 } else { 2382 els_io_printf(els, "Retries exhausted\n"); 2383 ocs_els_io_cleanup(els, OCS_EVT_SRRS_ELS_REQ_FAIL, &node_cbdata); 2384 } 2385 break; 2386 } 2387 2388 default: 2389 __ocs_els_common(__func__, ctx, evt, arg); 2390 break; 2391 } 2392 return NULL; 2393 } 2394 2395 /** 2396 * @brief Wait for a retry timer to expire having received an abort request 2397 * 2398 * <h3 class="desc">Description</h3> 2399 * This state is entered when waiting for a timer event, after having received 2400 * an abort request, to avoid a race condition with the timer handler 2401 * 2402 * @param ctx Remote node SM context. 2403 * @param evt Event to process. 2404 * @param arg Per event optional argument. 2405 * 2406 * @return Returns NULL. 2407 */ 2408 void * 2409 __ocs_els_aborted_delay_retry(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg) 2410 { 2411 std_els_state_decl(); 2412 2413 els_sm_trace(); 2414 2415 switch(evt) { 2416 case OCS_EVT_ENTER: 2417 /* mod/resched the timer for a short duration */ 2418 ocs_mod_timer(&els->delay_timer, 1); 2419 break; 2420 case OCS_EVT_TIMER_EXPIRED: 2421 /* Cancel the timer, skip post node event, and free the io */ 2422 node->els_req_cnt++; 2423 ocs_els_io_cleanup(els, OCS_EVT_SRRS_ELS_REQ_FAIL, arg); 2424 break; 2425 default: 2426 __ocs_els_common(__func__, ctx, evt, arg); 2427 break; 2428 } 2429 return NULL; 2430 } 2431 2432 /** 2433 * @brief Wait for a retry timer to expire 2434 * 2435 * <h3 class="desc">Description</h3> 2436 * This state is entered when waiting for a timer event, so that 2437 * the ELS request can be retried. 2438 * 2439 * @param ctx Remote node SM context. 2440 * @param evt Event to process. 2441 * @param arg Per event optional argument. 2442 * 2443 * @return Returns NULL. 2444 */ 2445 void * 2446 __ocs_els_delay_retry(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg) 2447 { 2448 std_els_state_decl(); 2449 2450 els_sm_trace(); 2451 2452 switch(evt) { 2453 case OCS_EVT_ENTER: 2454 ocs_setup_timer(ocs, &els->delay_timer, ocs_els_delay_timer_cb, els, 5000); 2455 break; 2456 case OCS_EVT_TIMER_EXPIRED: 2457 /* Retry delay timer expired, retry the ELS request, Free the HW IO so 2458 * that a new oxid is used. 2459 */ 2460 if (els->hio != NULL) { 2461 ocs_hw_io_free(&ocs->hw, els->hio); 2462 els->hio = NULL; 2463 } 2464 ocs_io_transition(els, __ocs_els_init, NULL); 2465 break; 2466 case OCS_EVT_ABORT_ELS: 2467 ocs_io_transition(els, __ocs_els_aborted_delay_retry, NULL); 2468 break; 2469 default: 2470 __ocs_els_common(__func__, ctx, evt, arg); 2471 break; 2472 } 2473 return NULL; 2474 } 2475 2476 /** 2477 * @brief Wait for the ELS IO abort request to complete. 2478 * 2479 * <h3 class="desc">Description</h3> 2480 * This state is entered after we abort an ELS WQE and are 2481 * waiting for either the original ELS WQE request or the abort 2482 * to complete. 2483 * 2484 * @param ctx Remote node SM context. 2485 * @param evt Event to process. 2486 * @param arg Per event optional argument. 2487 * 2488 * @return Returns NULL. 2489 */ 2490 2491 void * 2492 __ocs_els_aborting(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg) 2493 { 2494 std_els_state_decl(); 2495 2496 els_sm_trace(); 2497 2498 switch(evt) { 2499 case OCS_EVT_SRRS_ELS_REQ_OK: 2500 case OCS_EVT_SRRS_ELS_REQ_FAIL: 2501 case OCS_EVT_SRRS_ELS_REQ_RJT: 2502 case OCS_EVT_ELS_REQ_TIMEOUT: 2503 case OCS_EVT_ELS_REQ_ABORTED: { 2504 /* completion for ELS received first, transition to wait for abort cmpl */ 2505 els_io_printf(els, "request cmpl evt=%s\n", ocs_sm_event_name(evt)); 2506 ocs_io_transition(els, __ocs_els_aborting_wait_abort_cmpl, NULL); 2507 break; 2508 } 2509 case OCS_EVT_ELS_ABORT_CMPL: { 2510 /* completion for abort was received first, transition to wait for req cmpl */ 2511 els_io_printf(els, "abort cmpl evt=%s\n", ocs_sm_event_name(evt)); 2512 ocs_io_transition(els, __ocs_els_aborting_wait_req_cmpl, NULL); 2513 break; 2514 } 2515 case OCS_EVT_ABORT_ELS: 2516 /* nothing we can do but wait */ 2517 break; 2518 2519 default: 2520 __ocs_els_common(__func__, ctx, evt, arg); 2521 break; 2522 } 2523 return NULL; 2524 } 2525 2526 /** 2527 * @brief cleanup ELS after abort 2528 * 2529 * @param els ELS IO to cleanup 2530 * 2531 * @return Returns None. 2532 */ 2533 2534 static void 2535 ocs_els_abort_cleanup(ocs_io_t *els) 2536 { 2537 /* handle event for ABORT_WQE 2538 * whatever state ELS happened to be in, propagate aborted event up 2539 * to node state machine in lieu of OCS_EVT_SRRS_ELS_* event 2540 */ 2541 ocs_node_cb_t cbdata; 2542 cbdata.status = cbdata.ext_status = 0; 2543 cbdata.els = els; 2544 els_io_printf(els, "Request aborted\n"); 2545 ocs_els_io_cleanup(els, OCS_EVT_ELS_REQ_ABORTED, &cbdata); 2546 } 2547 2548 /** 2549 * @brief Wait for the ELS IO abort request to complete. 2550 * 2551 * <h3 class="desc">Description</h3> 2552 * This state is entered after we abort an ELS WQE, we received 2553 * the abort completion first and are waiting for the original 2554 * ELS WQE request to complete. 2555 * 2556 * @param ctx Remote node SM context. 2557 * @param evt Event to process. 2558 * @param arg Per event optional argument. 2559 * 2560 * @return Returns NULL. 2561 */ 2562 2563 void * 2564 __ocs_els_aborting_wait_req_cmpl(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg) 2565 { 2566 std_els_state_decl(); 2567 2568 els_sm_trace(); 2569 2570 switch(evt) { 2571 case OCS_EVT_SRRS_ELS_REQ_OK: 2572 case OCS_EVT_SRRS_ELS_REQ_FAIL: 2573 case OCS_EVT_SRRS_ELS_REQ_RJT: 2574 case OCS_EVT_ELS_REQ_TIMEOUT: 2575 case OCS_EVT_ELS_REQ_ABORTED: { 2576 /* completion for ELS that was aborted */ 2577 ocs_els_abort_cleanup(els); 2578 break; 2579 } 2580 case OCS_EVT_ABORT_ELS: 2581 /* nothing we can do but wait */ 2582 break; 2583 2584 default: 2585 __ocs_els_common(__func__, ctx, evt, arg); 2586 break; 2587 } 2588 return NULL; 2589 } 2590 2591 /** 2592 * @brief Wait for the ELS IO abort request to complete. 2593 * 2594 * <h3 class="desc">Description</h3> 2595 * This state is entered after we abort an ELS WQE, we received 2596 * the original ELS WQE request completion first and are waiting 2597 * for the abort to complete. 2598 * 2599 * @param ctx Remote node SM context. 2600 * @param evt Event to process. 2601 * @param arg Per event optional argument. 2602 * 2603 * @return Returns NULL. 2604 */ 2605 2606 void * 2607 __ocs_els_aborting_wait_abort_cmpl(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg) 2608 { 2609 std_els_state_decl(); 2610 2611 els_sm_trace(); 2612 2613 switch(evt) { 2614 case OCS_EVT_ELS_ABORT_CMPL: { 2615 ocs_els_abort_cleanup(els); 2616 break; 2617 } 2618 case OCS_EVT_ABORT_ELS: 2619 /* nothing we can do but wait */ 2620 break; 2621 2622 default: 2623 __ocs_els_common(__func__, ctx, evt, arg); 2624 break; 2625 } 2626 return NULL; 2627 } 2628 2629 /** 2630 * @brief Generate ELS context ddump data. 2631 * 2632 * <h3 class="desc">Description</h3> 2633 * Generate the ddump data for an ELS context. 2634 * 2635 * @param textbuf Pointer to the text buffer. 2636 * @param els Pointer to the ELS context. 2637 * 2638 * @return None. 2639 */ 2640 2641 void 2642 ocs_ddump_els(ocs_textbuf_t *textbuf, ocs_io_t *els) 2643 { 2644 ocs_ddump_section(textbuf, "els", -1); 2645 ocs_ddump_value(textbuf, "req_free", "%d", els->els_req_free); 2646 ocs_ddump_value(textbuf, "evtdepth", "%d", els->els_evtdepth); 2647 ocs_ddump_value(textbuf, "pend", "%d", els->els_pend); 2648 ocs_ddump_value(textbuf, "active", "%d", els->els_active); 2649 ocs_ddump_io(textbuf, els); 2650 ocs_ddump_endsection(textbuf, "els", -1); 2651 } 2652 2653 2654 /** 2655 * @brief return TRUE if given ELS list is empty (while taking proper locks) 2656 * 2657 * Test if given ELS list is empty while holding the node->active_ios_lock. 2658 * 2659 * @param node pointer to node object 2660 * @param list pointer to list 2661 * 2662 * @return TRUE if els_io_list is empty 2663 */ 2664 2665 int32_t 2666 ocs_els_io_list_empty(ocs_node_t *node, ocs_list_t *list) 2667 { 2668 int empty; 2669 ocs_lock(&node->active_ios_lock); 2670 empty = ocs_list_empty(list); 2671 ocs_unlock(&node->active_ios_lock); 2672 return empty; 2673 } 2674 2675 /** 2676 * @brief Handle CT send response completion 2677 * 2678 * Called when CT response completes, free IO 2679 * 2680 * @param hio Pointer to the HW IO context that completed. 2681 * @param rnode Pointer to the remote node. 2682 * @param length Length of the returned payload data. 2683 * @param status Status of the completion. 2684 * @param ext_status Extended status of the completion. 2685 * @param arg Application-specific argument (generally a pointer to the ELS IO context). 2686 * 2687 * @return returns 0 2688 */ 2689 static int32_t 2690 ocs_ct_acc_cb(ocs_hw_io_t *hio, ocs_remote_node_t *rnode, uint32_t length, int32_t status, uint32_t ext_status, void *arg) 2691 { 2692 ocs_io_t *io = arg; 2693 2694 ocs_els_io_free(io); 2695 2696 return 0; 2697 } 2698 2699 /** 2700 * @brief Send CT response 2701 * 2702 * Sends a CT response frame with payload 2703 * 2704 * @param io Pointer to the IO context. 2705 * @param ox_id Originator exchange ID 2706 * @param ct_hdr Pointer to the CT IU 2707 * @param cmd_rsp_code CT response code 2708 * @param reason_code Reason code 2709 * @param reason_code_explanation Reason code explanation 2710 * 2711 * @return returns 0 for success, a negative error code value for failure. 2712 */ 2713 int32_t 2714 ocs_send_ct_rsp(ocs_io_t *io, uint32_t ox_id, fcct_iu_header_t *ct_hdr, uint32_t cmd_rsp_code, uint32_t reason_code, uint32_t reason_code_explanation) 2715 { 2716 fcct_iu_header_t *rsp = io->els_rsp.virt; 2717 2718 io->io_type = OCS_IO_TYPE_CT_RESP; 2719 2720 *rsp = *ct_hdr; 2721 2722 fcct_build_req_header(rsp, cmd_rsp_code, 0); 2723 rsp->reason_code = reason_code; 2724 rsp->reason_code_explanation = reason_code_explanation; 2725 2726 io->display_name = "ct response"; 2727 io->init_task_tag = ox_id; 2728 io->wire_len += sizeof(*rsp); 2729 2730 ocs_memset(&io->iparam, 0, sizeof(io->iparam)); 2731 2732 io->io_type = OCS_IO_TYPE_CT_RESP; 2733 io->hio_type = OCS_HW_FC_CT_RSP; 2734 io->iparam.fc_ct_rsp.ox_id = ocs_htobe16(ox_id); 2735 io->iparam.fc_ct_rsp.r_ctl = 3; 2736 io->iparam.fc_ct_rsp.type = FC_TYPE_GS; 2737 io->iparam.fc_ct_rsp.df_ctl = 0; 2738 io->iparam.fc_ct_rsp.timeout = 5; 2739 2740 if (ocs_scsi_io_dispatch(io, ocs_ct_acc_cb) < 0) { 2741 ocs_els_io_free(io); 2742 return -1; 2743 } 2744 return 0; 2745 } 2746 2747 2748 /** 2749 * @brief Handle delay retry timeout 2750 * 2751 * Callback is invoked when the delay retry timer expires. 2752 * 2753 * @param arg pointer to the ELS IO object 2754 * 2755 * @return none 2756 */ 2757 static void 2758 ocs_els_delay_timer_cb(void *arg) 2759 { 2760 ocs_io_t *els = arg; 2761 ocs_node_t *node = els->node; 2762 2763 /* 2764 * There is a potential deadlock here since is Linux executes timers 2765 * in a soft IRQ context. The lock may be aready locked by the interrupt 2766 * thread. Handle this case by attempting to take the node lock and reset the 2767 * timer if we fail to acquire the lock. 2768 * 2769 * Note: This code relies on the fact that the node lock is recursive. 2770 */ 2771 if (ocs_node_lock_try(node)) { 2772 ocs_els_post_event(els, OCS_EVT_TIMER_EXPIRED, NULL); 2773 ocs_node_unlock(node); 2774 } else { 2775 ocs_setup_timer(els->ocs, &els->delay_timer, ocs_els_delay_timer_cb, els, 1); 2776 } 2777 } 2778