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 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 #ifndef _T10_SPC_H
28 #define _T10_SPC_H
29
30 #pragma ident "%Z%%M% %I% %E% SMI"
31
32 #ifdef __cplusplus
33 extern "C" {
34 #endif
35
36 /*
37 * []------------------------------------------------------------------[]
38 * | SPC-3 |
39 * []------------------------------------------------------------------[]
40 */
41
42 /*
43 * FIXED_SENSE_ADDL_INFO_LEN is the length of INFORMATION field
44 * in fixed format sense data
45 */
46 #define FIXED_SENSE_ADDL_INFO_LEN 0xFFFFFFFF
47 #define INFORMATION_SENSE_DESCR sizeof (struct scsi_information_sense_descr)
48
49 #include <sys/scsi/generic/inquiry.h>
50 #include <sys/scsi/generic/mode.h>
51
52 /*
53 * SPC Command Functions
54 */
55 void spc_tur(struct t10_cmd *cmd, uint8_t *cdb, size_t cdb_len);
56 void spc_request_sense(struct t10_cmd *cmd, uint8_t *cdb, size_t cdb_len);
57 void spc_unsupported(struct t10_cmd *cmd, uint8_t *cdb, size_t cdb_len);
58 void spc_inquiry(t10_cmd_t *cmd, uint8_t *cdb, size_t cdb_len);
59 void spc_mselect(t10_cmd_t *cmd, uint8_t *cdb, size_t cdb_len);
60 void spc_mselect_data(t10_cmd_t *cmd, emul_handle_t id, size_t offset,
61 char *data, size_t data_len);
62 void spc_report_luns(t10_cmd_t *cmd, uint8_t *cdb, size_t cdb_len);
63 void spc_report_tpgs(t10_cmd_t *cmd, uint8_t *cdb, size_t cdb_len);
64 void spc_msense(t10_cmd_t *cmd, uint8_t *cdb, size_t cdb_len);
65 void spc_startstop(t10_cmd_t *cmd, uint8_t *cdb, size_t cdb_len);
66 void spc_send_diag(t10_cmd_t *cmd, uint8_t *cdb, size_t cdb_len);
67
68 /*
69 * SPC Support Functions
70 */
71 void spc_cmd_offline(t10_cmd_t *cmd, uint8_t *cdb, size_t cdb_len);
72 void spc_sense_create(struct t10_cmd *cmd, int sense_key, int addl_sense_len);
73 void spc_sense_ascq(struct t10_cmd *cmd, int asc, int ascq);
74 void spc_sense_info(t10_cmd_t *cmd, uint64_t info);
75 void spc_sense_flags(t10_cmd_t *cmd, int flags);
76 void spc_sense_raw(t10_cmd_t *cmd, uchar_t *sense_buf, size_t sense_len);
77 Boolean_t spc_decode_lu_addr(uint8_t *buf, int len, uint32_t *val);
78 Boolean_t spc_encode_lu_addr(uint8_t *buf, int select_field, uint32_t lun);
79
80 /*
81 * SPC flags to use when setting various sense code flags
82 */
83 #define SPC_SENSE_EOM 0x01
84 #define SPC_SENSE_FM 0x02
85 #define SPC_SENSE_ILI 0x04
86
87 #ifdef _BIG_ENDIAN
88 #define htonll(x) (x)
89 #define ntohll(x) (x)
90 #else
91 #define htonll(x) ((((unsigned long long)htonl(x & 0xffffffff)) << 32) + \
92 htonl(x >> 32))
93 #define ntohll(x) ((((unsigned long long)ntohl(x)) << 32) + ntohl(x >> 32))
94 #endif
95
96 /*
97 * []------------------------------------------------------------------[]
98 * | SPC-3, revision 21c -- ASC/ASCQ values |
99 * | The full tables can be found in Appendix D (numerical order) or |
100 * | section 4.5.6 (alphabetical order). There are close to fifteen |
101 * | pages of values which will not be included here. Only those used |
102 * | by the code. |
103 * []------------------------------------------------------------------[]
104 */
105 #define SPC_ASC_FM_DETECTED 0x00 /* file-mark detected */
106 #define SPC_ASCQ_FM_DETECTED 0x01
107
108 #define SPC_ASC_EOP 0x00 /* end-of-partition/medium detected */
109 #define SPC_ASCQ_EOP 0x02
110
111 #define SPC_ASC_IN_PROG 0x04
112 #define SPC_ASCQ_IN_PROG 0x07
113
114 #define SPC_ASC_WRITE_ERROR 0x0c
115 #define SPC_ASCQ_WRITE_ERROR 0x00
116
117 #define SPC_ASC_PARAM_LIST_LEN 0x1a /* Parameter List Length Error */
118 #define SPC_ASCQ_PARAM_LIST_LEN 0x00
119
120 #define SPC_ASC_MISCOMPARE 0x1d
121 #define SPC_ASCQ_MISCOMPARE 0x00
122
123 #define SPC_ASC_INVALID_LU 0x20
124 #define SPC_ASCQ_INVALID_LU 0x09
125
126 #define SPC_ASC_BLOCK_RANGE 0x21
127 #define SPC_ASCQ_BLOCK_RANGE 0x00
128
129 #define SPC_ASC_INVALID_FIELD_IN_PARAMETER_LIST 0x26
130 #define SPC_ASCQ_INVALID_FIELD_IN_PARAMETER_LIST 0x00
131
132 #define SPC_ASC_INVALID_CDB 0x24
133 #define SPC_ASCQ_INVALID_CDB 0x00
134
135 #define SPC_ASC_PARAMETERS_CHANGED 0x2a
136 #define SPC_ASCQ_RES_PREEMPTED 0x03
137 #define SPC_ASCQ_RES_RELEASED 0x04
138
139 #define SPC_ASC_PWR_RESET 0x29
140 #define SPC_ASCQ_PWR_RESET 0x00
141
142 #define SPC_ASC_PWR_ON 0x29
143 #define SPC_ASCQ_PWR_ON 0x01
144
145 #define SPC_ASC_BUS_RESET 0x29
146 #define SPC_ASCQ_BUS_RESET 0x02
147
148 #define SPC_ASC_CAP_CHANGE 0x2a
149 #define SPC_ASCQ_CAP_CHANGE 0x09
150
151 #define SPC_ASC_DATA_PATH 0x41
152 #define SPC_ASCQ_DATA_PATH 0x00
153
154 #define SPC_ASC_MEMORY_OUT_OF 0x55 /* Auxillary Memory Out Of Space */
155 #define SPC_ASCQ_MEMORY_OUT_OF 0x00
156 #define SPC_ASCQ_RESERVATION_FAIL 0x02
157
158
159 /*
160 * []------------------------------------------------------------------[]
161 * | SAM-3, revision 14, section 5.2 - Command descriptor block (CDB) |
162 * | |
163 * | "All CDBs shall contain a CONTROL byte (see table 21). The |
164 * | location of the CONTROL byte within a CDB depends on the CDB |
165 * | format (see SPC-3)." |
166 * | |
167 * | bits meaning |
168 * | 6-7 vendor specific (we don't use so must be zero) |
169 * | 3-5 reserved must be zero |
170 * | 2 NACA (currently we don't support so must be zero) |
171 * | 1 Obsolete |
172 * | 0 Link (currently we don't support so must be zero) |
173 * | |
174 * | So, this means the control byte must be zero and therefore if |
175 * | this macro returns a non-zero value the emulation code should |
176 * | return a CHECK CONDITION with status set to ILLEGAL REQUEST |
177 * | and the additional sense code set to INVALID FIELD IN CDB. |
178 * | |
179 * | In the future this will likely change with support routines |
180 * | added for dealing with NACA and Linked commands. |
181 * []------------------------------------------------------------------[]
182 */
183 #define SAM_CONTROL_BYTE_RESERVED(byte) (byte)
184
185 /* ---- Disable Block Descriptors ---- */
186 #define SPC_MODE_SENSE_DBD 0x8
187
188 #define SPC_GROUP4_SERVICE_ACTION_MASK 0x1f
189
190 #define SPC_SEND_DIAG_SELFTEST 0x04
191
192 /*
193 * []------------------------------------------------------------------[]
194 * | SPC-3 revision 21c, section 6.4 -- INQUIRY |
195 * | Various defines. The structure for the inquiry command can be |
196 * | found in /usr/include/sys/scsi/generic/inquiry.h |
197 * []------------------------------------------------------------------[]
198 */
199 #define SPC_INQUIRY_CODE_SET_BINARY 1
200 #define SPC_INQUIRY_CODE_SET_ASCII 2
201 #define SPC_INQUIRY_CODE_SET_UTF8 3
202
203 /* ---- Table 82: Inquiry Version ---- */
204 #define SPC_INQ_VERS_NONE 0x00
205 #define SPC_INQ_VERS_OBSOLETE 0x02
206 #define SPC_INQ_VERS_SPC_1 0x03
207 #define SPC_INQ_VERS_SPC_2 0x04
208 #define SPC_INQ_VERS_SPC_3 0x05
209
210 /* ---- INQUIRY Response Data Format field ---- */
211 #define SPC_INQ_RDF 0x02 /* all other values are OBSOLETE */
212
213 /*
214 * Table 85 -- Version descriptor values
215 * There are many, many different values available, so we'll only include
216 * those that we actually use.
217 */
218 #define SPC_INQ_VD_SAM3 0x0076
219 #define SPC_INQ_VD_SPC3 0x0307
220 #define SPC_INQ_VD_SBC2 0x0322
221 #define SPC_INQ_VD_SSC3 0x0400
222 #define SPC_INQ_VD_OSD 0x0355
223
224 /* --- Version Descriptor length details --- */
225 #define SPC_INQ_VD_IDX 0x3A
226 #define SPC_INQ_VD_LEN 0x10
227
228 #define SPC_INQ_PAGE0 0x00
229 #define SPC_INQ_PAGE80 0x80
230 #define SPC_INQ_PAGE83 0x83
231 #define SPC_INQ_PAGE86 0x86
232
233 /* ---- REPORT LUNS select report has valid values of 0, 1, or 2 ---- */
234 #define SPC_RPT_LUNS_SELECT_MASK 0x03
235
236 /* ---- Table 293: IDENTIFIER TYPE field ---- */
237 #define SPC_INQUIRY_ID_TYPE_T10ID 1 /* ref 7.6.4.3 */
238 #define SPC_INQUIRY_ID_TYPE_EUI 2 /* ref 7.6.4.4 */
239 #define SPC_INQUIRY_ID_TYPE_NAA 3 /* ref 7.6.4.5 */
240 #define SPC_INQUIRY_ID_TYPE_RELATIVE 4 /* ref 7.6.4.6 */
241 #define SPC_INQUIRY_ID_TYPE_TARG_PORT 5 /* ref 7.6.4.7 */
242 #define SPC_INQUIRY_ID_TYPE_LUN 6 /* ref 7.6.4.8 */
243 #define SPC_INQUIRY_ID_TYPE_MD5 7 /* ref 7.6.4.9 */
244 #define SPC_INQUIRY_ID_TYPE_SCSI 8 /* ref 7.6.4.10 */
245
246 /* ---- Table 292: ASSOCIATION field ---- */
247 #define SPC_INQUIRY_ASSOC_LUN 0
248 #define SPC_INQUIRY_ASSOC_TARGPORT 1
249 #define SPC_INQUIRY_ASSOC_TARG 2
250
251 /* ---- Table 80: Peripheral qualifier ---- */
252 #define SPC_INQUIRY_PERIPH_CONN 0
253 #define SPC_INQUIRY_PERIPH_DISCONN 1
254 #define SPC_INQUIRY_PERIPH_INVALID 3
255
256 /* ---- Table 256: PROTOCOL IDENTIFIER values ---- */
257 #define SPC_INQUIRY_PROTOCOL_FC 0
258 #define SPC_INQUIRY_PROTOCOL_PSCSI 1
259 #define SPC_INQUIRY_PROTOCOL_SSA 2
260 #define SPC_INQUIRY_PROTOCOL_IEEE1394 3
261 #define SPC_INQUIRY_PROTOCOL_SCSIRDMA 4
262 #define SPC_INQUIRY_PROTOCOL_ISCSI 5
263 #define SPC_INQUIRY_PROTOCOL_SAS 6
264 #define SPC_INQUIRY_PROTOCOL_ADT 7
265 #define SPC_INQUIRY_PROTOCOL_ATA 8
266
267 #define SPC_DEFAULT_TPG 1
268
269 /*
270 * SPC-3, revision 21c, section 7.6.5
271 * Extended INQUIRY Data VPD page
272 */
273 typedef struct extended_inq_data {
274 struct vpd_hdr ei_hdr;
275 #if defined(_BIT_FIELDS_LTOH)
276 uchar_t ei_ref_chk : 1,
277 ei_app_chk : 1,
278 ei_grd_chk : 1,
279 ei_rto : 1,
280 ei_rsvd1 : 4;
281 uchar_t ei_simpsup : 1,
282 ei_ordsup : 1,
283 ei_headsup : 1,
284 ei_prior_sup : 1,
285 ei_group_sup : 1,
286 ei_rsvd2 : 3;
287 uchar_t ei_v_sup : 1,
288 ei_nv_sup : 1,
289 ei_rsvd3 : 6;
290 #elif defined(_BIT_FIELDS_HTOL)
291 uchar_t ei_ref_rsvd1 : 4,
292 ei_rto : 1,
293 ei_grd_chk : 1,
294 ei_app_chk : 1,
295 ei_ref_chk : 1;
296 uchar_t ei_rsvd2 : 2,
297 ei_group_sup : 1,
298 ei_prior_sup : 1,
299 ei_headsup : 1,
300 ei_ordsup : 1,
301 ei_simpsup : 1;
302 uchar_t ei_rsvd3 : 6,
303 ei_nv_sup : 1,
304 ei_v_sup : 1;
305 #else
306 #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
307 #endif
308 uchar_t ei_rsv4[57];
309 } extended_inq_data_t;
310
311
312 /*
313 * []------------------------------------------------------------------[]
314 * | SPC-4 revision 1a, section 6.25 -- REPORT TARGET PORT GROUPS |
315 * | Structures and defines |
316 * []------------------------------------------------------------------[]
317 */
318 /*
319 * The service action must be set to 0x0A. This command is really a
320 * MAINTENANCE_IN command with a specific service action.
321 */
322 #define SPC_MI_SVC_MASK 0x1f
323 #define SPC_MI_SVC_RTPG 0x0a
324
325 /* ---- Table 167: Target port descriptor format ---- */
326 typedef struct rtpg_targ_desc {
327 uchar_t obsolete[2],
328 rel_tpi[2];
329 } rtpg_targ_desc_t;
330
331 /* ---- Table 164: Target port group descript format ---- */
332 typedef struct rtpg_desc {
333 #if defined(_BIT_FIELDS_LTOH)
334 uchar_t access_state : 4,
335 : 3,
336 pref : 1;
337 uchar_t ao_sup : 1,
338 an_sup : 1,
339 s_sup : 1,
340 u_sup : 1,
341 : 3,
342 t_sup : 1;
343 #elif defined(_BIT_FIELDS_HTOL)
344 uchar_t pref : 1,
345 : 3,
346 access_state : 4;
347 uchar_t t_sup : 1,
348 : 3,
349 u_sup : 1,
350 s_sup : 1,
351 an_sup : 1,
352 ao_sup : 1;
353 #else
354 #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
355 #endif
356 uchar_t tpg[2],
357 reserve_1,
358 status_code,
359 vendor_spec,
360 tpg_cnt;
361 rtpg_targ_desc_t targ_list[1];
362 } rtpg_desc_t;
363
364 /* ---- Table 163: parameter data format. ---- */
365 typedef struct rtpg_data {
366 uchar_t len[4];
367 rtpg_desc_t desc_list[1];
368 } rtpg_hdr_t;
369
370 /*
371 * []------------------------------------------------------------------[]
372 * | SPC-3, revision 21c, section 6.6 -- LOG_SENSE |
373 * | Structure and defines |
374 * []------------------------------------------------------------------[]
375 */
376 #define SSC_LOG_SP 0x01 /* save parameters */
377 #define SSC_LOG_PPC 0x02 /* parameter pointer control */
378 #define SPC_LOG_PAGE_MASK 0x3f
379
380 /* ---- section 7.2.1, Table 192: Log Parameter ---- */
381 typedef struct spc_log_select_param {
382 char param_code[2];
383 #if defined(_BIT_FIELDS_LTOH)
384 char lp : 1, /* list parameter */
385 lbin : 1,
386 tmc : 2, /* threshold met criteria */
387 etc : 1, /* enable threshold comparison */
388 tsd : 1, /* target save disable */
389 ds : 1, /* disable save */
390 du : 1; /* disable update */
391 #elif defined(_BIT_FIELDS_HTOL)
392 char du : 1, /* disable update */
393 ds : 1, /* disable save */
394 tsd : 1, /* target save disable */
395 etc : 1, /* enable threshold comparison */
396 tmc : 2, /* threshold met criteria */
397 lbin : 1,
398 lp : 1; /* list parameter */
399 #else
400 #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
401 #endif
402 char len; /* length of bytes to follow */
403 } spc_log_select_param_t;
404
405 /* ---- section 7.2.12, table 218: Supported log pages ---- */
406 typedef struct spc_log_supported_pages {
407 char page_code,
408 resvd,
409 length[2],
410 list[1];
411 } spc_log_supported_pages_t;
412
413 /*
414 * []------------------------------------------------------------------[]
415 * | SPC-3, revision 21c, section 6.9 -- MODE_SENSE |
416 * | Structures and defines |
417 * []------------------------------------------------------------------[]
418 */
419 /* ---- Section 7.4.6, Table 241: Queue Algorithm Modifer field ---- */
420 #define SPC_QUEUE_RESTRICTED 0x00
421 #define SPC_QUEUE_UNRESTRICTED 0x01
422
423 /* ---- Section 7.4.11, Table 250: Information Controller Page ---- */
424 struct mode_info_ctrl {
425 struct mode_page mode_page;
426 /*
427 * Currently we don't sent any of this information and it's set
428 * to zero's. We only care about the size.
429 */
430 char info_data[10];
431 };
432
433 #define MODE_SENSE_PAGE3_CODE 0x03
434 #define MODE_SENSE_PAGE4_CODE 0x04
435 #define MODE_SENSE_CACHE 0x08
436 #define MODE_SENSE_CONTROL 0x0a
437 #define MODE_SENSE_COMPRESSION 0x0f
438 #define MODE_SENSE_DEV_CONFIG 0x10
439 #define MODE_SENSE_INFO_CTRL 0x1c
440 #define MODE_SENSE_SEND_ALL 0x3f
441
442 /* -- Page Control Mask for Mode Sense -- */
443 #define SPC_MODE_SENSE_PAGE_CODE_MASK 0x3f
444 #define SPC_MODE_SENSE_PC_MASK 0xc0
445 #define SPC_MODE_SENSE_PC_SHIFT 6
446
447 #define SPC_PC_CURRENT_VALUES 0
448 #define SPC_PC_MODIFIABLE_VALUES 1
449 #define SPC_PC_DEFAULT_VALUES 2
450 #define SPC_PC_SAVED_VALUES 3
451
452 #define SCSI_REPORTLUNS_ADDRESS_SIZE 8
453 #define SCSI_REPORTLUNS_ADDRESS_MASK 0xC0
454 #define SCSI_REPORTLUNS_ADDRESS_PERIPHERAL 0x00
455 #define SCSI_REPORTLUNS_ADDRESS_FLAT_SPACE 0x40
456 #define SCSI_REPORTLUNS_ADDRESS_LOGICAL_UNIT 0x80
457 #define SCSI_REPORTLUNS_ADDRESS_EXTENDED_UNIT 0xC0
458 #define SCSI_REPORTLUNS_ADDRESS_EXTENDED_2B 0x00
459 #define SCSI_REPORTLUNS_ADDRESS_EXTENDED_4B 0x10
460 #define SCSI_REPORTLUNS_ADDRESS_EXTENDED_6B 0x20
461 #define SCSI_REPORTLUNS_ADDRESS_EXTENDED_8B 0x30
462 #define SCSI_REPORTLUNS_ADDRESS_EXTENDED_MASK 0x30
463 #define SCSI_REPORTLUNS_SELECT_ALL 0x02
464
465 #ifdef __cplusplus
466 }
467 #endif
468
469 #endif /* _T10_SPC_H */