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