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 2009 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  * Copyright 2017 Nexenta Systems, Inc.
  26  */
  27 
  28 #ifndef _SYS_SCSI_GENERIC_MODE_H
  29 #define _SYS_SCSI_GENERIC_MODE_H
  30 
  31 #ifdef  __cplusplus
  32 extern "C" {
  33 #endif
  34 
  35 /*
  36  *
  37  * Defines and Structures for SCSI Mode Sense/Select data - generic
  38  *
  39  */
  40 
  41 /*
  42  * Structures and defines common for all device types
  43  */
  44 
  45 /*
  46  * Mode Sense/Select Header - Group 0 (6-byte).
  47  *
  48  * Mode Sense/Select data consists of a header, followed by zero or more
  49  * block descriptors, followed by zero or more mode pages.
  50  *
  51  */
  52 
  53 struct mode_header {
  54         uchar_t length;         /* number of bytes following */
  55         uchar_t medium_type;    /* device specific */
  56         uchar_t device_specific;        /* device specific parameters */
  57         uchar_t bdesc_length;   /* length of block descriptor(s), if any */
  58 };
  59 
  60 #define MODE_HEADER_LENGTH      (sizeof (struct mode_header))
  61 
  62 /*
  63  * Mode Sense/Select Header - Group 1 (10-bytes)
  64  */
  65 
  66 struct mode_header_g1 {
  67         ushort_t        length;         /* number of bytes following */
  68         uchar_t         medium_type;    /* device specific */
  69         uchar_t         device_specific;        /* device specific parameters */
  70         uchar_t         reserved[2];    /* device specific parameters */
  71         ushort_t        bdesc_length;   /* len of block descriptor(s), if any */
  72 };
  73 
  74 #define MODE_HEADER_LENGTH_G1   (sizeof (struct mode_header_g1))
  75 
  76 /*
  77  * Block Descriptor. Zero, one, or more may normally follow the mode header.
  78  *
  79  * The density code is device specific.
  80  *
  81  * The 24-bit value described by blks_{hi, mid, lo} describes the number of
  82  * blocks which this block descriptor applies to. A value of zero means
  83  * 'the rest of the blocks on the device'.
  84  *
  85  * The 24-bit value described by blksize_{hi, mid, lo} describes the blocksize
  86  * (in bytes) applicable for this block descriptor. For Sequential Access
  87  * devices, if this value is zero, the block size will be derived from
  88  * the transfer length in I/O operations.
  89  *
  90  */
  91 
  92 struct block_descriptor {
  93         uchar_t density_code;   /* device specific */
  94         uchar_t blks_hi;        /* hi  */
  95         uchar_t blks_mid;       /* mid */
  96         uchar_t blks_lo;        /* low */
  97         uchar_t reserved;       /* reserved */
  98         uchar_t blksize_hi;     /* hi  */
  99         uchar_t blksize_mid;    /* mid */
 100         uchar_t blksize_lo;     /* low */
 101 };
 102 
 103 #define MODE_BLK_DESC_LENGTH    (sizeof (struct block_descriptor))
 104 #define MODE_PARAM_LENGTH       (MODE_HEADER_LENGTH + MODE_BLK_DESC_LENGTH)
 105 
 106 /*
 107  * Define a macro to take an address of a mode header to the address
 108  * of the nth (0..n) block_descriptor, or NULL if there either aren't any
 109  * block descriptors or the nth block descriptor doesn't exist.
 110  */
 111 
 112 #define BLOCK_DESCRIPTOR_ADDR(mhdr, bdnum) \
 113         ((mhdr)->bdesc_length && ((unsigned)(bdnum)) < \
 114         ((mhdr)->bdesc_length/(sizeof (struct block_descriptor)))) ? \
 115         ((struct block_descriptor *)(((ulong_t)(mhdr))+MODE_HEADER_LENGTH+ \
 116         ((bdnum) * sizeof (struct block_descriptor)))) : \
 117         ((struct block_descriptor *)0)
 118 
 119 /*
 120  * Mode page header. Zero or more Mode Pages follow either the block
 121  * descriptors (if any), or the Mode Header.
 122  *
 123  * The 'ps' bit must be zero for mode select operations.
 124  *
 125  */
 126 
 127 struct mode_page {
 128 #if defined(_BIT_FIELDS_LTOH)
 129         uchar_t code    :6,     /* page code number */
 130                         :1,     /* reserved */
 131                 ps      :1;     /* 'Parameter Saveable' bit */
 132 #elif defined(_BIT_FIELDS_HTOL)
 133         uchar_t ps      :1,     /* 'Parameter Saveable' bit */
 134                         :1,     /* reserved */
 135                 code    :6;     /* page code number */
 136 #else
 137 #error  One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
 138 #endif  /* _BIT_FIELDS_LTOH */
 139         uchar_t length;         /* length of bytes to follow */
 140         /*
 141          * Mode Page specific data follows right after this...
 142          */
 143 };
 144 
 145 /*
 146  * Define a macro to retrieve the first mode page. Could be more
 147  * general (for multiple mode pages).
 148  */
 149 
 150 #define MODE_PAGE_ADDR(mhdr, type)      \
 151         ((type *)(((ulong_t)(mhdr))+MODE_HEADER_LENGTH+(mhdr)->bdesc_length))
 152 
 153 /*
 154  * Page Control field (bits 7 and 6) follows the following specification:
 155  *
 156  *      Value                   Meaning
 157  *      ----------------------------------------------------------------------
 158  *      00b                     current values
 159  *      01b                     changeable values
 160  *      10b                     default values
 161  *      11b                     saved values
 162  */
 163 
 164 #define MODEPAGE_CURRENT        0x00
 165 #define MODEPAGE_CHANGEABLE     0x40
 166 #define MODEPAGE_DEFAULT        0x80
 167 #define MODEPAGE_SAVED          0xC0
 168 
 169 /*
 170  * Page codes follow the following specification:
 171  *
 172  *      Code Value(s)           What
 173  *      ----------------------------------------------------------------------
 174  *      0x00                    Vendor Unique (does not require page format)
 175  *
 176  *      0x02, 0x09, 0x0A        pages for all Device Types
 177  *      0x1A, 0x1C
 178  *
 179  *      0x01, 0x03-0x08,        pages for specific Device Type
 180  *      0x0B-0x19, 0x1B,
 181  *      0x1D-0x1F
 182  *
 183  *      0x20-0x3E               Vendor Unique (requires page format)
 184  *
 185  *      0x3F                    Return all pages (valid for Mode Sense only)
 186  *
 187  */
 188 
 189 /*
 190  * Page codes and page length values (all device types)
 191  */
 192 
 193 #define MODEPAGE_DISCO_RECO     0x02
 194 #define MODEPAGE_FORMAT         0x03
 195 #define MODEPAGE_GEOMETRY       0x04
 196 #define MODEPAGE_CACHING        0x08
 197 #define MODEPAGE_PDEVICE        0x09
 198 #define MODEPAGE_CTRL_MODE      0x0A
 199 #define MODEPAGE_POWER_COND     0x1A
 200 #define MODEPAGE_INFO_EXCPT     0x1C
 201 
 202 #define MODEPAGE_ALLPAGES       0x3F
 203 
 204 /*
 205  * Mode Select/Sense page structures (for all device types)
 206  */
 207 
 208 /*
 209  * Disconnect/Reconnect Page
 210  */
 211 
 212 struct mode_disco_reco {
 213         struct  mode_page mode_page;    /* common mode page header */
 214         uchar_t buffer_full_ratio;      /* write, how full before reconnect? */
 215         uchar_t buffer_empty_ratio;     /* read, how full before reconnect? */
 216         ushort_t bus_inactivity_limit;  /* how much bus quiet time for BSY- */
 217         ushort_t disconect_time_limit;  /* min to remain disconnected */
 218         ushort_t connect_time_limit;    /* min to remain connected */
 219         ushort_t max_burst_size;        /* max data burst size */
 220 #if defined(_BIT_FIELDS_LTOH)
 221         uchar_t         dtdc    : 3,    /* data transfer disconenct control */
 222                         dimm    : 1,    /* disconnect immediate */
 223                         fastat  : 1,    /* fair for status */
 224                         fawrt   : 1,    /* fair for write */
 225                         fard    : 1,    /* fair for read */
 226                         emdp    : 1;    /* enable modify data pointers */
 227 #elif defined(_BIT_FIELDS_HTOL)
 228         uchar_t         emdp    : 1,    /* enable modify data pointers */
 229                         fard    : 1,    /* fair for read */
 230                         fawrt   : 1,    /* fair for write */
 231                         fastat  : 1,    /* fair for status */
 232                         dimm    : 1,    /* disconnect immediate */
 233                         dtdc    : 3;    /* data transfer disconenct control */
 234 #else
 235 #error  One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
 236 #endif  /* _BIT_FIELDS_LTOH */
 237         uchar_t reserved;
 238         ushort_t first_burst_sz;        /* first burst size */
 239 };
 240 
 241 #define DTDC_DATADONE   0x01
 242                                         /*
 243                                          * Target may not disconnect once
 244                                          * data transfer is started until
 245                                          * all data successfully transferred.
 246                                          */
 247 
 248 #define DTDC_CMDDONE    0x03
 249                                         /*
 250                                          * Target may not disconnect once
 251                                          * data transfer is started until
 252                                          * command completed.
 253                                          */
 254 /*
 255  * Caching Page
 256  */
 257 
 258 struct mode_caching {
 259         struct  mode_page mode_page;    /* common mode page header */
 260 #if defined(_BIT_FIELDS_LTOH)
 261         uchar_t rcd             : 1,    /* Read Cache Disable */
 262                 mf              : 1,    /* Multiplication Factor */
 263                 wce             : 1,    /* Write Cache Enable */
 264                                 : 5;    /* Reserved */
 265         uchar_t write_ret_prio  : 4,    /* Write Retention Priority */
 266                 dmd_rd_ret_prio : 4;    /* Demand Read Retention Priority */
 267 #elif defined(_BIT_FIELDS_HTOL)
 268         uchar_t                 : 5,    /* Reserved */
 269                 wce             : 1,    /* Write Cache Enable */
 270                 mf              : 1,    /* Multiplication Factor */
 271                 rcd             : 1;    /* Read Cache Disable */
 272         uchar_t dmd_rd_ret_prio : 4,    /* Demand Read Retention Priority */
 273                 write_ret_prio  : 4;    /* Write Retention Priority */
 274 #else
 275 #error  One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
 276 #endif  /* _BIT_FIELDS_LTOH */
 277         ushort_t pf_dsbl_trans_len;     /* Disable prefetch transfer length */
 278         ushort_t min_prefetch;          /* Minimum Prefetch */
 279         ushort_t max_prefetch;          /* Maximum Prefetch */
 280         ushort_t max_prefetch_ceiling;  /* Maximum Prefetch Ceiling */
 281 };
 282 
 283 /*
 284  * Peripheral Device Page
 285  */
 286 
 287 struct mode_pdevice {
 288         struct  mode_page mode_page;    /* common mode page header */
 289         ushort_t if_ident;              /* interface identifier */
 290         uchar_t reserved[4];            /* reserved */
 291         uchar_t vendor_uniqe[1];        /* vendor unique data */
 292 };
 293 
 294 #define PDEV_SCSI       0x0000          /* scsi interface */
 295 #define PDEV_SMD        0x0001          /* SMD interface */
 296 #define PDEV_ESDI       0x0002          /* ESDI interface */
 297 #define PDEV_IPI2       0x0003          /* IPI-2 interface */
 298 #define PDEV_IPI3       0x0004          /* IPI-3 interface */
 299 
 300 /*
 301  * Control Mode Page
 302  *
 303  * Note:        This structure is incompatible with previous SCSI
 304  *              implementations. See <scsi/impl/mode.h> for an
 305  *              alternative form of this structure. They can be
 306  *              distinguished by the length of data returned
 307  *              from a MODE SENSE command.
 308  */
 309 
 310 #define PAGELENGTH_MODE_CONTROL_SCSI3   0x0A
 311 
 312 struct mode_control_scsi3 {
 313         struct  mode_page mode_page;    /* common mode page header */
 314 #if defined(_BIT_FIELDS_LTOH)
 315         uchar_t         rlec    : 1,    /* Report Log Exception bit */
 316                         gltsd   : 1,    /* global logging target save disable */
 317                         d_sense : 1,    /* Use descriptor sense data (SPC-3) */
 318                                 : 5;
 319         uchar_t         qdisable: 1,    /* Queue disable */
 320                         que_err : 1,    /* Queue error */
 321                                 : 2,
 322                         que_mod : 4;    /* Queue algorithm modifier */
 323         uchar_t         eanp    : 1,    /* Enable AEN permission */
 324                         uaaenp  : 1,    /* Unit attention AEN permission */
 325                         raenp   : 1,    /* Ready AEN permission */
 326                                 : 1,
 327                         bybths  : 1,    /* By both RESET signal */
 328                         byprtm  : 1,    /* By port message */
 329                         rac     : 1,    /* report a check */
 330                         eeca    : 1;    /* enable extended contingent */
 331                                         /* allegiance (only pre-SCSI-3) */
 332 #elif defined(_BIT_FIELDS_HTOL)
 333         uchar_t                 : 5,
 334                         d_sense : 1,    /* Use descriptor sense data (SPC-3) */
 335                         gltsd   : 1,    /* global logging target save disable */
 336                         rlec    : 1;    /* Report Log Exception bit */
 337         uchar_t         que_mod : 4,    /* Queue algorithm modifier */
 338                                 : 2,
 339                         que_err : 1,    /* Queue error */
 340                         qdisable: 1;    /* Queue disable */
 341         uchar_t         eeca    : 1,    /* enable extended contingent */
 342                                         /* allegiance (only pre-SCSI-3) */
 343                         rac     : 1,    /* report a check */
 344                         byprtm  : 1,    /* By port message */
 345                         bybths  : 1,    /* By both RESET signal */
 346                                 : 1,
 347                         raenp   : 1,    /* Ready AEN permission */
 348                         uaaenp  : 1,    /* Unit attention AEN permission */
 349                         eanp    : 1;    /* Enable AEN permission */
 350 #else
 351 #error  One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
 352 #endif  /* _BIT_FIELDS_LTOH */
 353         uchar_t reserved;
 354         ushort_t ready_aen_holdoff;     /* Ready AEN holdoff period */
 355         ushort_t busy_timeout;          /* Busy timeout period */
 356         uchar_t reserved_2[2];
 357 };
 358 
 359 #ifdef __lock_lint
 360 _NOTE(SCHEME_PROTECTS_DATA("Unshared SCSI payload", \
 361         mode_control_scsi3))
 362 #endif
 363 
 364 #define CTRL_QMOD_RESTRICT      0x0
 365 #define CTRL_QMOD_UNRESTRICT    0x1
 366 
 367 /*
 368  * Informational Exceptions Control Mode Page
 369  */
 370 
 371 #define PAGELENGTH_INFO_EXCPT   0x0A
 372 
 373 struct mode_info_excpt_page {
 374         struct  mode_page mode_page;    /* common mode page header */
 375 #if defined(_BIT_FIELDS_LTOH)
 376         uchar_t         log_err : 1;    /* log errors */
 377         uchar_t                 : 1;    /* reserved */
 378         uchar_t         test    : 1;    /* create test failure */
 379         uchar_t         dexcpt  : 1;    /* disable exception */
 380         uchar_t         ewasc   : 1;    /* enable warning */
 381         uchar_t         ebf     : 1;    /* enable background function */
 382         uchar_t                 : 1;    /* reserved */
 383         uchar_t         perf    : 1;    /* performance */
 384         uchar_t         mrie    : 4;    /* method of reporting info. excpts. */
 385         uchar_t                 : 4;    /* reserved */
 386 #elif defined(_BIT_FIELDS_HTOL)
 387         uchar_t         perf    : 1;    /* performance */
 388         uchar_t                 : 1;    /* reserved */
 389         uchar_t         ebf     : 1;    /* enable background function */
 390         uchar_t         ewasc   : 1;    /* enable warning */
 391         uchar_t         dexcpt  : 1;    /* disable exception */
 392         uchar_t         test    : 1;    /* create test failure */
 393         uchar_t                 : 1;    /* reserved */
 394         uchar_t         log_err : 1;    /* log errors */
 395         uchar_t                 : 4;    /* reserved */
 396         uchar_t         mrie    : 4;    /* method of reporting info. excpts. */
 397 #else
 398 #error  One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
 399 #endif
 400         uchar_t interval_timer[4];      /* interval timer */
 401         uchar_t report_count[4];        /* report count */
 402 };
 403 
 404 #define MRIE_NO_REPORT          0x0
 405 #define MRIE_ASYNCH             0x1
 406 #define MRIE_UNIT_ATTN          0x2
 407 #define MRIE_COND_RECVD_ERR     0x3
 408 #define MRIE_UNCOND_RECVD_ERR   0x4
 409 #define MRIE_NO_SENSE           0x5
 410 #define MRIE_ONLY_ON_REQUEST    0x6
 411 
 412 struct mode_info_power_cond {
 413         struct mode_page mode_page;     /* common mode page header */
 414         uchar_t reserved;
 415 #if defined(_BIT_FIELDS_LTOH)
 416         uchar_t standby :1,     /* standby bit */
 417                 idle    :1,     /* idle bit */
 418                         :6;     /* reserved */
 419 #elif defined(_BIT_FIELDS_HTOL)
 420         uchar_t         :6,     /* reserved */
 421                 idle    :1,     /* idle bit */
 422                 standby :1;     /* standby bit */
 423 #else
 424 #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
 425 #endif
 426         uchar_t idle_cond_timer_high;
 427         uchar_t idle_cond_timer_low;
 428         uchar_t standby_cond_timer[4];
 429 };
 430 
 431 struct parameter_control {
 432 #if defined(_BIT_FIELDS_LTOH)
 433         uchar_t fmt_link:2,     /* format and link bit */
 434                 tmc     :2,     /* tmc bit */
 435                 etc     :1,     /* etc bit */
 436                 tsd     :1,     /* tsd bit */
 437                 reserv  :1,     /* obsolete */
 438                 du      :1;     /* du bit */
 439 #elif defined(_BIT_FIELDS_HTOL)
 440         uchar_t du      :1,     /* du bit */
 441                 reserv  :1,     /* obsolete */
 442                 tsd     :1,     /* tsd bit */
 443                 etc     :1,     /* etc bit */
 444                 tmc     :2,     /* tmc bit */
 445                 fmt_link:2;     /* format and link bit */
 446 #else
 447 #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
 448 #endif
 449 };
 450 
 451 struct start_stop_cycle_counter_log {
 452 #if defined(_BIT_FIELDS_LTOH)
 453         uchar_t code    :6,     /* page code bit */
 454                 spf     :1,     /* spf bit */
 455                 ds      :1;     /* ds bit */
 456 #elif defined(_BIT_FIELDS_HTOL)
 457         uchar_t ds      :1,     /* ds bit */
 458                 spf     :1,     /* spf bit */
 459                 code    :6;     /* page code bit */
 460 #else
 461 #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
 462 #endif
 463         uchar_t                 sub_page_code;
 464         uchar_t                 page_len_high;
 465         uchar_t                 page_len_low;
 466 
 467         uchar_t                 manufactor_date_high;
 468         uchar_t                 manufactor_date_low;
 469         struct parameter_control param_1;
 470         uchar_t                 param_len_1;
 471         uchar_t                 year_manu[4];
 472         uchar_t                 week_manu[2];
 473 
 474         uchar_t                 account_date_high;
 475         uchar_t                 account_date_low;
 476         struct parameter_control param_2;
 477         uchar_t                 param_len_2;
 478         uchar_t                 year_account[4];
 479         uchar_t                 week_account[2];
 480 
 481         uchar_t                 lifetime_code_high;
 482         uchar_t                 lifetime_code_low;
 483         struct parameter_control param_3;
 484         uchar_t                 param_len_3;
 485         uchar_t                 cycle_lifetime[4];
 486 
 487         uchar_t                 cycle_code_high;
 488         uchar_t                 cycle_code_low;
 489         struct parameter_control param_4;
 490         uchar_t                 param_len_4;
 491         uchar_t                 cycle_accumulated[4];
 492 };
 493 
 494 
 495 #ifdef  __cplusplus
 496 }
 497 #endif
 498 
 499 /*
 500  * Include known generic device specific mode definitions and structures
 501  */
 502 
 503 #include <sys/scsi/generic/dad_mode.h>
 504 
 505 /*
 506  * Include implementation specific mode information
 507  */
 508 
 509 #include <sys/scsi/impl/mode.h>
 510 
 511 #endif  /* _SYS_SCSI_GENERIC_MODE_H */