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