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