xref: /titanic_52/usr/src/lib/fm/libdiskstatus/common/ds_scsi.h (revision 24db46411fd54f70c35b94bb952eb7ba040e43b4)
1*24db4641Seschrock /*
2*24db4641Seschrock  * CDDL HEADER START
3*24db4641Seschrock  *
4*24db4641Seschrock  * The contents of this file are subject to the terms of the
5*24db4641Seschrock  * Common Development and Distribution License (the "License").
6*24db4641Seschrock  * You may not use this file except in compliance with the License.
7*24db4641Seschrock  *
8*24db4641Seschrock  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*24db4641Seschrock  * or http://www.opensolaris.org/os/licensing.
10*24db4641Seschrock  * See the License for the specific language governing permissions
11*24db4641Seschrock  * and limitations under the License.
12*24db4641Seschrock  *
13*24db4641Seschrock  * When distributing Covered Code, include this CDDL HEADER in each
14*24db4641Seschrock  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*24db4641Seschrock  * If applicable, add the following below this CDDL HEADER, with the
16*24db4641Seschrock  * fields enclosed by brackets "[]" replaced with your own identifying
17*24db4641Seschrock  * information: Portions Copyright [yyyy] [name of copyright owner]
18*24db4641Seschrock  *
19*24db4641Seschrock  * CDDL HEADER END
20*24db4641Seschrock  */
21*24db4641Seschrock /*
22*24db4641Seschrock  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
23*24db4641Seschrock  * Use is subject to license terms.
24*24db4641Seschrock  */
25*24db4641Seschrock 
26*24db4641Seschrock #ifndef	_DS_SCSI_H
27*24db4641Seschrock #define	_DS_SCSI_H
28*24db4641Seschrock 
29*24db4641Seschrock #pragma ident	"%Z%%M%	%I%	%E% SMI"
30*24db4641Seschrock 
31*24db4641Seschrock #include <sys/types.h>
32*24db4641Seschrock #include <sys/byteorder.h>
33*24db4641Seschrock #include <sys/scsi/scsi.h>
34*24db4641Seschrock 
35*24db4641Seschrock #include "ds_impl.h"
36*24db4641Seschrock 
37*24db4641Seschrock #ifdef	__cplusplus
38*24db4641Seschrock extern "C" {
39*24db4641Seschrock #endif
40*24db4641Seschrock 
41*24db4641Seschrock #if !defined(_BIT_FIELDS_LTOH) && !defined(_BIT_FIELDS_HTOL)
42*24db4641Seschrock #error	One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
43*24db4641Seschrock #endif
44*24db4641Seschrock 
45*24db4641Seschrock /*
46*24db4641Seschrock  * Log page structures
47*24db4641Seschrock  */
48*24db4641Seschrock #pragma pack(1)
49*24db4641Seschrock 
50*24db4641Seschrock typedef struct scsi_log_header {
51*24db4641Seschrock #if defined(_BIT_FIELDS_LTOH)
52*24db4641Seschrock 	uint8_t		lh_code : 6,
53*24db4641Seschrock 			__reserved : 2;
54*24db4641Seschrock #else
55*24db4641Seschrock 	uint8_t		__reserved : 2,
56*24db4641Seschrock 			lh_code : 6;
57*24db4641Seschrock #endif
58*24db4641Seschrock 	uint8_t		__reserved2;
59*24db4641Seschrock 	uint16_t	lh_length;
60*24db4641Seschrock } scsi_log_header_t;
61*24db4641Seschrock 
62*24db4641Seschrock typedef struct scsi_log_parameter_header {
63*24db4641Seschrock 	uint16_t	lph_param;
64*24db4641Seschrock #if defined(_BIT_FIELDS_LTOH)
65*24db4641Seschrock 	uint8_t		lph_lp	: 1,
66*24db4641Seschrock 			lph_lbin : 1,
67*24db4641Seschrock 			lph_tmc : 2,
68*24db4641Seschrock 			lph_etc	: 1,
69*24db4641Seschrock 			lph_tsd	: 1,
70*24db4641Seschrock 			lph_ds	: 1,
71*24db4641Seschrock 			lph_du	: 1;
72*24db4641Seschrock #else
73*24db4641Seschrock 	uint8_t		lph_du	: 1,
74*24db4641Seschrock 			lph_ds	: 1,
75*24db4641Seschrock 			lph_tsd	: 1,
76*24db4641Seschrock 			lph_etc	: 1,
77*24db4641Seschrock 			lph_tmc	: 2,
78*24db4641Seschrock 			lph_lbin : 1,
79*24db4641Seschrock 			lph_lp	: 1;
80*24db4641Seschrock #endif
81*24db4641Seschrock 	uint8_t		lph_length;
82*24db4641Seschrock } scsi_log_parameter_header_t;
83*24db4641Seschrock 
84*24db4641Seschrock typedef struct scsi_supported_log_pages {
85*24db4641Seschrock 	scsi_log_header_t	slp_hdr;
86*24db4641Seschrock 	uchar_t			slp_pages[1];
87*24db4641Seschrock } scsi_supported_log_pages_t;
88*24db4641Seschrock 
89*24db4641Seschrock typedef struct scsi_ie_log_param {
90*24db4641Seschrock 	scsi_log_parameter_header_t	ie_hdr;
91*24db4641Seschrock 	uchar_t				ie_asc;
92*24db4641Seschrock 	uchar_t				ie_ascq;
93*24db4641Seschrock } scsi_ie_log_param_t;
94*24db4641Seschrock 
95*24db4641Seschrock /*
96*24db4641Seschrock  * The SCSI-3 SPC document states that IE log page (0x2F) parameter 0
97*24db4641Seschrock  * must have a length of at least 4 (including the length byte).
98*24db4641Seschrock  */
99*24db4641Seschrock #define	LOGPARAM_IE_MIN_LEN		2	/* the asc and ascq fields */
100*24db4641Seschrock 
101*24db4641Seschrock #define	INVALID_TEMPERATURE		0xff
102*24db4641Seschrock 
103*24db4641Seschrock #define	LOGPARAM_IE			0x0000
104*24db4641Seschrock 
105*24db4641Seschrock typedef struct scsi_temp_log_param {
106*24db4641Seschrock 	scsi_log_parameter_header_t	t_hdr;
107*24db4641Seschrock 	uchar_t				__reserved;
108*24db4641Seschrock 	uchar_t				t_temp;
109*24db4641Seschrock } scsi_temp_log_param_t;
110*24db4641Seschrock 
111*24db4641Seschrock typedef struct scsi_selftest_log_param {
112*24db4641Seschrock 	scsi_log_parameter_header_t	st_hdr;
113*24db4641Seschrock #if defined(_BIT_FIELDS_LTOH)
114*24db4641Seschrock 	uint8_t		st_results	: 4,
115*24db4641Seschrock 			__reserved1	: 1,
116*24db4641Seschrock 			st_testcode	: 3;
117*24db4641Seschrock #else
118*24db4641Seschrock 	uint8_t		st_testcode	: 3,
119*24db4641Seschrock 			__reserved1	: 1,
120*24db4641Seschrock 			st_results	: 4;
121*24db4641Seschrock #endif
122*24db4641Seschrock 	uint8_t		st_number;
123*24db4641Seschrock 	uint16_t	st_timestamp;
124*24db4641Seschrock 	uint64_t	st_lba;
125*24db4641Seschrock #if defined(_BIT_FIELDS_LTOH)
126*24db4641Seschrock 	uint8_t		st_sensekey	: 4,
127*24db4641Seschrock 			__reserved2	: 4;
128*24db4641Seschrock #else
129*24db4641Seschrock 	uint8_t		__reserved2	: 4,
130*24db4641Seschrock 			st_sensekey	: 4;
131*24db4641Seschrock #endif
132*24db4641Seschrock 	uint8_t		st_asc;
133*24db4641Seschrock 	uint8_t		st_ascq;
134*24db4641Seschrock 	uint8_t		st_vendor;
135*24db4641Seschrock } scsi_selftest_log_param_t;
136*24db4641Seschrock 
137*24db4641Seschrock /* The results field of the self-test log parameter */
138*24db4641Seschrock #define	SELFTEST_OK			0x0
139*24db4641Seschrock #define	SELFTEST_ABORT_REQUEST		0x1
140*24db4641Seschrock #define	SELFTEST_ABORT_OTHER		0x2
141*24db4641Seschrock #define	SELFTEST_FAILURE_INCOMPLETE	0x3
142*24db4641Seschrock #define	SELFTEST_FAILURE_SEG_UNKNOWN	0x4
143*24db4641Seschrock #define	SELFTEST_FAILURE_SEG_FIRST	0x5
144*24db4641Seschrock #define	SELFTEST_FAILURE_SEG_SECOND	0x6
145*24db4641Seschrock #define	SELFTEST_FAILURE_SEG_OTHER	0x7
146*24db4641Seschrock #define	SELFTEST_INPROGRESS		0xf
147*24db4641Seschrock 
148*24db4641Seschrock #define	SELFTEST_COMPLETE(code)				\
149*24db4641Seschrock 	((code) == SELFTEST_OK ||			\
150*24db4641Seschrock 	((code) >= SELFTEST_FAILURE_INCOMPLETE &&	\
151*24db4641Seschrock 	((code) <= SELFTEST_FAILURE_SEG_OTHER)))
152*24db4641Seschrock 
153*24db4641Seschrock #define	LOGPARAM_TEMP_CURTEMP		0x0000
154*24db4641Seschrock #define	LOGPARAM_TEMP_REFTEMP		0x0001
155*24db4641Seschrock 
156*24db4641Seschrock #define	LOGPARAM_TEMP_LEN	\
157*24db4641Seschrock 	(sizeof (scsi_temp_log_param_t) - \
158*24db4641Seschrock 	    sizeof (scsi_log_parameter_header_t))
159*24db4641Seschrock 
160*24db4641Seschrock /*
161*24db4641Seschrock  * Mode sense/select page header information
162*24db4641Seschrock  */
163*24db4641Seschrock typedef struct scsi_ms_header {
164*24db4641Seschrock 	struct mode_header	ms_header;
165*24db4641Seschrock 	struct block_descriptor	ms_descriptor;
166*24db4641Seschrock } scsi_ms_header_t;
167*24db4641Seschrock 
168*24db4641Seschrock typedef struct scsi_ms_header_g1 {
169*24db4641Seschrock 	struct mode_header_g1	ms_header;
170*24db4641Seschrock 	struct block_descriptor	ms_descriptor;
171*24db4641Seschrock } scsi_ms_header_g1_t;
172*24db4641Seschrock 
173*24db4641Seschrock typedef struct scsi_ms_hdrs {
174*24db4641Seschrock 	int				ms_length;
175*24db4641Seschrock 	union {
176*24db4641Seschrock 		scsi_ms_header_t	g0;
177*24db4641Seschrock 		scsi_ms_header_g1_t	g1;
178*24db4641Seschrock 	} ms_hdr;
179*24db4641Seschrock } scsi_ms_hdrs_t;
180*24db4641Seschrock 
181*24db4641Seschrock typedef struct scsi_ie_page {
182*24db4641Seschrock 	struct mode_page ie_mp;
183*24db4641Seschrock #if defined(_BIT_FIELDS_LTOH)
184*24db4641Seschrock 	uint8_t		ie_logerr	: 1,	/* Errors should be logged */
185*24db4641Seschrock 			__reserved1	: 1,
186*24db4641Seschrock 			ie_test		: 1,	/* Enable test gen of IEs */
187*24db4641Seschrock 			ie_dexcpt	: 1,	/* Disable exceptions */
188*24db4641Seschrock 			ie_ewasc	: 1,	/* Enable warning generation */
189*24db4641Seschrock 			ie_ebf		: 1,	/* enable backgrnd functions */
190*24db4641Seschrock 			__reserved2	: 1,
191*24db4641Seschrock 			ie_perf		: 1;	/* No delays during excptns */
192*24db4641Seschrock 	uint8_t		ie_mrie		: 4,	/* Method/reporting excptons */
193*24db4641Seschrock 			__reserved3	: 4;
194*24db4641Seschrock #else
195*24db4641Seschrock 	uint8_t		ie_perf		: 1,	/* No delays during excptons */
196*24db4641Seschrock 			__reserved2	: 1,
197*24db4641Seschrock 			ie_ebf		: 1,	/* enable background funcs */
198*24db4641Seschrock 			ie_ewasc	: 1,	/* Enable warning generation */
199*24db4641Seschrock 			ie_dexcpt	: 1,	/* Disable exceptions */
200*24db4641Seschrock 			ie_test		: 1,	/* Enable test gen of IEs */
201*24db4641Seschrock 			__reserved1	: 1,
202*24db4641Seschrock 			ie_logerr	: 1;	/* Errors should be logged */
203*24db4641Seschrock 	uint8_t		__reserved3	: 4,
204*24db4641Seschrock 			ie_mrie		: 4;	/* Method of report excptns */
205*24db4641Seschrock #endif
206*24db4641Seschrock 	uint32_t	ie_interval_timer;	/* reporting interval for IEs */
207*24db4641Seschrock 	uint32_t	ie_report_count;	/* # of times to report an IE */
208*24db4641Seschrock } scsi_ie_page_t;
209*24db4641Seschrock 
210*24db4641Seschrock #pragma pack()
211*24db4641Seschrock 
212*24db4641Seschrock #define	MODEPAGE_INFO_EXCPT_LEN	(sizeof (scsi_ie_page_t))
213*24db4641Seschrock 
214*24db4641Seschrock #define	IEC_IE_ENABLED(ies) ((ies).ie_dexcpt == 0)
215*24db4641Seschrock #define	IEC_IE_CHANGEABLE(ies) ((ies).ie_dexcpt == 1)
216*24db4641Seschrock #define	IEC_MRIE_CHANGEABLE(ies) ((ies).ie_mrie == 0xf)
217*24db4641Seschrock #define	IEC_PERF_CHANGEABLE(ies) ((ies).ie_perf == 1)
218*24db4641Seschrock #define	IEC_EWASC_CHANGEABLE(ies) ((ies).ie_ewasc == 1)
219*24db4641Seschrock #define	IEC_TEST_CHANGEABLE(ies) ((ies).ie_test == 1)
220*24db4641Seschrock #define	IEC_RPTCNT_CHANGEABLE(ies) ((ies).ie_report_count == BE_32(0xffffffff))
221*24db4641Seschrock #define	IEC_LOGERR_CHANGEABLE(ies) ((ies).ie_logerr == 1)
222*24db4641Seschrock 
223*24db4641Seschrock /*
224*24db4641Seschrock  * Values for the MRIE field of the informational exceptions control mode page
225*24db4641Seschrock  */
226*24db4641Seschrock #define	IE_REPORT_NONE			0
227*24db4641Seschrock #define	IE_REPORT_ASYNCH		1
228*24db4641Seschrock #define	IE_REPORT_UNIT_ATTN		2
229*24db4641Seschrock #define	IE_REPORT_RECOV_ERR_COND	3
230*24db4641Seschrock #define	IE_REPORT_RECOV_ERR_ALWAYS	4
231*24db4641Seschrock #define	IE_REPORT_NO_SENSE		5
232*24db4641Seschrock #define	IE_REPORT_ON_REQUEST		6
233*24db4641Seschrock 
234*24db4641Seschrock /*
235*24db4641Seschrock  * Constants in support of the CONTROL MODE mode page (page 0xA)
236*24db4641Seschrock  */
237*24db4641Seschrock #define	MODEPAGE_CTRL_MODE_LEN	(sizeof (struct mode_control_scsi3))
238*24db4641Seschrock #define	GLTSD_CHANGEABLE(chg)	((chg).gltsd == 1)
239*24db4641Seschrock 
240*24db4641Seschrock #define	LOGPAGE_SELFTEST_MIN_PARAM_CODE	0x0001
241*24db4641Seschrock #define	LOGPAGE_SELFTEST_MAX_PARAM_CODE	0x0014
242*24db4641Seschrock 
243*24db4641Seschrock #define	LOGPAGE_SELFTEST_PARAM_LEN \
244*24db4641Seschrock 	((sizeof (scsi_selftest_log_param_t)) - \
245*24db4641Seschrock 	    (sizeof (scsi_log_parameter_header_t)))
246*24db4641Seschrock 
247*24db4641Seschrock /*
248*24db4641Seschrock  * Macro to extract the length of a mode sense page
249*24db4641Seschrock  * as returned by a target.
250*24db4641Seschrock  */
251*24db4641Seschrock #define	MODESENSE_PAGE_LEN(p)	(((int)((struct mode_page *)p)->length) + \
252*24db4641Seschrock 					sizeof (struct mode_page))
253*24db4641Seschrock 
254*24db4641Seschrock /*
255*24db4641Seschrock  * Mode Select options
256*24db4641Seschrock  */
257*24db4641Seschrock #define	MODE_SELECT_SP			0x01
258*24db4641Seschrock #define	MODE_SELECT_PF			0x10
259*24db4641Seschrock 
260*24db4641Seschrock 
261*24db4641Seschrock /*
262*24db4641Seschrock  * Mode Sense Page Control
263*24db4641Seschrock  */
264*24db4641Seschrock #define	PC_CURRENT		(0 << 6)
265*24db4641Seschrock #define	PC_CHANGEABLE		(1 << 6)
266*24db4641Seschrock #define	PC_DEFAULT		(2 << 6)
267*24db4641Seschrock #define	PC_SAVED		(3 << 6)
268*24db4641Seschrock 
269*24db4641Seschrock /*
270*24db4641Seschrock  * Log Sense Page Control
271*24db4641Seschrock  */
272*24db4641Seschrock #define	PC_CUMULATIVE		(1 << 6)
273*24db4641Seschrock 
274*24db4641Seschrock /*
275*24db4641Seschrock  * LOG page codes
276*24db4641Seschrock  */
277*24db4641Seschrock #define	LOGPAGE_SUPP_LIST	0x00
278*24db4641Seschrock #define	LOGPAGE_TEMP		0x0d
279*24db4641Seschrock #define	LOGPAGE_SELFTEST	0x10
280*24db4641Seschrock #define	LOGPAGE_IE		0x2f
281*24db4641Seschrock 
282*24db4641Seschrock /* ASC constants */
283*24db4641Seschrock #define	ASC_INVALID_OPCODE				0x20
284*24db4641Seschrock #define	ASC_INVALID_CDB_FIELD				0x24
285*24db4641Seschrock #define	ASC_FAILURE_PREDICTION_THRESHOLD_EXCEEDED	0x5d
286*24db4641Seschrock 
287*24db4641Seschrock /* ASCQ constants */
288*24db4641Seschrock #define	ASCQ_INVALID_OPCODE	0
289*24db4641Seschrock 
290*24db4641Seschrock /* Error tests */
291*24db4641Seschrock #define	SCSI_INVALID_OPCODE(s, a, aq) \
292*24db4641Seschrock 	(((s) == KEY_ILLEGAL_REQUEST) && ((a) == ASC_INVALID_OPCODE) && \
293*24db4641Seschrock 	((aq) == ASCQ_INVALID_OPCODE))
294*24db4641Seschrock 
295*24db4641Seschrock #define	MODE_PAGE_UNSUPPORTED(s, a, aq) \
296*24db4641Seschrock 	(((s) == KEY_ILLEGAL_REQUEST) && ((a) == ASC_INVALID_CDB_FIELD))
297*24db4641Seschrock 
298*24db4641Seschrock /* command length to use */
299*24db4641Seschrock #define	MODE_CMD_LEN_UNKNOWN		0
300*24db4641Seschrock #define	MODE_CMD_LEN_6			1
301*24db4641Seschrock #define	MODE_CMD_LEN_10			2
302*24db4641Seschrock 
303*24db4641Seschrock /* supported modepages bitmask */
304*24db4641Seschrock #define	MODEPAGE_SUPP_IEC		0x1
305*24db4641Seschrock 
306*24db4641Seschrock /* supported logpages bitmask */
307*24db4641Seschrock #define	LOGPAGE_SUPP_IE			0x1
308*24db4641Seschrock #define	LOGPAGE_SUPP_TEMP		0x2
309*24db4641Seschrock #define	LOGPAGE_SUPP_SELFTEST		0x4
310*24db4641Seschrock 
311*24db4641Seschrock #define	MSG_BUFLEN	256
312*24db4641Seschrock 
313*24db4641Seschrock /*
314*24db4641Seschrock  * For SCSI commands which want to accept arbitrary length responses, we need to
315*24db4641Seschrock  * allocate an appropriate sized buffer.  The maximum length is USHRT_MAX,
316*24db4641Seschrock  * because some devices return nothing if the buffer length is too big.
317*24db4641Seschrock  */
318*24db4641Seschrock #define	MAX_BUFLEN(type)	(USHRT_MAX - sizeof (type))
319*24db4641Seschrock 
320*24db4641Seschrock extern ds_transport_t ds_scsi_uscsi_transport;
321*24db4641Seschrock extern ds_transport_t ds_scsi_sim_transport;
322*24db4641Seschrock 
323*24db4641Seschrock #ifdef	__cplusplus
324*24db4641Seschrock }
325*24db4641Seschrock #endif
326*24db4641Seschrock 
327*24db4641Seschrock #endif	/* _DS_SCSI_H */
328