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 2006 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_READ32(Sr32_Addr) \
288 	(((uint32_t)*((uint8_t *)(Sr32_Addr)) << 24) | \
289 	    ((uint32_t)*((uint8_t *)((Sr32_Addr)+1)) << 16) | \
290 	    ((uint32_t)*((uint8_t *)((Sr32_Addr)+2)) << 8) | \
291 	    ((uint32_t)*((uint8_t *)((Sr32_Addr)+3))))
292 
293 #define	SCSI_READ64(Sr64_Addr) \
294 	(((uint64_t)*((uint8_t *)(Sr64_Addr)) << 56) | \
295 	    ((uint64_t)*((uint8_t *)((Sr64_Addr)+1)) << 48) | \
296 	    ((uint64_t)*((uint8_t *)((Sr64_Addr)+2)) << 40) | \
297 	    ((uint64_t)*((uint8_t *)((Sr64_Addr)+3)) << 32) | \
298 	    ((uint64_t)*((uint8_t *)((Sr64_Addr)+4)) << 24) | \
299 	    ((uint64_t)*((uint8_t *)((Sr64_Addr)+5)) << 16) | \
300 	    ((uint64_t)*((uint8_t *)((Sr64_Addr)+6)) << 8) | \
301 	    ((uint64_t)*((uint8_t *)((Sr64_Addr)+7))))
302 
303 #define	SCSI_WRITE16(Sr16_Addr, Sr16_Val) \
304 	*((uint8_t *)(Sr16_Addr)) = (((uint16_t)(Sr16_Val) >> 8) & 0xff); \
305 	*(((uint8_t *)(Sr16_Addr))+1) = ((uint16_t)(Sr16_Val) & 0xff);
306 
307 #define	SCSI_WRITE32(Sr32_Addr, Sr32_Val) \
308 	*(uint8_t *)(Sr32_Addr) = (((uint32_t)(Sr32_Val) >> 24) & 0xff); \
309 	*(((uint8_t *)(Sr32_Addr))+1) = \
310 	    (((uint32_t)(Sr32_Val) >> 16) & 0xff); \
311 	*(((uint8_t *)(Sr32_Addr))+2) = (((uint32_t)(Sr32_Val) >> 8) & 0xff); \
312 	*(((uint8_t *)(Sr32_Addr))+3) = (((uint32_t)(Sr32_Val)) & 0xff);
313 
314 #define	SCSI_WRITE64(Sr64_Addr, Sr64_Val) \
315 	*(uint8_t *)(Sr64_Addr) = (((uint64_t)(Sr64_Val) >> 56) & 0xff); \
316 	*(((uint8_t *)(Sr64_Addr))+1) = \
317 	    (((uint64_t)(Sr64_Val) >> 48) & 0xff); \
318 	*(((uint8_t *)(Sr64_Addr))+2) = \
319 	    (((uint64_t)(Sr64_Val) >> 40) & 0xff); \
320 	*(((uint8_t *)(Sr64_Addr))+3) = \
321 	    (((uint64_t)(Sr64_Val) >> 32) & 0xff); \
322 	*(((uint8_t *)(Sr64_Addr))+4) = \
323 	    (((uint64_t)(Sr64_Val) >> 24) & 0xff); \
324 	*(((uint8_t *)(Sr64_Addr))+5) = \
325 	    (((uint64_t)(Sr64_Val) >> 16) & 0xff); \
326 	*(((uint8_t *)(Sr64_Addr))+6) = \
327 	    (((uint64_t)(Sr64_Val) >> 8) & 0xff); \
328 	*(((uint8_t *)(Sr64_Addr))+7) = (((uint64_t)(Sr64_Val)) & 0xff);
329 
330 /*
331  * defines for getting/setting fields within the various command groups
332  */
333 
334 #define	GETCMD(cdb)		((cdb)->scc_cmd & 0x1F)
335 #define	GETGROUP(cdb)		(CDB_GROUPID((cdb)->scc_cmd))
336 
337 #define	FORMG0COUNT(cdb, cnt)	(cdb)->g0_count0  = (cnt)
338 
339 #define	FORMG0ADDR(cdb, addr) 	(cdb)->g0_addr2  = (addr) >> 16; \
340 				(cdb)->g0_addr1  = ((addr) >> 8) & 0xFF; \
341 				(cdb)->g0_addr0  = (addr) & 0xFF
342 
343 #define	GETG0COUNT(cdb)		(cdb)->g0_count0
344 
345 #define	GETG0ADDR(cdb)		((((cdb)->g0_addr2 & 0x1F) << 16) + \
346 				((cdb)->g0_addr1 << 8) + ((cdb)->g0_addr0))
347 
348 #define	GETG0TAG(cdb)		((cdb)->g0_addr2)
349 
350 #define	FORMG0COUNT_S(cdb, cnt)	(cdb)->high_count  = (cnt) >> 16; \
351 				(cdb)->mid_count = ((cnt) >> 8) & 0xFF; \
352 				(cdb)->low_count = (cnt) & 0xFF
353 
354 #define	FORMG1COUNT(cdb, cnt)	(cdb)->g1_count1 = ((cnt) >> 8); \
355 				(cdb)->g1_count0 = (cnt) & 0xFF
356 
357 #define	FORMG1ADDR(cdb, addr)	(cdb)->g1_addr3  = (addr) >> 24; \
358 				(cdb)->g1_addr2  = ((addr) >> 16) & 0xFF; \
359 				(cdb)->g1_addr1  = ((addr) >> 8) & 0xFF; \
360 				(cdb)->g1_addr0  = (addr) & 0xFF
361 
362 #define	GETG1COUNT(cdb)		(((cdb)->g1_count1 << 8) + ((cdb)->g1_count0))
363 
364 #define	GETG1ADDR(cdb)		(((cdb)->g1_addr3 << 24) + \
365 				((cdb)->g1_addr2 << 16) + \
366 				((cdb)->g1_addr1 << 8)  + \
367 				((cdb)->g1_addr0))
368 
369 #define	GETG1TAG(cdb)		(cdb)->g1_reladdr
370 
371 #define	FORMG4COUNT(cdb, cnt)	(cdb)->g4_count3 = ((cnt) >> 24); \
372 				(cdb)->g4_count2 = ((cnt) >> 16) & 0xFF; \
373 				(cdb)->g4_count1 = ((cnt) >> 8) & 0xFF; \
374 				(cdb)->g4_count0 = (cnt) & 0xFF
375 
376 #define	FORMG4LONGADDR(cdb, addr)	(cdb)->g4_addr3 = (addr) >> 56; \
377 					(cdb)->g4_addr2 = \
378 						((addr) >> 48) & 0xFF; \
379 					(cdb)->g4_addr1 = \
380 						((addr) >> 40) & 0xFF; \
381 					(cdb)->g4_addr0 = \
382 						((addr) >> 32) & 0xFF; \
383 					(cdb)->g4_addtl_cdb_data3 = \
384 						((addr) >> 24) & 0xFF; \
385 					(cdb)->g4_addtl_cdb_data2 = \
386 						((addr) >> 16) & 0xFF; \
387 					(cdb)->g4_addtl_cdb_data1 = \
388 						((addr) >> 8) & 0xFF; \
389 					(cdb)->g4_addtl_cdb_data0 = \
390 						(addr) & 0xFF
391 
392 #define	GETG4COUNT(cdb)		(((cdb)->g4_count3 << 24) + \
393 				((cdb)->g4_count2 << 16) + \
394 				((cdb)->g4_count1 << 8) + \
395 				((cdb)->g4_count0))
396 
397 #define	GETG4LONGADDR(cdb)	(((diskaddr_t)(cdb)->g4_addr3 << 56) + \
398 			((diskaddr_t)(cdb)->g4_addr2 << 48) + \
399 			((diskaddr_t)(cdb)->g4_addr1 << 40) + \
400 			((diskaddr_t)(cdb)->g4_addr0 << 32) + \
401 			((diskaddr_t)(cdb)->g4_addtl_cdb_data3 << 24) + \
402 			((diskaddr_t)(cdb)->g4_addtl_cdb_data2 << 16) + \
403 			((diskaddr_t)(cdb)->g4_addtl_cdb_data1 << 8) + \
404 			((diskaddr_t)(cdb)->g4_addtl_cdb_data0))
405 
406 #define	FORMG4ADDR(cdb, addr)	(cdb)->g4_addr3 = (addr) >> 24; \
407 				(cdb)->g4_addr2 = ((addr) >> 16) & 0xFF; \
408 				(cdb)->g4_addr1 = ((addr) >> 8) & 0xFF; \
409 				(cdb)->g4_addr0 = (addr) & 0xFF
410 
411 #define	FORMG4ADDTL(cdb, addtl_cdb_data) (cdb)->g4_addtl_cdb_data3 = \
412 					(addtl_cdb_data) >> 24; \
413 				(cdb)->g4_addtl_cdb_data2 = \
414 					((addtl_cdb_data) >> 16) & 0xFF; \
415 				(cdb)->g4_addtl_cdb_data1 = \
416 					((addtl_cdb_data) >> 8) & 0xFF; \
417 				(cdb)->g4_addtl_cdb_data0 = \
418 					(addtl_cdb_data) & 0xFF
419 
420 #define	GETG4ADDR(cdb)		((cdb)->g4_addr3 << 24) + \
421 				((cdb)->g4_addr2 << 16) + \
422 				((cdb)->g4_addr1 << 8)  + \
423 				((cdb)->g4_addr0)
424 
425 #define	GETG4ADDRTL(cdb)	(((cdb)->g4_addtl_cdb_data3 << 24) + \
426 				((cdb)->g4_addtl_cdb_data2 << 16) + \
427 				((cdb)->g4_addtl_cdb_data1 << 8) + \
428 				(cdb)->g4_addtl_cdb_data0)
429 
430 #define	GETG4TAG(cdb)		(cdb)->g4_reladdr
431 
432 #define	FORMG5COUNT(cdb, cnt)	(cdb)->scc5_count3 = ((cnt) >> 24); \
433 				(cdb)->scc5_count2 = ((cnt) >> 16) & 0xFF; \
434 				(cdb)->scc5_count1 = ((cnt) >> 8) & 0xFF; \
435 				(cdb)->scc5_count0 = (cnt) & 0xFF
436 
437 #define	FORMG5ADDR(cdb, addr)	(cdb)->scc5_addr3  = (addr) >> 24; \
438 				(cdb)->scc5_addr2  = ((addr) >> 16) & 0xFF; \
439 				(cdb)->scc5_addr1  = ((addr) >> 8) & 0xFF; \
440 				(cdb)->scc5_addr0  = (addr) & 0xFF
441 
442 #define	GETG5ADDR(cdb)		((cdb)->scc5_addr3 << 24) + \
443 				((cdb)->scc5_addr2 << 16) + \
444 				((cdb)->scc5_addr1 << 8)  + \
445 				((cdb)->scc5_addr0)
446 
447 #define	GETG5TAG(cdb)		(cdb)->scc5_reladdr
448 
449 
450 /*
451  * Shorthand macros for forming commands
452  *
453  * Works only with pre-SCSI-3 because they put lun as part of CDB.
454  * scsi_setup_cdb() is the recommended interface.
455  */
456 
457 #define	MAKECOM_COMMON(pktp, devp, flag, cmd)	\
458 	(pktp)->pkt_address = (devp)->sd_address, \
459 	(pktp)->pkt_flags = (flag), \
460 	((union scsi_cdb *)(pktp)->pkt_cdbp)->scc_cmd = (cmd), \
461 	((union scsi_cdb *)(pktp)->pkt_cdbp)->scc_lun = \
462 	    (pktp)->pkt_address.a_lun
463 
464 #define	MAKECOM_G0(pktp, devp, flag, cmd, addr, cnt)	\
465 	MAKECOM_COMMON((pktp), (devp), (flag), (cmd)), \
466 	FORMG0ADDR(((union scsi_cdb *)(pktp)->pkt_cdbp), (addr)), \
467 	FORMG0COUNT(((union scsi_cdb *)(pktp)->pkt_cdbp), (cnt))
468 
469 #define	MAKECOM_G0_S(pktp, devp, flag, cmd, cnt, fixbit)	\
470 	MAKECOM_COMMON((pktp), (devp), (flag), (cmd)), \
471 	FORMG0COUNT_S(((union scsi_cdb *)(pktp)->pkt_cdbp), (cnt)), \
472 	((union scsi_cdb *)(pktp)->pkt_cdbp)->t_code = (fixbit)
473 
474 #define	MAKECOM_G1(pktp, devp, flag, cmd, addr, cnt)	\
475 	MAKECOM_COMMON((pktp), (devp), (flag), (cmd)), \
476 	FORMG1ADDR(((union scsi_cdb *)(pktp)->pkt_cdbp), (addr)), \
477 	FORMG1COUNT(((union scsi_cdb *)(pktp)->pkt_cdbp), (cnt))
478 
479 #define	MAKECOM_G5(pktp, devp, flag, cmd, addr, cnt)	\
480 	MAKECOM_COMMON((pktp), (devp), (flag), (cmd)), \
481 	FORMG5ADDR(((union scsi_cdb *)(pktp)->pkt_cdbp), (addr)), \
482 	FORMG5COUNT(((union scsi_cdb *)(pktp)->pkt_cdbp), (cnt))
483 
484 
485 /*
486  * Direct access disk format defines and parameters.
487  *
488  * This is still pretty ugly and is mostly derived
489  * from Emulex MD21 specific formatting.
490  */
491 
492 #define	fmt_parm_bits		g0_addr2	/* for format options */
493 #define	fmt_interleave		g0_count0	/* for encode interleave */
494 #define	defect_list_descrip	g1_addr3	/* list description bits */
495 
496 /*
497  * defines for value of fmt_parm_bits.
498  */
499 
500 #define	FPB_BFI			0x04	/* bytes-from-index fmt */
501 #define	FPB_CMPLT		0x08	/* full defect list provided */
502 #define	FPB_DATA		0x10	/* defect list data provided */
503 
504 /*
505  * Defines for value of defect_list_descrip.
506  */
507 
508 #define	DLD_MAN_DEF_LIST	0x10	/* manufacturer's defect list */
509 #define	DLD_GROWN_DEF_LIST	0x08	/* grown defect list */
510 #define	DLD_BLOCK_FORMAT	0x00	/* block format */
511 #define	DLD_BFI_FORMAT		0x04	/* bytes-from-index format */
512 #define	DLD_PS_FORMAT		0x05	/* physical sector format */
513 
514 
515 /*
516  * Disk defect list - used by format command.
517  */
518 #define	RDEF_ALL	0	/* read all defects */
519 #define	RDEF_MANUF	1	/* read manufacturer's defects */
520 #define	RDEF_CKLEN	2	/* check length of manufacturer's list */
521 #define	ST506_NDEFECT	127	/* must fit in 1K controller buffer... */
522 #define	ESDI_NDEFECT	ST506_NDEFECT
523 
524 struct scsi_bfi_defect {	/* defect in bytes from index format */
525 	unsigned cyl  : 24;
526 	unsigned head : 8;
527 	int	bytes_from_index;
528 };
529 
530 struct scsi_format_params {	/* BFI format list */
531 	ushort_t reserved;
532 	ushort_t length;
533 	struct  scsi_bfi_defect list[ESDI_NDEFECT];
534 };
535 
536 /*
537  * Defect list returned by READ_DEFECT_LIST command.
538  */
539 struct scsi_defect_hdr {	/* For getting defect list size */
540 	uchar_t	reserved;
541 	uchar_t	descriptor;
542 	ushort_t length;
543 };
544 
545 struct scsi_defect_list {	/* BFI format list */
546 	uchar_t	reserved;
547 	uchar_t	descriptor;
548 	ushort_t length;
549 	struct	scsi_bfi_defect list[ESDI_NDEFECT];
550 };
551 
552 /*
553  *
554  * Direct Access device Reassign Block parameter
555  *
556  * Defect list format used by reassign block command (logical block format).
557  *
558  * This defect list is limited to 1 defect, as that is the only way we use it.
559  *
560  */
561 
562 struct scsi_reassign_blk {
563 	ushort_t reserved;
564 	ushort_t length;	/* defect length in bytes (defects * 4) */
565 	uint_t 	defect;		/* Logical block address of defect */
566 };
567 
568 /*
569  * Direct Access Device Capacity Structure -- 8 byte version
570  */
571 
572 struct scsi_capacity {
573 	uint_t	capacity;
574 	uint_t	lbasize;
575 };
576 
577 /*
578  * Direct Access Device Capacity Structure -- 16 byte version
579  */
580 
581 struct scsi_capacity_16 {
582 	uint64_t	sc_capacity;
583 	uint_t		sc_lbasize;
584 #if defined(_BIT_FIELDS_LTOH)
585 	uchar_t 	sc_rto_en	:1;
586 	uchar_t 	sc_prot_en	:1;
587 	uchar_t 	sc_rsvd0	:6;
588 #elif defined(_BIT_FIELDS_HTOL)
589 	uchar_t 	sc_rsvd0	:6;
590 	uchar_t 	sc_prot_en	:1;
591 	uchar_t 	sc_rto_en	:1;
592 #else
593 #error	One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
594 #endif	/* _BIT_FIELDS_LTOH */
595 	uchar_t 	sc_rsvd1[19];
596 };
597 
598 #ifdef	_KERNEL
599 
600 /*
601  * Functional versions of the above macros, and other functions.
602  * the makecom functions have been deprecated. Please use
603  * scsi_setup_cdb()
604  */
605 
606 #ifdef  __STDC__
607 extern void 	makecom_g0(struct scsi_pkt *pkt, struct scsi_device *devp,
608 				int flag, int cmd, int addr, int cnt);
609 extern void 	makecom_g0_s(struct scsi_pkt *pkt, struct scsi_device *devp,
610 				int flag, int cmd, int cnt, int fixbit);
611 extern void 	makecom_g1(struct scsi_pkt *pkt, struct scsi_device *devp,
612 				int flag, int cmd, int addr, int cnt);
613 extern void 	makecom_g5(struct scsi_pkt *pkt, struct scsi_device *devp,
614 				int flag, int cmd, int addr, int cnt);
615 extern int	scsi_setup_cdb(union scsi_cdb *cdbp, uchar_t cmd, uint_t addr,
616 				uint_t cnt, uint_t addtl_cdb_data);
617 
618 #else   /* __STDC__ */
619 
620 extern void 	makecom_g0();
621 extern void 	makecom_g0_s();
622 extern void 	makecom_g1();
623 extern void 	makecom_g5();
624 extern int	scsi_setup_cdb();
625 
626 #endif  /* __STDC__ */
627 
628 #endif /* _KERNEL */
629 
630 #ifdef	__cplusplus
631 }
632 #endif
633 
634 #endif	/* _SYS_SCSI_IMPL_COMMANDS_H */
635