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
31 extern "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
61 union 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
591 struct scsi_bfi_defect { /* defect in bytes from index format */
592 unsigned cyl : 24;
593 unsigned head : 8;
594 int bytes_from_index;
595 };
596
597 struct 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 */
606 struct scsi_defect_hdr { /* For getting defect list size */
607 uchar_t reserved;
608 uchar_t descriptor;
609 ushort_t length;
610 };
611
612 struct 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
629 struct 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
639 struct scsi_capacity {
640 uint_t capacity;
641 uint_t lbasize;
642 };
643
644 /*
645 * Direct Access Device Capacity Structure -- 16 byte version
646 */
647
648 struct 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
673 extern void makecom_g0(struct scsi_pkt *pkt, struct scsi_device *devp,
674 int flag, int cmd, int addr, int cnt);
675 extern void makecom_g0_s(struct scsi_pkt *pkt, struct scsi_device *devp,
676 int flag, int cmd, int cnt, int fixbit);
677 extern void makecom_g1(struct scsi_pkt *pkt, struct scsi_device *devp,
678 int flag, int cmd, int addr, int cnt);
679 extern void makecom_g5(struct scsi_pkt *pkt, struct scsi_device *devp,
680 int flag, int cmd, int addr, int cnt);
681 extern int scsi_setup_cdb(union scsi_cdb *cdbp, uchar_t cmd, uint_t addr,
682 uint_t cnt, uint_t addtl_cdb_data);
683
684 #endif /* _KERNEL */
685
686 #ifdef __cplusplus
687 }
688 #endif
689
690 #endif /* _SYS_SCSI_IMPL_COMMANDS_H */