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