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 2014 Garrett D'Amore <garrett@damore.org>
  24  * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
  25  */
  26 
  27 #ifndef _SYS_SCSI_IMPL_COMMANDS_H
  28 #define _SYS_SCSI_IMPL_COMMANDS_H
  29 
  30 #ifdef  __cplusplus
  31 extern "C" {
  32 #endif
  33 
  34 /*
  35  * Implementation dependent command definitions.
  36  * This file is included by <sys/scsi/generic/commands.h>
  37  */
  38 
  39 /*
  40  * Implementation dependent view of a SCSI command descriptor block
  41  */
  42 
  43 /*
  44  * Standard SCSI control blocks definitions.
  45  *
  46  * These go in or out over the SCSI bus.
  47  *
  48  * The first 8 bits of the command block are the same for all
  49  * defined command groups.  The first byte is an operation which consists
  50  * of a command code component and a group code component.
  51  *
  52  * The group code determines the length of the rest of the command.
  53  * Group 0 commands are 6 bytes, Group 1 and 2  are 10 bytes, Group 4
  54  * are 16 bytes, and Group 5 are 12 bytes. Groups 3 is Reserved.
  55  * Groups 6 and 7 are Vendor Unique.
  56  *
  57  */
  58 #define CDB_SIZE        CDB_GROUP5      /* deprecated, do not use */
  59 #define SCSI_CDB_SIZE   CDB_GROUP4      /* sizeof (union scsi_cdb) */
  60 
  61 union scsi_cdb {                /* scsi command description block */
  62         struct {
  63                 uchar_t cmd;            /* cmd code (byte 0) */
  64 #if defined(_BIT_FIELDS_LTOH)
  65                 uchar_t tag     :5;     /* rest of byte 1 */
  66                 uchar_t lun     :3;     /* lun (byte 1) (reserved in SCSI-3) */
  67 #elif defined(_BIT_FIELDS_HTOL)
  68                 uchar_t lun     :3,     /* lun (byte 1) (reserved in SCSI-3) */
  69                         tag     :5;     /* rest of byte 1 */
  70 #else
  71 #error  One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
  72 #endif  /* _BIT_FIELDS_LTOH */
  73                 union {
  74 
  75                 uchar_t scsi[SCSI_CDB_SIZE-2];
  76                 /*
  77                  *      G R O U P   0   F O R M A T (6 bytes)
  78                  */
  79 #define         scc_cmd         cdb_un.cmd
  80 #define         scc_lun         cdb_un.lun
  81 #define         g0_addr2        cdb_un.tag
  82 #define         g0_addr1        cdb_un.sg.g0.addr1
  83 #define         g0_addr0        cdb_un.sg.g0.addr0
  84 #define         g0_count0       cdb_un.sg.g0.count0
  85 #define         g0_vu_1         cdb_un.sg.g0.vu_57
  86 #define         g0_vu_0         cdb_un.sg.g0.vu_56
  87 #define         g0_naca         cdb_un.sg.g0.naca
  88 #define         g0_flag         cdb_un.sg.g0.flag
  89 #define         g0_link         cdb_un.sg.g0.link
  90         /*
  91          * defines for SCSI tape cdb.
  92          */
  93 #define         t_code          cdb_un.tag
  94 #define         high_count      cdb_un.sg.g0.addr1
  95 #define         mid_count       cdb_un.sg.g0.addr0
  96 #define         low_count       cdb_un.sg.g0.count0
  97                 struct scsi_g0 {
  98                         uchar_t addr1;  /* middle part of address */
  99                         uchar_t addr0;  /* low part of address */
 100                         uchar_t count0; /* usually block count */
 101 #if defined(_BIT_FIELDS_LTOH)
 102                         uchar_t link    :1; /* another command follows  */
 103                         uchar_t flag    :1; /* interrupt when done      */
 104                         uchar_t naca    :1; /* normal ACA               */
 105                         uchar_t rsvd    :3; /* reserved                 */
 106                         uchar_t vu_56   :1; /* vendor unique (byte 5 bit6) */
 107                         uchar_t vu_57   :1; /* vendor unique (byte 5 bit7) */
 108 #elif defined(_BIT_FIELDS_HTOL)
 109                         uchar_t vu_57   :1; /* vendor unique (byte 5 bit 7) */
 110                         uchar_t vu_56   :1; /* vendor unique (byte 5 bit 6) */
 111                         uchar_t rsvd    :3; /* reserved */
 112                         uchar_t naca    :1; /* normal ACA               */
 113                         uchar_t flag    :1; /* interrupt when done */
 114                         uchar_t link    :1; /* another command follows */
 115 #else
 116 #error  One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
 117 #endif  /* _BIT_FIELDS_LTOH */
 118                 } g0;
 119 
 120 
 121                 /*
 122                  *      G R O U P   1, 2   F O R M A T  (10 byte)
 123                  */
 124 #define         g1_reladdr      cdb_un.tag
 125 #define         g1_rsvd0        cdb_un.sg.g1.rsvd1
 126 #define         g1_addr3        cdb_un.sg.g1.addr3      /* msb */
 127 #define         g1_addr2        cdb_un.sg.g1.addr2
 128 #define         g1_addr1        cdb_un.sg.g1.addr1
 129 #define         g1_addr0        cdb_un.sg.g1.addr0      /* lsb */
 130 #define         g1_count1       cdb_un.sg.g1.count1     /* msb */
 131 #define         g1_count0       cdb_un.sg.g1.count0     /* lsb */
 132 #define         g1_vu_1         cdb_un.sg.g1.vu_97
 133 #define         g1_vu_0         cdb_un.sg.g1.vu_96
 134 #define         g1_naca         cdb_un.sg.g1.naca
 135 #define         g1_flag         cdb_un.sg.g1.flag
 136 #define         g1_link         cdb_un.sg.g1.link
 137                 struct scsi_g1 {
 138                         uchar_t addr3;  /* most sig. byte of address */
 139                         uchar_t addr2;
 140                         uchar_t addr1;
 141                         uchar_t addr0;
 142                         uchar_t rsvd1;  /* reserved (byte 6) */
 143                         uchar_t count1; /* transfer length (msb) */
 144                         uchar_t count0; /* transfer length (lsb) */
 145 #if defined(_BIT_FIELDS_LTOH)
 146                         uchar_t link    :1; /* another command follows  */
 147                         uchar_t flag    :1; /* interrupt when done      */
 148                         uchar_t naca    :1; /* normal ACA               */
 149                         uchar_t rsvd0   :3; /* reserved                 */
 150                         uchar_t vu_96   :1; /* vendor unique (byte 9 bit6) */
 151                         uchar_t vu_97   :1; /* vendor unique (byte 9 bit7) */
 152 #elif defined(_BIT_FIELDS_HTOL)
 153                         uchar_t vu_97   :1; /* vendor unique (byte 9 bit 7) */
 154                         uchar_t vu_96   :1; /* vendor unique (byte 9 bit 6) */
 155                         uchar_t rsvd0   :3; /* reserved */
 156                         uchar_t naca    :1; /* normal ACA               */
 157                         uchar_t flag    :1; /* interrupt when done */
 158                         uchar_t link    :1; /* another command follows */
 159 #else
 160 #error  One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
 161 #endif  /* _BIT_FIELDS_LTOH */
 162                 } g1;
 163 
 164                 /*
 165                  *      G R O U P   4   F O R M A T  (16 byte)
 166                  */
 167 #define         g4_reladdr              cdb_un.tag
 168 #define         g4_addr3                cdb_un.sg.g4.addr3      /* msb */
 169 #define         g4_addr2                cdb_un.sg.g4.addr2
 170 #define         g4_addr1                cdb_un.sg.g4.addr1
 171 #define         g4_addr0                cdb_un.sg.g4.addr0      /* lsb */
 172 #define         g4_addtl_cdb_data3      cdb_un.sg.g4.addtl_cdb_data3
 173 #define         g4_addtl_cdb_data2      cdb_un.sg.g4.addtl_cdb_data2
 174 #define         g4_addtl_cdb_data1      cdb_un.sg.g4.addtl_cdb_data1
 175 #define         g4_addtl_cdb_data0      cdb_un.sg.g4.addtl_cdb_data0
 176 #define         g4_count3               cdb_un.sg.g4.count3     /* msb */
 177 #define         g4_count2               cdb_un.sg.g4.count2
 178 #define         g4_count1               cdb_un.sg.g4.count1
 179 #define         g4_count0               cdb_un.sg.g4.count0     /* lsb */
 180 #define         g4_rsvd0                cdb_un.sg.g4.rsvd1
 181 #define         g4_vu_1                 cdb_un.sg.g4.vu_157
 182 #define         g4_vu_0                 cdb_un.sg.g4.vu_156
 183 #define         g4_naca                 cdb_un.sg.g4.naca
 184 #define         g4_flag                 cdb_un.sg.g4.flag
 185 #define         g4_link                 cdb_un.sg.g4.link
 186                 struct scsi_g4 {
 187                         uchar_t addr3;  /* most sig. byte of address */
 188                         uchar_t addr2;
 189                         uchar_t addr1;
 190                         uchar_t addr0;
 191                         uchar_t addtl_cdb_data3;
 192                         uchar_t addtl_cdb_data2;
 193                         uchar_t addtl_cdb_data1;
 194                         uchar_t addtl_cdb_data0;
 195                         uchar_t count3; /* transfer length (msb) */
 196                         uchar_t count2;
 197                         uchar_t count1;
 198                         uchar_t count0; /* transfer length (lsb) */
 199                         uchar_t rsvd1;  /* reserved */
 200 #if defined(_BIT_FIELDS_LTOH)
 201                         uchar_t link    :1; /* another command follows  */
 202                         uchar_t flag    :1; /* interrupt when done      */
 203                         uchar_t naca    :1; /* normal ACA               */
 204                         uchar_t rsvd0   :3; /* reserved                 */
 205                         uchar_t vu_156  :1; /* vendor unique (byte 15 bit6) */
 206                         uchar_t vu_157  :1; /* vendor unique (byte 15 bit7) */
 207 #elif defined(_BIT_FIELDS_HTOL)
 208                         uchar_t vu_157  :1; /* vendor unique (byte 15 bit 7) */
 209                         uchar_t vu_156  :1; /* vendor unique (byte 15 bit 6) */
 210                         uchar_t rsvd0   :3; /* reserved */
 211                         uchar_t naca    :1; /* normal ACA               */
 212                         uchar_t flag    :1; /* interrupt when done */
 213                         uchar_t link    :1; /* another command follows */
 214 #else
 215 #error  One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
 216 #endif  /* _BIT_FIELDS_LTOH */
 217                 } g4;
 218 
 219                 /*
 220                  *      G R O U P   5   F O R M A T  (12 byte)
 221                  */
 222 #define         scc5_reladdr    cdb_un.tag
 223 #define         scc5_addr3      cdb_un.sg.g5.addr3      /* msb */
 224 #define         scc5_addr2      cdb_un.sg.g5.addr2
 225 #define         scc5_addr1      cdb_un.sg.g5.addr1
 226 #define         scc5_addr0      cdb_un.sg.g5.addr0      /* lsb */
 227 #define         scc5_count3     cdb_un.sg.g5.count3     /* msb */
 228 #define         scc5_count2     cdb_un.sg.g5.count2
 229 #define         scc5_count1     cdb_un.sg.g5.count1
 230 #define         scc5_count0     cdb_un.sg.g5.count0     /* lsb */
 231 #define         scc5_rsvd0      cdb_un.sg.g5.rsvd1
 232 #define         scc5_vu_1       cdb_un.sg.g5.v117
 233 #define         scc5_vu_0       cdb_un.sg.g5.v116
 234 #define         scc5_naca       cdb_un.sg.g5.naca
 235 #define         scc5_flag       cdb_un.sg.g5.flag
 236 #define         scc5_link       cdb_un.sg.g5.link
 237                 struct scsi_g5 {
 238                         uchar_t addr3;  /* most sig. byte of address */
 239                         uchar_t addr2;
 240                         uchar_t addr1;
 241                         uchar_t addr0;
 242                         uchar_t count3; /* most sig. byte of count */
 243                         uchar_t count2;
 244                         uchar_t count1;
 245                         uchar_t count0;
 246                         uchar_t rsvd1;  /* reserved */
 247 #if defined(_BIT_FIELDS_LTOH)
 248                         uchar_t link    :1; /* another command follows  */
 249                         uchar_t flag    :1; /* interrupt when done      */
 250                         uchar_t naca    :1; /* normal ACA               */
 251                         uchar_t rsvd0   :3; /* reserved                 */
 252                         uchar_t vu_116  :1; /* vendor unique (byte 11 bit6) */
 253                         uchar_t vu_117  :1; /* vendor unique (byte 11 bit7) */
 254 #elif defined(_BIT_FIELDS_HTOL)
 255                         uchar_t vu_117  :1; /* vendor unique (byte 11 bit 7) */
 256                         uchar_t vu_116  :1; /* vendor unique (byte 11 bit 6) */
 257                         uchar_t rsvd0   :3; /* reserved */
 258                         uchar_t naca    :1; /* normal ACA               */
 259                         uchar_t flag    :1; /* interrupt when done */
 260                         uchar_t link    :1; /* another command follows */
 261 #else
 262 #error  One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
 263 #endif  /* _BIT_FIELDS_LTOH */
 264                 } g5;
 265                 }sg;
 266         } cdb_un;
 267         uchar_t cdb_opaque[SCSI_CDB_SIZE]; /* addressed as opaque char array */
 268         uint_t cdb_long[SCSI_CDB_SIZE / sizeof (uint_t)]; /* as a word array */
 269 };
 270 
 271 
 272 /*
 273  *      Various useful Macros for SCSI commands
 274  */
 275 
 276 /*
 277  * defines for getting/setting fields in data received from or destined for
 278  * a SCSI device.  These macros are necessary (in place of BE16/BE32/BE64)
 279  * because the address to be read or written may not be on a proper alignment.
 280  */
 281 
 282 #define SCSI_READ16(Sr16_Addr) \
 283         (((uint16_t)*((uint8_t *)(Sr16_Addr)) << 8) | \
 284             ((uint16_t)*((uint8_t *)(Sr16_Addr)+1)))
 285 
 286 #define SCSI_READ24(Sr32_Addr)  \
 287         (((uint32_t)*((uint8_t *)(Sr32_Addr)) << 16) | \
 288             ((uint32_t)*((uint8_t *)(Sr32_Addr)+1) << 8) | \
 289             ((uint32_t)*((uint8_t *)(Sr32_Addr)+2)))
 290 
 291 #define SCSI_READ32(Sr32_Addr) \
 292         (((uint32_t)*((uint8_t *)(Sr32_Addr)) << 24) | \
 293             ((uint32_t)*((uint8_t *)(Sr32_Addr)+1) << 16) | \
 294             ((uint32_t)*((uint8_t *)(Sr32_Addr)+2) << 8) | \
 295             ((uint32_t)*((uint8_t *)(Sr32_Addr)+3)))
 296 
 297 #define SCSI_READ40(Sr64_Addr)  \
 298         (((uint64_t)*((uint8_t *)(Sr64_Addr)) << 32) | \
 299             ((uint64_t)*((uint8_t *)(Sr64_Addr)+1) << 24) | \
 300             ((uint64_t)*((uint8_t *)(Sr64_Addr)+2) << 16) | \
 301             ((uint64_t)*((uint8_t *)(Sr64_Addr)+3) << 8) | \
 302             ((uint64_t)*((uint8_t *)(Sr64_Addr)+4)))
 303 
 304 #define SCSI_READ48(Sr64_Addr)  \
 305         (((uint64_t)*((uint8_t *)(Sr64_Addr)) << 40) | \
 306             ((uint64_t)*((uint8_t *)(Sr64_Addr)+1) << 32) | \
 307             ((uint64_t)*((uint8_t *)(Sr64_Addr)+2) << 24) | \
 308             ((uint64_t)*((uint8_t *)(Sr64_Addr)+3) << 16) | \
 309             ((uint64_t)*((uint8_t *)(Sr64_Addr)+4) << 8) | \
 310             ((uint64_t)*((uint8_t *)(Sr64_Addr)+5)))
 311 
 312 #define SCSI_READ64(Sr64_Addr) \
 313         (((uint64_t)*((uint8_t *)(Sr64_Addr)) << 56) | \
 314             ((uint64_t)*((uint8_t *)(Sr64_Addr)+1) << 48) | \
 315             ((uint64_t)*((uint8_t *)(Sr64_Addr)+2) << 40) | \
 316             ((uint64_t)*((uint8_t *)(Sr64_Addr)+3) << 32) | \
 317             ((uint64_t)*((uint8_t *)(Sr64_Addr)+4) << 24) | \
 318             ((uint64_t)*((uint8_t *)(Sr64_Addr)+5) << 16) | \
 319             ((uint64_t)*((uint8_t *)(Sr64_Addr)+6) << 8) | \
 320             ((uint64_t)*((uint8_t *)(Sr64_Addr)+7)))
 321 
 322 #define SCSI_WRITE16(Sr16_Addr, Sr16_Val) \
 323         *((uint8_t *)(Sr16_Addr)) = (((uint16_t)(Sr16_Val) >> 8) & 0xff), \
 324         *((uint8_t *)(Sr16_Addr)+1) = ((uint16_t)(Sr16_Val) & 0xff)
 325 
 326 #define SCSI_WRITE24(Sr24_Addr, Sr24_Val) \
 327         SCSI_WRITE16((Sr24_Addr), ((Sr24_Val) & 0xffff00) >> 8),      \
 328         *((uint8_t *)(Sr24_Addr)+2) = ((uint8_t)((Sr24_Val) & 0xff))
 329 
 330 #define SCSI_WRITE32(Sr32_Addr, Sr32_Val) \
 331         *(uint8_t *)(Sr32_Addr) = (((uint32_t)(Sr32_Val) >> 24) & 0xff), \
 332         *((uint8_t *)(Sr32_Addr)+1) = \
 333             (((uint32_t)(Sr32_Val) >> 16) & 0xff), \
 334         *((uint8_t *)(Sr32_Addr)+2) = (((uint32_t)(Sr32_Val) >> 8) & 0xff), \
 335         *((uint8_t *)(Sr32_Addr)+3) = (((uint32_t)(Sr32_Val)) & 0xff)
 336 
 337 #define SCSI_WRITE40(Sr40_Addr, Sr40_Val) \
 338         SCSI_WRITE32((Sr40_Addr), ((Sr40_Val) & 0xffffffff00ULL) >> 8),       \
 339         *((uint8_t *)(Sr40_Addr)+4) = ((uint8_t)(Sr40_Val) & 0xff)
 340 
 341 #define SCSI_WRITE48(Sr48_Addr, Sr40_Val) \
 342         SCSI_WRITE32((Sr48_Addr), ((Sr48_Val) & 0xffffffff0000ULL) >> 16), \
 343         SCSI_WRITE16((uint8_t *)(Sr48_Addr)+4, (Sr40_Val) & 0xffff)
 344 
 345 #define SCSI_WRITE64(Sr64_Addr, Sr64_Val) \
 346         *(uint8_t *)(Sr64_Addr) = (((uint64_t)(Sr64_Val) >> 56) & 0xff), \
 347         *((uint8_t *)(Sr64_Addr)+1) = \
 348             (((uint64_t)(Sr64_Val) >> 48) & 0xff), \
 349         *((uint8_t *)(Sr64_Addr)+2) = \
 350             (((uint64_t)(Sr64_Val) >> 40) & 0xff), \
 351         *((uint8_t *)(Sr64_Addr)+3) = \
 352             (((uint64_t)(Sr64_Val) >> 32) & 0xff), \
 353         *((uint8_t *)(Sr64_Addr)+4) = \
 354             (((uint64_t)(Sr64_Val) >> 24) & 0xff), \
 355         *((uint8_t *)(Sr64_Addr)+5) = \
 356             (((uint64_t)(Sr64_Val) >> 16) & 0xff), \
 357         *((uint8_t *)(Sr64_Addr)+6) = \
 358             (((uint64_t)(Sr64_Val) >> 8) & 0xff), \
 359         *((uint8_t *)(Sr64_Addr)+7) = (((uint64_t)(Sr64_Val)) & 0xff)
 360 
 361 /*
 362  * These macros deal with unaligned data that crosses a byte boundary.
 363  */
 364 #define SCSI_MK8(ms, ls)        \
 365         (((uint8_t)(ms) << 4) | (uint8_t)ls)
 366 
 367 #define SCSI_MK12_4_8(ms, ls)   \
 368         (((uint16_t)(ms) << 8) | (uint16_t)(ls))
 369 #define SCSI_MK12_8_4(ms, ls)   \
 370         (((uint16_t)(ms) << 4) | (uint16_t)(ls))
 371 
 372 #define SCSI_MK16_4_8_4(hi, mid, lo)    \
 373         (((uint16_t)(hi) << 12) | ((uint16_t)(mid) << 4) | (uint16_t)(lo))
 374 
 375 #define SCSI_MK20_4_16(ms, ls)  \
 376         (((uint32_t)(ms) << 16) | ((uint32_t)(ls)))
 377 #define SCSI_MK20_16_4(ms, ls)  \
 378         (((uint32_t)(ms) << 4) | ((uint32_t)(ls)))
 379 
 380 #define SCSI_MK24_4_16_4(hi, mid, lo)   \
 381         (((uint32_t)(hi) << 20) | ((uint32_t)(mid) << 4) | (uint32_t)(lo))
 382 
 383 #define SCSI_MK36_4_32(ms, ls)  \
 384         (((uint64_t)(ms) << 32) | (uint64_t)(ls))
 385 #define SCSI_MK36_32_4(ms, ls)  \
 386         (((uint64_t)(ms) << 4) | (uint64_t)(ls))
 387 
 388 /*
 389  * defines for getting/setting fields within the various command groups
 390  */
 391 
 392 #define GETCMD(cdb)             ((cdb)->scc_cmd & 0x1F)
 393 #define GETGROUP(cdb)           (CDB_GROUPID((cdb)->scc_cmd))
 394 
 395 #define FORMG0COUNT(cdb, cnt)   (cdb)->g0_count0  = (cnt)
 396 
 397 #define FORMG0ADDR(cdb, addr)   (cdb)->g0_addr2  = (addr) >> 16; \
 398                                 (cdb)->g0_addr1  = ((addr) >> 8) & 0xFF; \
 399                                 (cdb)->g0_addr0  = (addr) & 0xFF
 400 
 401 #define GETG0COUNT(cdb)         (cdb)->g0_count0
 402 
 403 #define GETG0ADDR(cdb)          ((((cdb)->g0_addr2 & 0x1F) << 16) + \
 404                                 ((cdb)->g0_addr1 << 8) + ((cdb)->g0_addr0))
 405 
 406 #define GETG0TAG(cdb)           ((cdb)->g0_addr2)
 407 
 408 #define FORMG0COUNT_S(cdb, cnt) (cdb)->high_count  = (cnt) >> 16; \
 409                                 (cdb)->mid_count = ((cnt) >> 8) & 0xFF; \
 410                                 (cdb)->low_count = (cnt) & 0xFF
 411 
 412 #define FORMG1COUNT(cdb, cnt)   (cdb)->g1_count1 = ((cnt) >> 8); \
 413                                 (cdb)->g1_count0 = (cnt) & 0xFF
 414 
 415 #define FORMG1ADDR(cdb, addr)   (cdb)->g1_addr3  = (addr) >> 24; \
 416                                 (cdb)->g1_addr2  = ((addr) >> 16) & 0xFF; \
 417                                 (cdb)->g1_addr1  = ((addr) >> 8) & 0xFF; \
 418                                 (cdb)->g1_addr0  = (addr) & 0xFF
 419 
 420 #define GETG1COUNT(cdb)         (((cdb)->g1_count1 << 8) + ((cdb)->g1_count0))
 421 
 422 #define GETG1ADDR(cdb)          (((cdb)->g1_addr3 << 24) + \
 423                                 ((cdb)->g1_addr2 << 16) + \
 424                                 ((cdb)->g1_addr1 << 8)  + \
 425                                 ((cdb)->g1_addr0))
 426 
 427 #define GETG1TAG(cdb)           (cdb)->g1_reladdr
 428 
 429 #define FORMG4COUNT(cdb, cnt)   (cdb)->g4_count3 = ((cnt) >> 24); \
 430                                 (cdb)->g4_count2 = ((cnt) >> 16) & 0xFF; \
 431                                 (cdb)->g4_count1 = ((cnt) >> 8) & 0xFF; \
 432                                 (cdb)->g4_count0 = (cnt) & 0xFF
 433 
 434 #define FORMG4LONGADDR(cdb, addr)       (cdb)->g4_addr3 = (addr) >> 56; \
 435                                         (cdb)->g4_addr2 = \
 436                                                 ((addr) >> 48) & 0xFF; \
 437                                         (cdb)->g4_addr1 = \
 438                                                 ((addr) >> 40) & 0xFF; \
 439                                         (cdb)->g4_addr0 = \
 440                                                 ((addr) >> 32) & 0xFF; \
 441                                         (cdb)->g4_addtl_cdb_data3 = \
 442                                                 ((addr) >> 24) & 0xFF; \
 443                                         (cdb)->g4_addtl_cdb_data2 = \
 444                                                 ((addr) >> 16) & 0xFF; \
 445                                         (cdb)->g4_addtl_cdb_data1 = \
 446                                                 ((addr) >> 8) & 0xFF; \
 447                                         (cdb)->g4_addtl_cdb_data0 = \
 448                                                 (addr) & 0xFF
 449 
 450 #define GETG4COUNT(cdb)         (((cdb)->g4_count3 << 24) + \
 451                                 ((cdb)->g4_count2 << 16) + \
 452                                 ((cdb)->g4_count1 << 8) + \
 453                                 ((cdb)->g4_count0))
 454 
 455 #define GETG4LONGADDR(cdb)      (((diskaddr_t)(cdb)->g4_addr3 << 56) + \
 456                         ((diskaddr_t)(cdb)->g4_addr2 << 48) + \
 457                         ((diskaddr_t)(cdb)->g4_addr1 << 40) + \
 458                         ((diskaddr_t)(cdb)->g4_addr0 << 32) + \
 459                         ((diskaddr_t)(cdb)->g4_addtl_cdb_data3 << 24) + \
 460                         ((diskaddr_t)(cdb)->g4_addtl_cdb_data2 << 16) + \
 461                         ((diskaddr_t)(cdb)->g4_addtl_cdb_data1 << 8) + \
 462                         ((diskaddr_t)(cdb)->g4_addtl_cdb_data0))
 463 
 464 #define FORMG4ADDR(cdb, addr)   (cdb)->g4_addr3 = (addr) >> 24; \
 465                                 (cdb)->g4_addr2 = ((addr) >> 16) & 0xFF; \
 466                                 (cdb)->g4_addr1 = ((addr) >> 8) & 0xFF; \
 467                                 (cdb)->g4_addr0 = (addr) & 0xFF
 468 
 469 #define FORMG4ADDTL(cdb, addtl_cdb_data) (cdb)->g4_addtl_cdb_data3 = \
 470                                         (addtl_cdb_data) >> 24; \
 471                                 (cdb)->g4_addtl_cdb_data2 = \
 472                                         ((addtl_cdb_data) >> 16) & 0xFF; \
 473                                 (cdb)->g4_addtl_cdb_data1 = \
 474                                         ((addtl_cdb_data) >> 8) & 0xFF; \
 475                                 (cdb)->g4_addtl_cdb_data0 = \
 476                                         (addtl_cdb_data) & 0xFF
 477 
 478 #define GETG4ADDR(cdb)          ((cdb)->g4_addr3 << 24) + \
 479                                 ((cdb)->g4_addr2 << 16) + \
 480                                 ((cdb)->g4_addr1 << 8)  + \
 481                                 ((cdb)->g4_addr0)
 482 
 483 #define GETG4ADDRTL(cdb)        (((cdb)->g4_addtl_cdb_data3 << 24) + \
 484                                 ((cdb)->g4_addtl_cdb_data2 << 16) + \
 485                                 ((cdb)->g4_addtl_cdb_data1 << 8) + \
 486                                 (cdb)->g4_addtl_cdb_data0)
 487 
 488 #define GETG4TAG(cdb)           (cdb)->g4_reladdr
 489 
 490 #define FORMG5COUNT(cdb, cnt)   (cdb)->scc5_count3 = ((cnt) >> 24); \
 491                                 (cdb)->scc5_count2 = ((cnt) >> 16) & 0xFF; \
 492                                 (cdb)->scc5_count1 = ((cnt) >> 8) & 0xFF; \
 493                                 (cdb)->scc5_count0 = (cnt) & 0xFF
 494 
 495 #define FORMG5ADDR(cdb, addr)   (cdb)->scc5_addr3  = (addr) >> 24; \
 496                                 (cdb)->scc5_addr2  = ((addr) >> 16) & 0xFF; \
 497                                 (cdb)->scc5_addr1  = ((addr) >> 8) & 0xFF; \
 498                                 (cdb)->scc5_addr0  = (addr) & 0xFF
 499 
 500 #define GETG5ADDR(cdb)          ((cdb)->scc5_addr3 << 24) + \
 501                                 ((cdb)->scc5_addr2 << 16) + \
 502                                 ((cdb)->scc5_addr1 << 8)  + \
 503                                 ((cdb)->scc5_addr0)
 504 
 505 #define GETG5COUNT(cdb)         ((cdb)->scc5_count3 << 24) + \
 506                                 ((cdb)->scc5_count2 << 16) + \
 507                                 ((cdb)->scc5_count1 << 8) + \
 508                                 ((cdb)->scc5_count0)
 509 
 510 #define GETG5TAG(cdb)           (cdb)->scc5_reladdr
 511 
 512 
 513 /*
 514  * Shorthand macros for forming commands
 515  *
 516  * Works only with pre-SCSI-3 because they put lun as part of CDB.
 517  * scsi_setup_cdb() is the recommended interface.
 518  */
 519 
 520 #define MAKECOM_COMMON(pktp, devp, flag, cmd)   \
 521         (pktp)->pkt_address = (devp)->sd_address, \
 522         (pktp)->pkt_flags = (flag), \
 523         ((union scsi_cdb *)(pktp)->pkt_cdbp)->scc_cmd = (cmd), \
 524         ((union scsi_cdb *)(pktp)->pkt_cdbp)->scc_lun = \
 525             (pktp)->pkt_address.a_lun
 526 
 527 #define MAKECOM_G0(pktp, devp, flag, cmd, addr, cnt)    \
 528         MAKECOM_COMMON((pktp), (devp), (flag), (cmd)), \
 529         FORMG0ADDR(((union scsi_cdb *)(pktp)->pkt_cdbp), (addr)), \
 530         FORMG0COUNT(((union scsi_cdb *)(pktp)->pkt_cdbp), (cnt))
 531 
 532 #define MAKECOM_G0_S(pktp, devp, flag, cmd, cnt, fixbit)        \
 533         MAKECOM_COMMON((pktp), (devp), (flag), (cmd)), \
 534         FORMG0COUNT_S(((union scsi_cdb *)(pktp)->pkt_cdbp), (cnt)), \
 535         ((union scsi_cdb *)(pktp)->pkt_cdbp)->t_code = (fixbit)
 536 
 537 #define MAKECOM_G1(pktp, devp, flag, cmd, addr, cnt)    \
 538         MAKECOM_COMMON((pktp), (devp), (flag), (cmd)), \
 539         FORMG1ADDR(((union scsi_cdb *)(pktp)->pkt_cdbp), (addr)), \
 540         FORMG1COUNT(((union scsi_cdb *)(pktp)->pkt_cdbp), (cnt))
 541 
 542 #define MAKECOM_G5(pktp, devp, flag, cmd, addr, cnt)    \
 543         MAKECOM_COMMON((pktp), (devp), (flag), (cmd)), \
 544         FORMG5ADDR(((union scsi_cdb *)(pktp)->pkt_cdbp), (addr)), \
 545         FORMG5COUNT(((union scsi_cdb *)(pktp)->pkt_cdbp), (cnt))
 546 
 547 
 548 /*
 549  * Direct access disk format defines and parameters.
 550  *
 551  * This is still pretty ugly and is mostly derived
 552  * from Emulex MD21 specific formatting.
 553  */
 554 
 555 #define fmt_parm_bits           g0_addr2        /* for format options */
 556 #define fmt_interleave          g0_count0       /* for encode interleave */
 557 #define defect_list_descrip     g1_addr3        /* list description bits */
 558 
 559 /*
 560  * defines for value of fmt_parm_bits.
 561  */
 562 
 563 #define FPB_BFI                 0x04    /* bytes-from-index fmt */
 564 #define FPB_CMPLT               0x08    /* full defect list provided */
 565 #define FPB_DATA                0x10    /* defect list data provided */
 566 
 567 /*
 568  * Defines for value of defect_list_descrip.
 569  */
 570 
 571 #define DLD_MAN_DEF_LIST        0x10    /* manufacturer's defect list */
 572 #define DLD_GROWN_DEF_LIST      0x08    /* grown defect list */
 573 #define DLD_BLOCK_FORMAT        0x00    /* block format */
 574 #define DLD_BFI_FORMAT          0x04    /* bytes-from-index format */
 575 #define DLD_PS_FORMAT           0x05    /* physical sector format */
 576 
 577 /*
 578  * Defines for value of CONTROL byte of cdb.
 579  */
 580 #define CDB_FLAG_NACA           0x04    /* naca flag */
 581 
 582 /*
 583  * Disk defect list - used by format command.
 584  */
 585 #define RDEF_ALL        0       /* read all defects */
 586 #define RDEF_MANUF      1       /* read manufacturer's defects */
 587 #define RDEF_CKLEN      2       /* check length of manufacturer's list */
 588 #define ST506_NDEFECT   127     /* must fit in 1K controller buffer... */
 589 #define ESDI_NDEFECT    ST506_NDEFECT
 590 
 591 struct scsi_bfi_defect {        /* defect in bytes from index format */
 592         unsigned cyl  : 24;
 593         unsigned head : 8;
 594         int     bytes_from_index;
 595 };
 596 
 597 struct scsi_format_params {     /* BFI format list */
 598         ushort_t reserved;
 599         ushort_t length;
 600         struct  scsi_bfi_defect list[ESDI_NDEFECT];
 601 };
 602 
 603 /*
 604  * Defect list returned by READ_DEFECT_LIST command.
 605  */
 606 struct scsi_defect_hdr {        /* For getting defect list size */
 607         uchar_t reserved;
 608         uchar_t descriptor;
 609         ushort_t length;
 610 };
 611 
 612 struct scsi_defect_list {       /* BFI format list */
 613         uchar_t reserved;
 614         uchar_t descriptor;
 615         ushort_t length;
 616         struct  scsi_bfi_defect list[ESDI_NDEFECT];
 617 };
 618 
 619 /*
 620  *
 621  * Direct Access device Reassign Block parameter
 622  *
 623  * Defect list format used by reassign block command (logical block format).
 624  *
 625  * This defect list is limited to 1 defect, as that is the only way we use it.
 626  *
 627  */
 628 
 629 struct scsi_reassign_blk {
 630         ushort_t reserved;
 631         ushort_t length;        /* defect length in bytes (defects * 4) */
 632         uint_t  defect;         /* Logical block address of defect */
 633 };
 634 
 635 /*
 636  * Direct Access Device Capacity Structure -- 8 byte version
 637  */
 638 
 639 struct scsi_capacity {
 640         uint_t  capacity;
 641         uint_t  lbasize;
 642 };
 643 
 644 /*
 645  * Direct Access Device Capacity Structure -- 16 byte version
 646  */
 647 
 648 struct scsi_capacity_16 {
 649         uint64_t        sc_capacity;
 650         uint_t          sc_lbasize;
 651 #if defined(_BIT_FIELDS_LTOH)
 652         uchar_t         sc_rto_en       :1;
 653         uchar_t         sc_prot_en      :1;
 654         uchar_t         sc_rsvd0        :6;
 655 #elif defined(_BIT_FIELDS_HTOL)
 656         uchar_t         sc_rsvd0        :6;
 657         uchar_t         sc_prot_en      :1;
 658         uchar_t         sc_rto_en       :1;
 659 #else
 660 #error  One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
 661 #endif  /* _BIT_FIELDS_LTOH */
 662         uchar_t         sc_rsvd1[19];
 663 };
 664 
 665 #ifdef  _KERNEL
 666 
 667 /*
 668  * Functional versions of the above macros, and other functions.
 669  * the makecom functions have been deprecated. Please use
 670  * scsi_setup_cdb()
 671  */
 672 
 673 extern void     makecom_g0(struct scsi_pkt *pkt, struct scsi_device *devp,
 674                                 int flag, int cmd, int addr, int cnt);
 675 extern void     makecom_g0_s(struct scsi_pkt *pkt, struct scsi_device *devp,
 676                                 int flag, int cmd, int cnt, int fixbit);
 677 extern void     makecom_g1(struct scsi_pkt *pkt, struct scsi_device *devp,
 678                                 int flag, int cmd, int addr, int cnt);
 679 extern void     makecom_g5(struct scsi_pkt *pkt, struct scsi_device *devp,
 680                                 int flag, int cmd, int addr, int cnt);
 681 extern int      scsi_setup_cdb(union scsi_cdb *cdbp, uchar_t cmd, uint_t addr,
 682                                 uint_t cnt, uint_t addtl_cdb_data);
 683 
 684 #endif /* _KERNEL */
 685 
 686 #ifdef  __cplusplus
 687 }
 688 #endif
 689 
 690 #endif  /* _SYS_SCSI_IMPL_COMMANDS_H */