1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * CDDL HEADER START
3*0Sstevel@tonic-gate  *
4*0Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*0Sstevel@tonic-gate  * with the License.
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate  * and limitations under the License.
13*0Sstevel@tonic-gate  *
14*0Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate  *
20*0Sstevel@tonic-gate  * CDDL HEADER END
21*0Sstevel@tonic-gate  */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24*0Sstevel@tonic-gate  * Use is subject to license terms.
25*0Sstevel@tonic-gate  */
26*0Sstevel@tonic-gate 
27*0Sstevel@tonic-gate #ifndef	_SYS_SCSI_IMPL_COMMANDS_H
28*0Sstevel@tonic-gate #define	_SYS_SCSI_IMPL_COMMANDS_H
29*0Sstevel@tonic-gate 
30*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
31*0Sstevel@tonic-gate 
32*0Sstevel@tonic-gate #ifdef	__cplusplus
33*0Sstevel@tonic-gate extern "C" {
34*0Sstevel@tonic-gate #endif
35*0Sstevel@tonic-gate 
36*0Sstevel@tonic-gate /*
37*0Sstevel@tonic-gate  * Implementation dependent command definitions.
38*0Sstevel@tonic-gate  * This file is included by <sys/scsi/generic/commands.h>
39*0Sstevel@tonic-gate  */
40*0Sstevel@tonic-gate 
41*0Sstevel@tonic-gate /*
42*0Sstevel@tonic-gate  * Implementation dependent view of a SCSI command descriptor block
43*0Sstevel@tonic-gate  */
44*0Sstevel@tonic-gate 
45*0Sstevel@tonic-gate /*
46*0Sstevel@tonic-gate  * Standard SCSI control blocks definitions.
47*0Sstevel@tonic-gate  *
48*0Sstevel@tonic-gate  * These go in or out over the SCSI bus.
49*0Sstevel@tonic-gate  *
50*0Sstevel@tonic-gate  * The first 8 bits of the command block are the same for all
51*0Sstevel@tonic-gate  * defined command groups.  The first byte is an operation which consists
52*0Sstevel@tonic-gate  * of a command code component and a group code component.
53*0Sstevel@tonic-gate  *
54*0Sstevel@tonic-gate  * The group code determines the length of the rest of the command.
55*0Sstevel@tonic-gate  * Group 0 commands are 6 bytes, Group 1 and 2  are 10 bytes, Group 4
56*0Sstevel@tonic-gate  * are 16 bytes, and Group 5 are 12 bytes. Groups 3 is Reserved.
57*0Sstevel@tonic-gate  * Groups 6 and 7 are Vendor Unique.
58*0Sstevel@tonic-gate  *
59*0Sstevel@tonic-gate  */
60*0Sstevel@tonic-gate #define	CDB_SIZE	CDB_GROUP5	/* deprecated, do not use */
61*0Sstevel@tonic-gate #define	SCSI_CDB_SIZE	CDB_GROUP4	/* sizeof (union scsi_cdb) */
62*0Sstevel@tonic-gate 
63*0Sstevel@tonic-gate union scsi_cdb {		/* scsi command description block */
64*0Sstevel@tonic-gate 	struct {
65*0Sstevel@tonic-gate 		uchar_t	cmd;		/* cmd code (byte 0) */
66*0Sstevel@tonic-gate #if defined(_BIT_FIELDS_LTOH)
67*0Sstevel@tonic-gate 		uchar_t tag	:5;	/* rest of byte 1 */
68*0Sstevel@tonic-gate 		uchar_t lun	:3;	/* lun (byte 1) (reserved in SCSI-3) */
69*0Sstevel@tonic-gate #elif defined(_BIT_FIELDS_HTOL)
70*0Sstevel@tonic-gate 		uchar_t	lun	:3,	/* lun (byte 1) (reserved in SCSI-3) */
71*0Sstevel@tonic-gate 			tag	:5;	/* rest of byte 1 */
72*0Sstevel@tonic-gate #else
73*0Sstevel@tonic-gate #error	One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
74*0Sstevel@tonic-gate #endif	/* _BIT_FIELDS_LTOH */
75*0Sstevel@tonic-gate 		union {
76*0Sstevel@tonic-gate 
77*0Sstevel@tonic-gate 		uchar_t	scsi[SCSI_CDB_SIZE-2];
78*0Sstevel@tonic-gate 		/*
79*0Sstevel@tonic-gate 		 *	G R O U P   0   F O R M A T (6 bytes)
80*0Sstevel@tonic-gate 		 */
81*0Sstevel@tonic-gate #define		scc_cmd		cdb_un.cmd
82*0Sstevel@tonic-gate #define		scc_lun		cdb_un.lun
83*0Sstevel@tonic-gate #define		g0_addr2	cdb_un.tag
84*0Sstevel@tonic-gate #define		g0_addr1	cdb_un.sg.g0.addr1
85*0Sstevel@tonic-gate #define		g0_addr0	cdb_un.sg.g0.addr0
86*0Sstevel@tonic-gate #define		g0_count0	cdb_un.sg.g0.count0
87*0Sstevel@tonic-gate #define		g0_vu_1		cdb_un.sg.g0.vu_57
88*0Sstevel@tonic-gate #define		g0_vu_0		cdb_un.sg.g0.vu_56
89*0Sstevel@tonic-gate #define		g0_naca		cdb_un.sg.g0.naca
90*0Sstevel@tonic-gate #define		g0_flag		cdb_un.sg.g0.flag
91*0Sstevel@tonic-gate #define		g0_link		cdb_un.sg.g0.link
92*0Sstevel@tonic-gate 	/*
93*0Sstevel@tonic-gate 	 * defines for SCSI tape cdb.
94*0Sstevel@tonic-gate 	 */
95*0Sstevel@tonic-gate #define		t_code		cdb_un.tag
96*0Sstevel@tonic-gate #define		high_count	cdb_un.sg.g0.addr1
97*0Sstevel@tonic-gate #define		mid_count	cdb_un.sg.g0.addr0
98*0Sstevel@tonic-gate #define		low_count	cdb_un.sg.g0.count0
99*0Sstevel@tonic-gate 		struct scsi_g0 {
100*0Sstevel@tonic-gate 			uchar_t addr1;	/* middle part of address */
101*0Sstevel@tonic-gate 			uchar_t addr0;	/* low part of address */
102*0Sstevel@tonic-gate 			uchar_t count0;	/* usually block count */
103*0Sstevel@tonic-gate #if defined(_BIT_FIELDS_LTOH)
104*0Sstevel@tonic-gate 			uchar_t link	:1; /* another command follows 	*/
105*0Sstevel@tonic-gate 			uchar_t flag	:1; /* interrupt when done 	*/
106*0Sstevel@tonic-gate 			uchar_t naca	:1; /* normal ACA  		*/
107*0Sstevel@tonic-gate 			uchar_t rsvd	:3; /* reserved 		*/
108*0Sstevel@tonic-gate 			uchar_t vu_56	:1; /* vendor unique (byte 5 bit6) */
109*0Sstevel@tonic-gate 			uchar_t vu_57	:1; /* vendor unique (byte 5 bit7) */
110*0Sstevel@tonic-gate #elif defined(_BIT_FIELDS_HTOL)
111*0Sstevel@tonic-gate 			uchar_t vu_57	:1; /* vendor unique (byte 5 bit 7) */
112*0Sstevel@tonic-gate 			uchar_t vu_56	:1; /* vendor unique (byte 5 bit 6) */
113*0Sstevel@tonic-gate 			uchar_t rsvd	:3; /* reserved */
114*0Sstevel@tonic-gate 			uchar_t naca	:1; /* normal ACA  		*/
115*0Sstevel@tonic-gate 			uchar_t flag	:1; /* interrupt when done */
116*0Sstevel@tonic-gate 			uchar_t link	:1; /* another command follows */
117*0Sstevel@tonic-gate #else
118*0Sstevel@tonic-gate #error	One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
119*0Sstevel@tonic-gate #endif	/* _BIT_FIELDS_LTOH */
120*0Sstevel@tonic-gate 		} g0;
121*0Sstevel@tonic-gate 
122*0Sstevel@tonic-gate 
123*0Sstevel@tonic-gate 		/*
124*0Sstevel@tonic-gate 		 *	G R O U P   1, 2   F O R M A T  (10 byte)
125*0Sstevel@tonic-gate 		 */
126*0Sstevel@tonic-gate #define		g1_reladdr	cdb_un.tag
127*0Sstevel@tonic-gate #define		g1_rsvd0	cdb_un.sg.g1.rsvd1
128*0Sstevel@tonic-gate #define		g1_addr3	cdb_un.sg.g1.addr3	/* msb */
129*0Sstevel@tonic-gate #define		g1_addr2	cdb_un.sg.g1.addr2
130*0Sstevel@tonic-gate #define		g1_addr1	cdb_un.sg.g1.addr1
131*0Sstevel@tonic-gate #define		g1_addr0	cdb_un.sg.g1.addr0	/* lsb */
132*0Sstevel@tonic-gate #define		g1_count1	cdb_un.sg.g1.count1	/* msb */
133*0Sstevel@tonic-gate #define		g1_count0	cdb_un.sg.g1.count0	/* lsb */
134*0Sstevel@tonic-gate #define		g1_vu_1		cdb_un.sg.g1.vu_97
135*0Sstevel@tonic-gate #define		g1_vu_0		cdb_un.sg.g1.vu_96
136*0Sstevel@tonic-gate #define		g1_naca		cdb_un.sg.g1.naca
137*0Sstevel@tonic-gate #define		g1_flag		cdb_un.sg.g1.flag
138*0Sstevel@tonic-gate #define		g1_link		cdb_un.sg.g1.link
139*0Sstevel@tonic-gate 		struct scsi_g1 {
140*0Sstevel@tonic-gate 			uchar_t addr3;	/* most sig. byte of address */
141*0Sstevel@tonic-gate 			uchar_t addr2;
142*0Sstevel@tonic-gate 			uchar_t addr1;
143*0Sstevel@tonic-gate 			uchar_t addr0;
144*0Sstevel@tonic-gate 			uchar_t rsvd1;	/* reserved (byte 6) */
145*0Sstevel@tonic-gate 			uchar_t count1;	/* transfer length (msb) */
146*0Sstevel@tonic-gate 			uchar_t count0;	/* transfer length (lsb) */
147*0Sstevel@tonic-gate #if defined(_BIT_FIELDS_LTOH)
148*0Sstevel@tonic-gate 			uchar_t link	:1; /* another command follows 	*/
149*0Sstevel@tonic-gate 			uchar_t flag	:1; /* interrupt when done 	*/
150*0Sstevel@tonic-gate 			uchar_t naca	:1; /* normal ACA		*/
151*0Sstevel@tonic-gate 			uchar_t rsvd0	:3; /* reserved 		*/
152*0Sstevel@tonic-gate 			uchar_t vu_96	:1; /* vendor unique (byte 9 bit6) */
153*0Sstevel@tonic-gate 			uchar_t vu_97	:1; /* vendor unique (byte 9 bit7) */
154*0Sstevel@tonic-gate #elif defined(_BIT_FIELDS_HTOL)
155*0Sstevel@tonic-gate 			uchar_t vu_97	:1; /* vendor unique (byte 9 bit 7) */
156*0Sstevel@tonic-gate 			uchar_t vu_96	:1; /* vendor unique (byte 9 bit 6) */
157*0Sstevel@tonic-gate 			uchar_t rsvd0	:3; /* reserved */
158*0Sstevel@tonic-gate 			uchar_t naca	:1; /* normal ACA		*/
159*0Sstevel@tonic-gate 			uchar_t flag	:1; /* interrupt when done */
160*0Sstevel@tonic-gate 			uchar_t link	:1; /* another command follows */
161*0Sstevel@tonic-gate #else
162*0Sstevel@tonic-gate #error	One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
163*0Sstevel@tonic-gate #endif	/* _BIT_FIELDS_LTOH */
164*0Sstevel@tonic-gate 		} g1;
165*0Sstevel@tonic-gate 
166*0Sstevel@tonic-gate 		/*
167*0Sstevel@tonic-gate 		 *	G R O U P   4   F O R M A T  (16 byte)
168*0Sstevel@tonic-gate 		 */
169*0Sstevel@tonic-gate #define		g4_reladdr		cdb_un.tag
170*0Sstevel@tonic-gate #define		g4_addr3		cdb_un.sg.g4.addr3	/* msb */
171*0Sstevel@tonic-gate #define		g4_addr2		cdb_un.sg.g4.addr2
172*0Sstevel@tonic-gate #define		g4_addr1		cdb_un.sg.g4.addr1
173*0Sstevel@tonic-gate #define		g4_addr0		cdb_un.sg.g4.addr0	/* lsb */
174*0Sstevel@tonic-gate #define		g4_addtl_cdb_data3	cdb_un.sg.g4.addtl_cdb_data3
175*0Sstevel@tonic-gate #define		g4_addtl_cdb_data2	cdb_un.sg.g4.addtl_cdb_data2
176*0Sstevel@tonic-gate #define		g4_addtl_cdb_data1	cdb_un.sg.g4.addtl_cdb_data1
177*0Sstevel@tonic-gate #define		g4_addtl_cdb_data0	cdb_un.sg.g4.addtl_cdb_data0
178*0Sstevel@tonic-gate #define		g4_count3		cdb_un.sg.g4.count3	/* msb */
179*0Sstevel@tonic-gate #define		g4_count2		cdb_un.sg.g4.count2
180*0Sstevel@tonic-gate #define		g4_count1		cdb_un.sg.g4.count1
181*0Sstevel@tonic-gate #define		g4_count0		cdb_un.sg.g4.count0	/* lsb */
182*0Sstevel@tonic-gate #define		g4_rsvd0		cdb_un.sg.g4.rsvd1
183*0Sstevel@tonic-gate #define		g4_vu_1			cdb_un.sg.g4.vu_157
184*0Sstevel@tonic-gate #define		g4_vu_0			cdb_un.sg.g4.vu_156
185*0Sstevel@tonic-gate #define		g4_naca			cdb_un.sg.g4.naca
186*0Sstevel@tonic-gate #define		g4_flag			cdb_un.sg.g4.flag
187*0Sstevel@tonic-gate #define		g4_link			cdb_un.sg.g4.link
188*0Sstevel@tonic-gate 		struct scsi_g4 {
189*0Sstevel@tonic-gate 			uchar_t addr3;	/* most sig. byte of address */
190*0Sstevel@tonic-gate 			uchar_t addr2;
191*0Sstevel@tonic-gate 			uchar_t addr1;
192*0Sstevel@tonic-gate 			uchar_t addr0;
193*0Sstevel@tonic-gate 			uchar_t addtl_cdb_data3;
194*0Sstevel@tonic-gate 			uchar_t addtl_cdb_data2;
195*0Sstevel@tonic-gate 			uchar_t addtl_cdb_data1;
196*0Sstevel@tonic-gate 			uchar_t addtl_cdb_data0;
197*0Sstevel@tonic-gate 			uchar_t count3;	/* transfer length (msb) */
198*0Sstevel@tonic-gate 			uchar_t count2;
199*0Sstevel@tonic-gate 			uchar_t count1;
200*0Sstevel@tonic-gate 			uchar_t count0;	/* transfer length (lsb) */
201*0Sstevel@tonic-gate 			uchar_t rsvd1;	/* reserved */
202*0Sstevel@tonic-gate #if defined(_BIT_FIELDS_LTOH)
203*0Sstevel@tonic-gate 			uchar_t link	:1; /* another command follows 	*/
204*0Sstevel@tonic-gate 			uchar_t flag	:1; /* interrupt when done 	*/
205*0Sstevel@tonic-gate 			uchar_t naca	:1; /* normal ACA		*/
206*0Sstevel@tonic-gate 			uchar_t rsvd0	:3; /* reserved 		*/
207*0Sstevel@tonic-gate 			uchar_t vu_156	:1; /* vendor unique (byte 15 bit6) */
208*0Sstevel@tonic-gate 			uchar_t vu_157	:1; /* vendor unique (byte 15 bit7) */
209*0Sstevel@tonic-gate #elif defined(_BIT_FIELDS_HTOL)
210*0Sstevel@tonic-gate 			uchar_t vu_157	:1; /* vendor unique (byte 15 bit 7) */
211*0Sstevel@tonic-gate 			uchar_t vu_156	:1; /* vendor unique (byte 15 bit 6) */
212*0Sstevel@tonic-gate 			uchar_t rsvd0	:3; /* reserved */
213*0Sstevel@tonic-gate 			uchar_t naca	:1; /* normal ACA		*/
214*0Sstevel@tonic-gate 			uchar_t flag	:1; /* interrupt when done */
215*0Sstevel@tonic-gate 			uchar_t link	:1; /* another command follows */
216*0Sstevel@tonic-gate #else
217*0Sstevel@tonic-gate #error	One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
218*0Sstevel@tonic-gate #endif	/* _BIT_FIELDS_LTOH */
219*0Sstevel@tonic-gate 		} g4;
220*0Sstevel@tonic-gate 
221*0Sstevel@tonic-gate 		/*
222*0Sstevel@tonic-gate 		 *	G R O U P   5   F O R M A T  (12 byte)
223*0Sstevel@tonic-gate 		 */
224*0Sstevel@tonic-gate #define		scc5_reladdr	cdb_un.tag
225*0Sstevel@tonic-gate #define		scc5_addr3	cdb_un.sg.g5.addr3	/* msb */
226*0Sstevel@tonic-gate #define		scc5_addr2	cdb_un.sg.g5.addr2
227*0Sstevel@tonic-gate #define		scc5_addr1	cdb_un.sg.g5.addr1
228*0Sstevel@tonic-gate #define		scc5_addr0	cdb_un.sg.g5.addr0	/* lsb */
229*0Sstevel@tonic-gate #define		scc5_count3	cdb_un.sg.g5.count3	/* msb */
230*0Sstevel@tonic-gate #define		scc5_count2	cdb_un.sg.g5.count2
231*0Sstevel@tonic-gate #define		scc5_count1	cdb_un.sg.g5.count1
232*0Sstevel@tonic-gate #define		scc5_count0	cdb_un.sg.g5.count0	/* lsb */
233*0Sstevel@tonic-gate #define		scc5_rsvd0	cdb_un.sg.g5.rsvd1
234*0Sstevel@tonic-gate #define		scc5_vu_1	cdb_un.sg.g5.v117
235*0Sstevel@tonic-gate #define		scc5_vu_0	cdb_un.sg.g5.v116
236*0Sstevel@tonic-gate #define		scc5_naca	cdb_un.sg.g5.naca
237*0Sstevel@tonic-gate #define		scc5_flag	cdb_un.sg.g5.flag
238*0Sstevel@tonic-gate #define		scc5_link	cdb_un.sg.g5.link
239*0Sstevel@tonic-gate 		struct scsi_g5 {
240*0Sstevel@tonic-gate 			uchar_t addr3;	/* most sig. byte of address */
241*0Sstevel@tonic-gate 			uchar_t addr2;
242*0Sstevel@tonic-gate 			uchar_t addr1;
243*0Sstevel@tonic-gate 			uchar_t addr0;
244*0Sstevel@tonic-gate 			uchar_t count3;	/* most sig. byte of count */
245*0Sstevel@tonic-gate 			uchar_t count2;
246*0Sstevel@tonic-gate 			uchar_t count1;
247*0Sstevel@tonic-gate 			uchar_t count0;
248*0Sstevel@tonic-gate 			uchar_t rsvd1;	/* reserved */
249*0Sstevel@tonic-gate #if defined(_BIT_FIELDS_LTOH)
250*0Sstevel@tonic-gate 			uchar_t link	:1; /* another command follows 	*/
251*0Sstevel@tonic-gate 			uchar_t flag	:1; /* interrupt when done 	*/
252*0Sstevel@tonic-gate 			uchar_t naca	:1; /* normal ACA		*/
253*0Sstevel@tonic-gate 			uchar_t rsvd0	:3; /* reserved 		*/
254*0Sstevel@tonic-gate 			uchar_t vu_116	:1; /* vendor unique (byte 11 bit6) */
255*0Sstevel@tonic-gate 			uchar_t vu_117	:1; /* vendor unique (byte 11 bit7) */
256*0Sstevel@tonic-gate #elif defined(_BIT_FIELDS_HTOL)
257*0Sstevel@tonic-gate 			uchar_t vu_117	:1; /* vendor unique (byte 11 bit 7) */
258*0Sstevel@tonic-gate 			uchar_t vu_116	:1; /* vendor unique (byte 11 bit 6) */
259*0Sstevel@tonic-gate 			uchar_t rsvd0	:3; /* reserved */
260*0Sstevel@tonic-gate 			uchar_t naca	:1; /* normal ACA		*/
261*0Sstevel@tonic-gate 			uchar_t flag	:1; /* interrupt when done */
262*0Sstevel@tonic-gate 			uchar_t link	:1; /* another command follows */
263*0Sstevel@tonic-gate #else
264*0Sstevel@tonic-gate #error	One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
265*0Sstevel@tonic-gate #endif	/* _BIT_FIELDS_LTOH */
266*0Sstevel@tonic-gate 		} g5;
267*0Sstevel@tonic-gate 		}sg;
268*0Sstevel@tonic-gate 	} cdb_un;
269*0Sstevel@tonic-gate 	uchar_t cdb_opaque[SCSI_CDB_SIZE]; /* addressed as opaque char array */
270*0Sstevel@tonic-gate 	uint_t cdb_long[SCSI_CDB_SIZE / sizeof (uint_t)]; /* as a word array */
271*0Sstevel@tonic-gate };
272*0Sstevel@tonic-gate 
273*0Sstevel@tonic-gate 
274*0Sstevel@tonic-gate /*
275*0Sstevel@tonic-gate  *	Various useful Macros for SCSI commands
276*0Sstevel@tonic-gate  */
277*0Sstevel@tonic-gate 
278*0Sstevel@tonic-gate /*
279*0Sstevel@tonic-gate  * defines for getting/setting fields within the various command groups
280*0Sstevel@tonic-gate  */
281*0Sstevel@tonic-gate 
282*0Sstevel@tonic-gate #define	GETCMD(cdb)		((cdb)->scc_cmd & 0x1F)
283*0Sstevel@tonic-gate #define	GETGROUP(cdb)		(CDB_GROUPID((cdb)->scc_cmd))
284*0Sstevel@tonic-gate 
285*0Sstevel@tonic-gate #define	FORMG0COUNT(cdb, cnt)	(cdb)->g0_count0  = (cnt)
286*0Sstevel@tonic-gate 
287*0Sstevel@tonic-gate #define	FORMG0ADDR(cdb, addr) 	(cdb)->g0_addr2  = (addr) >> 16; \
288*0Sstevel@tonic-gate 				(cdb)->g0_addr1  = ((addr) >> 8) & 0xFF; \
289*0Sstevel@tonic-gate 				(cdb)->g0_addr0  = (addr) & 0xFF
290*0Sstevel@tonic-gate 
291*0Sstevel@tonic-gate #define	GETG0ADDR(cdb)		(((cdb)->g0_addr2 & 0x1F) << 16) + \
292*0Sstevel@tonic-gate 				((cdb)->g0_addr1 << 8) + ((cdb)->g0_addr0)
293*0Sstevel@tonic-gate 
294*0Sstevel@tonic-gate #define	GETG0TAG(cdb)		((cdb)->g0_addr2)
295*0Sstevel@tonic-gate 
296*0Sstevel@tonic-gate #define	FORMG0COUNT_S(cdb, cnt)	(cdb)->high_count  = (cnt) >> 16; \
297*0Sstevel@tonic-gate 				(cdb)->mid_count = ((cnt) >> 8) & 0xFF; \
298*0Sstevel@tonic-gate 				(cdb)->low_count = (cnt) & 0xFF
299*0Sstevel@tonic-gate 
300*0Sstevel@tonic-gate #define	FORMG1COUNT(cdb, cnt)	(cdb)->g1_count1 = ((cnt) >> 8); \
301*0Sstevel@tonic-gate 				(cdb)->g1_count0 = (cnt) & 0xFF
302*0Sstevel@tonic-gate 
303*0Sstevel@tonic-gate #define	FORMG1ADDR(cdb, addr)	(cdb)->g1_addr3  = (addr) >> 24; \
304*0Sstevel@tonic-gate 				(cdb)->g1_addr2  = ((addr) >> 16) & 0xFF; \
305*0Sstevel@tonic-gate 				(cdb)->g1_addr1  = ((addr) >> 8) & 0xFF; \
306*0Sstevel@tonic-gate 				(cdb)->g1_addr0  = (addr) & 0xFF
307*0Sstevel@tonic-gate 
308*0Sstevel@tonic-gate #define	GETG1ADDR(cdb)		((cdb)->g1_addr3 << 24) + \
309*0Sstevel@tonic-gate 				((cdb)->g1_addr2 << 16) + \
310*0Sstevel@tonic-gate 				((cdb)->g1_addr1 << 8)  + \
311*0Sstevel@tonic-gate 				((cdb)->g1_addr0)
312*0Sstevel@tonic-gate 
313*0Sstevel@tonic-gate #define	GETG1TAG(cdb)		(cdb)->g1_reladdr
314*0Sstevel@tonic-gate 
315*0Sstevel@tonic-gate #define	FORMG4COUNT(cdb, cnt)	(cdb)->g4_count3 = ((cnt) >> 24); \
316*0Sstevel@tonic-gate 				(cdb)->g4_count2 = ((cnt) >> 16) & 0xFF; \
317*0Sstevel@tonic-gate 				(cdb)->g4_count1 = ((cnt) >> 8) & 0xFF; \
318*0Sstevel@tonic-gate 				(cdb)->g4_count0 = (cnt) & 0xFF
319*0Sstevel@tonic-gate 
320*0Sstevel@tonic-gate #define	FORMG4LONGADDR(cdb, addr)	(cdb)->g4_addr3 = (addr) >> 56; \
321*0Sstevel@tonic-gate 					(cdb)->g4_addr2 = \
322*0Sstevel@tonic-gate 						((addr) >> 48) & 0xFF; \
323*0Sstevel@tonic-gate 					(cdb)->g4_addr1 = \
324*0Sstevel@tonic-gate 						((addr) >> 40) & 0xFF; \
325*0Sstevel@tonic-gate 					(cdb)->g4_addr0 = \
326*0Sstevel@tonic-gate 						((addr) >> 32) & 0xFF; \
327*0Sstevel@tonic-gate 					(cdb)->g4_addtl_cdb_data3 = \
328*0Sstevel@tonic-gate 						((addr) >> 24) & 0xFF; \
329*0Sstevel@tonic-gate 					(cdb)->g4_addtl_cdb_data2 = \
330*0Sstevel@tonic-gate 						((addr) >> 16) & 0xFF; \
331*0Sstevel@tonic-gate 					(cdb)->g4_addtl_cdb_data1 = \
332*0Sstevel@tonic-gate 						((addr) >> 8) & 0xFF; \
333*0Sstevel@tonic-gate 					(cdb)->g4_addtl_cdb_data0 = \
334*0Sstevel@tonic-gate 						(addr) & 0xFF
335*0Sstevel@tonic-gate 
336*0Sstevel@tonic-gate #define	FORMG4ADDR(cdb, addr)	(cdb)->g4_addr3 = (addr) >> 24; \
337*0Sstevel@tonic-gate 				(cdb)->g4_addr2 = ((addr) >> 16) & 0xFF; \
338*0Sstevel@tonic-gate 				(cdb)->g4_addr1 = ((addr) >> 8) & 0xFF; \
339*0Sstevel@tonic-gate 				(cdb)->g4_addr0 = (addr) & 0xFF
340*0Sstevel@tonic-gate 
341*0Sstevel@tonic-gate #define	FORMG4ADDTL(cdb, addtl_cdb_data) (cdb)->g4_addtl_cdb_data3 = \
342*0Sstevel@tonic-gate 					(addtl_cdb_data) >> 24; \
343*0Sstevel@tonic-gate 				(cdb)->g4_addtl_cdb_data2 = \
344*0Sstevel@tonic-gate 					((addtl_cdb_data) >> 16) & 0xFF; \
345*0Sstevel@tonic-gate 				(cdb)->g4_addtl_cdb_data1 = \
346*0Sstevel@tonic-gate 					((addtl_cdb_data) >> 8) & 0xFF; \
347*0Sstevel@tonic-gate 				(cdb)->g4_addtl_cdb_data0 = \
348*0Sstevel@tonic-gate 					(addtl_cdb_data) & 0xFF
349*0Sstevel@tonic-gate 
350*0Sstevel@tonic-gate #define	GETG4ADDR(cdb)		((cdb)->g4_addr3 << 24) + \
351*0Sstevel@tonic-gate 				((cdb)->g4_addr2 << 16) + \
352*0Sstevel@tonic-gate 				((cdb)->g4_addr1 << 8)  + \
353*0Sstevel@tonic-gate 				((cdb)->g4_addr0)
354*0Sstevel@tonic-gate 
355*0Sstevel@tonic-gate #define	GETG4ADDRTL(cdb)	(((cdb)->g4_addtl_cdb_data3 << 24) + \
356*0Sstevel@tonic-gate 				((cdb)->g4_addtl_cdb_data2 << 16) + \
357*0Sstevel@tonic-gate 				((cdb)->g4_addtl_cdb_data1 << 8) + \
358*0Sstevel@tonic-gate 				(cdb)->g4_addtl_cdb_data0)
359*0Sstevel@tonic-gate 
360*0Sstevel@tonic-gate #define	GETG4TAG(cdb)		(cdb)->g4_reladdr
361*0Sstevel@tonic-gate 
362*0Sstevel@tonic-gate #define	FORMG5COUNT(cdb, cnt)	(cdb)->scc5_count3 = ((cnt) >> 24); \
363*0Sstevel@tonic-gate 				(cdb)->scc5_count2 = ((cnt) >> 16) & 0xFF; \
364*0Sstevel@tonic-gate 				(cdb)->scc5_count1 = ((cnt) >> 8) & 0xFF; \
365*0Sstevel@tonic-gate 				(cdb)->scc5_count0 = (cnt) & 0xFF
366*0Sstevel@tonic-gate 
367*0Sstevel@tonic-gate #define	FORMG5ADDR(cdb, addr)	(cdb)->scc5_addr3  = (addr) >> 24; \
368*0Sstevel@tonic-gate 				(cdb)->scc5_addr2  = ((addr) >> 16) & 0xFF; \
369*0Sstevel@tonic-gate 				(cdb)->scc5_addr1  = ((addr) >> 8) & 0xFF; \
370*0Sstevel@tonic-gate 				(cdb)->scc5_addr0  = (addr) & 0xFF
371*0Sstevel@tonic-gate 
372*0Sstevel@tonic-gate #define	GETG5ADDR(cdb)		((cdb)->scc5_addr3 << 24) + \
373*0Sstevel@tonic-gate 				((cdb)->scc5_addr2 << 16) + \
374*0Sstevel@tonic-gate 				((cdb)->scc5_addr1 << 8)  + \
375*0Sstevel@tonic-gate 				((cdb)->scc5_addr0)
376*0Sstevel@tonic-gate 
377*0Sstevel@tonic-gate #define	GETG5TAG(cdb)		(cdb)->scc5_reladdr
378*0Sstevel@tonic-gate 
379*0Sstevel@tonic-gate 
380*0Sstevel@tonic-gate /*
381*0Sstevel@tonic-gate  * Shorthand macros for forming commands
382*0Sstevel@tonic-gate  *
383*0Sstevel@tonic-gate  * Works only with pre-SCSI-3 because they put lun as part of CDB.
384*0Sstevel@tonic-gate  * scsi_setup_cdb() is the recommended interface.
385*0Sstevel@tonic-gate  */
386*0Sstevel@tonic-gate 
387*0Sstevel@tonic-gate #define	MAKECOM_COMMON(pktp, devp, flag, cmd)	\
388*0Sstevel@tonic-gate 	(pktp)->pkt_address = (devp)->sd_address, \
389*0Sstevel@tonic-gate 	(pktp)->pkt_flags = (flag), \
390*0Sstevel@tonic-gate 	((union scsi_cdb *)(pktp)->pkt_cdbp)->scc_cmd = (cmd), \
391*0Sstevel@tonic-gate 	((union scsi_cdb *)(pktp)->pkt_cdbp)->scc_lun = \
392*0Sstevel@tonic-gate 	    (pktp)->pkt_address.a_lun
393*0Sstevel@tonic-gate 
394*0Sstevel@tonic-gate #define	MAKECOM_G0(pktp, devp, flag, cmd, addr, cnt)	\
395*0Sstevel@tonic-gate 	MAKECOM_COMMON((pktp), (devp), (flag), (cmd)), \
396*0Sstevel@tonic-gate 	FORMG0ADDR(((union scsi_cdb *)(pktp)->pkt_cdbp), (addr)), \
397*0Sstevel@tonic-gate 	FORMG0COUNT(((union scsi_cdb *)(pktp)->pkt_cdbp), (cnt))
398*0Sstevel@tonic-gate 
399*0Sstevel@tonic-gate #define	MAKECOM_G0_S(pktp, devp, flag, cmd, cnt, fixbit)	\
400*0Sstevel@tonic-gate 	MAKECOM_COMMON((pktp), (devp), (flag), (cmd)), \
401*0Sstevel@tonic-gate 	FORMG0COUNT_S(((union scsi_cdb *)(pktp)->pkt_cdbp), (cnt)), \
402*0Sstevel@tonic-gate 	((union scsi_cdb *)(pktp)->pkt_cdbp)->t_code = (fixbit)
403*0Sstevel@tonic-gate 
404*0Sstevel@tonic-gate #define	MAKECOM_G1(pktp, devp, flag, cmd, addr, cnt)	\
405*0Sstevel@tonic-gate 	MAKECOM_COMMON((pktp), (devp), (flag), (cmd)), \
406*0Sstevel@tonic-gate 	FORMG1ADDR(((union scsi_cdb *)(pktp)->pkt_cdbp), (addr)), \
407*0Sstevel@tonic-gate 	FORMG1COUNT(((union scsi_cdb *)(pktp)->pkt_cdbp), (cnt))
408*0Sstevel@tonic-gate 
409*0Sstevel@tonic-gate #define	MAKECOM_G5(pktp, devp, flag, cmd, addr, cnt)	\
410*0Sstevel@tonic-gate 	MAKECOM_COMMON((pktp), (devp), (flag), (cmd)), \
411*0Sstevel@tonic-gate 	FORMG5ADDR(((union scsi_cdb *)(pktp)->pkt_cdbp), (addr)), \
412*0Sstevel@tonic-gate 	FORMG5COUNT(((union scsi_cdb *)(pktp)->pkt_cdbp), (cnt))
413*0Sstevel@tonic-gate 
414*0Sstevel@tonic-gate 
415*0Sstevel@tonic-gate /*
416*0Sstevel@tonic-gate  * Direct access disk format defines and parameters.
417*0Sstevel@tonic-gate  *
418*0Sstevel@tonic-gate  * This is still pretty ugly and is mostly derived
419*0Sstevel@tonic-gate  * from Emulex MD21 specific formatting.
420*0Sstevel@tonic-gate  */
421*0Sstevel@tonic-gate 
422*0Sstevel@tonic-gate #define	fmt_parm_bits		g0_addr2	/* for format options */
423*0Sstevel@tonic-gate #define	fmt_interleave		g0_count0	/* for encode interleave */
424*0Sstevel@tonic-gate #define	defect_list_descrip	g1_addr3	/* list description bits */
425*0Sstevel@tonic-gate 
426*0Sstevel@tonic-gate /*
427*0Sstevel@tonic-gate  * defines for value of fmt_parm_bits.
428*0Sstevel@tonic-gate  */
429*0Sstevel@tonic-gate 
430*0Sstevel@tonic-gate #define	FPB_BFI			0x04	/* bytes-from-index fmt */
431*0Sstevel@tonic-gate #define	FPB_CMPLT		0x08	/* full defect list provided */
432*0Sstevel@tonic-gate #define	FPB_DATA		0x10	/* defect list data provided */
433*0Sstevel@tonic-gate 
434*0Sstevel@tonic-gate /*
435*0Sstevel@tonic-gate  * Defines for value of defect_list_descrip.
436*0Sstevel@tonic-gate  */
437*0Sstevel@tonic-gate 
438*0Sstevel@tonic-gate #define	DLD_MAN_DEF_LIST	0x10	/* manufacturer's defect list */
439*0Sstevel@tonic-gate #define	DLD_GROWN_DEF_LIST	0x08	/* grown defect list */
440*0Sstevel@tonic-gate #define	DLD_BLOCK_FORMAT	0x00	/* block format */
441*0Sstevel@tonic-gate #define	DLD_BFI_FORMAT		0x04	/* bytes-from-index format */
442*0Sstevel@tonic-gate #define	DLD_PS_FORMAT		0x05	/* physical sector format */
443*0Sstevel@tonic-gate 
444*0Sstevel@tonic-gate 
445*0Sstevel@tonic-gate /*
446*0Sstevel@tonic-gate  * Disk defect list - used by format command.
447*0Sstevel@tonic-gate  */
448*0Sstevel@tonic-gate #define	RDEF_ALL	0	/* read all defects */
449*0Sstevel@tonic-gate #define	RDEF_MANUF	1	/* read manufacturer's defects */
450*0Sstevel@tonic-gate #define	RDEF_CKLEN	2	/* check length of manufacturer's list */
451*0Sstevel@tonic-gate #define	ST506_NDEFECT	127	/* must fit in 1K controller buffer... */
452*0Sstevel@tonic-gate #define	ESDI_NDEFECT	ST506_NDEFECT
453*0Sstevel@tonic-gate 
454*0Sstevel@tonic-gate struct scsi_bfi_defect {	/* defect in bytes from index format */
455*0Sstevel@tonic-gate 	unsigned cyl  : 24;
456*0Sstevel@tonic-gate 	unsigned head : 8;
457*0Sstevel@tonic-gate 	int	bytes_from_index;
458*0Sstevel@tonic-gate };
459*0Sstevel@tonic-gate 
460*0Sstevel@tonic-gate struct scsi_format_params {	/* BFI format list */
461*0Sstevel@tonic-gate 	ushort_t reserved;
462*0Sstevel@tonic-gate 	ushort_t length;
463*0Sstevel@tonic-gate 	struct  scsi_bfi_defect list[ESDI_NDEFECT];
464*0Sstevel@tonic-gate };
465*0Sstevel@tonic-gate 
466*0Sstevel@tonic-gate /*
467*0Sstevel@tonic-gate  * Defect list returned by READ_DEFECT_LIST command.
468*0Sstevel@tonic-gate  */
469*0Sstevel@tonic-gate struct scsi_defect_hdr {	/* For getting defect list size */
470*0Sstevel@tonic-gate 	uchar_t	reserved;
471*0Sstevel@tonic-gate 	uchar_t	descriptor;
472*0Sstevel@tonic-gate 	ushort_t length;
473*0Sstevel@tonic-gate };
474*0Sstevel@tonic-gate 
475*0Sstevel@tonic-gate struct scsi_defect_list {	/* BFI format list */
476*0Sstevel@tonic-gate 	uchar_t	reserved;
477*0Sstevel@tonic-gate 	uchar_t	descriptor;
478*0Sstevel@tonic-gate 	ushort_t length;
479*0Sstevel@tonic-gate 	struct	scsi_bfi_defect list[ESDI_NDEFECT];
480*0Sstevel@tonic-gate };
481*0Sstevel@tonic-gate 
482*0Sstevel@tonic-gate /*
483*0Sstevel@tonic-gate  *
484*0Sstevel@tonic-gate  * Direct Access device Reassign Block parameter
485*0Sstevel@tonic-gate  *
486*0Sstevel@tonic-gate  * Defect list format used by reassign block command (logical block format).
487*0Sstevel@tonic-gate  *
488*0Sstevel@tonic-gate  * This defect list is limited to 1 defect, as that is the only way we use it.
489*0Sstevel@tonic-gate  *
490*0Sstevel@tonic-gate  */
491*0Sstevel@tonic-gate 
492*0Sstevel@tonic-gate struct scsi_reassign_blk {
493*0Sstevel@tonic-gate 	ushort_t reserved;
494*0Sstevel@tonic-gate 	ushort_t length;	/* defect length in bytes (defects * 4) */
495*0Sstevel@tonic-gate 	uint_t 	defect;		/* Logical block address of defect */
496*0Sstevel@tonic-gate };
497*0Sstevel@tonic-gate 
498*0Sstevel@tonic-gate /*
499*0Sstevel@tonic-gate  * Direct Access Device Capacity Structure -- 8 byte version
500*0Sstevel@tonic-gate  */
501*0Sstevel@tonic-gate 
502*0Sstevel@tonic-gate struct scsi_capacity {
503*0Sstevel@tonic-gate 	uint_t	capacity;
504*0Sstevel@tonic-gate 	uint_t	lbasize;
505*0Sstevel@tonic-gate };
506*0Sstevel@tonic-gate 
507*0Sstevel@tonic-gate /*
508*0Sstevel@tonic-gate  * Direct Access Device Capacity Structure -- 16 byte version
509*0Sstevel@tonic-gate  */
510*0Sstevel@tonic-gate 
511*0Sstevel@tonic-gate struct scsi_capacity_16 {
512*0Sstevel@tonic-gate 	uint64_t	sc_capacity;
513*0Sstevel@tonic-gate 	uint_t		sc_lbasize;
514*0Sstevel@tonic-gate #if defined(_BIT_FIELDS_LTOH)
515*0Sstevel@tonic-gate 	uchar_t 	sc_rto_en	:1;
516*0Sstevel@tonic-gate 	uchar_t 	sc_prot_en	:1;
517*0Sstevel@tonic-gate 	uchar_t 	sc_rsvd0	:6;
518*0Sstevel@tonic-gate #elif defined(_BIT_FIELDS_HTOL)
519*0Sstevel@tonic-gate 	uchar_t 	sc_rsvd0	:6;
520*0Sstevel@tonic-gate 	uchar_t 	sc_prot_en	:1;
521*0Sstevel@tonic-gate 	uchar_t 	sc_rto_en	:1;
522*0Sstevel@tonic-gate #else
523*0Sstevel@tonic-gate #error	One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
524*0Sstevel@tonic-gate #endif	/* _BIT_FIELDS_LTOH */
525*0Sstevel@tonic-gate 	uchar_t 	sc_rsvd1[19];
526*0Sstevel@tonic-gate };
527*0Sstevel@tonic-gate 
528*0Sstevel@tonic-gate #ifdef	_KERNEL
529*0Sstevel@tonic-gate 
530*0Sstevel@tonic-gate /*
531*0Sstevel@tonic-gate  * Functional versions of the above macros, and other functions.
532*0Sstevel@tonic-gate  * the makecom functions have been deprecated. Please use
533*0Sstevel@tonic-gate  * scsi_setup_cdb()
534*0Sstevel@tonic-gate  */
535*0Sstevel@tonic-gate 
536*0Sstevel@tonic-gate #ifdef  __STDC__
537*0Sstevel@tonic-gate extern void 	makecom_g0(struct scsi_pkt *pkt, struct scsi_device *devp,
538*0Sstevel@tonic-gate 				int flag, int cmd, int addr, int cnt);
539*0Sstevel@tonic-gate extern void 	makecom_g0_s(struct scsi_pkt *pkt, struct scsi_device *devp,
540*0Sstevel@tonic-gate 				int flag, int cmd, int cnt, int fixbit);
541*0Sstevel@tonic-gate extern void 	makecom_g1(struct scsi_pkt *pkt, struct scsi_device *devp,
542*0Sstevel@tonic-gate 				int flag, int cmd, int addr, int cnt);
543*0Sstevel@tonic-gate extern void 	makecom_g5(struct scsi_pkt *pkt, struct scsi_device *devp,
544*0Sstevel@tonic-gate 				int flag, int cmd, int addr, int cnt);
545*0Sstevel@tonic-gate extern int	scsi_setup_cdb(union scsi_cdb *cdbp, uchar_t cmd, uint_t addr,
546*0Sstevel@tonic-gate 				uint_t cnt, uint_t addtl_cdb_data);
547*0Sstevel@tonic-gate 
548*0Sstevel@tonic-gate #else   /* __STDC__ */
549*0Sstevel@tonic-gate 
550*0Sstevel@tonic-gate extern void 	makecom_g0();
551*0Sstevel@tonic-gate extern void 	makecom_g0_s();
552*0Sstevel@tonic-gate extern void 	makecom_g1();
553*0Sstevel@tonic-gate extern void 	makecom_g5();
554*0Sstevel@tonic-gate extern int	scsi_setup_cdb();
555*0Sstevel@tonic-gate 
556*0Sstevel@tonic-gate #endif  /* __STDC__ */
557*0Sstevel@tonic-gate 
558*0Sstevel@tonic-gate #endif /* _KERNEL */
559*0Sstevel@tonic-gate 
560*0Sstevel@tonic-gate #ifdef	__cplusplus
561*0Sstevel@tonic-gate }
562*0Sstevel@tonic-gate #endif
563*0Sstevel@tonic-gate 
564*0Sstevel@tonic-gate #endif	/* _SYS_SCSI_IMPL_COMMANDS_H */
565