]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/ocs_fc/ocs_els.c
contrib/libarchive: Import libarchive 3.5.1
[FreeBSD/FreeBSD.git] / sys / dev / ocs_fc / ocs_els.c
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 }