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 */