1235911Smav/*-
2235911Smav * Copyright (c) 2000 Matthew Jacob
3235911Smav * All rights reserved.
4235911Smav *
5235911Smav * Redistribution and use in source and binary forms, with or without
6235911Smav * modification, are permitted provided that the following conditions
7235911Smav * are met:
8235911Smav * 1. Redistributions of source code must retain the above copyright
9235911Smav *    notice, this list of conditions, and the following disclaimer,
10235911Smav *    without modification, immediately at the beginning of the file.
11235911Smav * 2. The name of the author may not be used to endorse or promote products
12235911Smav *    derived from this software without specific prior written permission.
13235911Smav *
14235911Smav * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15235911Smav * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16235911Smav * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17235911Smav * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
18235911Smav * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19235911Smav * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20235911Smav * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21235911Smav * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22235911Smav * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23235911Smav * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24235911Smav * SUCH DAMAGE.
25235911Smav *
26235911Smav * $FreeBSD$
27235911Smav */
28235911Smav
29235911Smav/*
30235911Smav * This file contains definitions only intended for use within
31235911Smav * sys/cam/scsi/scsi_enc*.c, and not in other kernel components.
32235911Smav */
33235911Smav
34235911Smav#ifndef	__SCSI_ENC_INTERNAL_H__
35235911Smav#define	__SCSI_ENC_INTERNAL_H__
36235911Smav
37235911Smavtypedef struct enc_element {
38235911Smav	uint32_t
39235911Smav		 enctype	: 8,	/* enclosure type */
40235911Smav		 subenclosure : 8,	/* subenclosure id */
41235911Smav		 svalid	: 1,		/* enclosure information valid */
42235911Smav		 overall_status_elem: 1,/*
43235911Smav					 * This object represents generic
44235911Smav					 * status about all objects of this
45235911Smav					 * type.
46235911Smav					 */
47235911Smav		 priv	: 14;		/* private data, per object */
48235911Smav	uint8_t	 encstat[4];		/* state && stats */
49235911Smav	uint8_t *physical_path;		/* Device physical path data. */
50235911Smav	u_int    physical_path_len;	/* Length of device path data. */
51235911Smav	void    *elm_private;		/* per-type object data */
52235911Smav} enc_element_t;
53235911Smav
54235911Smavtypedef enum {
55235911Smav	ENC_NONE,
56235911Smav	ENC_SES_SCSI2,
57235911Smav	ENC_SES,
58235911Smav	ENC_SES_PASSTHROUGH,
59235911Smav	ENC_SEN,
60235911Smav	ENC_SAFT,
61235911Smav	ENC_SEMB_SES,
62235911Smav	ENC_SEMB_SAFT
63235911Smav} enctyp;
64235911Smav
65235911Smav/* Platform Independent Driver Internal Definitions for enclosure devices. */
66235911Smavtypedef struct enc_softc enc_softc_t;
67235911Smav
68235911Smavstruct enc_fsm_state;
69235911Smavtypedef int fsm_fill_handler_t(enc_softc_t *ssc,
70235911Smav				struct enc_fsm_state *state,
71235911Smav				union ccb *ccb,
72235911Smav				uint8_t *buf);
73235911Smavtypedef int fsm_error_handler_t(union ccb *ccb, uint32_t cflags,
74235911Smav				uint32_t sflags);
75235911Smavtypedef int fsm_done_handler_t(enc_softc_t *ssc,
76235911Smav			       struct enc_fsm_state *state, union ccb *ccb,
77235911Smav			       uint8_t **bufp, int error, int xfer_len);
78235911Smav
79235911Smavstruct enc_fsm_state {
80235911Smav	const char	    *name;
81235911Smav	int		     page_code;
82235911Smav	size_t		     buf_size;
83235911Smav	uint32_t	     timeout;
84235911Smav	fsm_fill_handler_t  *fill;
85235911Smav	fsm_done_handler_t  *done;
86235911Smav	fsm_error_handler_t *error;
87235911Smav};
88235911Smav
89235911Smavtypedef int (enc_softc_init_t)(enc_softc_t *);
90235911Smavtypedef void (enc_softc_invalidate_t)(enc_softc_t *);
91235911Smavtypedef void (enc_softc_cleanup_t)(enc_softc_t *);
92235911Smavtypedef int (enc_init_enc_t)(enc_softc_t *);
93235911Smavtypedef int (enc_get_enc_status_t)(enc_softc_t *, int);
94235911Smavtypedef int (enc_set_enc_status_t)(enc_softc_t *, encioc_enc_status_t, int);
95235911Smavtypedef int (enc_get_elm_status_t)(enc_softc_t *, encioc_elm_status_t *, int);
96235911Smavtypedef int (enc_set_elm_status_t)(enc_softc_t *, encioc_elm_status_t *, int);
97235911Smavtypedef int (enc_get_elm_desc_t)(enc_softc_t *, encioc_elm_desc_t *);
98235911Smavtypedef int (enc_get_elm_devnames_t)(enc_softc_t *, encioc_elm_devnames_t *);
99235911Smavtypedef int (enc_handle_string_t)(enc_softc_t *, encioc_string_t *, int);
100235911Smavtypedef void (enc_device_found_t)(enc_softc_t *);
101235911Smavtypedef void (enc_poll_status_t)(enc_softc_t *);
102235911Smav
103235911Smavstruct enc_vec {
104235911Smav	enc_softc_invalidate_t	*softc_invalidate;
105235911Smav	enc_softc_cleanup_t	*softc_cleanup;
106235911Smav	enc_init_enc_t		*init_enc;
107235911Smav	enc_get_enc_status_t	*get_enc_status;
108235911Smav	enc_set_enc_status_t	*set_enc_status;
109235911Smav	enc_get_elm_status_t	*get_elm_status;
110235911Smav	enc_set_elm_status_t	*set_elm_status;
111235911Smav	enc_get_elm_desc_t	*get_elm_desc;
112235911Smav	enc_get_elm_devnames_t	*get_elm_devnames;
113235911Smav	enc_handle_string_t	*handle_string;
114235911Smav	enc_device_found_t	*device_found;
115235911Smav	enc_poll_status_t	*poll_status;
116235911Smav};
117235911Smav
118235911Smavtypedef struct enc_cache {
119235911Smav	enc_element_t		*elm_map;	/* objects */
120235911Smav	int			 nelms;		/* number of objects */
121235911Smav	encioc_enc_status_t	 enc_status;	/* overall status */
122235911Smav	void			*private;	/* per-type private data */
123235911Smav} enc_cache_t;
124235911Smav
125235911Smav/* Enclosure instance toplevel structure */
126235911Smavstruct enc_softc {
127235911Smav	enctyp			 enc_type;	/* type of enclosure */
128235911Smav	struct enc_vec		 enc_vec;	/* vector to handlers */
129235911Smav	void			*enc_private;	/* per-type private data */
130235911Smav
131235911Smav	/**
132235911Smav	 * "Published" configuration and state data available to
133235911Smav	 * external consumers.
134235911Smav	 */
135235911Smav	enc_cache_t		 enc_cache;
136235911Smav
137235911Smav	/**
138235911Smav	 * Configuration and state data being actively updated
139235911Smav	 * by the enclosure daemon.
140235911Smav	 */
141235911Smav	enc_cache_t		 enc_daemon_cache;
142235911Smav
143235911Smav	struct sx		 enc_cache_lock;
144235911Smav	uint8_t			 enc_flags;
145235911Smav#define	ENC_FLAG_INVALID	0x01
146235911Smav#define	ENC_FLAG_INITIALIZED	0x02
147235911Smav#define	ENC_FLAG_SHUTDOWN	0x04
148235911Smav	union ccb		 saved_ccb;
149235911Smav	struct cdev		*enc_dev;
150235911Smav	struct cam_periph	*periph;
151244014Sken	int			 open_count;
152235911Smav
153235911Smav	/* Bitmap of pending operations. */
154235911Smav	uint32_t		 pending_actions;
155235911Smav
156235911Smav	/* The action on which the state machine is currently working. */
157235911Smav	uint32_t		 current_action;
158235911Smav#define	ENC_UPDATE_NONE		0x00
159235911Smav#define	ENC_UPDATE_INVALID	0xff
160235911Smav
161235911Smav	/* Callout for auto-updating enclosure status */
162235911Smav	struct callout		 status_updater;
163235911Smav
164235911Smav	struct proc		*enc_daemon;
165235911Smav
166235911Smav	struct enc_fsm_state 	*enc_fsm_states;
167235911Smav
168235911Smav	struct intr_config_hook  enc_boot_hold_ch;
169235911Smav};
170235911Smav
171235911Smavstatic inline enc_cache_t *
172235911Smavenc_other_cache(enc_softc_t *enc, enc_cache_t *primary)
173235911Smav{
174235911Smav	return (primary == &enc->enc_cache
175235911Smav	      ? &enc->enc_daemon_cache : &enc->enc_cache);
176235911Smav}
177235911Smav
178235911Smav/* SES Management mode page - SES2r20 Table 59 */
179235911Smavstruct ses_mgmt_mode_page {
180235911Smav	struct scsi_mode_header_6 header;
181235911Smav	struct scsi_mode_blk_desc blk_desc;
182235911Smav	uint8_t byte0;  /* ps : 1, spf : 1, page_code : 6 */
183235911Smav#define SES_MGMT_MODE_PAGE_CODE 0x14
184235911Smav	uint8_t length;
185235911Smav#define SES_MGMT_MODE_PAGE_LEN  6
186235911Smav	uint8_t reserved[3];
187235911Smav	uint8_t byte5;  /* reserved : 7, enbltc : 1 */
188235911Smav#define SES_MGMT_TIMED_COMP_EN  0x1
189235911Smav	uint8_t max_comp_time[2];
190235911Smav};
191235911Smav
192235911Smav/* Enclosure core interface for sub-drivers */
193235911Smavint  enc_runcmd(struct enc_softc *, char *, int, char *, int *);
194235911Smavvoid enc_log(struct enc_softc *, const char *, ...);
195235911Smavvoid enc_done(struct cam_periph *, union ccb *);
196235911Smavint  enc_error(union ccb *, uint32_t, uint32_t);
197235911Smavvoid enc_update_request(enc_softc_t *, uint32_t);
198235911Smav
199235911Smav/* SES Native interface */
200235911Smavenc_softc_init_t	ses_softc_init;
201235911Smav
202235911Smav/* SAF-TE interface */
203235911Smavenc_softc_init_t	safte_softc_init;
204235911Smav
205235911Smav/* Helper macros */
206235911SmavMALLOC_DECLARE(M_SCSIENC);
207235911Smav#define	ENC_CFLAGS		CAM_RETRY_SELTO
208235911Smav#define	ENC_FLAGS		SF_NO_PRINT | SF_RETRY_UA
209235911Smav#define	STRNCMP			strncmp
210235911Smav#define	PRINTF			printf
211235911Smav#define	ENC_LOG			enc_log
212235911Smav#if defined(DEBUG) || defined(ENC_DEBUG)
213235911Smav#define	ENC_DLOG		enc_log
214235911Smav#else
215235911Smav#define	ENC_DLOG		if (0) enc_log
216235911Smav#endif
217235911Smav#define	ENC_VLOG		if (bootverbose) enc_log
218235911Smav#define	ENC_MALLOC(amt)		malloc(amt, M_SCSIENC, M_NOWAIT)
219235911Smav#define	ENC_MALLOCZ(amt)	malloc(amt, M_SCSIENC, M_ZERO|M_NOWAIT)
220235911Smav/* Cast away const avoiding GCC warnings. */
221235911Smav#define	ENC_FREE(ptr)		free((void *)((uintptr_t)ptr), M_SCSIENC)
222235911Smav#define	ENC_FREE_AND_NULL(ptr)	do {	\
223235911Smav	if (ptr != NULL) {		\
224235911Smav		ENC_FREE(ptr);		\
225235911Smav		ptr = NULL;		\
226235911Smav	}				\
227235911Smav} while(0)
228235911Smav#define	MEMZERO			bzero
229235911Smav#define	MEMCPY(dest, src, amt)	bcopy(src, dest, amt)
230235911Smav
231235911Smav#endif	/* __SCSI_ENC_INTERNAL_H__ */
232