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, 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 /* Target states and events, update pppt_ts_name table whenever modified */ 53 typedef enum { 54 TS_UNDEFINED = 0, 55 TS_CREATED, 56 TS_ONLINING, 57 TS_ONLINE, 58 TS_STMF_ONLINE, 59 TS_DELETING_NEED_OFFLINE, 60 TS_OFFLINING, 61 TS_OFFLINE, 62 TS_STMF_OFFLINE, 63 TS_DELETING_STMF_DEREG, 64 TS_DELETING_STMF_DEREG_FAIL, 65 TS_DELETING, 66 TS_MAX_STATE 67 } pppt_tgt_state_t; 68 69 #ifdef PPPT_TGT_SM_STRINGS 70 static const char *pppt_ts_name[TS_MAX_STATE+1] = { 71 "TS_UNDEFINED", 72 "TS_CREATED", 73 "TS_ONLINING", 74 "TS_ONLINE", 75 "TS_STMF_ONLINE", 76 "TS_DELETING_NEED_OFFLINE", 77 "TS_OFFLINING", 78 "TS_OFFLINE", 79 "TS_STMF_OFFLINE", 80 "TS_DELETING_STMF_DEREG", 81 "TS_DELETING_STMF_DEREG_FAIL", 82 "TS_DELETING", 83 "TS_MAX_STATE" 84 }; 85 #endif 86 87 typedef enum { 88 TE_UNDEFINED = 0, 89 TE_STMF_ONLINE_REQ, 90 TE_ONLINE_SUCCESS, 91 TE_ONLINE_FAIL, 92 TE_STMF_ONLINE_COMPLETE_ACK, 93 TE_STMF_OFFLINE_REQ, 94 TE_OFFLINE_COMPLETE, 95 TE_STMF_OFFLINE_COMPLETE_ACK, 96 TE_DELETE, 97 TE_STMF_DEREG_SUCCESS, 98 TE_STMF_DEREG_FAIL, 99 TE_STMF_DEREG_RETRY, 100 TE_WAIT_REF_COMPLETE, /* XXX */ 101 TE_MAX_EVENT 102 } pppt_tgt_event_t; 103 104 #ifdef PPPT_TGT_SM_STRINGS 105 static const char *pppt_te_name[TE_MAX_EVENT+1] = { 106 "TE_UNDEFINED", 107 "TE_STMF_ONLINE_REQ", 108 "TE_ONLINE_SUCCESS", 109 "TE_ONLINE_FAIL", 110 "TE_STMF_ONLINE_COMPLETE_ACK", 111 "TE_STMF_OFFLINE_REQ", 112 "TE_OFFLINE_COMPLETE", 113 "TE_STMF_OFFLINE_COMPLETE_ACK", 114 "TE_DELETE", 115 "TE_STMF_DEREG_SUCCESS", 116 "TE_STMF_DEREG_FAIL", 117 "TE_STMF_DEREG_RETRY", 118 "TE_WAIT_REF_COMPLETE", 119 "TE_MAX_EVENT" 120 }; 121 #endif 122 123 typedef struct pppt_tgt_s { 124 kmutex_t target_mutex; 125 kcondvar_t target_cv; 126 avl_node_t target_global_ln; 127 scsi_devid_desc_t *target_devid; 128 stmf_local_port_t *target_stmf_lport; 129 avl_tree_t target_sess_list; 130 131 /* Target state */ 132 boolean_t target_sm_busy; 133 boolean_t target_deleting; 134 pppt_tgt_state_t target_state; 135 pppt_tgt_state_t target_last_state; 136 int target_refcount; 137 list_t target_events; 138 } pppt_tgt_t; 139 140 typedef struct { 141 struct pppt_tgt_s *ps_target; 142 uint64_t ps_session_id; 143 int ps_refcnt; 144 kmutex_t ps_mutex; 145 kcondvar_t ps_cv; 146 boolean_t ps_closed; 147 avl_node_t ps_global_ln; 148 avl_node_t ps_target_ln; 149 avl_tree_t ps_task_list; 150 stmf_scsi_session_t *ps_stmf_sess; 151 } pppt_sess_t; 152 153 typedef struct { 154 stmf_data_buf_t *pbuf_stmf_buf; 155 boolean_t pbuf_is_immed; 156 stmf_ic_msg_t *pbuf_immed_msg; 157 } pppt_buf_t; 158 159 typedef enum { 160 PTS_INIT = 0, 161 PTS_ACTIVE, 162 PTS_DONE, 163 PTS_SENT_STATUS, 164 PTS_ABORTED 165 } pppt_task_state_t; 166 167 typedef struct { 168 pppt_sess_t *pt_sess; 169 avl_node_t pt_sess_ln; 170 int pt_refcnt; 171 kmutex_t pt_mutex; 172 stmf_ic_msgid_t pt_task_id; 173 uint8_t pt_lun_id[16]; 174 pppt_task_state_t pt_state; 175 scsi_task_t *pt_stmf_task; 176 pppt_buf_t *pt_immed_data; 177 pppt_buf_t *pt_read_buf; 178 stmf_ic_msgid_t pt_read_xfer_msgid; 179 } pppt_task_t; 180 181 /* 182 * Error statistics 183 */ 184 typedef struct { 185 uint64_t es_tgt_reg_svc_disabled; 186 uint64_t es_tgt_reg_duplicate; 187 uint64_t es_tgt_reg_create_fail; 188 uint64_t es_tgt_dereg_svc_disabled; 189 uint64_t es_tgt_dereg_not_found; 190 uint64_t es_sess_destroy_no_session; 191 uint64_t es_sess_lookup_no_session; 192 uint64_t es_sess_lookup_ident_mismatch; 193 uint64_t es_sess_lookup_bad_tgt_state; 194 uint64_t es_scmd_ptask_alloc_fail; 195 uint64_t es_scmd_sess_create_fail; 196 uint64_t es_scmd_stask_alloc_fail; 197 uint64_t es_scmd_dup_task_count; 198 } pppt_error_stats_t; 199 200 #define PPPT_INC_STAT(stat_field) \ 201 atomic_inc_64(&pppt_global.global_error_stats.stat_field); 202 203 /* 204 * State values for the iscsit service 205 */ 206 typedef enum { 207 PSS_UNDEFINED = 0, 208 PSS_DETACHED, 209 PSS_DISABLED, 210 PSS_ENABLING, 211 PSS_ENABLED, 212 PSS_BUSY, 213 PSS_DISABLING 214 } pppt_service_state_t; 215 216 217 typedef struct { 218 pppt_service_state_t global_svc_state; 219 dev_info_t *global_dip; 220 stmf_port_provider_t *global_pp; 221 stmf_dbuf_store_t *global_dbuf_store; 222 taskq_t *global_dispatch_taskq; 223 taskq_t *global_sess_taskq; 224 avl_tree_t global_sess_list; 225 avl_tree_t global_target_list; 226 kmutex_t global_lock; 227 door_handle_t global_door; 228 kmutex_t global_door_lock; 229 pppt_error_stats_t global_error_stats; 230 } pppt_global_t; 231 232 extern pppt_global_t pppt_global; 233 234 stmf_status_t pppt_lport_xfer_data(scsi_task_t *task, stmf_data_buf_t *dbuf, 235 uint32_t ioflags); 236 237 void pppt_xfer_read_complete(pppt_task_t *pppt_task, stmf_status_t status); 238 239 stmf_status_t pppt_lport_send_status(scsi_task_t *task, uint32_t ioflags); 240 241 void pppt_lport_task_free(scsi_task_t *task); 242 243 stmf_status_t pppt_lport_abort(stmf_local_port_t *lport, int abort_cmd, 244 void *arg, uint32_t flags); 245 246 void pppt_lport_ctl(stmf_local_port_t *lport, int cmd, void *arg); 247 248 pppt_sess_t *pppt_sess_lookup_locked(uint64_t session_id, 249 scsi_devid_desc_t *lport_devid, 250 stmf_remote_port_t *rport); 251 252 pppt_sess_t *pppt_sess_lookup_by_id_locked(uint64_t session_id); 253 254 pppt_sess_t *pppt_sess_lookup_create(scsi_devid_desc_t *lport_devid, 255 scsi_devid_desc_t *rport_devid, stmf_remote_port_t *rport, 256 uint64_t session_id, stmf_status_t *statusp); 257 258 void pppt_sess_rele(pppt_sess_t *sks); 259 260 void pppt_sess_rele_locked(pppt_sess_t *sks); 261 262 void pppt_sess_close_locked(pppt_sess_t *ps); 263 264 int pppt_sess_avl_compare_by_id(const void *void_sess1, 265 const void *void_sess2); 266 267 int pppt_sess_avl_compare_by_name(const void *void_sess1, 268 const void *void_sess2); 269 270 pppt_task_t *pppt_task_alloc(void); 271 272 void pppt_task_free(pppt_task_t *ptask); 273 274 pppt_status_t pppt_task_start(pppt_task_t *ptask); 275 276 pppt_status_t pppt_task_done(pppt_task_t *ptask); 277 278 pppt_task_t *pppt_task_lookup(stmf_ic_msgid_t msgid); 279 280 void pppt_msg_rx(stmf_ic_msg_t *msg); 281 282 void pppt_msg_tx_status(stmf_ic_msg_t *orig_msg, stmf_status_t status); 283 284 pppt_tgt_t *pppt_tgt_lookup(scsi_devid_desc_t *tgt_devid); 285 286 pppt_tgt_t *pppt_tgt_lookup_locked(scsi_devid_desc_t *tgt_devid); 287 288 pppt_tgt_t *pppt_tgt_create(stmf_ic_reg_port_msg_t *reg_port, 289 stmf_status_t *errcode); 290 291 void pppt_tgt_async_delete(pppt_tgt_t *tgt); 292 293 void pppt_tgt_destroy(pppt_tgt_t *tgt); 294 295 int pppt_tgt_avl_compare(const void *void_tgt1, const void *void_tgt2); 296 297 void pppt_tgt_sm_ctl(stmf_local_port_t *lport, int cmd, void *arg); 298 299 pppt_status_t pppt_task_hold(pppt_task_t *); 300 301 #ifdef __cplusplus 302 } 303 #endif 304 305 #endif /* _PPPT_H */ 306