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