1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. 23 * Copyright 2013, 2015 Nexenta Systems, Inc. All rights reserved. 24 */ 25 #ifndef _PPPT_H 26 #define _PPPT_H 27 28 #include <sys/pppt_ic_if.h> 29 30 #ifdef __cplusplus 31 extern "C" { 32 #endif 33 34 #define PPPT_GLOBAL_LOCK() mutex_enter(&pppt_global.global_lock) 35 #define PPPT_GLOBAL_UNLOCK() mutex_exit(&pppt_global.global_lock) 36 37 extern int pppt_logging; 38 39 #define PPPT_LOG if (pppt_logging) cmn_err 40 41 #define TGT_DEREG_RETRY_SECONDS 1 42 43 typedef enum { 44 PPPT_STATUS_SUCCESS = 0, 45 PPPT_STATUS_FAIL, 46 PPPT_STATUS_ABORTED, 47 PPPT_STATUS_DONE 48 } pppt_status_t; 49 50 #define PPPT_MODNAME "pppt" 51 52 #define TGT_STATE_LIST() \ 53 item(TS_UNDEFINED) \ 54 item(TS_CREATED) \ 55 item(TS_ONLINING) \ 56 item(TS_ONLINE) \ 57 item(TS_STMF_ONLINE) \ 58 item(TS_DELETING_NEED_OFFLINE) \ 59 item(TS_OFFLINING) \ 60 item(TS_OFFLINE) \ 61 item(TS_STMF_OFFLINE) \ 62 item(TS_DELETING_STMF_DEREG) \ 63 item(TS_DELETING_STMF_DEREG_FAIL) \ 64 item(TS_DELETING) \ 65 item(TS_MAX_STATE) 66 67 /* Target states and events, update pppt_ts_name table whenever modified */ 68 typedef enum { 69 #define item(a) a, 70 TGT_STATE_LIST() 71 #undef item 72 } pppt_tgt_state_t; 73 74 #ifdef PPPT_TGT_SM_STRINGS 75 static const char *pppt_ts_name[TS_MAX_STATE + 1] = { 76 #define item(a) #a, 77 TGT_STATE_LIST() 78 #undef item 79 }; 80 #endif 81 82 #define TGT_EVENT_LIST() \ 83 item(TE_UNDEFINED) \ 84 item(TE_STMF_ONLINE_REQ) \ 85 item(TE_ONLINE_SUCCESS) \ 86 item(TE_ONLINE_FAIL) \ 87 item(TE_STMF_ONLINE_COMPLETE_ACK) \ 88 item(TE_STMF_OFFLINE_REQ) \ 89 item(TE_OFFLINE_COMPLETE) \ 90 item(TE_STMF_OFFLINE_COMPLETE_ACK) \ 91 item(TE_DELETE) \ 92 item(TE_STMF_DEREG_SUCCESS) \ 93 item(TE_STMF_DEREG_FAIL) \ 94 item(TE_STMF_DEREG_RETRY) \ 95 item(TE_WAIT_REF_COMPLETE) /* XXX */ \ 96 item(TE_MAX_EVENT) 97 98 typedef enum { 99 #define item(a) a, 100 TGT_EVENT_LIST() 101 #undef item 102 } pppt_tgt_event_t; 103 104 #ifdef PPPT_TGT_SM_STRINGS 105 static const char *pppt_te_name[TE_MAX_EVENT + 1] = { 106 #define item(a) #a, 107 TGT_EVENT_LIST() 108 #undef item 109 }; 110 #endif 111 112 typedef struct pppt_tgt_s { 113 kmutex_t target_mutex; 114 kcondvar_t target_cv; 115 avl_node_t target_global_ln; 116 scsi_devid_desc_t *target_devid; 117 stmf_local_port_t *target_stmf_lport; 118 avl_tree_t target_sess_list; 119 120 /* Target state */ 121 boolean_t target_sm_busy; 122 boolean_t target_deleting; 123 pppt_tgt_state_t target_state; 124 pppt_tgt_state_t target_last_state; 125 int target_refcount; 126 list_t target_events; 127 } pppt_tgt_t; 128 129 typedef struct { 130 struct pppt_tgt_s *ps_target; 131 uint64_t ps_session_id; 132 int ps_refcnt; 133 kmutex_t ps_mutex; 134 kcondvar_t ps_cv; 135 boolean_t ps_closed; 136 avl_node_t ps_global_ln; 137 avl_node_t ps_target_ln; 138 avl_tree_t ps_task_list; 139 stmf_scsi_session_t *ps_stmf_sess; 140 } pppt_sess_t; 141 142 typedef struct { 143 stmf_data_buf_t *pbuf_stmf_buf; 144 boolean_t pbuf_is_immed; 145 stmf_ic_msg_t *pbuf_immed_msg; 146 } pppt_buf_t; 147 148 typedef enum { 149 PTS_INIT = 0, 150 PTS_ACTIVE, 151 PTS_DONE, 152 PTS_SENT_STATUS, 153 PTS_ABORTED 154 } pppt_task_state_t; 155 156 typedef struct { 157 pppt_sess_t *pt_sess; 158 avl_node_t pt_sess_ln; 159 int pt_refcnt; 160 kmutex_t pt_mutex; 161 stmf_ic_msgid_t pt_task_id; 162 uint8_t pt_lun_id[16]; 163 pppt_task_state_t pt_state; 164 scsi_task_t *pt_stmf_task; 165 pppt_buf_t *pt_immed_data; 166 pppt_buf_t *pt_read_buf; 167 stmf_ic_msgid_t pt_read_xfer_msgid; 168 } pppt_task_t; 169 170 /* 171 * Error statistics 172 */ 173 typedef struct { 174 uint64_t es_tgt_reg_svc_disabled; 175 uint64_t es_tgt_reg_duplicate; 176 uint64_t es_tgt_reg_create_fail; 177 uint64_t es_tgt_dereg_svc_disabled; 178 uint64_t es_tgt_dereg_not_found; 179 uint64_t es_sess_destroy_no_session; 180 uint64_t es_sess_lookup_no_session; 181 uint64_t es_sess_lookup_ident_mismatch; 182 uint64_t es_sess_lookup_bad_tgt_state; 183 uint64_t es_scmd_ptask_alloc_fail; 184 uint64_t es_scmd_sess_create_fail; 185 uint64_t es_scmd_stask_alloc_fail; 186 uint64_t es_scmd_dup_task_count; 187 } pppt_error_stats_t; 188 189 #define PPPT_INC_STAT(stat_field) \ 190 atomic_inc_64(&pppt_global.global_error_stats.stat_field); 191 192 /* 193 * State values for the iscsit service 194 */ 195 typedef enum { 196 PSS_UNDEFINED = 0, 197 PSS_DETACHED, 198 PSS_DISABLED, 199 PSS_ENABLING, 200 PSS_ENABLED, 201 PSS_BUSY, 202 PSS_DISABLING 203 } pppt_service_state_t; 204 205 206 typedef struct { 207 pppt_service_state_t global_svc_state; 208 dev_info_t *global_dip; 209 stmf_port_provider_t *global_pp; 210 stmf_dbuf_store_t *global_dbuf_store; 211 taskq_t *global_dispatch_taskq; 212 taskq_t *global_sess_taskq; 213 avl_tree_t global_sess_list; 214 avl_tree_t global_target_list; 215 kmutex_t global_lock; 216 door_handle_t global_door; 217 kmutex_t global_door_lock; 218 pppt_error_stats_t global_error_stats; 219 } pppt_global_t; 220 221 extern pppt_global_t pppt_global; 222 223 stmf_status_t pppt_lport_xfer_data(scsi_task_t *task, stmf_data_buf_t *dbuf, 224 uint32_t ioflags); 225 226 void pppt_xfer_read_complete(pppt_task_t *pppt_task, stmf_status_t status); 227 228 stmf_status_t pppt_lport_send_status(scsi_task_t *task, uint32_t ioflags); 229 230 void pppt_lport_task_free(scsi_task_t *task); 231 232 stmf_status_t pppt_lport_abort(stmf_local_port_t *lport, int abort_cmd, 233 void *arg, uint32_t flags); 234 235 void pppt_lport_ctl(stmf_local_port_t *lport, int cmd, void *arg); 236 237 pppt_sess_t *pppt_sess_lookup_locked(uint64_t session_id, 238 scsi_devid_desc_t *lport_devid, 239 stmf_remote_port_t *rport); 240 241 pppt_sess_t *pppt_sess_lookup_by_id_locked(uint64_t session_id); 242 243 pppt_sess_t *pppt_sess_lookup_create(scsi_devid_desc_t *lport_devid, 244 scsi_devid_desc_t *rport_devid, stmf_remote_port_t *rport, 245 uint64_t session_id, stmf_status_t *statusp); 246 247 void pppt_sess_rele(pppt_sess_t *sks); 248 249 void pppt_sess_rele_locked(pppt_sess_t *sks); 250 251 void pppt_sess_close_locked(pppt_sess_t *ps); 252 253 int pppt_sess_avl_compare_by_id(const void *void_sess1, 254 const void *void_sess2); 255 256 int pppt_sess_avl_compare_by_name(const void *void_sess1, 257 const void *void_sess2); 258 259 pppt_task_t *pppt_task_alloc(void); 260 261 void pppt_task_free(pppt_task_t *ptask); 262 263 pppt_status_t pppt_task_start(pppt_task_t *ptask); 264 265 pppt_status_t pppt_task_done(pppt_task_t *ptask); 266 267 pppt_task_t *pppt_task_lookup(stmf_ic_msgid_t msgid); 268 269 void pppt_msg_rx(stmf_ic_msg_t *msg); 270 271 void pppt_msg_tx_status(stmf_ic_msg_t *orig_msg, stmf_status_t status); 272 273 pppt_tgt_t *pppt_tgt_lookup(scsi_devid_desc_t *tgt_devid); 274 275 pppt_tgt_t *pppt_tgt_lookup_locked(scsi_devid_desc_t *tgt_devid); 276 277 pppt_tgt_t *pppt_tgt_create(stmf_ic_reg_port_msg_t *reg_port, 278 stmf_status_t *errcode); 279 280 void pppt_tgt_async_delete(pppt_tgt_t *tgt); 281 282 void pppt_tgt_destroy(pppt_tgt_t *tgt); 283 284 int pppt_tgt_avl_compare(const void *void_tgt1, const void *void_tgt2); 285 286 void pppt_tgt_sm_ctl(stmf_local_port_t *lport, int cmd, void *arg); 287 288 pppt_status_t pppt_task_hold(pppt_task_t *); 289 290 #ifdef __cplusplus 291 } 292 #endif 293 294 #endif /* _PPPT_H */ 295