1*ef270ab1SKenneth D. Merry /*- 2*ef270ab1SKenneth D. Merry * Copyright (c) 2017 Broadcom. All rights reserved. 3*ef270ab1SKenneth D. Merry * The term "Broadcom" refers to Broadcom Limited and/or its subsidiaries. 4*ef270ab1SKenneth D. Merry * 5*ef270ab1SKenneth D. Merry * Redistribution and use in source and binary forms, with or without 6*ef270ab1SKenneth D. Merry * modification, are permitted provided that the following conditions are met: 7*ef270ab1SKenneth D. Merry * 8*ef270ab1SKenneth D. Merry * 1. Redistributions of source code must retain the above copyright notice, 9*ef270ab1SKenneth D. Merry * this list of conditions and the following disclaimer. 10*ef270ab1SKenneth D. Merry * 11*ef270ab1SKenneth D. Merry * 2. Redistributions in binary form must reproduce the above copyright notice, 12*ef270ab1SKenneth D. Merry * this list of conditions and the following disclaimer in the documentation 13*ef270ab1SKenneth D. Merry * and/or other materials provided with the distribution. 14*ef270ab1SKenneth D. Merry * 15*ef270ab1SKenneth D. Merry * 3. Neither the name of the copyright holder nor the names of its contributors 16*ef270ab1SKenneth D. Merry * may be used to endorse or promote products derived from this software 17*ef270ab1SKenneth D. Merry * without specific prior written permission. 18*ef270ab1SKenneth D. Merry * 19*ef270ab1SKenneth D. Merry * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20*ef270ab1SKenneth D. Merry * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21*ef270ab1SKenneth D. Merry * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22*ef270ab1SKenneth D. Merry * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 23*ef270ab1SKenneth D. Merry * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24*ef270ab1SKenneth D. Merry * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25*ef270ab1SKenneth D. Merry * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26*ef270ab1SKenneth D. Merry * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27*ef270ab1SKenneth D. Merry * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28*ef270ab1SKenneth D. Merry * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29*ef270ab1SKenneth D. Merry * POSSIBILITY OF SUCH DAMAGE. 30*ef270ab1SKenneth D. Merry * 31*ef270ab1SKenneth D. Merry * $FreeBSD$ 32*ef270ab1SKenneth D. Merry */ 33*ef270ab1SKenneth D. Merry 34*ef270ab1SKenneth D. Merry /** 35*ef270ab1SKenneth D. Merry * @file 36*ef270ab1SKenneth D. Merry * OCS linux driver remote node callback declarations 37*ef270ab1SKenneth D. Merry */ 38*ef270ab1SKenneth D. Merry 39*ef270ab1SKenneth D. Merry #if !defined(__OCS_NODE_H__) 40*ef270ab1SKenneth D. Merry #define __OCS_NODE_H__ 41*ef270ab1SKenneth D. Merry 42*ef270ab1SKenneth D. Merry 43*ef270ab1SKenneth D. Merry #define node_sm_trace() \ 44*ef270ab1SKenneth D. Merry do { \ 45*ef270ab1SKenneth D. Merry if (OCS_LOG_ENABLE_SM_TRACE(node->ocs)) \ 46*ef270ab1SKenneth D. Merry ocs_log_info(node->ocs, "[%s] %-20s\n", node->display_name, ocs_sm_event_name(evt)); \ 47*ef270ab1SKenneth D. Merry } while (0) 48*ef270ab1SKenneth D. Merry 49*ef270ab1SKenneth D. Merry #define node_printf(node, fmt, ...) ocs_log_debug(node->ocs, "[%s] " fmt, node->display_name, ##__VA_ARGS__) 50*ef270ab1SKenneth D. Merry 51*ef270ab1SKenneth D. Merry #define std_node_state_decl(...) \ 52*ef270ab1SKenneth D. Merry ocs_node_t *node = NULL; \ 53*ef270ab1SKenneth D. Merry ocs_t *ocs = NULL; \ 54*ef270ab1SKenneth D. Merry node = ctx->app; \ 55*ef270ab1SKenneth D. Merry ocs_assert(node, NULL); \ 56*ef270ab1SKenneth D. Merry ocs = node->ocs; \ 57*ef270ab1SKenneth D. Merry ocs_assert(ocs, NULL); \ 58*ef270ab1SKenneth D. Merry if (evt == OCS_EVT_ENTER) { \ 59*ef270ab1SKenneth D. Merry ocs_strncpy(node->current_state_name, __func__, sizeof(node->current_state_name)); \ 60*ef270ab1SKenneth D. Merry } else if (evt == OCS_EVT_EXIT) { \ 61*ef270ab1SKenneth D. Merry ocs_strncpy(node->prev_state_name, node->current_state_name, sizeof(node->prev_state_name)); \ 62*ef270ab1SKenneth D. Merry ocs_strncpy(node->current_state_name, "invalid", sizeof(node->current_state_name)); \ 63*ef270ab1SKenneth D. Merry } \ 64*ef270ab1SKenneth D. Merry node->prev_evt = node->current_evt; \ 65*ef270ab1SKenneth D. Merry node->current_evt = evt; 66*ef270ab1SKenneth D. Merry 67*ef270ab1SKenneth D. Merry #define OCS_NODEDB_PAUSE_FABRIC_LOGIN (1U << 0) 68*ef270ab1SKenneth D. Merry #define OCS_NODEDB_PAUSE_NAMESERVER (1U << 1) 69*ef270ab1SKenneth D. Merry #define OCS_NODEDB_PAUSE_NEW_NODES (1U << 2) 70*ef270ab1SKenneth D. Merry 71*ef270ab1SKenneth D. Merry /** 72*ef270ab1SKenneth D. Merry * @brief Node SM IO Context Callback structure 73*ef270ab1SKenneth D. Merry * 74*ef270ab1SKenneth D. Merry * Structure used as callback argument 75*ef270ab1SKenneth D. Merry */ 76*ef270ab1SKenneth D. Merry 77*ef270ab1SKenneth D. Merry struct ocs_node_cb_s { 78*ef270ab1SKenneth D. Merry ocs_io_t *io; /**< SCSI IO for sending response */ 79*ef270ab1SKenneth D. Merry int32_t status; /**< completion status */ 80*ef270ab1SKenneth D. Merry int32_t ext_status; /**< extended completion status */ 81*ef270ab1SKenneth D. Merry ocs_hw_rq_buffer_t *header; /**< completion header buffer */ 82*ef270ab1SKenneth D. Merry ocs_hw_rq_buffer_t *payload; /**< completion payload buffers */ 83*ef270ab1SKenneth D. Merry ocs_io_t *els; /**< ELS IO object */ 84*ef270ab1SKenneth D. Merry }; 85*ef270ab1SKenneth D. Merry 86*ef270ab1SKenneth D. Merry /** 87*ef270ab1SKenneth D. Merry * @brief hold frames in pending frame list 88*ef270ab1SKenneth D. Merry * 89*ef270ab1SKenneth D. Merry * Unsolicited receive frames are held on the node pending frame list, rather than 90*ef270ab1SKenneth D. Merry * being processed. 91*ef270ab1SKenneth D. Merry * 92*ef270ab1SKenneth D. Merry * @param node pointer to node structure 93*ef270ab1SKenneth D. Merry * 94*ef270ab1SKenneth D. Merry * @return none 95*ef270ab1SKenneth D. Merry */ 96*ef270ab1SKenneth D. Merry 97*ef270ab1SKenneth D. Merry static inline void 98*ef270ab1SKenneth D. Merry ocs_node_hold_frames(ocs_node_t *node) 99*ef270ab1SKenneth D. Merry { 100*ef270ab1SKenneth D. Merry ocs_assert(node); 101*ef270ab1SKenneth D. Merry node->hold_frames = TRUE; 102*ef270ab1SKenneth D. Merry } 103*ef270ab1SKenneth D. Merry 104*ef270ab1SKenneth D. Merry /** 105*ef270ab1SKenneth D. Merry * @brief accept frames 106*ef270ab1SKenneth D. Merry * 107*ef270ab1SKenneth D. Merry * Unsolicited receive frames processed rather than being held on the node 108*ef270ab1SKenneth D. Merry * pending frame list. 109*ef270ab1SKenneth D. Merry * 110*ef270ab1SKenneth D. Merry * @param node pointer to node structure 111*ef270ab1SKenneth D. Merry * 112*ef270ab1SKenneth D. Merry * @return none 113*ef270ab1SKenneth D. Merry */ 114*ef270ab1SKenneth D. Merry 115*ef270ab1SKenneth D. Merry static inline void 116*ef270ab1SKenneth D. Merry ocs_node_accept_frames(ocs_node_t *node) 117*ef270ab1SKenneth D. Merry { 118*ef270ab1SKenneth D. Merry ocs_assert(node); 119*ef270ab1SKenneth D. Merry node->hold_frames = FALSE; 120*ef270ab1SKenneth D. Merry } 121*ef270ab1SKenneth D. Merry 122*ef270ab1SKenneth D. Merry extern int32_t ocs_node_create_pool(ocs_t *ocs, uint32_t node_count); 123*ef270ab1SKenneth D. Merry extern void ocs_node_free_pool(ocs_t *ocs); 124*ef270ab1SKenneth D. Merry extern ocs_node_t *ocs_node_get_instance(ocs_t *ocs, uint32_t index); 125*ef270ab1SKenneth D. Merry 126*ef270ab1SKenneth D. Merry static inline void 127*ef270ab1SKenneth D. Merry ocs_node_lock_init(ocs_node_t *node) 128*ef270ab1SKenneth D. Merry { 129*ef270ab1SKenneth D. Merry ocs_rlock_init(node->ocs, &node->lock, "node rlock"); 130*ef270ab1SKenneth D. Merry } 131*ef270ab1SKenneth D. Merry 132*ef270ab1SKenneth D. Merry static inline void 133*ef270ab1SKenneth D. Merry ocs_node_lock_free(ocs_node_t *node) 134*ef270ab1SKenneth D. Merry { 135*ef270ab1SKenneth D. Merry ocs_rlock_free(&node->lock); 136*ef270ab1SKenneth D. Merry } 137*ef270ab1SKenneth D. Merry 138*ef270ab1SKenneth D. Merry static inline int32_t 139*ef270ab1SKenneth D. Merry ocs_node_lock_try(ocs_node_t *node) 140*ef270ab1SKenneth D. Merry { 141*ef270ab1SKenneth D. Merry return ocs_rlock_try(&node->lock); 142*ef270ab1SKenneth D. Merry } 143*ef270ab1SKenneth D. Merry 144*ef270ab1SKenneth D. Merry static inline void 145*ef270ab1SKenneth D. Merry ocs_node_lock(ocs_node_t *node) 146*ef270ab1SKenneth D. Merry { 147*ef270ab1SKenneth D. Merry ocs_rlock_acquire(&node->lock); 148*ef270ab1SKenneth D. Merry } 149*ef270ab1SKenneth D. Merry static inline void 150*ef270ab1SKenneth D. Merry ocs_node_unlock(ocs_node_t *node) 151*ef270ab1SKenneth D. Merry { 152*ef270ab1SKenneth D. Merry ocs_rlock_release(&node->lock); 153*ef270ab1SKenneth D. Merry } 154*ef270ab1SKenneth D. Merry 155*ef270ab1SKenneth D. Merry /** 156*ef270ab1SKenneth D. Merry * @brief Node initiator/target enable defines 157*ef270ab1SKenneth D. Merry * 158*ef270ab1SKenneth D. Merry * All combinations of the SLI port (sport) initiator/target enable, and remote 159*ef270ab1SKenneth D. Merry * node initiator/target enable are enumerated. 160*ef270ab1SKenneth D. Merry * 161*ef270ab1SKenneth D. Merry */ 162*ef270ab1SKenneth D. Merry 163*ef270ab1SKenneth D. Merry typedef enum { 164*ef270ab1SKenneth D. Merry OCS_NODE_ENABLE_x_TO_x, 165*ef270ab1SKenneth D. Merry OCS_NODE_ENABLE_x_TO_T, 166*ef270ab1SKenneth D. Merry OCS_NODE_ENABLE_x_TO_I, 167*ef270ab1SKenneth D. Merry OCS_NODE_ENABLE_x_TO_IT, 168*ef270ab1SKenneth D. Merry OCS_NODE_ENABLE_T_TO_x, 169*ef270ab1SKenneth D. Merry OCS_NODE_ENABLE_T_TO_T, 170*ef270ab1SKenneth D. Merry OCS_NODE_ENABLE_T_TO_I, 171*ef270ab1SKenneth D. Merry OCS_NODE_ENABLE_T_TO_IT, 172*ef270ab1SKenneth D. Merry OCS_NODE_ENABLE_I_TO_x, 173*ef270ab1SKenneth D. Merry OCS_NODE_ENABLE_I_TO_T, 174*ef270ab1SKenneth D. Merry OCS_NODE_ENABLE_I_TO_I, 175*ef270ab1SKenneth D. Merry OCS_NODE_ENABLE_I_TO_IT, 176*ef270ab1SKenneth D. Merry OCS_NODE_ENABLE_IT_TO_x, 177*ef270ab1SKenneth D. Merry OCS_NODE_ENABLE_IT_TO_T, 178*ef270ab1SKenneth D. Merry OCS_NODE_ENABLE_IT_TO_I, 179*ef270ab1SKenneth D. Merry OCS_NODE_ENABLE_IT_TO_IT, 180*ef270ab1SKenneth D. Merry } ocs_node_enable_e; 181*ef270ab1SKenneth D. Merry 182*ef270ab1SKenneth D. Merry static inline ocs_node_enable_e ocs_node_get_enable(ocs_node_t *node) 183*ef270ab1SKenneth D. Merry { 184*ef270ab1SKenneth D. Merry uint32_t retval = 0; 185*ef270ab1SKenneth D. Merry 186*ef270ab1SKenneth D. Merry if (node->sport->enable_ini) retval |= (1U << 3); 187*ef270ab1SKenneth D. Merry if (node->sport->enable_tgt) retval |= (1U << 2); 188*ef270ab1SKenneth D. Merry if (node->init) retval |= (1U << 1); 189*ef270ab1SKenneth D. Merry if (node->targ) retval |= (1U << 0); 190*ef270ab1SKenneth D. Merry return (ocs_node_enable_e) retval; 191*ef270ab1SKenneth D. Merry } 192*ef270ab1SKenneth D. Merry 193*ef270ab1SKenneth D. Merry typedef void* (*ocs_node_common_func_t)(const char *funcname, ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg); 194*ef270ab1SKenneth D. Merry 195*ef270ab1SKenneth D. Merry extern int32_t node_check_els_req(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg, uint8_t cmd, ocs_node_common_func_t node_common_func, const char *funcname); 196*ef270ab1SKenneth D. Merry extern int32_t node_check_ns_req(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg, uint32_t cmd, ocs_node_common_func_t node_common_func, const char *funcname); 197*ef270ab1SKenneth D. Merry extern int32_t ocs_remote_node_cb(void *arg, ocs_hw_remote_node_event_e event, void *data); 198*ef270ab1SKenneth D. Merry extern int32_t ocs_node_attach(ocs_node_t *node); 199*ef270ab1SKenneth D. Merry extern ocs_node_t *ocs_node_find(ocs_sport_t *sport, uint32_t port_id); 200*ef270ab1SKenneth D. Merry extern ocs_node_t *ocs_node_find_wwpn(ocs_sport_t *sport, uint64_t wwpn); 201*ef270ab1SKenneth D. Merry extern void ocs_node_dump(ocs_t *ocs); 202*ef270ab1SKenneth D. Merry extern ocs_node_t *ocs_node_alloc(ocs_sport_t *sport, uint32_t port_id, uint8_t init, uint8_t targ); 203*ef270ab1SKenneth D. Merry extern int32_t ocs_node_free(ocs_node_t *node); 204*ef270ab1SKenneth D. Merry extern void ocs_node_force_free(ocs_node_t *node); 205*ef270ab1SKenneth D. Merry extern void ocs_node_fcid_display(uint32_t fc_id, char *buffer, uint32_t buffer_length); 206*ef270ab1SKenneth D. Merry extern void ocs_node_update_display_name(ocs_node_t *node); 207*ef270ab1SKenneth D. Merry 208*ef270ab1SKenneth D. Merry extern void *__ocs_node_shutdown(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg); 209*ef270ab1SKenneth D. Merry extern void * __ocs_node_wait_node_free(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg); 210*ef270ab1SKenneth D. Merry extern void *__ocs_node_wait_els_shutdown(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg); 211*ef270ab1SKenneth D. Merry extern void *__ocs_node_wait_ios_shutdown(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg); 212*ef270ab1SKenneth D. Merry extern void ocs_node_save_sparms(ocs_node_t *node, void *payload); 213*ef270ab1SKenneth D. Merry extern void ocs_node_post_event(ocs_node_t *node, ocs_sm_event_t evt, void *arg); 214*ef270ab1SKenneth D. Merry extern void ocs_node_transition(ocs_node_t *node, ocs_sm_function_t state, void *data); 215*ef270ab1SKenneth D. Merry extern void *__ocs_node_common(const char *funcname, ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg); 216*ef270ab1SKenneth D. Merry 217*ef270ab1SKenneth D. Merry 218*ef270ab1SKenneth D. Merry extern void ocs_node_initiate_cleanup(ocs_node_t *node); 219*ef270ab1SKenneth D. Merry extern int ocs_ddump_node(ocs_textbuf_t *textbuf, ocs_node_t *node); 220*ef270ab1SKenneth D. Merry 221*ef270ab1SKenneth D. Merry extern void ocs_node_build_eui_name(char *buffer, uint32_t buffer_len, uint64_t eui_name); 222*ef270ab1SKenneth D. Merry extern uint64_t ocs_node_get_wwpn(ocs_node_t *node); 223*ef270ab1SKenneth D. Merry extern uint64_t ocs_node_get_wwnn(ocs_node_t *node); 224*ef270ab1SKenneth D. Merry extern void ocs_node_abort_all_els(ocs_node_t *node); 225*ef270ab1SKenneth D. Merry 226*ef270ab1SKenneth D. Merry extern void ocs_node_pause(ocs_node_t *node, ocs_sm_function_t state); 227*ef270ab1SKenneth D. Merry extern int32_t ocs_node_resume(ocs_node_t *node); 228*ef270ab1SKenneth D. Merry extern void *__ocs_node_paused(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg); 229*ef270ab1SKenneth D. Merry 230*ef270ab1SKenneth D. Merry extern int ocs_node_active_ios_empty(ocs_node_t *node); 231*ef270ab1SKenneth D. Merry extern void ocs_node_send_ls_io_cleanup(ocs_node_t *node); 232*ef270ab1SKenneth D. Merry 233*ef270ab1SKenneth D. Merry extern int32_t ocs_node_recv_link_services_frame(ocs_node_t *node, ocs_hw_sequence_t *seq); 234*ef270ab1SKenneth D. Merry extern int32_t ocs_node_recv_abts_frame(ocs_node_t *node, ocs_hw_sequence_t *seq); 235*ef270ab1SKenneth D. Merry extern int32_t ocs_node_recv_els_frame(ocs_node_t *node, ocs_hw_sequence_t *seq); 236*ef270ab1SKenneth D. Merry extern int32_t ocs_node_recv_ct_frame(ocs_node_t *node, ocs_hw_sequence_t *seq); 237*ef270ab1SKenneth D. Merry extern int32_t ocs_node_recv_fcp_cmd(ocs_node_t *node, ocs_hw_sequence_t *seq); 238*ef270ab1SKenneth D. Merry extern int32_t ocs_node_recv_bls_no_sit(ocs_node_t *node, ocs_hw_sequence_t *seq); 239*ef270ab1SKenneth D. Merry 240*ef270ab1SKenneth D. Merry #endif 241