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 * OCS linux driver remote node callback declarations 37 */ 38 39 #if !defined(__OCS_NODE_H__) 40 #define __OCS_NODE_H__ 41 42 43 #define node_sm_trace() \ 44 do { \ 45 if (OCS_LOG_ENABLE_SM_TRACE(node->ocs)) \ 46 ocs_log_info(node->ocs, "[%s] %-20s\n", node->display_name, ocs_sm_event_name(evt)); \ 47 } while (0) 48 49 #define node_printf(node, fmt, ...) ocs_log_debug(node->ocs, "[%s] " fmt, node->display_name, ##__VA_ARGS__) 50 51 #define std_node_state_decl(...) \ 52 ocs_node_t *node = NULL; \ 53 ocs_t *ocs = NULL; \ 54 node = ctx->app; \ 55 ocs_assert(node, NULL); \ 56 ocs = node->ocs; \ 57 ocs_assert(ocs, NULL); \ 58 if (evt == OCS_EVT_ENTER) { \ 59 ocs_strncpy(node->current_state_name, __func__, sizeof(node->current_state_name)); \ 60 } else if (evt == OCS_EVT_EXIT) { \ 61 ocs_strncpy(node->prev_state_name, node->current_state_name, sizeof(node->prev_state_name)); \ 62 ocs_strncpy(node->current_state_name, "invalid", sizeof(node->current_state_name)); \ 63 } \ 64 node->prev_evt = node->current_evt; \ 65 node->current_evt = evt; 66 67 #define OCS_NODEDB_PAUSE_FABRIC_LOGIN (1U << 0) 68 #define OCS_NODEDB_PAUSE_NAMESERVER (1U << 1) 69 #define OCS_NODEDB_PAUSE_NEW_NODES (1U << 2) 70 71 /** 72 * @brief Node SM IO Context Callback structure 73 * 74 * Structure used as callback argument 75 */ 76 77 struct ocs_node_cb_s { 78 ocs_io_t *io; /**< SCSI IO for sending response */ 79 int32_t status; /**< completion status */ 80 int32_t ext_status; /**< extended completion status */ 81 ocs_hw_rq_buffer_t *header; /**< completion header buffer */ 82 ocs_hw_rq_buffer_t *payload; /**< completion payload buffers */ 83 ocs_io_t *els; /**< ELS IO object */ 84 }; 85 86 /** 87 * @brief hold frames in pending frame list 88 * 89 * Unsolicited receive frames are held on the node pending frame list, rather than 90 * being processed. 91 * 92 * @param node pointer to node structure 93 * 94 * @return none 95 */ 96 97 static inline void 98 ocs_node_hold_frames(ocs_node_t *node) 99 { 100 ocs_assert(node); 101 node->hold_frames = TRUE; 102 } 103 104 /** 105 * @brief accept frames 106 * 107 * Unsolicited receive frames processed rather than being held on the node 108 * pending frame list. 109 * 110 * @param node pointer to node structure 111 * 112 * @return none 113 */ 114 115 static inline void 116 ocs_node_accept_frames(ocs_node_t *node) 117 { 118 ocs_assert(node); 119 node->hold_frames = FALSE; 120 } 121 122 extern int32_t ocs_node_create_pool(ocs_t *ocs, uint32_t node_count); 123 extern void ocs_node_free_pool(ocs_t *ocs); 124 extern ocs_node_t *ocs_node_get_instance(ocs_t *ocs, uint32_t index); 125 126 static inline void 127 ocs_node_lock_init(ocs_node_t *node) 128 { 129 ocs_rlock_init(node->ocs, &node->lock, "node rlock"); 130 } 131 132 static inline void 133 ocs_node_lock_free(ocs_node_t *node) 134 { 135 ocs_rlock_free(&node->lock); 136 } 137 138 static inline int32_t 139 ocs_node_lock_try(ocs_node_t *node) 140 { 141 return ocs_rlock_try(&node->lock); 142 } 143 144 static inline void 145 ocs_node_lock(ocs_node_t *node) 146 { 147 ocs_rlock_acquire(&node->lock); 148 } 149 static inline void 150 ocs_node_unlock(ocs_node_t *node) 151 { 152 ocs_rlock_release(&node->lock); 153 } 154 155 /** 156 * @brief Node initiator/target enable defines 157 * 158 * All combinations of the SLI port (sport) initiator/target enable, and remote 159 * node initiator/target enable are enumerated. 160 * 161 */ 162 163 typedef enum { 164 OCS_NODE_ENABLE_x_TO_x, 165 OCS_NODE_ENABLE_x_TO_T, 166 OCS_NODE_ENABLE_x_TO_I, 167 OCS_NODE_ENABLE_x_TO_IT, 168 OCS_NODE_ENABLE_T_TO_x, 169 OCS_NODE_ENABLE_T_TO_T, 170 OCS_NODE_ENABLE_T_TO_I, 171 OCS_NODE_ENABLE_T_TO_IT, 172 OCS_NODE_ENABLE_I_TO_x, 173 OCS_NODE_ENABLE_I_TO_T, 174 OCS_NODE_ENABLE_I_TO_I, 175 OCS_NODE_ENABLE_I_TO_IT, 176 OCS_NODE_ENABLE_IT_TO_x, 177 OCS_NODE_ENABLE_IT_TO_T, 178 OCS_NODE_ENABLE_IT_TO_I, 179 OCS_NODE_ENABLE_IT_TO_IT, 180 } ocs_node_enable_e; 181 182 static inline ocs_node_enable_e ocs_node_get_enable(ocs_node_t *node) 183 { 184 uint32_t retval = 0; 185 186 if (node->sport->enable_ini) retval |= (1U << 3); 187 if (node->sport->enable_tgt) retval |= (1U << 2); 188 if (node->init) retval |= (1U << 1); 189 if (node->targ) retval |= (1U << 0); 190 return (ocs_node_enable_e) retval; 191 } 192 193 typedef void* (*ocs_node_common_func_t)(const char *funcname, ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg); 194 195 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 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 extern int32_t ocs_remote_node_cb(void *arg, ocs_hw_remote_node_event_e event, void *data); 198 extern int32_t ocs_node_attach(ocs_node_t *node); 199 extern ocs_node_t *ocs_node_find(ocs_sport_t *sport, uint32_t port_id); 200 extern ocs_node_t *ocs_node_find_wwpn(ocs_sport_t *sport, uint64_t wwpn); 201 extern void ocs_node_dump(ocs_t *ocs); 202 extern ocs_node_t *ocs_node_alloc(ocs_sport_t *sport, uint32_t port_id, uint8_t init, uint8_t targ); 203 extern int32_t ocs_node_free(ocs_node_t *node); 204 extern void ocs_node_force_free(ocs_node_t *node); 205 extern void ocs_node_fcid_display(uint32_t fc_id, char *buffer, uint32_t buffer_length); 206 extern void ocs_node_update_display_name(ocs_node_t *node); 207 208 extern void *__ocs_node_shutdown(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg); 209 extern void * __ocs_node_wait_node_free(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg); 210 extern void *__ocs_node_wait_els_shutdown(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg); 211 extern void *__ocs_node_wait_ios_shutdown(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg); 212 extern void ocs_node_save_sparms(ocs_node_t *node, void *payload); 213 extern void ocs_node_post_event(ocs_node_t *node, ocs_sm_event_t evt, void *arg); 214 extern void ocs_node_transition(ocs_node_t *node, ocs_sm_function_t state, void *data); 215 extern void *__ocs_node_common(const char *funcname, ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg); 216 217 218 extern void ocs_node_initiate_cleanup(ocs_node_t *node); 219 extern int ocs_ddump_node(ocs_textbuf_t *textbuf, ocs_node_t *node); 220 221 extern void ocs_node_build_eui_name(char *buffer, uint32_t buffer_len, uint64_t eui_name); 222 extern uint64_t ocs_node_get_wwpn(ocs_node_t *node); 223 extern uint64_t ocs_node_get_wwnn(ocs_node_t *node); 224 extern void ocs_node_abort_all_els(ocs_node_t *node); 225 226 extern void ocs_node_pause(ocs_node_t *node, ocs_sm_function_t state); 227 extern int32_t ocs_node_resume(ocs_node_t *node); 228 extern void *__ocs_node_paused(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg); 229 230 extern int ocs_node_active_ios_empty(ocs_node_t *node); 231 extern void ocs_node_send_ls_io_cleanup(ocs_node_t *node); 232 233 extern int32_t ocs_node_recv_link_services_frame(ocs_node_t *node, ocs_hw_sequence_t *seq); 234 extern int32_t ocs_node_recv_abts_frame(ocs_node_t *node, ocs_hw_sequence_t *seq); 235 extern int32_t ocs_node_recv_els_frame(ocs_node_t *node, ocs_hw_sequence_t *seq); 236 extern int32_t ocs_node_recv_ct_frame(ocs_node_t *node, ocs_hw_sequence_t *seq); 237 extern int32_t ocs_node_recv_fcp_cmd(ocs_node_t *node, ocs_hw_sequence_t *seq); 238 extern int32_t ocs_node_recv_bls_no_sit(ocs_node_t *node, ocs_hw_sequence_t *seq); 239 240 #endif 241