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