xref: /freebsd-11-stable/sys/cam/scsi/scsi_enc_internal.h (revision 067170185bb9863a46a382fa69f170d0f40a9ec9)
1 /*-
2  * Copyright (c) 2000 Matthew Jacob
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions, and the following disclaimer,
10  *    without modification, immediately at the beginning of the file.
11  * 2. The name of the author may not be used to endorse or promote products
12  *    derived from this software without specific prior written permission.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
18  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  * $FreeBSD$
27  */
28 
29 /*
30  * This file contains definitions only intended for use within
31  * sys/cam/scsi/scsi_enc*.c, and not in other kernel components.
32  */
33 
34 #ifndef	__SCSI_ENC_INTERNAL_H__
35 #define	__SCSI_ENC_INTERNAL_H__
36 
37 #include <sys/sysctl.h>
38 
39 typedef struct enc_element {
40 	uint8_t	 elm_idx;		/* index of element */
41 	uint8_t	 elm_type;		/* element type */
42 	uint8_t	 subenclosure;		/* subenclosure id */
43 	uint8_t	 type_elm_idx;		/* index of element within type */
44 	uint8_t	 svalid;		/* enclosure information valid */
45 	uint16_t priv;			/* private data, per object */
46 	uint8_t	 encstat[4];		/* state && stats */
47 	uint8_t *physical_path;		/* Device physical path data. */
48 	u_int    physical_path_len;	/* Length of device path data. */
49 	void    *elm_private;		/* per-type object data */
50 } enc_element_t;
51 
52 typedef enum {
53 	ENC_NONE,
54 	ENC_SES,
55 	ENC_SES_PASSTHROUGH,
56 	ENC_SAFT,
57 	ENC_SEMB_SES,
58 	ENC_SEMB_SAFT
59 } enctyp;
60 
61 /* Platform Independent Driver Internal Definitions for enclosure devices. */
62 typedef struct enc_softc enc_softc_t;
63 
64 struct enc_fsm_state;
65 typedef int fsm_fill_handler_t(enc_softc_t *ssc,
66 				struct enc_fsm_state *state,
67 				union ccb *ccb,
68 				uint8_t *buf);
69 typedef int fsm_error_handler_t(union ccb *ccb, uint32_t cflags,
70 				uint32_t sflags);
71 typedef int fsm_done_handler_t(enc_softc_t *ssc,
72 			       struct enc_fsm_state *state, union ccb *ccb,
73 			       uint8_t **bufp, int error, int xfer_len);
74 
75 struct enc_fsm_state {
76 	const char	    *name;
77 	int		     page_code;
78 	size_t		     buf_size;
79 	uint32_t	     timeout;
80 	fsm_fill_handler_t  *fill;
81 	fsm_done_handler_t  *done;
82 	fsm_error_handler_t *error;
83 };
84 
85 typedef int (enc_softc_init_t)(enc_softc_t *);
86 typedef void (enc_softc_invalidate_t)(enc_softc_t *);
87 typedef void (enc_softc_cleanup_t)(enc_softc_t *);
88 typedef int (enc_init_enc_t)(enc_softc_t *);
89 typedef int (enc_get_enc_status_t)(enc_softc_t *, int);
90 typedef int (enc_set_enc_status_t)(enc_softc_t *, encioc_enc_status_t, int);
91 typedef int (enc_get_elm_status_t)(enc_softc_t *, encioc_elm_status_t *, int);
92 typedef int (enc_set_elm_status_t)(enc_softc_t *, encioc_elm_status_t *, int);
93 typedef int (enc_get_elm_desc_t)(enc_softc_t *, encioc_elm_desc_t *);
94 typedef int (enc_get_elm_devnames_t)(enc_softc_t *, encioc_elm_devnames_t *);
95 typedef int (enc_handle_string_t)(enc_softc_t *, encioc_string_t *, int);
96 typedef void (enc_device_found_t)(enc_softc_t *);
97 typedef void (enc_poll_status_t)(enc_softc_t *);
98 
99 struct enc_vec {
100 	enc_softc_invalidate_t	*softc_invalidate;
101 	enc_softc_cleanup_t	*softc_cleanup;
102 	enc_init_enc_t		*init_enc;
103 	enc_get_enc_status_t	*get_enc_status;
104 	enc_set_enc_status_t	*set_enc_status;
105 	enc_get_elm_status_t	*get_elm_status;
106 	enc_set_elm_status_t	*set_elm_status;
107 	enc_get_elm_desc_t	*get_elm_desc;
108 	enc_get_elm_devnames_t	*get_elm_devnames;
109 	enc_handle_string_t	*handle_string;
110 	enc_device_found_t	*device_found;
111 	enc_poll_status_t	*poll_status;
112 };
113 
114 typedef struct enc_cache {
115 	enc_element_t		*elm_map;	/* objects */
116 	int			 nelms;		/* number of objects */
117 	encioc_enc_status_t	 enc_status;	/* overall status */
118 	void			*private;	/* per-type private data */
119 } enc_cache_t;
120 
121 /* Enclosure instance toplevel structure */
122 struct enc_softc {
123 	enctyp			 enc_type;	/* type of enclosure */
124 	struct enc_vec		 enc_vec;	/* vector to handlers */
125 	void			*enc_private;	/* per-type private data */
126 
127 	/**
128 	 * "Published" configuration and state data available to
129 	 * external consumers.
130 	 */
131 	enc_cache_t		 enc_cache;
132 
133 	/**
134 	 * Configuration and state data being actively updated
135 	 * by the enclosure daemon.
136 	 */
137 	enc_cache_t		 enc_daemon_cache;
138 
139 	struct sx		 enc_cache_lock;
140 	uint8_t			 enc_flags;
141 #define	ENC_FLAG_INVALID	0x01
142 #define	ENC_FLAG_INITIALIZED	0x02
143 #define	ENC_FLAG_SHUTDOWN	0x04
144 	union ccb		 saved_ccb;
145 	struct cdev		*enc_dev;
146 	struct cam_periph	*periph;
147 	int			 open_count;
148 
149 	/* Bitmap of pending operations. */
150 	uint32_t		 pending_actions;
151 
152 	/* The action on which the state machine is currently working. */
153 	uint32_t		 current_action;
154 #define	ENC_UPDATE_NONE		0x00
155 #define	ENC_UPDATE_INVALID	0xff
156 
157 	/* Callout for auto-updating enclosure status */
158 	struct callout		 status_updater;
159 
160 	struct proc		*enc_daemon;
161 
162 	struct enc_fsm_state 	*enc_fsm_states;
163 
164 	struct intr_config_hook  enc_boot_hold_ch;
165 };
166 
167 static inline enc_cache_t *
enc_other_cache(enc_softc_t * enc,enc_cache_t * primary)168 enc_other_cache(enc_softc_t *enc, enc_cache_t *primary)
169 {
170 	return (primary == &enc->enc_cache
171 	      ? &enc->enc_daemon_cache : &enc->enc_cache);
172 }
173 
174 /* SES Management mode page - SES2r20 Table 59 */
175 struct ses_mgmt_mode_page {
176 	struct scsi_mode_header_6 header;
177 	struct scsi_mode_blk_desc blk_desc;
178 	uint8_t byte0;  /* ps : 1, spf : 1, page_code : 6 */
179 #define SES_MGMT_MODE_PAGE_CODE 0x14
180 	uint8_t length;
181 #define SES_MGMT_MODE_PAGE_LEN  6
182 	uint8_t reserved[3];
183 	uint8_t byte5;  /* reserved : 7, enbltc : 1 */
184 #define SES_MGMT_TIMED_COMP_EN  0x1
185 	uint8_t max_comp_time[2];
186 };
187 
188 /* Enclosure core interface for sub-drivers */
189 int  enc_runcmd(struct enc_softc *, char *, int, char *, int *);
190 void enc_log(struct enc_softc *, const char *, ...);
191 int  enc_error(union ccb *, uint32_t, uint32_t);
192 void enc_update_request(enc_softc_t *, uint32_t);
193 
194 /* SES Native interface */
195 enc_softc_init_t	ses_softc_init;
196 
197 /* SAF-TE interface */
198 enc_softc_init_t	safte_softc_init;
199 
200 SYSCTL_DECL(_kern_cam_enc);
201 extern int enc_verbose;
202 
203 /* Helper macros */
204 MALLOC_DECLARE(M_SCSIENC);
205 #define	ENC_CFLAGS		CAM_RETRY_SELTO
206 #define	ENC_FLAGS		SF_NO_PRINT | SF_RETRY_UA
207 #define	STRNCMP			strncmp
208 #define	PRINTF			printf
209 #define	ENC_LOG			enc_log
210 #if defined(DEBUG) || defined(ENC_DEBUG)
211 #define	ENC_DLOG		enc_log
212 #else
213 #define	ENC_DLOG		if (0) enc_log
214 #endif
215 #define	ENC_VLOG		if (enc_verbose) enc_log
216 #define	ENC_MALLOC(amt)		malloc(amt, M_SCSIENC, M_NOWAIT)
217 #define	ENC_MALLOCZ(amt)	malloc(amt, M_SCSIENC, M_ZERO|M_NOWAIT)
218 /* Cast away const avoiding GCC warnings. */
219 #define	ENC_FREE(ptr)		free((void *)((uintptr_t)ptr), M_SCSIENC)
220 #define	ENC_FREE_AND_NULL(ptr)	do {	\
221 	if (ptr != NULL) {		\
222 		ENC_FREE(ptr);		\
223 		ptr = NULL;		\
224 	}				\
225 } while(0)
226 #define	MEMZERO			bzero
227 #define	MEMCPY(dest, src, amt)	bcopy(src, dest, amt)
228 
229 #endif	/* __SCSI_ENC_INTERNAL_H__ */
230