commands.h revision 6316:40d5384cc8b2
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
32extern "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
62union 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
588struct scsi_bfi_defect {	/* defect in bytes from index format */
589	unsigned cyl  : 24;
590	unsigned head : 8;
591	int	bytes_from_index;
592};
593
594struct 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 */
603struct scsi_defect_hdr {	/* For getting defect list size */
604	uchar_t	reserved;
605	uchar_t	descriptor;
606	ushort_t length;
607};
608
609struct 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
626struct 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
636struct scsi_capacity {
637	uint_t	capacity;
638	uint_t	lbasize;
639};
640
641/*
642 * Direct Access Device Capacity Structure -- 16 byte version
643 */
644
645struct 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__
671extern void 	makecom_g0(struct scsi_pkt *pkt, struct scsi_device *devp,
672				int flag, int cmd, int addr, int cnt);
673extern void 	makecom_g0_s(struct scsi_pkt *pkt, struct scsi_device *devp,
674				int flag, int cmd, int cnt, int fixbit);
675extern void 	makecom_g1(struct scsi_pkt *pkt, struct scsi_device *devp,
676				int flag, int cmd, int addr, int cnt);
677extern void 	makecom_g5(struct scsi_pkt *pkt, struct scsi_device *devp,
678				int flag, int cmd, int addr, int cnt);
679extern 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
684extern void 	makecom_g0();
685extern void 	makecom_g0_s();
686extern void 	makecom_g1();
687extern void 	makecom_g5();
688extern 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