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