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) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright 2016 Nexenta Systems, Inc. All rights reserved.
  25  * Copyright (c) 2013 by Delphix. All rights reserved.
  26  */
  27 
  28 #ifndef _STMF_H
  29 #define _STMF_H
  30 
  31 #include <sys/stmf_defines.h>
  32 
  33 #ifdef  __cplusplus
  34 extern "C" {
  35 #endif
  36 
  37 typedef enum stmf_struct_id {
  38         STMF_STRUCT_LU_PROVIDER = 1,
  39         STMF_STRUCT_PORT_PROVIDER,
  40         STMF_STRUCT_STMF_LOCAL_PORT,
  41         STMF_STRUCT_STMF_LU,
  42         STMF_STRUCT_SCSI_SESSION,
  43         STMF_STRUCT_SCSI_TASK,
  44         STMF_STRUCT_DATA_BUF,
  45         STMF_STRUCT_DBUF_STORE,
  46         STMF_MAX_STRUCT_IDS
  47 } stmf_struct_id_t;
  48 
  49 /*
  50  * Provider callback commands
  51  */
  52 #define STMF_PROVIDER_DATA_UPDATED      0x01
  53 
  54 /*
  55  * Provider callback flags
  56  */
  57 #define STMF_PCB_STMF_ONLINING          0x0001
  58 #define STMF_PCB_PREG_COMPLETE          0x0002
  59 
  60 typedef void *data_seg_handle_t;
  61 #define STMF_MAX_LU_CACHE_NTASKS 16
  62 
  63 #define STMF_NO_HANDLE  0xffffffff
  64 
  65 #define COMPANY_ID_NONE                 0xFFFFFFFF
  66 #define COMPANY_ID_SUN                  0x00144F
  67 
  68 /*
  69  * The scatter/gather list buffer format is used in 2 different
  70  * contexts within stmf:
  71  * 1) supplied by the port provider that the LU provider uses to exchange
  72  *    data with the backing store.
  73  * 2) supplied by the LU provider that the port provider uses exchange
  74  *    data with the host initiator.
  75  * The second format is optionally supported by the port provided as
  76  * indicated by the command task flags.
  77  */
  78 
  79 typedef struct stmf_sglist_ent {
  80         uint32_t        seg_length;
  81         uint8_t         *seg_addr;
  82 } stmf_sglist_ent_t;
  83 
  84 typedef struct stmf_data_buf {
  85         void            *db_stmf_private;
  86         void            *db_port_private;
  87         void            *db_lu_private;
  88         uint32_t        db_buf_size;    /* Total size of this buffer */
  89         uint32_t        db_data_size;   /* Intended xfer size of this buffer */
  90         uint32_t        db_relative_offset;
  91         uint16_t        db_sglist_length;
  92         uint16_t        db_flags;       /* Direction, auto status etc */
  93         stmf_status_t   db_xfer_status;
  94         uint8_t         db_handle;      /* To track parallel buffers */
  95         hrtime_t        db_xfer_start_timestamp;
  96         stmf_sglist_ent_t db_sglist[1]; /* PP scatter/gather list */
  97 } stmf_data_buf_t;
  98 
  99 /*
 100  * db_flags
 101  */
 102 #define DB_DIRECTION_TO_RPORT           0x0001
 103 #define DB_DIRECTION_FROM_RPORT         0x0002
 104 #define DB_SEND_STATUS_GOOD             0x0004
 105 #define DB_STATUS_GOOD_SENT             0x0008
 106 #define DB_DONT_CACHE                   0x0010
 107 #define DB_DONT_REUSE                   0x0020
 108 #define DB_LU_DATA_BUF                  0x0040
 109 #define DB_LPORT_XFER_ACTIVE            0x8000
 110 
 111 typedef struct scsi_task {
 112         void            *task_stmf_private;
 113         void            *task_port_private;
 114 
 115         void            *task_lu_private;
 116         struct stmf_scsi_session *task_session;
 117         struct stmf_local_port *task_lport;
 118         struct stmf_lu  *task_lu;
 119         void            *task_lu_itl_handle;    /* Assigned by LU */
 120 
 121         /* CMD information from initiator */
 122         uint8_t         task_lun_no[8];
 123         uint8_t         task_flags;             /* See def. for task flags */
 124         uint8_t         task_priority;          /* As per SAM-3 */
 125         uint8_t         task_mgmt_function;     /* If this is a TM request */
 126         uint8_t         task_max_nbufs;
 127         uint8_t         task_cur_nbufs;
 128         uint8_t         task_csn_size;          /* cmd seq no size in bits */
 129         uint16_t        task_additional_flags;
 130         uint32_t        task_cmd_seq_no;
 131         uint32_t        task_expected_xfer_length;
 132         uint32_t        task_timeout;           /* In seconds */
 133         uint16_t        task_ext_id;
 134         uint16_t        task_cdb_length;
 135         uint8_t         *task_cdb;
 136 
 137         /* Fields to manage data phase */
 138         uint32_t        task_cmd_xfer_length;   /* xfer len based on CDB */
 139         uint32_t        task_nbytes_transferred;
 140         uint32_t        task_max_xfer_len;      /* largest xfer allowed */
 141         uint32_t        task_1st_xfer_len;      /* 1st xfer hint */
 142         uint32_t        task_copy_threshold;    /* copy reduction threshold */
 143 
 144 
 145         /* Status Phase */
 146         stmf_status_t   task_completion_status;
 147         uint32_t        task_resid;
 148         uint8_t         task_status_ctrl;       /* See def. for status ctrl */
 149         uint8_t         task_scsi_status;
 150         uint16_t        task_sense_length;
 151         uint8_t         *task_sense_data;
 152 
 153         /* Misc. task data */
 154         void            *task_extended_cmd;
 155 
 156 } scsi_task_t;
 157 
 158 /*
 159  * Maximum expected transfer length.   Can also be used when the transfer
 160  * length is unknown when the task is allocated (e.g. SAS)
 161  */
 162 
 163 #define TASK_MAX_XFER_LENGTH    0xFFFFFFFF
 164 
 165 /*
 166  * task_flags definitions.
 167  */
 168 /*
 169  * If TF_INITIAL_BURST is set, the dbuf passed with new_task() contains
 170  * data from initial burst. Otherwise its just a buffer which the port
 171  * passed to the LU.
 172  */
 173 #define TF_INITIAL_BURST        0x80
 174 /* Both READ_DATA and WRITE_DATA can be set for bidirectional xfers */
 175 #define TF_READ_DATA            0x40
 176 #define TF_WRITE_DATA           0x20
 177 #define TF_ATTR_MASK            0x07
 178 #define TF_ATTR_UNTAGGED        0x0
 179 #define TF_ATTR_SIMPLE_QUEUE    0x1
 180 #define TF_ATTR_ORDERED_QUEUE   0x2
 181 #define TF_ATTR_HEAD_OF_QUEUE   0x3
 182 #define TF_ATTR_ACA             0x4
 183 
 184 /*
 185  * Task Management flags.
 186  */
 187 #define TM_NONE                 0x00
 188 #define TM_ABORT_TASK           0x01
 189 #define TM_ABORT_TASK_SET       0x02
 190 #define TM_CLEAR_ACA            0x03
 191 #define TM_CLEAR_TASK_SET       0x04
 192 #define TM_LUN_RESET            0x05
 193 #define TM_TARGET_WARM_RESET    0x06
 194 #define TM_TARGET_COLD_RESET    0x07
 195 #define TM_TASK_REASSIGN        0x08
 196 #define TM_TARGET_RESET         0x09
 197 #define TM_QUERY_TASK           0x0A
 198 
 199 /*
 200  * additional flags
 201  */
 202 #define TASK_AF_ENABLE_COMP_CONF        0x01
 203 #define TASK_AF_PORT_LOAD_HIGH          0x02
 204 #define TASK_AF_NO_EXPECTED_XFER_LENGTH 0x04
 205 /*
 206  * PP sets this flag if it can process dbufs created by the LU.
 207  */
 208 #define TASK_AF_ACCEPT_LU_DBUF          0x08
 209 
 210 /*
 211  * Indicating a PPPT task
 212  */
 213 #define TASK_AF_PPPT_TASK               0x10
 214 
 215 /*
 216  * scsi_task_t extension identifiers
 217  */
 218 #define STMF_TASK_EXT_NONE              0
 219 
 220 /*
 221  * max_nbufs
 222  */
 223 #define STMF_BUFS_MAX           255
 224 
 225 /*
 226  * Task status ctrl
 227  */
 228 #define TASK_SCTRL_OVER         1
 229 #define TASK_SCTRL_UNDER        2
 230 
 231 /*
 232  * The flags used by I/O flow.
 233  */
 234 #define STMF_IOF_LU_DONE                0x0001
 235 #define STMF_IOF_LPORT_DONE             0x0002
 236 #define STMF_IOF_STATS_ONLY             0x0004
 237 
 238 /*
 239  * struct allocation flags
 240  */
 241 #define AF_FORCE_NOSLEEP        0x0001
 242 #define AF_DONTZERO             0x0002
 243 
 244 typedef struct stmf_state_change_info {
 245         uint64_t        st_rflags;      /* Reason behind this change */
 246         char            *st_additional_info;
 247 } stmf_state_change_info_t;
 248 
 249 typedef struct stmf_change_status {
 250         stmf_status_t   st_completion_status;
 251         char            *st_additional_info;
 252 } stmf_change_status_t;
 253 
 254 /*
 255  * conditions causing or affecting the change.
 256  */
 257 #define STMF_RFLAG_USER_REQUEST         0x0001
 258 #define STMF_RFLAG_FATAL_ERROR          0x0002
 259 #define STMF_RFLAG_STAY_OFFLINED        0x0004
 260 #define STMF_RFLAG_RESET                0x0008
 261 #define STMF_RFLAG_COLLECT_DEBUG_DUMP   0x0010
 262 #define STMF_RFLAG_LU_ABORT             0x0020
 263 #define STMF_RFLAG_LPORT_ABORT          0x0040
 264 
 265 #define STMF_CHANGE_INFO_LEN            160
 266 
 267 /*
 268  * cmds to stmf_abort entry point
 269  */
 270 #define STMF_QUEUE_TASK_ABORT           1
 271 #define STMF_REQUEUE_TASK_ABORT_LPORT   2
 272 #define STMF_REQUEUE_TASK_ABORT_LU      3
 273 #define STMF_QUEUE_ABORT_LU             4
 274 
 275 /*
 276  * cmds to be used by stmf ctl
 277  */
 278 #define STMF_CMD_LU_OP                  0x0100
 279 #define STMF_CMD_LPORT_OP               0x0200
 280 #define STMF_CMD_MASK                   0x00ff
 281 #define STMF_CMD_ONLINE                 0x0001
 282 #define STMF_CMD_OFFLINE                0x0002
 283 #define STMF_CMD_GET_STATUS             0x0003
 284 #define STMF_CMD_ONLINE_COMPLETE        0x0004
 285 #define STMF_CMD_OFFLINE_COMPLETE       0x0005
 286 #define STMF_ACK_ONLINE_COMPLETE        0x0006
 287 #define STMF_ACK_OFFLINE_COMPLETE       0x0007
 288 
 289 #define STMF_CMD_LU_ONLINE              (STMF_CMD_LU_OP | STMF_CMD_ONLINE)
 290 #define STMF_CMD_LU_OFFLINE             (STMF_CMD_LU_OP | STMF_CMD_OFFLINE)
 291 #define STMF_CMD_LPORT_ONLINE           (STMF_CMD_LPORT_OP | STMF_CMD_ONLINE)
 292 #define STMF_CMD_LPORT_OFFLINE          (STMF_CMD_LPORT_OP | STMF_CMD_OFFLINE)
 293 #define STMF_CMD_GET_LU_STATUS          (STMF_CMD_LU_OP | STMF_CMD_GET_STATUS)
 294 #define STMF_CMD_GET_LPORT_STATUS       \
 295                         (STMF_CMD_LPORT_OP | STMF_CMD_GET_STATUS)
 296 #define STMF_CMD_LU_ONLINE_COMPLETE     \
 297                         (STMF_CMD_LU_OP | STMF_CMD_ONLINE_COMPLETE)
 298 #define STMF_CMD_LPORT_ONLINE_COMPLETE  \
 299                         (STMF_CMD_LPORT_OP | STMF_CMD_ONLINE_COMPLETE)
 300 #define STMF_ACK_LU_ONLINE_COMPLETE     \
 301                         (STMF_CMD_LU_OP | STMF_ACK_ONLINE_COMPLETE)
 302 #define STMF_ACK_LPORT_ONLINE_COMPLETE  \
 303                         (STMF_CMD_LPORT_OP | STMF_ACK_ONLINE_COMPLETE)
 304 #define STMF_CMD_LU_OFFLINE_COMPLETE    \
 305                         (STMF_CMD_LU_OP | STMF_CMD_OFFLINE_COMPLETE)
 306 #define STMF_CMD_LPORT_OFFLINE_COMPLETE \
 307                         (STMF_CMD_LPORT_OP | STMF_CMD_OFFLINE_COMPLETE)
 308 #define STMF_ACK_LU_OFFLINE_COMPLETE    \
 309                         (STMF_CMD_LU_OP | STMF_ACK_OFFLINE_COMPLETE)
 310 #define STMF_ACK_LPORT_OFFLINE_COMPLETE \
 311                         (STMF_CMD_LPORT_OP | STMF_ACK_OFFLINE_COMPLETE)
 312 /*
 313  * For LPORTs and LUs to create their own ctl cmds which dont
 314  * conflict with stmf ctl cmds.
 315  */
 316 #define STMF_LPORT_CTL_CMDS             0x1000
 317 #define STMF_LU_CTL_CMDS                0x2000
 318 
 319 /*
 320  * Commands for various info routines.
 321  */
 322 /* Command classifiers */
 323 #define SI_LPORT                0x1000000
 324 #define SI_STMF                 0x2000000
 325 #define SI_LU                   0x4000000
 326 #define SI_LPORT_FC             0x0000000
 327 #define SI_LPORT_ISCSI          0x0010000
 328 #define SI_LPORT_SAS            0x0020000
 329 #define SI_STMF_LU              0x0010000
 330 #define SI_STMF_LPORT           0x0020000
 331 
 332 #define SI_GET_CLASS(v)         ((v) & 0xFF000000)
 333 #define SI_GET_SUBCLASS(v)      ((v) & 0x00FF0000)
 334 
 335 /* Commands for LPORT info routines */
 336 /* XXX - Implement these. */
 337 #if 0
 338 #define SI_LPORT_FC_PORTINFO            (SI_LPORT | SI_LPORT_FC | 1)
 339 #define SI_RPORT_FC_PORTINFO            (SI_LPORT | SI_LPORT_FC | 2)
 340 #endif
 341 
 342 /*
 343  * Events
 344  */
 345 #define STMF_EVENT_ALL                  ((int)-1)
 346 #define LPORT_EVENT_INITIAL_LUN_MAPPED  0
 347 
 348 /*
 349  * This needs to go into common/ddi/sunddi.h
 350  */
 351 #define DDI_NT_STMF             "ddi_scsi_target:framework"
 352 #define DDI_NT_STMF_LP          "ddi_scsi_target:lu_provider"
 353 #define DDI_NT_STMF_PP          "ddi_scsi_target:port_provider"
 354 
 355 /*
 356  * VPD page bits.
 357  */
 358 #define STMF_VPD_LU_ID          0x01
 359 #define STMF_VPD_TARGET_ID      0x02
 360 #define STMF_VPD_TP_GROUP       0x04
 361 #define STMF_VPD_RELATIVE_TP_ID 0x08
 362 
 363 /*
 364  * Common macros to simplify coding
 365  */
 366 #define STMF_SEC2TICK(x_sec)    (drv_usectohz((x_sec) * 1000000))
 367 
 368 void stmf_trace(caddr_t ident, const char *fmt, ...);
 369 void *stmf_alloc(stmf_struct_id_t sid, int additional_size, int alloc_flags);
 370 void stmf_free(void *struct_ptr);
 371 struct scsi_task *stmf_task_alloc(struct stmf_local_port *lport,
 372     struct stmf_scsi_session *ss, uint8_t *lun, uint16_t cdb_length,
 373     uint16_t ext_id);
 374 void stmf_post_task(scsi_task_t *task, stmf_data_buf_t *dbuf);
 375 stmf_data_buf_t *stmf_alloc_dbuf(scsi_task_t *task, uint32_t size,
 376     uint32_t *pminsize, uint32_t flags);
 377 void stmf_free_dbuf(scsi_task_t *task, stmf_data_buf_t *dbuf);
 378 stmf_status_t stmf_setup_dbuf(scsi_task_t *task, stmf_data_buf_t *dbuf,
 379     uint32_t flags);
 380 void stmf_teardown_dbuf(scsi_task_t *task, stmf_data_buf_t *dbuf);
 381 stmf_status_t stmf_xfer_data(scsi_task_t *task, stmf_data_buf_t *dbuf,
 382     uint32_t ioflags);
 383 stmf_status_t stmf_send_scsi_status(scsi_task_t *task, uint32_t ioflags);
 384 void stmf_data_xfer_done(scsi_task_t *task, stmf_data_buf_t *dbuf,
 385     uint32_t iof);
 386 void stmf_send_status_done(scsi_task_t *task, stmf_status_t s, uint32_t iof);
 387 void stmf_task_lu_done(scsi_task_t *task);
 388 void stmf_abort(int abort_cmd, scsi_task_t *task, stmf_status_t s, void *arg);
 389 void stmf_task_lu_aborted(scsi_task_t *task, stmf_status_t s, uint32_t iof);
 390 void stmf_task_lport_aborted_unlocked(scsi_task_t *task, stmf_status_t s,
 391     uint32_t iof);
 392 stmf_status_t stmf_task_poll_lu(scsi_task_t *task, uint32_t timeout);
 393 stmf_status_t stmf_task_poll_lport(scsi_task_t *task, uint32_t timeout);
 394 stmf_status_t stmf_ctl(int cmd, void *obj, void *arg);
 395 stmf_status_t stmf_register_itl_handle(struct stmf_lu *lu, uint8_t *lun,
 396     struct stmf_scsi_session *ss, uint64_t session_id, void *itl_handle);
 397 stmf_status_t stmf_deregister_all_lu_itl_handles(struct stmf_lu *lu);
 398 stmf_status_t stmf_get_itl_handle(struct stmf_lu *lu, uint8_t *lun,
 399     struct stmf_scsi_session *ss, uint64_t session_id, void **itl_handle_retp);
 400 stmf_data_buf_t *stmf_handle_to_buf(scsi_task_t *task, uint8_t h);
 401 stmf_status_t stmf_lu_add_event(struct stmf_lu *lu, int eventid);
 402 stmf_status_t stmf_lu_remove_event(struct stmf_lu *lu, int eventid);
 403 stmf_status_t stmf_lport_add_event(struct stmf_local_port *lport, int eventid);
 404 stmf_status_t stmf_lport_remove_event(struct stmf_local_port *lport,
 405     int eventid);
 406 void stmf_wwn_to_devid_desc(struct scsi_devid_desc *sdid, uint8_t *wwn,
 407     uint8_t protocol_id);
 408 stmf_status_t stmf_scsilib_uniq_lu_id(uint32_t company_id,
 409     struct scsi_devid_desc *lu_id);
 410 stmf_status_t stmf_scsilib_uniq_lu_id2(uint32_t company_id, uint32_t host_id,
 411     struct scsi_devid_desc *lu_id);
 412 void stmf_scsilib_send_status(scsi_task_t *task, uint8_t st, uint32_t saa);
 413 uint32_t stmf_scsilib_prepare_vpd_page83(scsi_task_t *task, uint8_t *page,
 414                 uint32_t page_len, uint8_t byte0, uint32_t vpd_mask);
 415 uint16_t stmf_scsilib_get_lport_rtid(struct scsi_devid_desc *devid);
 416 struct scsi_devid_desc *stmf_scsilib_get_devid_desc(uint16_t rtpid);
 417 void stmf_scsilib_handle_report_tpgs(scsi_task_t *task, stmf_data_buf_t *dbuf);
 418 void stmf_scsilib_handle_task_mgmt(scsi_task_t *task);
 419 
 420 struct stmf_remote_port *stmf_scsilib_devid_to_remote_port(
 421     struct scsi_devid_desc *);
 422 boolean_t stmf_scsilib_tptid_validate(struct scsi_transport_id *,
 423     uint32_t, uint16_t *);
 424 boolean_t stmf_scsilib_tptid_compare(struct scsi_transport_id *,
 425     struct scsi_transport_id *);
 426 struct stmf_remote_port *stmf_remote_port_alloc(uint16_t);
 427 void stmf_remote_port_free(struct stmf_remote_port *);
 428 struct stmf_lu *stmf_check_and_hold_lu(struct scsi_task *task, uint8_t *guid);
 429 void stmf_release_lu(struct stmf_lu *lu);
 430 int stmf_is_task_being_aborted(struct scsi_task *task);
 431 #ifdef  __cplusplus
 432 }
 433 #endif
 434 
 435 #endif  /* _STMF_H */