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