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  * Copyright 2016 Nexenta Systems, Inc.  All rights reserved.
  25  */
  26 
  27 #ifndef _SBD_IMPL_H
  28 #define _SBD_IMPL_H
  29 
  30 #ifdef  __cplusplus
  31 extern "C" {
  32 #endif
  33 
  34 struct register_lu_cmd;
  35 struct modify_lu_cmd;
  36 struct sbd_lu_attr;
  37 struct sbd_it_data;
  38 
  39 #define ATOMIC8_GET(val) (              \
  40                         (atomic_add_8_nv(&(val), 0)))
  41 #define ATOMIC32_GET(val) (             \
  42                         (atomic_add_32_nv(&(val), 0)))
  43 
  44 /*
  45  * sms endianess
  46  */
  47 #define SMS_BIG_ENDIAN                  0x00
  48 #define SMS_LITTLE_ENDIAN               0xFF
  49 
  50 #ifdef  _BIG_ENDIAN
  51 #define SMS_DATA_ORDER  SMS_BIG_ENDIAN
  52 #else
  53 #define SMS_DATA_ORDER  SMS_LITTLE_ENDIAN
  54 #endif
  55 
  56 /* Test if one of the BitOrder definitions exists */
  57 #ifdef _BIT_FIELDS_LTOH
  58 #elif defined(_BIT_FIELDS_HTOL)
  59 #else
  60 #error  One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
  61 #endif
  62 
  63 #define SBD_V0_MAGIC    0x53554e4d4943524f
  64 #define SBD_MAGIC       0x53554e5342444c55
  65 
  66 typedef struct sbd_v0_meta_start {
  67         uint64_t                sm_magic;       /* SBD_MAGIC */
  68         uint64_t                sm_meta_size;   /* Includes everything */
  69 } sbd_v0_meta_start_t;
  70 
  71 typedef struct sbd_meta_start {
  72         uint64_t                sm_magic;
  73         uint64_t                sm_meta_size;
  74         uint64_t                sm_meta_size_used;
  75         uint64_t                sm_rsvd1;       /* Defaults to zero */
  76         uint64_t                sm_rsvd2;
  77         uint16_t                sm_ver_major;
  78         uint16_t                sm_ver_minor;
  79         uint16_t                sm_ver_subminor;
  80         uint8_t                 sm_flags;       /* None at this moment */
  81         uint8_t                 sm_chksum;
  82 } sbd_meta_start_t;
  83 
  84 typedef struct sm_v0_section_hdr {
  85         uint64_t        sms_offset;     /* Offset of this section */
  86         uint64_t        sms_size;       /* Includes the header and padding */
  87         uint16_t        sms_id;         /* Section identifier */
  88         uint16_t        sms_padding;    /* For alignment */
  89         uint32_t        sms_seqno;      /* For multiple sections with same ID */
  90         uint8_t         sms_hdr_data_order; /* 0x00 or 0xff */
  91         uint8_t         sms_payload_data_order;
  92         uint16_t        rsvd2;
  93         uint32_t        rsvd3;          /* 8 byte align */
  94 } sm_v0_section_hdr_t;
  95 
  96 /*
  97  * sbd_it_flags
  98  */
  99 #define SBD_IT_HAS_SCSI2_RESERVATION    0x0001
 100 #define SBD_IT_PGR_REGISTERED           0x0002
 101 #define SBD_IT_PGR_EXCLUSIVE_RSV_HOLDER 0x0004
 102 #define SBD_IT_PGR_CHECK_FLAG           0x0008
 103 
 104 /*
 105  * PGR flags
 106  */
 107 #define SBD_PGR_APTPL                   0x01
 108 #define SBD_PGR_RSVD_ONE                0x02
 109 #define SBD_PGR_RSVD_ALL_REGISTRANTS    0x04
 110 #define SBD_PGR_ALL_KEYS_HAS_IT         0x08
 111 
 112 #define SBD_PGR_RSVD(pgr)       (((pgr)->pgr_flags) & (SBD_PGR_RSVD_ONE | \
 113                                         SBD_PGR_RSVD_ALL_REGISTRANTS))
 114 #define SBD_PGR_RSVD_NONE(pgr)  (!(SBD_PGR_RSVD(pgr)))
 115 
 116 /*
 117  * PGR key flags
 118  */
 119 #define SBD_PGR_KEY_ALL_TG_PT           0x01
 120 #define SBD_PGR_KEY_TPT_ID_FLAG         0x02
 121 
 122 typedef struct sbd_pgr_key_info {
 123         uint64_t        pgr_key;
 124         uint16_t        pgr_key_lpt_len;
 125         uint16_t        pgr_key_rpt_len;
 126         uint8_t         pgr_key_flags;
 127         uint8_t         pgr_key_it[1];  /* order:- initiator info followed by */
 128                                         /* scsi_devid_desc of local port */
 129 } sbd_pgr_key_info_t;
 130 
 131 typedef struct sbd_pgr_info {
 132         sm_section_hdr_t        pgr_sms_header;
 133         uint32_t                pgr_rsvholder_indx;
 134         uint32_t                pgr_numkeys;
 135         uint8_t                 pgr_flags;
 136         uint8_t                 pgr_data_order;
 137 #ifdef _BIT_FIELDS_LTOH
 138         uint8_t                 pgr_rsv_type:4,
 139                                 pgr_rsv_scope:4;
 140 #else
 141         uint8_t                 pgr_rsv_scope:4,
 142                                 pgr_rsv_type:4;
 143 #endif
 144         uint8_t                 rsvd[5];        /* 8 byte boundary */
 145 
 146 } sbd_pgr_info_t;
 147 
 148 typedef struct sbd_pgr_key {
 149         uint64_t                pgr_key;
 150         uint16_t                pgr_key_lpt_len;
 151         uint16_t                pgr_key_rpt_len;
 152         uint8_t                 pgr_key_flags;
 153         struct scsi_devid_desc  *pgr_key_lpt_id;
 154         struct scsi_transport_id *pgr_key_rpt_id;
 155         struct sbd_it_data      *pgr_key_it;
 156         struct sbd_pgr_key      *pgr_key_next;
 157         struct sbd_pgr_key      *pgr_key_prev;
 158 } sbd_pgr_key_t;
 159 
 160 typedef struct sbd_pgr {
 161         sbd_pgr_key_t           *pgr_keylist;
 162         sbd_pgr_key_t           *pgr_rsvholder;
 163         uint32_t                pgr_PRgeneration; /* PGR PRgeneration value */
 164         uint8_t                 pgr_flags;      /* PGR flags (eg: APTPL)  */
 165         uint8_t                 pgr_rsv_type:4,
 166                                 pgr_rsv_scope:4;
 167         krwlock_t               pgr_lock; /* Lock order pgr_lock, sl_lock */
 168 } sbd_pgr_t;
 169 
 170 
 171 typedef struct sbd_v0_lu_info {
 172         sm_v0_section_hdr_t     sli_sms_header;
 173         uint64_t                sli_total_store_size;
 174         uint64_t                sli_total_meta_size;
 175         uint64_t                rsvd0;
 176         uint64_t                sli_lu_data_offset;
 177         uint64_t                sli_lu_data_size;
 178         uint64_t                rsvd1;
 179         uint32_t                sli_flags;
 180         uint16_t                sli_blocksize;
 181         uint16_t                rsvd2;
 182         uint8_t                 sli_lu_devid[20];
 183         uint32_t                rsvd3;
 184 } sbd_v0_lu_info_t;
 185 
 186 typedef struct sbd_lu_info {
 187         sm_section_hdr_t        sli_sms_header;
 188         uint64_t                sli_total_store_size;
 189         uint64_t                sli_total_meta_size;
 190         uint64_t                sli_lu_data_offset;
 191         uint64_t                sli_lu_data_size;
 192         uint32_t                sli_flags;
 193         uint16_t                sli_blocksize;
 194         uint8_t                 sli_data_order;
 195         uint8_t                 rsvd1;
 196         uint8_t                 sli_lu_devid[20];
 197         uint32_t                rsvd2;
 198 } sbd_lu_info_t;
 199 
 200 /*
 201  * sl_flags
 202  */
 203 #define SBD_LU_HAS_SCSI2_RESERVATION    0x0001
 204 
 205 typedef struct sbd_cmd {
 206         uint8_t         flags;
 207         uint8_t         nbufs;
 208         uint16_t        cmd_type;       /* Type of command */
 209         uint32_t        trans_data_len; /* Length of transient data buf */
 210         uint64_t        addr;           /* current */
 211         uint32_t        len;            /* len left */
 212         uint32_t        current_ro;     /* running relative offset */
 213         uint8_t         *trans_data;    /* Any transient data */
 214         ats_state_t     *ats_state;
 215         uint32_t        rsvd;
 216 } sbd_cmd_t;
 217 
 218 /*
 219  * flags for sbd_cmd
 220  *
 221  * SBD_SCSI_CMD_ACTIVE means that a command is running.  This is the time
 222  *      between the function sbd_new_task is called and either the command
 223  *      completion is sent (stmf_scsilib_send_status) or an abort is
 224  *      issued
 225  *
 226  * SBD_SCSI_CMD_ABORT_REQUESTED is when a command is being aborted.  It may
 227  *      be set prior to the task being dispatched or anywhere in the process
 228  *      of the command.
 229  *
 230  * SBD_SCSI_CMD_XFER_FAIL is set when a command data buffer transfer was
 231  *      errored.  Usually it leads to an abort.
 232  *
 233  * SBD_SCSI_CMD_SYNC_WRITE synchronous write being done.
 234  *
 235  * SBD_SCSI_CMD_TRANS_DATA means that a buffer has been allocated to
 236  *      be used for the transfer of data.
 237  */
 238 #define SBD_SCSI_CMD_ACTIVE             0x01
 239 #define SBD_SCSI_CMD_ABORT_REQUESTED    0x02
 240 #define SBD_SCSI_CMD_XFER_FAIL          0x04
 241 #define SBD_SCSI_CMD_SYNC_WRITE         0x08
 242 #define SBD_SCSI_CMD_TRANS_DATA         0x10
 243 #define SBD_SCSI_CMD_ATS_RELATED        0x20
 244 
 245 /*
 246  * cmd types
 247  */
 248 #define SBD_CMD_SCSI_READ       0x01
 249 #define SBD_CMD_SCSI_WRITE      0x02
 250 #define SBD_CMD_SMALL_READ      0x03
 251 #define SBD_CMD_SMALL_WRITE     0x04
 252 #define SBD_CMD_SCSI_PR_OUT     0x05
 253 
 254 typedef struct sbd_it_data {
 255         struct sbd_it_data      *sbd_it_next;
 256         uint64_t                sbd_it_session_id;
 257         uint8_t                 sbd_it_lun[8];
 258         uint8_t                 sbd_it_ua_conditions;
 259         uint8_t                 sbd_it_flags;
 260         sbd_pgr_key_t           *pgr_key_ptr;
 261 } sbd_it_data_t;
 262 
 263 typedef struct sbd_create_standby_lu {
 264         uint32_t        stlu_meta_fname_size;
 265         uint32_t        stlu_rsvd;
 266         uint8_t         stlu_guid[16];
 267         char            stlu_meta_fname[8];
 268 } sbd_create_standby_lu_t;
 269 
 270 /*
 271  * Different UA conditions
 272  */
 273 #define SBD_UA_POR                          0x01
 274 #define SBD_UA_CAPACITY_CHANGED             0x02
 275 #define SBD_UA_MODE_PARAMETERS_CHANGED      0x04
 276 #define SBD_UA_ACCESS_STATE_TRANSITION      0x08
 277 #define SBD_UA_REGISTRATIONS_PREEMPTED      0x10
 278 #define SBD_UA_RESERVATIONS_PREEMPTED       0x20
 279 #define SBD_UA_RESERVATIONS_RELEASED        0x40
 280 #define SBD_UA_ASYMMETRIC_ACCESS_CHANGED    0x80
 281 
 282 /*
 283  * sbd_it_flags
 284  */
 285 #define SBD_IT_HAS_SCSI2_RESERVATION    0x0001
 286 
 287 /*
 288  * dbuf private data needed for direct zvol data transfers
 289  *
 290  * To further isolate the zvol knowledge, the object handles
 291  * needed to call into zfs are declared void * here.
 292  */
 293 
 294 typedef struct sbd_zvol_io {
 295         uint64_t        zvio_offset;    /* offset into volume */
 296         int             zvio_flags;     /* flags */
 297         void            *zvio_dbp;      /* array of dmu buffers */
 298         void            *zvio_abp;      /* array of arc buffers */
 299         uio_t           *zvio_uio;      /* for copy operations */
 300 } sbd_zvol_io_t;
 301 
 302 #define ZVIO_DEFAULT    0
 303 #define ZVIO_COMMIT     1
 304 #define ZVIO_ABORT      2
 305 #define ZVIO_SYNC       4
 306 #define ZVIO_ASYNC      8
 307 
 308 /*
 309  * zvol data path functions
 310  */
 311 int sbd_zvol_get_volume_params(sbd_lu_t *sl);
 312 uint32_t sbd_zvol_numsegs(sbd_lu_t *sl, uint64_t off, uint32_t len);
 313 int sbd_zvol_alloc_read_bufs(sbd_lu_t *sl, stmf_data_buf_t *dbuf);
 314 void sbd_zvol_rele_read_bufs(sbd_lu_t *sl, stmf_data_buf_t *dbuf);
 315 int sbd_zvol_alloc_write_bufs(sbd_lu_t *sl, stmf_data_buf_t *dbuf);
 316 void sbd_zvol_rele_write_bufs_abort(sbd_lu_t *sl, stmf_data_buf_t *dbuf);
 317 int sbd_zvol_rele_write_bufs(sbd_lu_t *sl, stmf_data_buf_t *dbuf);
 318 int sbd_zvol_copy_read(sbd_lu_t *sl, uio_t *uio);
 319 int sbd_zvol_copy_write(sbd_lu_t *sl, uio_t *uio, int flags);
 320 
 321 stmf_status_t sbd_task_alloc(struct scsi_task *task);
 322 void sbd_new_task(struct scsi_task *task, struct stmf_data_buf *initial_dbuf);
 323 void sbd_dbuf_xfer_done(struct scsi_task *task, struct stmf_data_buf *dbuf);
 324 void sbd_send_status_done(struct scsi_task *task);
 325 void sbd_task_free(struct scsi_task *task);
 326 stmf_status_t sbd_abort(struct stmf_lu *lu, int abort_cmd, void *arg,
 327                                                         uint32_t flags);
 328 void sbd_task_poll(struct scsi_task *task);
 329 void sbd_dbuf_free(struct scsi_task *task, struct stmf_data_buf *dbuf);
 330 void sbd_ctl(struct stmf_lu *lu, int cmd, void *arg);
 331 stmf_status_t sbd_info(uint32_t cmd, stmf_lu_t *lu, void *arg,
 332                                 uint8_t *buf, uint32_t *bufsizep);
 333 uint8_t sbd_get_lbasize_shift(stmf_lu_t *lu);
 334 int sbd_is_valid_lu(stmf_lu_t *lu);
 335 
 336 #ifdef  __cplusplus
 337 }
 338 #endif
 339 
 340 #endif /* _SBD_IMPL_H */