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