xref: /titanic_44/usr/src/uts/common/sys/scsi/impl/commands.h (revision 3e14f97f673e8a630f076077de35afdd43dc1587)
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 */
701