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