2 * Copyright (c) 2017 Broadcom. All rights reserved.
3 * The term "Broadcom" refers to Broadcom Limited and/or its subsidiaries.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
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.
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.
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.
36 * Functions to build and send ELS/CT/BLS commands and responses.
40 @defgroup els_api ELS/BLS/CT Command and Response Functions
46 #include "ocs_device.h"
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
51 #define node_els_trace() \
53 if (OCS_LOG_ENABLE_ELS_TRACE(ocs)) \
54 ocs_log_info(ocs, "[%s] %-20s\n", node->display_name, __func__); \
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__);
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);
74 * @brief ELS state machine transition wrapper.
76 * <h3 class="desc">Description</h3>
77 * This function is the transition wrapper for the ELS state machine. It grabs
78 * the node lock prior to making the transition to protect
79 * against multiple threads accessing a particular ELS. For example,
80 * one thread transitioning from __els_init to
81 * __ocs_els_wait_resp and another thread (tasklet) handling the
82 * completion of that ELS request.
84 * @param els Pointer to the IO context.
85 * @param state State to transition to.
86 * @param data Data to pass in with the transition.
91 ocs_io_transition(ocs_io_t *els, ocs_sm_function_t state, void *data)
93 /* protect ELS events with node lock */
94 ocs_node_t *node = els->node;
96 ocs_sm_transition(&els->els_sm, state, data);
97 ocs_node_unlock(node);
102 * @brief ELS state machine post event wrapper.
104 * <h3 class="desc">Description</h3>
105 * Post an event wrapper for the ELS state machine. This function grabs
106 * the node lock prior to posting the event.
108 * @param els Pointer to the IO context.
109 * @param evt Event to process.
110 * @param data Data to pass in with the transition.
115 ocs_els_post_event(ocs_io_t *els, ocs_sm_event_t evt, void *data)
117 /* protect ELS events with node lock */
118 ocs_node_t *node = els->node;
120 els->els_evtdepth ++;
121 ocs_sm_post_event(&els->els_sm, evt, data);
122 els->els_evtdepth --;
123 ocs_node_unlock(node);
124 if (els->els_evtdepth == 0 && els->els_req_free) {
125 ocs_els_io_free(els);
131 * @brief Allocate an IO structure for an ELS IO context.
133 * <h3 class="desc">Description</h3>
134 * Allocate an IO for an ELS context. Uses OCS_ELS_RSP_LEN as response size.
136 * @param node node to associate ELS IO with
137 * @param reqlen Length of ELS request
138 * @param role Role of ELS (originator/responder)
140 * @return pointer to IO structure allocated
144 ocs_els_io_alloc(ocs_node_t *node, uint32_t reqlen, ocs_els_role_e role)
146 return ocs_els_io_alloc_size(node, reqlen, OCS_ELS_RSP_LEN, role);
151 * @brief Allocate an IO structure for an ELS IO context.
153 * <h3 class="desc">Description</h3>
154 * Allocate an IO for an ELS context, allowing the caller to specify the size of the response.
156 * @param node node to associate ELS IO with
157 * @param reqlen Length of ELS request
158 * @param rsplen Length of ELS response
159 * @param role Role of ELS (originator/responder)
161 * @return pointer to IO structure allocated
165 ocs_els_io_alloc_size(ocs_node_t *node, uint32_t reqlen, uint32_t rsplen, ocs_els_role_e role)
171 ocs_assert(node, NULL);
172 ocs_assert(node->ocs, NULL);
174 ocs_assert(ocs->xport, NULL);
177 ocs_lock(&node->active_ios_lock);
178 if (!node->io_alloc_enabled) {
179 ocs_log_debug(ocs, "called with io_alloc_enabled = FALSE\n");
180 ocs_unlock(&node->active_ios_lock);
184 els = ocs_io_alloc(ocs);
186 ocs_atomic_add_return(&xport->io_alloc_failed_count, 1);
187 ocs_unlock(&node->active_ios_lock);
191 /* initialize refcount */
192 ocs_ref_init(&els->ref, _ocs_els_io_free, els);
195 case OCS_ELS_ROLE_ORIGINATOR:
197 els->cmd_tgt = FALSE;
199 case OCS_ELS_ROLE_RESPONDER:
200 els->cmd_ini = FALSE;
205 /* IO should not have an associated HW IO yet. Assigned below. */
206 if (els->hio != NULL) {
207 ocs_log_err(ocs, "assertion failed. HIO is not null\n");
208 ocs_io_free(ocs, els);
209 ocs_unlock(&node->active_ios_lock);
213 /* populate generic io fields */
217 /* set type and ELS-specific fields */
218 els->io_type = OCS_IO_TYPE_ELS;
219 els->display_name = "pending";
221 if (reqlen > OCS_ELS_REQ_LEN) {
222 ocs_log_err(ocs, "ELS command request len greater than allocated\n");
223 ocs_io_free(ocs, els);
224 ocs_unlock(&node->active_ios_lock);
228 if (rsplen > OCS_ELS_GID_PT_RSP_LEN) {
229 ocs_log_err(ocs, "ELS command response len: %d "
230 "greater than allocated\n", rsplen);
231 ocs_io_free(ocs, els);
232 ocs_unlock(&node->active_ios_lock);
236 els->els_req.size = reqlen;
237 els->els_rsp.size = rsplen;
240 ocs_memset(&els->els_sm, 0, sizeof(els->els_sm));
241 els->els_sm.app = els;
243 /* initialize fields */
244 els->els_retries_remaining = OCS_FC_ELS_DEFAULT_RETRIES;
245 els->els_evtdepth = 0;
249 /* add els structure to ELS IO list */
250 ocs_list_add_tail(&node->els_io_pend_list, els);
253 ocs_unlock(&node->active_ios_lock);
259 * @brief Free IO structure for an ELS IO context.
261 * <h3 class="desc">Description</h3> Free IO for an ELS
264 * @param els ELS IO structure for which IO is allocated
270 ocs_els_io_free(ocs_io_t *els)
272 ocs_ref_put(&els->ref);
277 * @brief Free IO structure for an ELS IO context.
279 * <h3 class="desc">Description</h3> Free IO for an ELS
282 * @param arg ELS IO structure for which IO is allocated
288 _ocs_els_io_free(void *arg)
290 ocs_io_t *els = (ocs_io_t *)arg;
293 int send_empty_event = FALSE;
296 ocs_assert(els->node);
297 ocs_assert(els->node->ocs);
298 ocs = els->node->ocs;
303 ocs_lock(&node->active_ios_lock);
304 if (els->els_active) {
305 /* if active, remove from active list and check empty */
306 ocs_list_remove(&node->els_io_active_list, els);
307 /* Send list empty event if the IO allocator is disabled, and the list is empty
308 * If node->io_alloc_enabled was not checked, the event would be posted continually
310 send_empty_event = (!node->io_alloc_enabled) && ocs_list_empty(&node->els_io_active_list);
312 } else if (els->els_pend) {
313 /* if pending, remove from pending list; node shutdown isn't
314 * gated off the pending list (only the active list), so no
315 * need to check if pending list is empty
317 ocs_list_remove(&node->els_io_pend_list, els);
320 ocs_log_err(ocs, "assertion failed: niether els->els_pend nor els->active set\n");
321 ocs_unlock(&node->active_ios_lock);
325 ocs_unlock(&node->active_ios_lock);
327 ocs_io_free(ocs, els);
329 if (send_empty_event) {
330 ocs_node_post_event(node, OCS_EVT_ALL_CHILD_NODES_FREE, NULL);
333 ocs_scsi_check_pending(ocs);
338 * @brief Make ELS IO active
340 * @param els Pointer to the IO context to make active.
342 * @return Returns 0 on success; or a negative error code value on failure.
346 ocs_els_make_active(ocs_io_t *els)
348 ocs_node_t *node = els->node;
350 /* move ELS from pending list to active list */
351 ocs_lock(&node->active_ios_lock);
353 if (els->els_active) {
354 ocs_log_err(node->ocs, "assertion failed: both els->els_pend and els->active set\n");
355 ocs_unlock(&node->active_ios_lock);
359 /* remove from pending list */
360 ocs_list_remove(&node->els_io_pend_list, els);
363 /* add els structure to ELS IO list */
364 ocs_list_add_tail(&node->els_io_active_list, els);
368 /* must be retrying; make sure it's already active */
369 if (!els->els_active) {
370 ocs_log_err(node->ocs, "assertion failed: niether els->els_pend nor els->active set\n");
373 ocs_unlock(&node->active_ios_lock);
378 * @brief Send the ELS command.
380 * <h3 class="desc">Description</h3>
381 * The command, given by the \c els IO context, is sent to the node that the IO was
382 * configured with, using ocs_hw_srrs_send(). Upon completion,
383 * the \c cb callback is invoked,
384 * with the application-specific argument set to the \c els IO context.
386 * @param els Pointer to the IO context.
387 * @param reqlen Byte count in the payload to send.
388 * @param timeout_sec Command timeout, in seconds (0 -> 2*R_A_TOV).
389 * @param cb Completion callback.
391 * @return Returns 0 on success; or a negative error code value on failure.
395 ocs_els_send(ocs_io_t *els, uint32_t reqlen, uint32_t timeout_sec, ocs_hw_srrs_cb_t cb)
397 ocs_node_t *node = els->node;
399 /* update ELS request counter */
402 /* move ELS from pending list to active list */
403 ocs_els_make_active(els);
405 els->wire_len = reqlen;
406 return ocs_scsi_io_dispatch(els, cb);
411 * @brief Send the ELS response.
413 * <h3 class="desc">Description</h3>
414 * The ELS response, given by the \c els IO context, is sent to the node
415 * that the IO was configured with, using ocs_hw_srrs_send().
417 * @param els Pointer to the IO context.
418 * @param rsplen Byte count in the payload to send.
420 * @return Returns 0 on success; or a negative error value on failure.
424 ocs_els_send_rsp(ocs_io_t *els, uint32_t rsplen)
426 ocs_node_t *node = els->node;
428 /* increment ELS completion counter */
429 node->els_cmpl_cnt++;
431 /* move ELS from pending list to active list */
432 ocs_els_make_active(els);
434 els->wire_len = rsplen;
435 return ocs_scsi_io_dispatch(els, ocs_els_acc_cb);
440 * @brief Handle ELS IO request completions.
442 * <h3 class="desc">Description</h3>
443 * This callback is used for several ELS send operations.
445 * @param hio Pointer to the HW IO context that completed.
446 * @param rnode Pointer to the remote node.
447 * @param length Length of the returned payload data.
448 * @param status Status of the completion.
449 * @param ext_status Extended status of the completion.
450 * @param arg Application-specific argument (generally a pointer to the ELS IO context).
452 * @return Returns 0 on success; or a negative error value on failure.
456 ocs_els_req_cb(ocs_hw_io_t *hio, ocs_remote_node_t *rnode, uint32_t length, int32_t status, uint32_t ext_status, void *arg)
461 ocs_node_cb_t cbdata;
468 ocs_assert(els->node, -1);
470 ocs_assert(node->ocs, -1);
473 ocs_assert(io->hio, -1);
474 ocs_assert(hio == io->hio, -1);
477 els_io_printf(els, "status x%x ext x%x\n", status, ext_status);
480 /* set the response len element of els->rsp */
481 els->els_rsp.len = length;
483 cbdata.status = status;
484 cbdata.ext_status = ext_status;
485 cbdata.header = NULL;
488 /* FW returns the number of bytes received on the link in
489 * the WCQE, not the amount placed in the buffer; use this info to
490 * check if there was an overrun.
492 if (length > els->els_rsp.size) {
493 ocs_log_warn(ocs, "ELS response returned len=%d > buflen=%zu\n",
494 length, els->els_rsp.size);
495 ocs_els_post_event(els, OCS_EVT_SRRS_ELS_REQ_FAIL, &cbdata);
499 /* Post event to ELS IO object */
501 case SLI4_FC_WCQE_STATUS_SUCCESS:
502 ocs_els_post_event(els, OCS_EVT_SRRS_ELS_REQ_OK, &cbdata);
505 case SLI4_FC_WCQE_STATUS_LS_RJT:
506 ocs_els_post_event(els, OCS_EVT_SRRS_ELS_REQ_RJT, &cbdata);
510 case SLI4_FC_WCQE_STATUS_LOCAL_REJECT:
511 switch (ext_status) {
512 case SLI4_FC_LOCAL_REJECT_SEQUENCE_TIMEOUT:
513 ocs_els_post_event(els, OCS_EVT_ELS_REQ_TIMEOUT, &cbdata);
515 case SLI4_FC_LOCAL_REJECT_ABORT_REQUESTED:
516 ocs_els_post_event(els, OCS_EVT_ELS_REQ_ABORTED, &cbdata);
519 ocs_els_post_event(els, OCS_EVT_SRRS_ELS_REQ_FAIL, &cbdata);
524 ocs_log_warn(ocs, "els req complete: failed status x%x, ext_status, x%x\n", status, ext_status);
525 ocs_els_post_event(els, OCS_EVT_SRRS_ELS_REQ_FAIL, &cbdata);
534 * @brief Handle ELS IO accept/response completions.
536 * <h3 class="desc">Description</h3>
537 * This callback is used for several ELS send operations.
539 * @param hio Pointer to the HW IO context that completed.
540 * @param rnode Pointer to the remote node.
541 * @param length Length of the returned payload data.
542 * @param status Status of the completion.
543 * @param ext_status Extended status of the completion.
544 * @param arg Application-specific argument (generally a pointer to the ELS IO context).
546 * @return Returns 0 on success; or a negative error value on failure.
550 ocs_els_acc_cb(ocs_hw_io_t *hio, ocs_remote_node_t *rnode, uint32_t length, int32_t status, uint32_t ext_status, void *arg)
555 ocs_node_cb_t cbdata;
562 ocs_assert(els->node, -1);
564 ocs_assert(node->ocs, -1);
567 ocs_assert(io->hio, -1);
568 ocs_assert(hio == io->hio, -1);
570 cbdata.status = status;
571 cbdata.ext_status = ext_status;
572 cbdata.header = NULL;
575 /* Post node event */
577 case SLI4_FC_WCQE_STATUS_SUCCESS:
578 ocs_node_post_event(node, OCS_EVT_SRRS_ELS_CMPL_OK, &cbdata);
582 ocs_log_warn(ocs, "[%s] %-8s failed status x%x, ext_status x%x\n",
583 node->display_name, els->display_name, status, ext_status);
584 ocs_log_warn(ocs, "els acc complete: failed status x%x, ext_status, x%x\n", status, ext_status);
585 ocs_node_post_event(node, OCS_EVT_SRRS_ELS_CMPL_FAIL, &cbdata);
589 /* If this IO has a callback, invoke it */
590 if (els->els_callback) {
591 (*els->els_callback)(node, &cbdata, els->els_callback_arg);
594 ocs_els_io_free(els);
601 * @brief Format and send a PLOGI ELS command.
603 * <h3 class="desc">Description</h3>
604 * Construct a PLOGI payload using the domain SLI port service parameters,
605 * and send to the \c node.
607 * @param node Node to which the PLOGI is sent.
608 * @param timeout_sec Command timeout, in seconds.
609 * @param retries Number of times to retry errors before reporting a failure.
610 * @param cb Callback function.
611 * @param cbarg Callback function argument.
613 * @return Returns pointer to IO object, or NULL if error.
617 ocs_send_plogi(ocs_node_t *node, uint32_t timeout_sec, uint32_t retries,
618 void (*cb)(ocs_node_t *node, ocs_node_cb_t *cbdata, void *arg), void *cbarg)
621 ocs_t *ocs = node->ocs;
622 fc_plogi_payload_t *plogi;
626 els = ocs_els_io_alloc(node, sizeof(*plogi), OCS_ELS_ROLE_ORIGINATOR);
628 ocs_log_err(ocs, "IO alloc failed\n");
630 els->els_timeout_sec = timeout_sec;
631 els->els_retries_remaining = retries;
632 els->els_callback = cb;
633 els->els_callback_arg = cbarg;
634 els->display_name = "plogi";
636 /* Build PLOGI request */
637 plogi = els->els_req.virt;
639 ocs_memcpy(plogi, node->sport->service_params, sizeof(*plogi));
641 plogi->command_code = FC_ELS_CMD_PLOGI;
644 ocs_display_sparams(node->display_name, "plogi send req", 0, NULL, plogi->common_service_parameters);
646 els->hio_type = OCS_HW_ELS_REQ;
647 els->iparam.els.timeout = timeout_sec;
649 ocs_io_transition(els, __ocs_els_init, NULL);
657 * @brief Format and send a FLOGI ELS command.
659 * <h3 class="desc">Description</h3>
660 * Construct an FLOGI payload, and send to the \c node.
662 * @param node Node to which the FLOGI is sent.
663 * @param timeout_sec Command timeout, in seconds.
664 * @param retries Number of times to retry errors before reporting a failure.
665 * @param cb Callback function.
666 * @param cbarg Callback function argument.
668 * @return Returns pointer to IO object, or NULL if error.
672 ocs_send_flogi(ocs_node_t *node, uint32_t timeout_sec, uint32_t retries,
673 els_cb_t cb, void *cbarg)
677 fc_plogi_payload_t *flogi;
679 ocs_assert(node, NULL);
680 ocs_assert(node->ocs, NULL);
681 ocs_assert(node->sport, NULL);
686 els = ocs_els_io_alloc(node, sizeof(*flogi), OCS_ELS_ROLE_ORIGINATOR);
688 ocs_log_err(ocs, "IO alloc failed\n");
690 els->els_timeout_sec = timeout_sec;
691 els->els_retries_remaining = retries;
692 els->els_callback = cb;
693 els->els_callback_arg = cbarg;
694 els->display_name = "flogi";
696 /* Build FLOGI request */
697 flogi = els->els_req.virt;
699 ocs_memcpy(flogi, node->sport->service_params, sizeof(*flogi));
700 flogi->command_code = FC_ELS_CMD_FLOGI;
703 /* Priority tagging support */
704 flogi->common_service_parameters[1] |= ocs_htobe32(1U << 23);
706 ocs_display_sparams(node->display_name, "flogi send req", 0, NULL, flogi->common_service_parameters);
708 els->hio_type = OCS_HW_ELS_REQ;
709 els->iparam.els.timeout = timeout_sec;
710 ocs_io_transition(els, __ocs_els_init, NULL);
717 * @brief Format and send a FDISC ELS command.
719 * <h3 class="desc">Description</h3>
720 * Construct an FDISC payload, and send to the \c node.
722 * @param node Node to which the FDISC is sent.
723 * @param timeout_sec Command timeout, in seconds.
724 * @param retries Number of times to retry errors before reporting a failure.
725 * @param cb Callback function.
726 * @param cbarg Callback function argument.
728 * @return Returns pointer to IO object, or NULL if error.
732 ocs_send_fdisc(ocs_node_t *node, uint32_t timeout_sec, uint32_t retries,
733 els_cb_t cb, void *cbarg)
737 fc_plogi_payload_t *fdisc;
739 ocs_assert(node, NULL);
740 ocs_assert(node->ocs, NULL);
745 els = ocs_els_io_alloc(node, sizeof(*fdisc), OCS_ELS_ROLE_ORIGINATOR);
747 ocs_log_err(ocs, "IO alloc failed\n");
749 els->els_timeout_sec = timeout_sec;
750 els->els_retries_remaining = retries;
751 els->els_callback = cb;
752 els->els_callback_arg = cbarg;
753 els->display_name = "fdisc";
755 /* Build FDISC request */
756 fdisc = els->els_req.virt;
758 ocs_memcpy(fdisc, node->sport->service_params, sizeof(*fdisc));
759 fdisc->command_code = FC_ELS_CMD_FDISC;
762 ocs_display_sparams(node->display_name, "fdisc send req", 0, NULL, fdisc->common_service_parameters);
764 els->hio_type = OCS_HW_ELS_REQ;
765 els->iparam.els.timeout = timeout_sec;
766 ocs_io_transition(els, __ocs_els_init, NULL);
773 * @brief Send a PRLI ELS command.
775 * <h3 class="desc">Description</h3>
776 * Construct a PRLI ELS command, and send to the \c node.
778 * @param node Node to which the PRLI is sent.
779 * @param timeout_sec Command timeout, in seconds.
780 * @param retries Number of times to retry errors before reporting a failure.
781 * @param cb Callback function.
782 * @param cbarg Callback function argument.
784 * @return Returns pointer to IO object, or NULL if error.
788 ocs_send_prli(ocs_node_t *node, uint32_t timeout_sec, uint32_t retries,
789 els_cb_t cb, void *cbarg)
791 ocs_t *ocs = node->ocs;
793 fc_prli_payload_t *prli;
797 els = ocs_els_io_alloc(node, sizeof(*prli), OCS_ELS_ROLE_ORIGINATOR);
799 ocs_log_err(ocs, "IO alloc failed\n");
801 els->els_timeout_sec = timeout_sec;
802 els->els_retries_remaining = retries;
803 els->els_callback = cb;
804 els->els_callback_arg = cbarg;
805 els->display_name = "prli";
807 /* Build PRLI request */
808 prli = els->els_req.virt;
810 ocs_memset(prli, 0, sizeof(*prli));
812 prli->command_code = FC_ELS_CMD_PRLI;
813 prli->page_length = 16;
814 prli->payload_length = ocs_htobe16(sizeof(fc_prli_payload_t));
815 prli->type = FC_TYPE_FCP;
817 prli->flags = ocs_htobe16(FC_PRLI_ESTABLISH_IMAGE_PAIR);
818 prli->service_params = ocs_htobe16(FC_PRLI_READ_XRDY_DISABLED |
819 (node->sport->enable_ini ? FC_PRLI_INITIATOR_FUNCTION : 0) |
820 (node->sport->enable_tgt ? FC_PRLI_TARGET_FUNCTION : 0));
822 /* For Tape Drive support */
823 prli->service_params |= ocs_htobe16(FC_PRLI_CONFIRMED_COMPLETION | FC_PRLI_RETRY |
824 FC_PRLI_TASK_RETRY_ID_REQ| FC_PRLI_REC_SUPPORT);
826 els->hio_type = OCS_HW_ELS_REQ;
827 els->iparam.els.timeout = timeout_sec;
828 ocs_io_transition(els, __ocs_els_init, NULL);
836 * @brief Send a PRLO ELS command.
838 * <h3 class="desc">Description</h3>
839 * Construct a PRLO ELS command, and send to the \c node.
841 * @param node Node to which the PRLO is sent.
842 * @param timeout_sec Command timeout, in seconds.
843 * @param retries Number of times to retry errors before reporting a failure.
844 * @param cb Callback function.
845 * @param cbarg Callback function argument.
847 * @return Returns pointer to IO object, or NULL if error.
851 ocs_send_prlo(ocs_node_t *node, uint32_t timeout_sec, uint32_t retries,
852 els_cb_t cb, void *cbarg)
854 ocs_t *ocs = node->ocs;
856 fc_prlo_payload_t *prlo;
860 els = ocs_els_io_alloc(node, sizeof(*prlo), OCS_ELS_ROLE_ORIGINATOR);
862 ocs_log_err(ocs, "IO alloc failed\n");
864 els->els_timeout_sec = timeout_sec;
865 els->els_retries_remaining = retries;
866 els->els_callback = cb;
867 els->els_callback_arg = cbarg;
868 els->display_name = "prlo";
870 /* Build PRLO request */
871 prlo = els->els_req.virt;
873 ocs_memset(prlo, 0, sizeof(*prlo));
874 prlo->command_code = FC_ELS_CMD_PRLO;
875 prlo->page_length = 16;
876 prlo->payload_length = ocs_htobe16(sizeof(fc_prlo_payload_t));
877 prlo->type = FC_TYPE_FCP;
880 els->hio_type = OCS_HW_ELS_REQ;
881 els->iparam.els.timeout = timeout_sec;
882 ocs_io_transition(els, __ocs_els_init, NULL);
889 * @brief Send a LOGO ELS command.
891 * <h3 class="desc">Description</h3>
892 * Format a LOGO, and send to the \c node.
894 * @param node Node to which the LOGO is sent.
895 * @param timeout_sec Command timeout, in seconds.
896 * @param retries Number of times to retry errors before reporting a failure.
897 * @param cb Callback function.
898 * @param cbarg Callback function argument.
900 * @return Returns pointer to IO object, or NULL if error.
904 ocs_send_logo(ocs_node_t *node, uint32_t timeout_sec, uint32_t retries,
905 els_cb_t cb, void *cbarg)
909 fc_logo_payload_t *logo;
910 fc_plogi_payload_t *sparams;
917 sparams = (fc_plogi_payload_t*) node->sport->service_params;
919 els = ocs_els_io_alloc(node, sizeof(*logo), OCS_ELS_ROLE_ORIGINATOR);
921 ocs_log_err(ocs, "IO alloc failed\n");
923 els->els_timeout_sec = timeout_sec;
924 els->els_retries_remaining = retries;
925 els->els_callback = cb;
926 els->els_callback_arg = cbarg;
927 els->display_name = "logo";
929 /* Build LOGO request */
931 logo = els->els_req.virt;
933 ocs_memset(logo, 0, sizeof(*logo));
934 logo->command_code = FC_ELS_CMD_LOGO;
936 logo->port_id = fc_htobe24(node->rnode.sport->fc_id);
937 logo->port_name_hi = sparams->port_name_hi;
938 logo->port_name_lo = sparams->port_name_lo;
940 els->hio_type = OCS_HW_ELS_REQ;
941 els->iparam.els.timeout = timeout_sec;
942 ocs_io_transition(els, __ocs_els_init, NULL);
949 * @brief Send an ADISC ELS command.
951 * <h3 class="desc">Description</h3>
952 * Construct an ADISC ELS command, and send to the \c node.
954 * @param node Node to which the ADISC is sent.
955 * @param timeout_sec Command timeout, in seconds.
956 * @param retries Number of times to retry errors before reporting a failure.
957 * @param cb Callback function.
958 * @param cbarg Callback function argument.
960 * @return Returns pointer to IO object, or NULL if error.
964 ocs_send_adisc(ocs_node_t *node, uint32_t timeout_sec, uint32_t retries,
965 els_cb_t cb, void *cbarg)
969 fc_adisc_payload_t *adisc;
970 fc_plogi_payload_t *sparams;
971 ocs_sport_t *sport = node->sport;
977 sparams = (fc_plogi_payload_t*) node->sport->service_params;
979 els = ocs_els_io_alloc(node, sizeof(*adisc), OCS_ELS_ROLE_ORIGINATOR);
981 ocs_log_err(ocs, "IO alloc failed\n");
983 els->els_timeout_sec = timeout_sec;
984 els->els_retries_remaining = retries;
985 els->els_callback = cb;
986 els->els_callback_arg = cbarg;
987 els->display_name = "adisc";
989 /* Build ADISC request */
991 adisc = els->els_req.virt;
992 sparams = (fc_plogi_payload_t*) node->sport->service_params;
994 ocs_memset(adisc, 0, sizeof(*adisc));
995 adisc->command_code = FC_ELS_CMD_ADISC;
996 adisc->hard_address = fc_htobe24(sport->fc_id);
997 adisc->port_name_hi = sparams->port_name_hi;
998 adisc->port_name_lo = sparams->port_name_lo;
999 adisc->node_name_hi = sparams->node_name_hi;
1000 adisc->node_name_lo = sparams->node_name_lo;
1001 adisc->port_id = fc_htobe24(node->rnode.sport->fc_id);
1003 els->hio_type = OCS_HW_ELS_REQ;
1004 els->iparam.els.timeout = timeout_sec;
1005 ocs_io_transition(els, __ocs_els_init, NULL);
1012 * @brief Send a PDISC ELS command.
1014 * <h3 class="desc">Description</h3>
1015 * Construct a PDISC ELS command, and send to the \c node.
1017 * @param node Node to which the PDISC is sent.
1018 * @param timeout_sec Command timeout, in seconds.
1019 * @param retries Number of times to retry errors before reporting a failure.
1020 * @param cb Callback function.
1021 * @param cbarg Callback function argument.
1023 * @return Returns pointer to IO object, or NULL if error.
1027 ocs_send_pdisc(ocs_node_t *node, uint32_t timeout_sec, uint32_t retries,
1028 els_cb_t cb, void *cbarg)
1031 ocs_t *ocs = node->ocs;
1032 fc_plogi_payload_t *pdisc;
1036 els = ocs_els_io_alloc(node, sizeof(*pdisc), OCS_ELS_ROLE_ORIGINATOR);
1038 ocs_log_err(ocs, "IO alloc failed\n");
1040 els->els_timeout_sec = timeout_sec;
1041 els->els_retries_remaining = retries;
1042 els->els_callback = cb;
1043 els->els_callback_arg = cbarg;
1044 els->display_name = "pdisc";
1046 pdisc = els->els_req.virt;
1048 ocs_memcpy(pdisc, node->sport->service_params, sizeof(*pdisc));
1050 pdisc->command_code = FC_ELS_CMD_PDISC;
1053 els->hio_type = OCS_HW_ELS_REQ;
1054 els->iparam.els.timeout = timeout_sec;
1055 ocs_io_transition(els, __ocs_els_init, NULL);
1062 * @brief Send an SCR ELS command.
1064 * <h3 class="desc">Description</h3>
1065 * Format an SCR, and send to the \c node.
1067 * @param node Node to which the SCR is sent.
1068 * @param timeout_sec Command timeout, in seconds.
1069 * @param retries Number of times to retry errors before reporting a failure.
1070 * @param cb Callback function
1071 * @param cbarg Callback function arg
1073 * @return Returns pointer to IO object, or NULL if error.
1077 ocs_send_scr(ocs_node_t *node, uint32_t timeout_sec, uint32_t retries,
1078 els_cb_t cb, void *cbarg)
1081 ocs_t *ocs = node->ocs;
1082 fc_scr_payload_t *req;
1086 els = ocs_els_io_alloc(node, sizeof(*req), OCS_ELS_ROLE_ORIGINATOR);
1088 ocs_log_err(ocs, "IO alloc failed\n");
1090 els->els_timeout_sec = timeout_sec;
1091 els->els_retries_remaining = retries;
1092 els->els_callback = cb;
1093 els->els_callback_arg = cbarg;
1094 els->display_name = "scr";
1096 req = els->els_req.virt;
1098 ocs_memset(req, 0, sizeof(*req));
1099 req->command_code = FC_ELS_CMD_SCR;
1100 req->function = FC_SCR_REG_FULL;
1102 els->hio_type = OCS_HW_ELS_REQ;
1103 els->iparam.els.timeout = timeout_sec;
1104 ocs_io_transition(els, __ocs_els_init, NULL);
1111 * @brief Send an RRQ ELS command.
1113 * <h3 class="desc">Description</h3>
1114 * Format an RRQ, and send to the \c node.
1116 * @param node Node to which the RRQ is sent.
1117 * @param timeout_sec Command timeout, in seconds.
1118 * @param retries Number of times to retry errors before reporting a failure.
1119 * @param cb Callback function
1120 * @param cbarg Callback function arg
1122 * @return Returns pointer to IO object, or NULL if error.
1126 ocs_send_rrq(ocs_node_t *node, uint32_t timeout_sec, uint32_t retries,
1127 els_cb_t cb, void *cbarg)
1130 ocs_t *ocs = node->ocs;
1131 fc_scr_payload_t *req;
1135 els = ocs_els_io_alloc(node, sizeof(*req), OCS_ELS_ROLE_ORIGINATOR);
1137 ocs_log_err(ocs, "IO alloc failed\n");
1139 els->els_timeout_sec = timeout_sec;
1140 els->els_retries_remaining = retries;
1141 els->els_callback = cb;
1142 els->els_callback_arg = cbarg;
1143 els->display_name = "scr";
1145 req = els->els_req.virt;
1147 ocs_memset(req, 0, sizeof(*req));
1148 req->command_code = FC_ELS_CMD_RRQ;
1149 req->function = FC_SCR_REG_FULL;
1151 els->hio_type = OCS_HW_ELS_REQ;
1152 els->iparam.els.timeout = timeout_sec;
1153 ocs_io_transition(els, __ocs_els_init, NULL);
1160 * @brief Send an RSCN ELS command.
1162 * <h3 class="desc">Description</h3>
1163 * Format an RSCN, and send to the \c node.
1165 * @param node Node to which the RRQ is sent.
1166 * @param timeout_sec Command timeout, in seconds.
1167 * @param retries Number of times to retry errors before reporting a failure.
1168 * @param port_ids Pointer to port IDs
1169 * @param port_ids_count Count of port IDs
1170 * @param cb Callback function
1171 * @param cbarg Callback function arg
1173 * @return Returns pointer to IO object, or NULL if error.
1176 ocs_send_rscn(ocs_node_t *node, uint32_t timeout_sec, uint32_t retries,
1177 void *port_ids, uint32_t port_ids_count, els_cb_t cb, void *cbarg)
1180 ocs_t *ocs = node->ocs;
1181 fc_rscn_payload_t *req;
1182 uint32_t payload_length = sizeof(fc_rscn_affected_port_id_page_t)*(port_ids_count - 1) +
1183 sizeof(fc_rscn_payload_t);
1187 els = ocs_els_io_alloc(node, payload_length, OCS_ELS_ROLE_ORIGINATOR);
1189 ocs_log_err(ocs, "IO alloc failed\n");
1191 els->els_timeout_sec = timeout_sec;
1192 els->els_retries_remaining = retries;
1193 els->els_callback = cb;
1194 els->els_callback_arg = cbarg;
1195 els->display_name = "rscn";
1197 req = els->els_req.virt;
1199 req->command_code = FC_ELS_CMD_RSCN;
1200 req->page_length = sizeof(fc_rscn_affected_port_id_page_t);
1201 req->payload_length = ocs_htobe16(sizeof(*req) +
1202 sizeof(fc_rscn_affected_port_id_page_t)*(port_ids_count-1));
1204 els->hio_type = OCS_HW_ELS_REQ;
1205 els->iparam.els.timeout = timeout_sec;
1207 /* copy in the payload */
1208 ocs_memcpy(req->port_list, port_ids, port_ids_count*sizeof(fc_rscn_affected_port_id_page_t));
1210 /* Submit the request */
1211 ocs_io_transition(els, __ocs_els_init, NULL);
1217 * @brief Send an LS_RJT ELS response.
1219 * <h3 class="desc">Description</h3>
1220 * Send an LS_RJT ELS response.
1222 * @param io Pointer to a SCSI IO object.
1223 * @param ox_id Originator exchange ID being responded to.
1224 * @param reason_code Reason code value for LS_RJT.
1225 * @param reason_code_expl Reason code explanation value for LS_RJT.
1226 * @param vendor_unique Vendor-unique value for LS_RJT.
1227 * @param cb Callback function.
1228 * @param cbarg Callback function argument.
1230 * @return Returns pointer to IO object, or NULL if error.
1234 ocs_send_ls_rjt(ocs_io_t *io, uint32_t ox_id, uint32_t reason_code, uint32_t reason_code_expl,
1235 uint32_t vendor_unique, els_cb_t cb, void *cbarg)
1237 ocs_node_t *node = io->node;
1239 ocs_t *ocs = node->ocs;
1240 fc_ls_rjt_payload_t *rjt;
1244 io->els_callback = cb;
1245 io->els_callback_arg = cbarg;
1246 io->display_name = "ls_rjt";
1247 io->init_task_tag = ox_id;
1249 ocs_memset(&io->iparam, 0, sizeof(io->iparam));
1250 io->iparam.els.ox_id = ox_id;
1252 rjt = io->els_req.virt;
1253 ocs_memset(rjt, 0, sizeof(*rjt));
1255 rjt->command_code = FC_ELS_CMD_RJT;
1256 rjt->reason_code = reason_code;
1257 rjt->reason_code_exp = reason_code_expl;
1259 io->hio_type = OCS_HW_ELS_RSP;
1260 if ((rc = ocs_els_send_rsp(io, sizeof(*rjt)))) {
1261 ocs_els_io_free(io);
1270 * @brief Send a PLOGI accept response.
1272 * <h3 class="desc">Description</h3>
1273 * Construct a PLOGI LS_ACC, and send to the \c node, using the originator exchange ID
1276 * @param io Pointer to a SCSI IO object.
1277 * @param ox_id Originator exchange ID being responsed to.
1278 * @param cb Callback function.
1279 * @param cbarg Callback function argument.
1281 * @return Returns pointer to IO object, or NULL if error.
1284 ocs_send_plogi_acc(ocs_io_t *io, uint32_t ox_id, els_cb_t cb, void *cbarg)
1286 ocs_node_t *node = io->node;
1288 ocs_t *ocs = node->ocs;
1289 fc_plogi_payload_t *plogi;
1290 fc_plogi_payload_t *req = (fc_plogi_payload_t *)node->service_params;
1294 io->els_callback = cb;
1295 io->els_callback_arg = cbarg;
1296 io->display_name = "plog_acc";
1297 io->init_task_tag = ox_id;
1299 ocs_memset(&io->iparam, 0, sizeof(io->iparam));
1300 io->iparam.els.ox_id = ox_id;
1302 plogi = io->els_req.virt;
1304 /* copy our port's service parameters to payload */
1305 ocs_memcpy(plogi, node->sport->service_params, sizeof(*plogi));
1306 plogi->command_code = FC_ELS_CMD_ACC;
1309 /* Set Application header support bit if requested */
1310 if (req->common_service_parameters[1] & ocs_htobe32(1U << 24)) {
1311 plogi->common_service_parameters[1] |= ocs_htobe32(1U << 24);
1314 /* Priority tagging support. */
1315 if (req->common_service_parameters[1] & ocs_htobe32(1U << 23)) {
1316 plogi->common_service_parameters[1] |= ocs_htobe32(1U << 23);
1319 ocs_display_sparams(node->display_name, "plogi send resp", 0, NULL, plogi->common_service_parameters);
1321 io->hio_type = OCS_HW_ELS_RSP;
1322 if ((rc = ocs_els_send_rsp(io, sizeof(*plogi)))) {
1323 ocs_els_io_free(io);
1331 * @brief Send an FLOGI accept response for point-to-point negotiation.
1333 * <h3 class="desc">Description</h3>
1334 * Construct an FLOGI accept response, and send to the \c node using the originator
1335 * exchange id \c ox_id. The \c s_id is used for the response frame source FC ID.
1337 * @param io Pointer to a SCSI IO object.
1338 * @param ox_id Originator exchange ID for the response.
1339 * @param s_id Source FC ID to be used in the response frame.
1340 * @param cb Callback function.
1341 * @param cbarg Callback function argument.
1343 * @return Returns pointer to IO object, or NULL if error.
1346 ocs_send_flogi_p2p_acc(ocs_io_t *io, uint32_t ox_id, uint32_t s_id, els_cb_t cb, void *cbarg)
1348 ocs_node_t *node = io->node;
1350 ocs_t *ocs = node->ocs;
1351 fc_plogi_payload_t *flogi;
1355 io->els_callback = cb;
1356 io->els_callback_arg = cbarg;
1357 io->display_name = "flogi_p2p_acc";
1358 io->init_task_tag = ox_id;
1360 ocs_memset(&io->iparam, 0, sizeof(io->iparam));
1361 io->iparam.els_sid.ox_id = ox_id;
1362 io->iparam.els_sid.s_id = s_id;
1364 flogi = io->els_req.virt;
1366 /* copy our port's service parameters to payload */
1367 ocs_memcpy(flogi, node->sport->service_params, sizeof(*flogi));
1368 flogi->command_code = FC_ELS_CMD_ACC;
1370 ocs_memset(flogi->class1_service_parameters, 0, sizeof(flogi->class1_service_parameters));
1371 ocs_memset(flogi->class2_service_parameters, 0, sizeof(flogi->class1_service_parameters));
1372 ocs_memset(flogi->class3_service_parameters, 0, sizeof(flogi->class1_service_parameters));
1373 ocs_memset(flogi->class4_service_parameters, 0, sizeof(flogi->class1_service_parameters));
1375 io->hio_type = OCS_HW_ELS_RSP_SID;
1376 if ((rc = ocs_els_send_rsp(io, sizeof(*flogi)))) {
1377 ocs_els_io_free(io);
1385 ocs_send_flogi_acc(ocs_io_t *io, uint32_t ox_id, uint32_t is_fport, els_cb_t cb, void *cbarg)
1387 ocs_node_t *node = io->node;
1389 ocs_t *ocs = node->ocs;
1390 fc_plogi_payload_t *flogi;
1394 io->els_callback = cb;
1395 io->els_callback_arg = cbarg;
1396 io->display_name = "flogi_acc";
1397 io->init_task_tag = ox_id;
1399 ocs_memset(&io->iparam, 0, sizeof(io->iparam));
1400 io->iparam.els_sid.ox_id = ox_id;
1401 io->iparam.els_sid.s_id = io->node->sport->fc_id;
1403 flogi = io->els_req.virt;
1405 /* copy our port's service parameters to payload */
1406 ocs_memcpy(flogi, node->sport->service_params, sizeof(*flogi));
1410 /* Set F_PORT and Multiple N_PORT_ID Assignment */
1411 flogi->common_service_parameters[1] |= ocs_be32toh(3U << 28);
1414 flogi->command_code = FC_ELS_CMD_ACC;
1417 ocs_display_sparams(node->display_name, "flogi send resp", 0, NULL, flogi->common_service_parameters);
1419 ocs_memset(flogi->class1_service_parameters, 0, sizeof(flogi->class1_service_parameters));
1420 ocs_memset(flogi->class2_service_parameters, 0, sizeof(flogi->class1_service_parameters));
1421 ocs_memset(flogi->class3_service_parameters, 0, sizeof(flogi->class1_service_parameters));
1422 ocs_memset(flogi->class4_service_parameters, 0, sizeof(flogi->class1_service_parameters));
1424 io->hio_type = OCS_HW_ELS_RSP_SID;
1425 if ((rc = ocs_els_send_rsp(io, sizeof(*flogi)))) {
1426 ocs_els_io_free(io);
1435 * @brief Send a PRLI accept response
1437 * <h3 class="desc">Description</h3>
1438 * Construct a PRLI LS_ACC response, and send to the \c node, using the originator
1439 * \c ox_id exchange ID.
1441 * @param io Pointer to a SCSI IO object.
1442 * @param ox_id Originator exchange ID.
1443 * @param cb Callback function.
1444 * @param cbarg Callback function argument.
1446 * @return Returns pointer to IO object, or NULL if error.
1450 ocs_send_prli_acc(ocs_io_t *io, uint32_t ox_id, uint8_t fc_type, els_cb_t cb, void *cbarg)
1452 ocs_node_t *node = io->node;
1454 ocs_t *ocs = node->ocs;
1455 fc_prli_payload_t *prli;
1459 io->els_callback = cb;
1460 io->els_callback_arg = cbarg;
1461 io->display_name = "prli_acc";
1462 io->init_task_tag = ox_id;
1464 ocs_memset(&io->iparam, 0, sizeof(io->iparam));
1465 io->iparam.els.ox_id = ox_id;
1467 prli = io->els_req.virt;
1468 ocs_memset(prli, 0, sizeof(*prli));
1470 prli->command_code = FC_ELS_CMD_ACC;
1471 prli->page_length = 16;
1472 prli->payload_length = ocs_htobe16(sizeof(fc_prli_payload_t));
1473 prli->type = fc_type;
1475 prli->flags = ocs_htobe16(FC_PRLI_ESTABLISH_IMAGE_PAIR | FC_PRLI_REQUEST_EXECUTED);
1477 prli->service_params = ocs_htobe16(FC_PRLI_READ_XRDY_DISABLED |
1478 (node->sport->enable_ini ? FC_PRLI_INITIATOR_FUNCTION : 0) |
1479 (node->sport->enable_tgt ? FC_PRLI_TARGET_FUNCTION : 0));
1481 io->hio_type = OCS_HW_ELS_RSP;
1482 if ((rc = ocs_els_send_rsp(io, sizeof(*prli)))) {
1483 ocs_els_io_free(io);
1492 * @brief Send a PRLO accept response.
1494 * <h3 class="desc">Description</h3>
1495 * Construct a PRLO LS_ACC response, and send to the \c node, using the originator
1496 * exchange ID \c ox_id.
1498 * @param io Pointer to a SCSI IO object.
1499 * @param ox_id Originator exchange ID.
1500 * @param cb Callback function.
1501 * @param cbarg Callback function argument.
1503 * @return Returns pointer to IO object, or NULL if error.
1507 ocs_send_prlo_acc(ocs_io_t *io, uint32_t ox_id, uint8_t fc_type, els_cb_t cb, void *cbarg)
1509 ocs_node_t *node = io->node;
1511 ocs_t *ocs = node->ocs;
1512 fc_prlo_acc_payload_t *prlo_acc;
1516 io->els_callback = cb;
1517 io->els_callback_arg = cbarg;
1518 io->display_name = "prlo_acc";
1519 io->init_task_tag = ox_id;
1521 ocs_memset(&io->iparam, 0, sizeof(io->iparam));
1522 io->iparam.els.ox_id = ox_id;
1524 prlo_acc = io->els_req.virt;
1525 ocs_memset(prlo_acc, 0, sizeof(*prlo_acc));
1527 prlo_acc->command_code = FC_ELS_CMD_ACC;
1528 prlo_acc->page_length = 16;
1529 prlo_acc->payload_length = ocs_htobe16(sizeof(fc_prlo_acc_payload_t));
1530 prlo_acc->type = fc_type;
1531 prlo_acc->type_ext = 0;
1532 prlo_acc->response_code = FC_PRLO_REQUEST_EXECUTED;
1534 io->hio_type = OCS_HW_ELS_RSP;
1535 if ((rc = ocs_els_send_rsp(io, sizeof(*prlo_acc)))) {
1536 ocs_els_io_free(io);
1545 * @brief Send a generic LS_ACC response without a payload.
1547 * <h3 class="desc">Description</h3>
1548 * A generic LS_ACC response is sent to the \c node using the originator exchange ID
1551 * @param io Pointer to a SCSI IO object.
1552 * @param ox_id Originator exchange id.
1553 * @param cb Callback function.
1554 * @param cbarg Callback function argument.
1556 * @return Returns pointer to IO object, or NULL if error.
1559 ocs_send_ls_acc(ocs_io_t *io, uint32_t ox_id, els_cb_t cb, void *cbarg)
1561 ocs_node_t *node = io->node;
1563 ocs_t *ocs = node->ocs;
1564 fc_acc_payload_t *acc;
1568 io->els_callback = cb;
1569 io->els_callback_arg = cbarg;
1570 io->display_name = "ls_acc";
1571 io->init_task_tag = ox_id;
1573 ocs_memset(&io->iparam, 0, sizeof(io->iparam));
1574 io->iparam.els.ox_id = ox_id;
1576 acc = io->els_req.virt;
1577 ocs_memset(acc, 0, sizeof(*acc));
1579 acc->command_code = FC_ELS_CMD_ACC;
1581 io->hio_type = OCS_HW_ELS_RSP;
1582 if ((rc = ocs_els_send_rsp(io, sizeof(*acc)))) {
1583 ocs_els_io_free(io);
1592 * @brief Send a LOGO accept response.
1594 * <h3 class="desc">Description</h3>
1595 * Construct a LOGO LS_ACC response, and send to the \c node, using the originator
1596 * exchange ID \c ox_id.
1598 * @param io Pointer to a SCSI IO object.
1599 * @param ox_id Originator exchange ID.
1600 * @param cb Callback function.
1601 * @param cbarg Callback function argument.
1603 * @return Returns pointer to IO object, or NULL if error.
1606 ocs_send_logo_acc(ocs_io_t *io, uint32_t ox_id, els_cb_t cb, void *cbarg)
1608 ocs_node_t *node = io->node;
1610 ocs_t *ocs = node->ocs;
1611 fc_acc_payload_t *logo;
1615 io->els_callback = cb;
1616 io->els_callback_arg = cbarg;
1617 io->display_name = "logo_acc";
1618 io->init_task_tag = ox_id;
1620 ocs_memset(&io->iparam, 0, sizeof(io->iparam));
1621 io->iparam.els.ox_id = ox_id;
1623 logo = io->els_req.virt;
1624 ocs_memset(logo, 0, sizeof(*logo));
1626 logo->command_code = FC_ELS_CMD_ACC;
1629 io->hio_type = OCS_HW_ELS_RSP;
1630 if ((rc = ocs_els_send_rsp(io, sizeof(*logo)))) {
1631 ocs_els_io_free(io);
1640 * @brief Send an ADISC accept response.
1642 * <h3 class="desc">Description</h3>
1643 * Construct an ADISC LS__ACC, and send to the \c node, using the originator
1644 * exchange id \c ox_id.
1646 * @param io Pointer to a SCSI IO object.
1647 * @param ox_id Originator exchange ID.
1648 * @param cb Callback function.
1649 * @param cbarg Callback function argument.
1651 * @return Returns pointer to IO object, or NULL if error.
1655 ocs_send_adisc_acc(ocs_io_t *io, uint32_t ox_id, els_cb_t cb, void *cbarg)
1657 ocs_node_t *node = io->node;
1659 fc_adisc_payload_t *adisc;
1660 fc_plogi_payload_t *sparams;
1663 ocs_assert(node, NULL);
1664 ocs_assert(node->ocs, NULL);
1669 io->els_callback = cb;
1670 io->els_callback_arg = cbarg;
1671 io->display_name = "adisc_acc";
1672 io->init_task_tag = ox_id;
1674 /* Go ahead and send the ELS_ACC */
1675 ocs_memset(&io->iparam, 0, sizeof(io->iparam));
1676 io->iparam.els.ox_id = ox_id;
1678 sparams = (fc_plogi_payload_t*) node->sport->service_params;
1679 adisc = io->els_req.virt;
1680 ocs_memset(adisc, 0, sizeof(fc_adisc_payload_t));
1681 adisc->command_code = FC_ELS_CMD_ACC;
1682 adisc->hard_address = 0;
1683 adisc->port_name_hi = sparams->port_name_hi;
1684 adisc->port_name_lo = sparams->port_name_lo;
1685 adisc->node_name_hi = sparams->node_name_hi;
1686 adisc->node_name_lo = sparams->node_name_lo;
1687 adisc->port_id = fc_htobe24(node->rnode.sport->fc_id);
1689 io->hio_type = OCS_HW_ELS_RSP;
1690 if ((rc = ocs_els_send_rsp(io, sizeof(*adisc)))) {
1691 ocs_els_io_free(io);
1700 * @brief Send a RFTID CT request.
1702 * <h3 class="desc">Description</h3>
1703 * Construct an RFTID CT request, and send to the \c node.
1705 * @param node Node to which the RFTID request is sent.
1706 * @param timeout_sec Time, in seconds, to wait before timing out the ELS.
1707 * @param retries Number of times to retry errors before reporting a failure.
1708 * @param cb Callback function.
1709 * @param cbarg Callback function argument.
1711 * @return Returns pointer to IO object, or NULL if error.
1714 ocs_ns_send_rftid(ocs_node_t *node, uint32_t timeout_sec, uint32_t retries,
1715 els_cb_t cb, void *cbarg)
1718 ocs_t *ocs = node->ocs;
1719 fcct_rftid_req_t *rftid;
1723 els = ocs_els_io_alloc(node, sizeof(*rftid), OCS_ELS_ROLE_ORIGINATOR);
1725 ocs_log_err(ocs, "IO alloc failed\n");
1728 els->iparam.fc_ct.r_ctl = FC_RCTL_ELS;
1729 els->iparam.fc_ct.type = FC_TYPE_GS;
1730 els->iparam.fc_ct.df_ctl = 0;
1731 els->iparam.fc_ct.timeout = timeout_sec;
1733 els->els_callback = cb;
1734 els->els_callback_arg = cbarg;
1735 els->display_name = "rftid";
1737 rftid = els->els_req.virt;
1739 ocs_memset(rftid, 0, sizeof(*rftid));
1740 fcct_build_req_header(&rftid->hdr, FC_GS_NAMESERVER_RFT_ID, (OCS_ELS_RSP_LEN - sizeof(rftid->hdr)));
1741 rftid->port_id = ocs_htobe32(node->rnode.sport->fc_id);
1742 rftid->fc4_types[FC_GS_TYPE_WORD(FC_TYPE_FCP)] = ocs_htobe32(1 << FC_GS_TYPE_BIT(FC_TYPE_FCP));
1744 els->hio_type = OCS_HW_FC_CT;
1746 ocs_io_transition(els, __ocs_els_init, NULL);
1753 * @brief Send a RFFID CT request.
1755 * <h3 class="desc">Description</h3>
1756 * Construct an RFFID CT request, and send to the \c node.
1758 * @param node Node to which the RFFID request is sent.
1759 * @param timeout_sec Time, in seconds, to wait before timing out the ELS.
1760 * @param retries Number of times to retry errors before reporting a failure.
1761 * @param cb Callback function
1762 * @param cbarg Callback function argument.
1764 * @return Returns pointer to IO object, or NULL if error.
1767 ocs_ns_send_rffid(ocs_node_t *node, uint32_t timeout_sec, uint32_t retries,
1768 els_cb_t cb, void *cbarg)
1771 ocs_t *ocs = node->ocs;
1772 fcct_rffid_req_t *rffid;
1776 els = ocs_els_io_alloc(node, sizeof(*rffid), OCS_ELS_ROLE_ORIGINATOR);
1778 ocs_log_err(ocs, "IO alloc failed\n");
1781 els->iparam.fc_ct.r_ctl = FC_RCTL_ELS;
1782 els->iparam.fc_ct.type = FC_TYPE_GS;
1783 els->iparam.fc_ct.df_ctl = 0;
1784 els->iparam.fc_ct.timeout = timeout_sec;
1786 els->els_callback = cb;
1787 els->els_callback_arg = cbarg;
1788 els->display_name = "rffid";
1790 rffid = els->els_req.virt;
1792 ocs_memset(rffid, 0, sizeof(*rffid));
1794 fcct_build_req_header(&rffid->hdr, FC_GS_NAMESERVER_RFF_ID, (OCS_ELS_RSP_LEN - sizeof(rffid->hdr)));
1795 rffid->port_id = ocs_htobe32(node->rnode.sport->fc_id);
1796 if (node->sport->enable_ini) {
1797 rffid->fc4_feature_bits |= FC4_FEATURE_INITIATOR;
1799 if (node->sport->enable_tgt) {
1800 rffid->fc4_feature_bits |= FC4_FEATURE_TARGET;
1802 rffid->type = FC_TYPE_FCP;
1804 els->hio_type = OCS_HW_FC_CT;
1806 ocs_io_transition(els, __ocs_els_init, NULL);
1814 * @brief Send a GIDPT CT request.
1816 * <h3 class="desc">Description</h3>
1817 * Construct a GIDPT CT request, and send to the \c node.
1819 * @param node Node to which the GIDPT request is sent.
1820 * @param timeout_sec Time, in seconds, to wait before timing out the ELS.
1821 * @param retries Number of times to retry errors before reporting a failure.
1822 * @param cb Callback function.
1823 * @param cbarg Callback function argument.
1825 * @return Returns pointer to IO object, or NULL if error.
1829 ocs_ns_send_gidpt(ocs_node_t *node, uint32_t timeout_sec, uint32_t retries,
1830 els_cb_t cb, void *cbarg)
1833 ocs_t *ocs = node->ocs;
1834 fcct_gidpt_req_t *gidpt;
1838 els = ocs_els_io_alloc_size(node, sizeof(*gidpt), OCS_ELS_GID_PT_RSP_LEN, OCS_ELS_ROLE_ORIGINATOR);
1840 ocs_log_err(ocs, "IO alloc failed\n");
1843 els->iparam.fc_ct.r_ctl = FC_RCTL_ELS;
1844 els->iparam.fc_ct.type = FC_TYPE_GS;
1845 els->iparam.fc_ct.df_ctl = 0;
1846 els->iparam.fc_ct.timeout = timeout_sec;
1848 els->els_callback = cb;
1849 els->els_callback_arg = cbarg;
1850 els->display_name = "gidpt";
1852 gidpt = els->els_req.virt;
1854 ocs_memset(gidpt, 0, sizeof(*gidpt));
1855 fcct_build_req_header(&gidpt->hdr, FC_GS_NAMESERVER_GID_PT, (OCS_ELS_GID_PT_RSP_LEN - sizeof(gidpt->hdr)) );
1856 gidpt->domain_id_scope = 0;
1857 gidpt->area_id_scope = 0;
1858 gidpt->port_type = 0x7f;
1860 els->hio_type = OCS_HW_FC_CT;
1862 ocs_io_transition(els, __ocs_els_init, NULL);
1869 * @brief Send a BA_ACC given the request's FC header
1871 * <h3 class="desc">Description</h3>
1872 * Using the S_ID/D_ID from the request's FC header, generate a BA_ACC.
1874 * @param io Pointer to a SCSI IO object.
1875 * @param hdr Pointer to the FC header.
1877 * @return Returns pointer to IO object, or NULL if error.
1881 ocs_bls_send_acc_hdr(ocs_io_t *io, fc_header_t *hdr)
1883 uint16_t ox_id = ocs_be16toh(hdr->ox_id);
1884 uint16_t rx_id = ocs_be16toh(hdr->rx_id);
1885 uint32_t d_id = fc_be24toh(hdr->d_id);
1887 return ocs_bls_send_acc(io, d_id, ox_id, rx_id);
1892 * @brief Send a BLS BA_ACC response.
1894 * <h3 class="desc">Description</h3>
1895 * Construct a BLS BA_ACC response, and send to the \c node.
1897 * @param io Pointer to a SCSI IO object.
1898 * @param s_id S_ID to use for the response. If UINT32_MAX, then use our SLI port
1900 * @param ox_id Originator exchange ID.
1901 * @param rx_id Responder exchange ID.
1903 * @return Returns pointer to IO object, or NULL if error.
1907 ocs_bls_send_acc(ocs_io_t *io, uint32_t s_id, uint16_t ox_id, uint16_t rx_id)
1909 ocs_node_t *node = io->node;
1911 fc_ba_acc_payload_t *acc;
1914 ocs_assert(node, NULL);
1915 ocs_assert(node->ocs, NULL);
1918 if (node->rnode.sport->fc_id == s_id) {
1922 /* fill out generic fields */
1927 /* fill out BLS Response-specific fields */
1928 io->io_type = OCS_IO_TYPE_BLS_RESP;
1929 io->display_name = "ba_acc";
1930 io->hio_type = OCS_HW_BLS_ACC_SID;
1931 io->init_task_tag = ox_id;
1933 /* fill out iparam fields */
1934 ocs_memset(&io->iparam, 0, sizeof(io->iparam));
1935 io->iparam.bls_sid.s_id = s_id;
1936 io->iparam.bls_sid.ox_id = ox_id;
1937 io->iparam.bls_sid.rx_id = rx_id;
1939 acc = (void *)io->iparam.bls_sid.payload;
1941 ocs_memset(io->iparam.bls_sid.payload, 0, sizeof(io->iparam.bls_sid.payload));
1942 acc->ox_id = io->iparam.bls_sid.ox_id;
1943 acc->rx_id = io->iparam.bls_sid.rx_id;
1944 acc->high_seq_cnt = UINT16_MAX;
1946 if ((rc = ocs_scsi_io_dispatch(io, ocs_bls_send_acc_cb))) {
1947 ocs_log_err(ocs, "ocs_scsi_io_dispatch() failed: %d\n", rc);
1948 ocs_scsi_io_free(io);
1955 * @brief Handle the BLS accept completion.
1957 * <h3 class="desc">Description</h3>
1958 * Upon completion of sending a BA_ACC, this callback is invoked by the HW.
1960 * @param hio Pointer to the HW IO object.
1961 * @param rnode Pointer to the HW remote node.
1962 * @param length Length of the response payload, in bytes.
1963 * @param status Completion status.
1964 * @param ext_status Extended completion status.
1965 * @param app Callback private argument.
1967 * @return Returns 0 on success; or a negative error value on failure.
1971 ocs_bls_send_acc_cb(ocs_hw_io_t *hio, ocs_remote_node_t *rnode, uint32_t length, int32_t status, uint32_t ext_status, void *app)
1977 ocs_scsi_io_free(io);
1982 * @brief ELS abort callback.
1984 * <h3 class="desc">Description</h3>
1985 * This callback is invoked by the HW when an ELS IO is aborted.
1987 * @param hio Pointer to the HW IO object.
1988 * @param rnode Pointer to the HW remote node.
1989 * @param length Length of the response payload, in bytes.
1990 * @param status Completion status.
1991 * @param ext_status Extended completion status.
1992 * @param app Callback private argument.
1994 * @return Returns 0 on success; or a negative error value on failure.
1998 ocs_els_abort_cb(ocs_hw_io_t *hio, ocs_remote_node_t *rnode, uint32_t length, int32_t status, uint32_t ext_status, void *app)
2001 ocs_io_t *abort_io = NULL; /* IO structure used to abort ELS */
2004 ocs_assert(app, -1);
2006 els = abort_io->io_to_abort;
2007 ocs_assert(els->node, -1);
2008 ocs_assert(els->node->ocs, -1);
2010 ocs = els->node->ocs;
2013 ocs_log_warn(ocs, "status x%x ext x%x\n", status, ext_status);
2016 /* now free the abort IO */
2017 ocs_io_free(ocs, abort_io);
2019 /* send completion event to indicate abort process is complete
2020 * Note: The ELS SM will already be receiving ELS_REQ_OK/FAIL/RJT/ABORTED
2022 ocs_els_post_event(els, OCS_EVT_ELS_ABORT_CMPL, NULL);
2024 /* done with ELS IO to abort */
2025 ocs_ref_put(&els->ref); /* ocs_ref_get(): ocs_els_abort_io() */
2030 * @brief Abort an ELS IO.
2032 * <h3 class="desc">Description</h3>
2033 * The ELS IO is aborted by making a HW abort IO request,
2034 * optionally requesting that an ABTS is sent.
2036 * \b Note: This function allocates a HW IO, and associates the HW IO
2037 * with the ELS IO that it is aborting. It does not associate
2038 * the HW IO with the node directly, like for ELS requests. The
2039 * abort completion is propagated up to the node once the
2040 * original WQE and the abort WQE are complete (the original WQE
2041 * completion is not propagated up to node).
2043 * @param els Pointer to the ELS IO.
2044 * @param send_abts Boolean to indicate if hardware will automatically generate an ABTS.
2046 * @return Returns pointer to Abort IO object, or NULL if error.
2050 ocs_els_abort_io(ocs_io_t *els, int send_abts)
2055 ocs_io_t *abort_io = NULL;
2057 ocs_assert(els, NULL);
2058 ocs_assert(els->node, NULL);
2059 ocs_assert(els->node->ocs, NULL);
2061 ocs = els->node->ocs;
2062 ocs_assert(ocs->xport, NULL);
2065 /* take a reference on IO being aborted */
2066 if ((ocs_ref_get_unless_zero(&els->ref) == 0)) {
2067 /* command no longer active */
2068 ocs_log_debug(ocs, "els no longer active\n");
2072 /* allocate IO structure to send abort */
2073 abort_io = ocs_io_alloc(ocs);
2074 if (abort_io == NULL) {
2075 ocs_atomic_add_return(&xport->io_alloc_failed_count, 1);
2077 ocs_assert(abort_io->hio == NULL, NULL);
2079 /* set generic fields */
2080 abort_io->ocs = ocs;
2081 abort_io->node = els->node;
2082 abort_io->cmd_ini = TRUE;
2084 /* set type and ABORT-specific fields */
2085 abort_io->io_type = OCS_IO_TYPE_ABORT;
2086 abort_io->display_name = "abort_els";
2087 abort_io->io_to_abort = els;
2088 abort_io->send_abts = send_abts;
2090 /* now dispatch IO */
2091 if ((rc = ocs_scsi_io_dispatch_abort(abort_io, ocs_els_abort_cb))) {
2092 ocs_log_err(ocs, "ocs_scsi_io_dispatch failed: %d\n", rc);
2093 ocs_io_free(ocs, abort_io);
2098 /* if something failed, put reference on ELS to abort */
2099 if (abort_io == NULL) {
2100 ocs_ref_put(&els->ref); /* ocs_ref_get(): same function */
2107 * ELS IO State Machine
2110 #define std_els_state_decl(...) \
2111 ocs_io_t *els = NULL; \
2112 ocs_node_t *node = NULL; \
2113 ocs_t *ocs = NULL; \
2114 ocs_assert(ctx != NULL, NULL); \
2116 ocs_assert(els != NULL, NULL); \
2118 ocs_assert(node != NULL, NULL); \
2120 ocs_assert(ocs != NULL, NULL);
2122 #define els_sm_trace(...) \
2124 if (OCS_LOG_ENABLE_ELS_TRACE(ocs)) \
2125 ocs_log_info(ocs, "[%s] %-8s %-20s %-20s\n", node->display_name, els->display_name, \
2126 __func__, ocs_sm_event_name(evt)); \
2131 * @brief Cleanup an ELS IO
2133 * <h3 class="desc">Description</h3>
2134 * Cleans up an ELS IO by posting the requested event to the owning node object;
2135 * invoking the callback, if one is provided; and then freeing the
2138 * @param els Pointer to the ELS IO.
2139 * @param node_evt Node SM event to post.
2140 * @param arg Node SM event argument.
2146 ocs_els_io_cleanup(ocs_io_t *els, ocs_sm_event_t node_evt, void *arg)
2150 /* don't want further events that could come; e.g. abort requests
2151 * from the node state machine; thus, disable state machine
2153 ocs_sm_disable(&els->els_sm);
2154 ocs_node_post_event(els->node, node_evt, arg);
2156 /* If this IO has a callback, invoke it */
2157 if (els->els_callback) {
2158 (*els->els_callback)(els->node, arg, els->els_callback_arg);
2160 els->els_req_free = 1;
2165 * @brief Common event handler for the ELS IO state machine.
2167 * <h3 class="desc">Description</h3>
2168 * Provide handler for events for which default actions are desired.
2170 * @param funcname Name of the calling function (for logging).
2171 * @param ctx Remote node SM context.
2172 * @param evt Event to process.
2173 * @param arg Per event optional argument.
2175 * @return Returns NULL.
2179 __ocs_els_common(const char *funcname, ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg)
2181 std_els_state_decl();
2185 case OCS_EVT_REENTER:
2189 /* If ELS_REQ_FAIL is not handled in state, then we'll terminate this ELS and
2190 * pass the event to the node
2192 case OCS_EVT_SRRS_ELS_REQ_FAIL:
2193 ocs_log_warn(els->node->ocs, "[%s] %-20s %-20s not handled - terminating ELS\n", node->display_name, funcname,
2194 ocs_sm_event_name(evt));
2195 ocs_els_io_cleanup(els, OCS_EVT_SRRS_ELS_REQ_FAIL, arg);
2198 ocs_log_warn(els->node->ocs, "[%s] %-20s %-20s not handled\n", node->display_name, funcname,
2199 ocs_sm_event_name(evt));
2206 * @brief Initial ELS IO state
2208 * <h3 class="desc">Description</h3>
2209 * This is the initial ELS IO state. Upon entry, the requested ELS/CT is submitted to
2212 * @param ctx Remote node SM context.
2213 * @param evt Event to process.
2214 * @param arg Per event optional argument.
2216 * @return Returns NULL.
2220 __ocs_els_init(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg)
2223 std_els_state_decl();
2228 case OCS_EVT_ENTER: {
2229 rc = ocs_els_send(els, els->els_req.size, els->els_timeout_sec, ocs_els_req_cb);
2231 ocs_node_cb_t cbdata;
2232 cbdata.status = cbdata.ext_status = (~0);
2234 ocs_log_err(ocs, "ocs_els_send failed: %d\n", rc);
2235 ocs_els_io_cleanup(els, OCS_EVT_SRRS_ELS_REQ_FAIL, &cbdata);
2237 ocs_io_transition(els, __ocs_els_wait_resp, NULL);
2242 __ocs_els_common(__func__, ctx, evt, arg);
2250 * @brief Wait for the ELS request to complete.
2252 * <h3 class="desc">Description</h3>
2253 * This is the ELS IO state that waits for the submitted ELS event to complete.
2254 * If an error completion event is received, the requested ELS is aborted.
2256 * @param ctx Remote node SM context.
2257 * @param evt Event to process.
2258 * @param arg Per event optional argument.
2260 * @return Returns NULL.
2264 __ocs_els_wait_resp(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg)
2267 std_els_state_decl();
2272 case OCS_EVT_SRRS_ELS_REQ_OK: {
2273 ocs_els_io_cleanup(els, OCS_EVT_SRRS_ELS_REQ_OK, arg);
2277 case OCS_EVT_SRRS_ELS_REQ_FAIL: {
2278 ocs_els_io_cleanup(els, OCS_EVT_SRRS_ELS_REQ_FAIL, arg);
2282 case OCS_EVT_ELS_REQ_TIMEOUT: {
2283 els_io_printf(els, "Timed out, retry (%d tries remaining)\n",
2284 els->els_retries_remaining-1);
2285 ocs_io_transition(els, __ocs_els_retry, NULL);
2289 case OCS_EVT_SRRS_ELS_REQ_RJT: {
2290 ocs_node_cb_t *cbdata = arg;
2291 uint32_t reason_code = (cbdata->ext_status >> 16) & 0xff;
2293 /* delay and retry if reason code is Logical Busy */
2294 switch (reason_code) {
2295 case FC_REASON_LOGICAL_BUSY:
2296 els->node->els_req_cnt--;
2297 els_io_printf(els, "LS_RJT Logical Busy response, delay and retry\n");
2298 ocs_io_transition(els, __ocs_els_delay_retry, NULL);
2301 ocs_els_io_cleanup(els, evt, arg);
2307 case OCS_EVT_ABORT_ELS: {
2308 /* request to abort this ELS without an ABTS */
2309 els_io_printf(els, "ELS abort requested\n");
2310 els->els_retries_remaining = 0; /* Set retries to zero, we are done */
2311 io = ocs_els_abort_io(els, FALSE);
2313 ocs_log_err(ocs, "ocs_els_send failed\n");
2314 ocs_els_io_cleanup(els, OCS_EVT_SRRS_ELS_REQ_FAIL, arg);
2316 ocs_io_transition(els, __ocs_els_aborting, NULL);
2322 __ocs_els_common(__func__, ctx, evt, arg);
2329 * @brief Wait for the ELS IO abort request to complete, and retry the ELS.
2331 * <h3 class="desc">Description</h3>
2332 * This state is entered when waiting for an abort of an ELS
2333 * request to complete so the request can be retried.
2335 * @param ctx Remote node SM context.
2336 * @param evt Event to process.
2337 * @param arg Per event optional argument.
2339 * @return Returns NULL.
2343 __ocs_els_retry(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg)
2346 std_els_state_decl();
2351 case OCS_EVT_ENTER: {
2352 /* handle event for ABORT_XRI WQE
2353 * once abort is complete, retry if retries left;
2354 * don't need to wait for OCS_EVT_SRRS_ELS_REQ_* event because we got
2355 * by receiving OCS_EVT_ELS_REQ_TIMEOUT
2357 ocs_node_cb_t node_cbdata;
2358 node_cbdata.status = node_cbdata.ext_status = (~0);
2359 node_cbdata.els = els;
2360 if (els->els_retries_remaining && --els->els_retries_remaining) {
2361 /* Use a different XRI for the retry (would like a new oxid),
2362 * so free the HW IO (dispatch will allocate a new one). It's an
2363 * optimization to only free the HW IO here and not the ocs_io_t;
2364 * Freeing the ocs_io_t object would require copying all the necessary
2365 * info from the old ocs_io_t object to the * new one; and allocating
2366 * a new ocs_io_t could fail.
2368 ocs_assert(els->hio, NULL);
2369 ocs_hw_io_free(&ocs->hw, els->hio);
2372 /* result isn't propagated up to node sm, need to decrement req cnt */
2373 ocs_assert(els->node->els_req_cnt, NULL);
2374 els->node->els_req_cnt--;
2375 rc = ocs_els_send(els, els->els_req.size, els->els_timeout_sec, ocs_els_req_cb);
2377 ocs_log_err(ocs, "ocs_els_send failed: %d\n", rc);
2378 ocs_els_io_cleanup(els, OCS_EVT_SRRS_ELS_REQ_FAIL, &node_cbdata);
2380 ocs_io_transition(els, __ocs_els_wait_resp, NULL);
2382 els_io_printf(els, "Retries exhausted\n");
2383 ocs_els_io_cleanup(els, OCS_EVT_SRRS_ELS_REQ_FAIL, &node_cbdata);
2389 __ocs_els_common(__func__, ctx, evt, arg);
2396 * @brief Wait for a retry timer to expire having received an abort request
2398 * <h3 class="desc">Description</h3>
2399 * This state is entered when waiting for a timer event, after having received
2400 * an abort request, to avoid a race condition with the timer handler
2402 * @param ctx Remote node SM context.
2403 * @param evt Event to process.
2404 * @param arg Per event optional argument.
2406 * @return Returns NULL.
2409 __ocs_els_aborted_delay_retry(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg)
2411 std_els_state_decl();
2417 /* mod/resched the timer for a short duration */
2418 ocs_mod_timer(&els->delay_timer, 1);
2420 case OCS_EVT_TIMER_EXPIRED:
2421 /* Cancel the timer, skip post node event, and free the io */
2422 node->els_req_cnt++;
2423 ocs_els_io_cleanup(els, OCS_EVT_SRRS_ELS_REQ_FAIL, arg);
2426 __ocs_els_common(__func__, ctx, evt, arg);
2433 * @brief Wait for a retry timer to expire
2435 * <h3 class="desc">Description</h3>
2436 * This state is entered when waiting for a timer event, so that
2437 * the ELS request can be retried.
2439 * @param ctx Remote node SM context.
2440 * @param evt Event to process.
2441 * @param arg Per event optional argument.
2443 * @return Returns NULL.
2446 __ocs_els_delay_retry(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg)
2448 std_els_state_decl();
2454 ocs_setup_timer(ocs, &els->delay_timer, ocs_els_delay_timer_cb, els, 5000);
2456 case OCS_EVT_TIMER_EXPIRED:
2457 /* Retry delay timer expired, retry the ELS request, Free the HW IO so
2458 * that a new oxid is used.
2460 if (els->hio != NULL) {
2461 ocs_hw_io_free(&ocs->hw, els->hio);
2464 ocs_io_transition(els, __ocs_els_init, NULL);
2466 case OCS_EVT_ABORT_ELS:
2467 ocs_io_transition(els, __ocs_els_aborted_delay_retry, NULL);
2470 __ocs_els_common(__func__, ctx, evt, arg);
2477 * @brief Wait for the ELS IO abort request to complete.
2479 * <h3 class="desc">Description</h3>
2480 * This state is entered after we abort an ELS WQE and are
2481 * waiting for either the original ELS WQE request or the abort
2484 * @param ctx Remote node SM context.
2485 * @param evt Event to process.
2486 * @param arg Per event optional argument.
2488 * @return Returns NULL.
2492 __ocs_els_aborting(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg)
2494 std_els_state_decl();
2499 case OCS_EVT_SRRS_ELS_REQ_OK:
2500 case OCS_EVT_SRRS_ELS_REQ_FAIL:
2501 case OCS_EVT_SRRS_ELS_REQ_RJT:
2502 case OCS_EVT_ELS_REQ_TIMEOUT:
2503 case OCS_EVT_ELS_REQ_ABORTED: {
2504 /* completion for ELS received first, transition to wait for abort cmpl */
2505 els_io_printf(els, "request cmpl evt=%s\n", ocs_sm_event_name(evt));
2506 ocs_io_transition(els, __ocs_els_aborting_wait_abort_cmpl, NULL);
2509 case OCS_EVT_ELS_ABORT_CMPL: {
2510 /* completion for abort was received first, transition to wait for req cmpl */
2511 els_io_printf(els, "abort cmpl evt=%s\n", ocs_sm_event_name(evt));
2512 ocs_io_transition(els, __ocs_els_aborting_wait_req_cmpl, NULL);
2515 case OCS_EVT_ABORT_ELS:
2516 /* nothing we can do but wait */
2520 __ocs_els_common(__func__, ctx, evt, arg);
2527 * @brief cleanup ELS after abort
2529 * @param els ELS IO to cleanup
2531 * @return Returns None.
2535 ocs_els_abort_cleanup(ocs_io_t *els)
2537 /* handle event for ABORT_WQE
2538 * whatever state ELS happened to be in, propagate aborted event up
2539 * to node state machine in lieu of OCS_EVT_SRRS_ELS_* event
2541 ocs_node_cb_t cbdata;
2542 cbdata.status = cbdata.ext_status = 0;
2544 els_io_printf(els, "Request aborted\n");
2545 ocs_els_io_cleanup(els, OCS_EVT_ELS_REQ_ABORTED, &cbdata);
2549 * @brief Wait for the ELS IO abort request to complete.
2551 * <h3 class="desc">Description</h3>
2552 * This state is entered after we abort an ELS WQE, we received
2553 * the abort completion first and are waiting for the original
2554 * ELS WQE request to complete.
2556 * @param ctx Remote node SM context.
2557 * @param evt Event to process.
2558 * @param arg Per event optional argument.
2560 * @return Returns NULL.
2564 __ocs_els_aborting_wait_req_cmpl(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg)
2566 std_els_state_decl();
2571 case OCS_EVT_SRRS_ELS_REQ_OK:
2572 case OCS_EVT_SRRS_ELS_REQ_FAIL:
2573 case OCS_EVT_SRRS_ELS_REQ_RJT:
2574 case OCS_EVT_ELS_REQ_TIMEOUT:
2575 case OCS_EVT_ELS_REQ_ABORTED: {
2576 /* completion for ELS that was aborted */
2577 ocs_els_abort_cleanup(els);
2580 case OCS_EVT_ABORT_ELS:
2581 /* nothing we can do but wait */
2585 __ocs_els_common(__func__, ctx, evt, arg);
2592 * @brief Wait for the ELS IO abort request to complete.
2594 * <h3 class="desc">Description</h3>
2595 * This state is entered after we abort an ELS WQE, we received
2596 * the original ELS WQE request completion first and are waiting
2597 * for the abort to complete.
2599 * @param ctx Remote node SM context.
2600 * @param evt Event to process.
2601 * @param arg Per event optional argument.
2603 * @return Returns NULL.
2607 __ocs_els_aborting_wait_abort_cmpl(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg)
2609 std_els_state_decl();
2614 case OCS_EVT_ELS_ABORT_CMPL: {
2615 ocs_els_abort_cleanup(els);
2618 case OCS_EVT_ABORT_ELS:
2619 /* nothing we can do but wait */
2623 __ocs_els_common(__func__, ctx, evt, arg);
2630 * @brief Generate ELS context ddump data.
2632 * <h3 class="desc">Description</h3>
2633 * Generate the ddump data for an ELS context.
2635 * @param textbuf Pointer to the text buffer.
2636 * @param els Pointer to the ELS context.
2642 ocs_ddump_els(ocs_textbuf_t *textbuf, ocs_io_t *els)
2644 ocs_ddump_section(textbuf, "els", -1);
2645 ocs_ddump_value(textbuf, "req_free", "%d", els->els_req_free);
2646 ocs_ddump_value(textbuf, "evtdepth", "%d", els->els_evtdepth);
2647 ocs_ddump_value(textbuf, "pend", "%d", els->els_pend);
2648 ocs_ddump_value(textbuf, "active", "%d", els->els_active);
2649 ocs_ddump_io(textbuf, els);
2650 ocs_ddump_endsection(textbuf, "els", -1);
2655 * @brief return TRUE if given ELS list is empty (while taking proper locks)
2657 * Test if given ELS list is empty while holding the node->active_ios_lock.
2659 * @param node pointer to node object
2660 * @param list pointer to list
2662 * @return TRUE if els_io_list is empty
2666 ocs_els_io_list_empty(ocs_node_t *node, ocs_list_t *list)
2669 ocs_lock(&node->active_ios_lock);
2670 empty = ocs_list_empty(list);
2671 ocs_unlock(&node->active_ios_lock);
2676 * @brief Handle CT send response completion
2678 * Called when CT response completes, free IO
2680 * @param hio Pointer to the HW IO context that completed.
2681 * @param rnode Pointer to the remote node.
2682 * @param length Length of the returned payload data.
2683 * @param status Status of the completion.
2684 * @param ext_status Extended status of the completion.
2685 * @param arg Application-specific argument (generally a pointer to the ELS IO context).
2690 ocs_ct_acc_cb(ocs_hw_io_t *hio, ocs_remote_node_t *rnode, uint32_t length, int32_t status, uint32_t ext_status, void *arg)
2694 ocs_els_io_free(io);
2700 * @brief Send CT response
2702 * Sends a CT response frame with payload
2704 * @param io Pointer to the IO context.
2705 * @param ox_id Originator exchange ID
2706 * @param ct_hdr Pointer to the CT IU
2707 * @param cmd_rsp_code CT response code
2708 * @param reason_code Reason code
2709 * @param reason_code_explanation Reason code explanation
2711 * @return returns 0 for success, a negative error code value for failure.
2714 ocs_send_ct_rsp(ocs_io_t *io, uint32_t ox_id, fcct_iu_header_t *ct_hdr, uint32_t cmd_rsp_code, uint32_t reason_code, uint32_t reason_code_explanation)
2716 fcct_iu_header_t *rsp = io->els_rsp.virt;
2718 io->io_type = OCS_IO_TYPE_CT_RESP;
2722 fcct_build_req_header(rsp, cmd_rsp_code, 0);
2723 rsp->reason_code = reason_code;
2724 rsp->reason_code_explanation = reason_code_explanation;
2726 io->display_name = "ct response";
2727 io->init_task_tag = ox_id;
2728 io->wire_len += sizeof(*rsp);
2730 ocs_memset(&io->iparam, 0, sizeof(io->iparam));
2732 io->io_type = OCS_IO_TYPE_CT_RESP;
2733 io->hio_type = OCS_HW_FC_CT_RSP;
2734 io->iparam.fc_ct_rsp.ox_id = ocs_htobe16(ox_id);
2735 io->iparam.fc_ct_rsp.r_ctl = 3;
2736 io->iparam.fc_ct_rsp.type = FC_TYPE_GS;
2737 io->iparam.fc_ct_rsp.df_ctl = 0;
2738 io->iparam.fc_ct_rsp.timeout = 5;
2740 if (ocs_scsi_io_dispatch(io, ocs_ct_acc_cb) < 0) {
2741 ocs_els_io_free(io);
2749 * @brief Handle delay retry timeout
2751 * Callback is invoked when the delay retry timer expires.
2753 * @param arg pointer to the ELS IO object
2758 ocs_els_delay_timer_cb(void *arg)
2760 ocs_io_t *els = arg;
2761 ocs_node_t *node = els->node;
2764 * There is a potential deadlock here since is Linux executes timers
2765 * in a soft IRQ context. The lock may be aready locked by the interrupt
2766 * thread. Handle this case by attempting to take the node lock and reset the
2767 * timer if we fail to acquire the lock.
2769 * Note: This code relies on the fact that the node lock is recursive.
2771 if (ocs_node_lock_try(node)) {
2772 ocs_els_post_event(els, OCS_EVT_TIMER_EXPIRED, NULL);
2773 ocs_node_unlock(node);
2775 ocs_setup_timer(els->ocs, &els->delay_timer, ocs_els_delay_timer_cb, els, 1);