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