1331766Sken/*- 2331766Sken * Copyright (c) 2017 Broadcom. All rights reserved. 3331766Sken * The term "Broadcom" refers to Broadcom Limited and/or its subsidiaries. 4331766Sken * 5331766Sken * Redistribution and use in source and binary forms, with or without 6331766Sken * modification, are permitted provided that the following conditions are met: 7331766Sken * 8331766Sken * 1. Redistributions of source code must retain the above copyright notice, 9331766Sken * this list of conditions and the following disclaimer. 10331766Sken * 11331766Sken * 2. Redistributions in binary form must reproduce the above copyright notice, 12331766Sken * this list of conditions and the following disclaimer in the documentation 13331766Sken * and/or other materials provided with the distribution. 14331766Sken * 15331766Sken * 3. Neither the name of the copyright holder nor the names of its contributors 16331766Sken * may be used to endorse or promote products derived from this software 17331766Sken * without specific prior written permission. 18331766Sken * 19331766Sken * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20331766Sken * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21331766Sken * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22331766Sken * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 23331766Sken * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24331766Sken * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25331766Sken * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26331766Sken * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27331766Sken * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28331766Sken * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29331766Sken * POSSIBILITY OF SUCH DAMAGE. 30331766Sken * 31331766Sken * $FreeBSD: stable/11/sys/dev/ocs_fc/ocs_node.h 331766 2018-03-30 15:28:25Z ken $ 32331766Sken */ 33331766Sken 34331766Sken/** 35331766Sken * @file 36331766Sken * OCS linux driver remote node callback declarations 37331766Sken */ 38331766Sken 39331766Sken#if !defined(__OCS_NODE_H__) 40331766Sken#define __OCS_NODE_H__ 41331766Sken 42331766Sken 43331766Sken#define node_sm_trace() \ 44331766Sken do { \ 45331766Sken if (OCS_LOG_ENABLE_SM_TRACE(node->ocs)) \ 46331766Sken ocs_log_info(node->ocs, "[%s] %-20s\n", node->display_name, ocs_sm_event_name(evt)); \ 47331766Sken } while (0) 48331766Sken 49331766Sken#define node_printf(node, fmt, ...) ocs_log_debug(node->ocs, "[%s] " fmt, node->display_name, ##__VA_ARGS__) 50331766Sken 51331766Sken#define std_node_state_decl(...) \ 52331766Sken ocs_node_t *node = NULL; \ 53331766Sken ocs_t *ocs = NULL; \ 54331766Sken node = ctx->app; \ 55331766Sken ocs_assert(node, NULL); \ 56331766Sken ocs = node->ocs; \ 57331766Sken ocs_assert(ocs, NULL); \ 58331766Sken if (evt == OCS_EVT_ENTER) { \ 59331766Sken ocs_strncpy(node->current_state_name, __func__, sizeof(node->current_state_name)); \ 60331766Sken } else if (evt == OCS_EVT_EXIT) { \ 61331766Sken ocs_strncpy(node->prev_state_name, node->current_state_name, sizeof(node->prev_state_name)); \ 62331766Sken ocs_strncpy(node->current_state_name, "invalid", sizeof(node->current_state_name)); \ 63331766Sken } \ 64331766Sken node->prev_evt = node->current_evt; \ 65331766Sken node->current_evt = evt; 66331766Sken 67331766Sken#define OCS_NODEDB_PAUSE_FABRIC_LOGIN (1U << 0) 68331766Sken#define OCS_NODEDB_PAUSE_NAMESERVER (1U << 1) 69331766Sken#define OCS_NODEDB_PAUSE_NEW_NODES (1U << 2) 70331766Sken 71331766Sken/** 72331766Sken * @brief Node SM IO Context Callback structure 73331766Sken * 74331766Sken * Structure used as callback argument 75331766Sken */ 76331766Sken 77331766Skenstruct ocs_node_cb_s { 78331766Sken ocs_io_t *io; /**< SCSI IO for sending response */ 79331766Sken int32_t status; /**< completion status */ 80331766Sken int32_t ext_status; /**< extended completion status */ 81331766Sken ocs_hw_rq_buffer_t *header; /**< completion header buffer */ 82331766Sken ocs_hw_rq_buffer_t *payload; /**< completion payload buffers */ 83331766Sken ocs_io_t *els; /**< ELS IO object */ 84331766Sken}; 85331766Sken 86331766Sken/** 87331766Sken * @brief hold frames in pending frame list 88331766Sken * 89331766Sken * Unsolicited receive frames are held on the node pending frame list, rather than 90331766Sken * being processed. 91331766Sken * 92331766Sken * @param node pointer to node structure 93331766Sken * 94331766Sken * @return none 95331766Sken */ 96331766Sken 97331766Skenstatic inline void 98331766Skenocs_node_hold_frames(ocs_node_t *node) 99331766Sken{ 100331766Sken ocs_assert(node); 101331766Sken node->hold_frames = TRUE; 102331766Sken} 103331766Sken 104331766Sken/** 105331766Sken * @brief accept frames 106331766Sken * 107331766Sken * Unsolicited receive frames processed rather than being held on the node 108331766Sken * pending frame list. 109331766Sken * 110331766Sken * @param node pointer to node structure 111331766Sken * 112331766Sken * @return none 113331766Sken */ 114331766Sken 115331766Skenstatic inline void 116331766Skenocs_node_accept_frames(ocs_node_t *node) 117331766Sken{ 118331766Sken ocs_assert(node); 119331766Sken node->hold_frames = FALSE; 120331766Sken} 121331766Sken 122331766Skenextern int32_t ocs_node_create_pool(ocs_t *ocs, uint32_t node_count); 123331766Skenextern void ocs_node_free_pool(ocs_t *ocs); 124331766Skenextern ocs_node_t *ocs_node_get_instance(ocs_t *ocs, uint32_t index); 125331766Sken 126331766Skenstatic inline void 127331766Skenocs_node_lock_init(ocs_node_t *node) 128331766Sken{ 129331766Sken ocs_rlock_init(node->ocs, &node->lock, "node rlock"); 130331766Sken} 131331766Sken 132331766Skenstatic inline void 133331766Skenocs_node_lock_free(ocs_node_t *node) 134331766Sken{ 135331766Sken ocs_rlock_free(&node->lock); 136331766Sken} 137331766Sken 138331766Skenstatic inline int32_t 139331766Skenocs_node_lock_try(ocs_node_t *node) 140331766Sken{ 141331766Sken return ocs_rlock_try(&node->lock); 142331766Sken} 143331766Sken 144331766Skenstatic inline void 145331766Skenocs_node_lock(ocs_node_t *node) 146331766Sken{ 147331766Sken ocs_rlock_acquire(&node->lock); 148331766Sken} 149331766Skenstatic inline void 150331766Skenocs_node_unlock(ocs_node_t *node) 151331766Sken{ 152331766Sken ocs_rlock_release(&node->lock); 153331766Sken} 154331766Sken 155331766Sken/** 156331766Sken * @brief Node initiator/target enable defines 157331766Sken * 158331766Sken * All combinations of the SLI port (sport) initiator/target enable, and remote 159331766Sken * node initiator/target enable are enumerated. 160331766Sken * 161331766Sken */ 162331766Sken 163331766Skentypedef enum { 164331766Sken OCS_NODE_ENABLE_x_TO_x, 165331766Sken OCS_NODE_ENABLE_x_TO_T, 166331766Sken OCS_NODE_ENABLE_x_TO_I, 167331766Sken OCS_NODE_ENABLE_x_TO_IT, 168331766Sken OCS_NODE_ENABLE_T_TO_x, 169331766Sken OCS_NODE_ENABLE_T_TO_T, 170331766Sken OCS_NODE_ENABLE_T_TO_I, 171331766Sken OCS_NODE_ENABLE_T_TO_IT, 172331766Sken OCS_NODE_ENABLE_I_TO_x, 173331766Sken OCS_NODE_ENABLE_I_TO_T, 174331766Sken OCS_NODE_ENABLE_I_TO_I, 175331766Sken OCS_NODE_ENABLE_I_TO_IT, 176331766Sken OCS_NODE_ENABLE_IT_TO_x, 177331766Sken OCS_NODE_ENABLE_IT_TO_T, 178331766Sken OCS_NODE_ENABLE_IT_TO_I, 179331766Sken OCS_NODE_ENABLE_IT_TO_IT, 180331766Sken} ocs_node_enable_e; 181331766Sken 182331766Skenstatic inline ocs_node_enable_e ocs_node_get_enable(ocs_node_t *node) 183331766Sken{ 184331766Sken uint32_t retval = 0; 185331766Sken 186331766Sken if (node->sport->enable_ini) retval |= (1U << 3); 187331766Sken if (node->sport->enable_tgt) retval |= (1U << 2); 188331766Sken if (node->init) retval |= (1U << 1); 189331766Sken if (node->targ) retval |= (1U << 0); 190331766Sken return (ocs_node_enable_e) retval; 191331766Sken} 192331766Sken 193331766Skentypedef void* (*ocs_node_common_func_t)(const char *funcname, ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg); 194331766Sken 195331766Skenextern 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); 196331766Skenextern 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); 197331766Skenextern int32_t ocs_remote_node_cb(void *arg, ocs_hw_remote_node_event_e event, void *data); 198331766Skenextern int32_t ocs_node_attach(ocs_node_t *node); 199331766Skenextern ocs_node_t *ocs_node_find(ocs_sport_t *sport, uint32_t port_id); 200331766Skenextern ocs_node_t *ocs_node_find_wwpn(ocs_sport_t *sport, uint64_t wwpn); 201331766Skenextern void ocs_node_dump(ocs_t *ocs); 202331766Skenextern ocs_node_t *ocs_node_alloc(ocs_sport_t *sport, uint32_t port_id, uint8_t init, uint8_t targ); 203331766Skenextern int32_t ocs_node_free(ocs_node_t *node); 204331766Skenextern void ocs_node_force_free(ocs_node_t *node); 205331766Skenextern void ocs_node_fcid_display(uint32_t fc_id, char *buffer, uint32_t buffer_length); 206331766Skenextern void ocs_node_update_display_name(ocs_node_t *node); 207331766Sken 208331766Skenextern void *__ocs_node_shutdown(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg); 209331766Skenextern void * __ocs_node_wait_node_free(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg); 210331766Skenextern void *__ocs_node_wait_els_shutdown(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg); 211331766Skenextern void *__ocs_node_wait_ios_shutdown(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg); 212331766Skenextern void ocs_node_save_sparms(ocs_node_t *node, void *payload); 213331766Skenextern void ocs_node_post_event(ocs_node_t *node, ocs_sm_event_t evt, void *arg); 214331766Skenextern void ocs_node_transition(ocs_node_t *node, ocs_sm_function_t state, void *data); 215331766Skenextern void *__ocs_node_common(const char *funcname, ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg); 216331766Sken 217331766Sken 218331766Skenextern void ocs_node_initiate_cleanup(ocs_node_t *node); 219331766Skenextern int ocs_ddump_node(ocs_textbuf_t *textbuf, ocs_node_t *node); 220331766Sken 221331766Skenextern void ocs_node_build_eui_name(char *buffer, uint32_t buffer_len, uint64_t eui_name); 222331766Skenextern uint64_t ocs_node_get_wwpn(ocs_node_t *node); 223331766Skenextern uint64_t ocs_node_get_wwnn(ocs_node_t *node); 224331766Skenextern void ocs_node_abort_all_els(ocs_node_t *node); 225331766Sken 226331766Skenextern void ocs_node_pause(ocs_node_t *node, ocs_sm_function_t state); 227331766Skenextern int32_t ocs_node_resume(ocs_node_t *node); 228331766Skenextern void *__ocs_node_paused(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg); 229331766Sken 230331766Skenextern int ocs_node_active_ios_empty(ocs_node_t *node); 231331766Skenextern void ocs_node_send_ls_io_cleanup(ocs_node_t *node); 232331766Sken 233331766Skenextern int32_t ocs_node_recv_link_services_frame(ocs_node_t *node, ocs_hw_sequence_t *seq); 234331766Skenextern int32_t ocs_node_recv_abts_frame(ocs_node_t *node, ocs_hw_sequence_t *seq); 235331766Skenextern int32_t ocs_node_recv_els_frame(ocs_node_t *node, ocs_hw_sequence_t *seq); 236331766Skenextern int32_t ocs_node_recv_ct_frame(ocs_node_t *node, ocs_hw_sequence_t *seq); 237331766Skenextern int32_t ocs_node_recv_fcp_cmd(ocs_node_t *node, ocs_hw_sequence_t *seq); 238331766Skenextern int32_t ocs_node_recv_bls_no_sit(ocs_node_t *node, ocs_hw_sequence_t *seq); 239331766Sken 240331766Sken#endif 241