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