1139743Simp/*-
239212Sgibbs * Data structures and definitions for CAM peripheral ("type") drivers.
339212Sgibbs *
439212Sgibbs * Copyright (c) 1997, 1998 Justin T. Gibbs.
539212Sgibbs * All rights reserved.
639212Sgibbs *
739212Sgibbs * Redistribution and use in source and binary forms, with or without
839212Sgibbs * modification, are permitted provided that the following conditions
939212Sgibbs * are met:
1039212Sgibbs * 1. Redistributions of source code must retain the above copyright
1139212Sgibbs *    notice, this list of conditions, and the following disclaimer,
1239212Sgibbs *    without modification, immediately at the beginning of the file.
1339212Sgibbs * 2. The name of the author may not be used to endorse or promote products
1439212Sgibbs *    derived from this software without specific prior written permission.
1539212Sgibbs *
1639212Sgibbs * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1739212Sgibbs * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1839212Sgibbs * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1939212Sgibbs * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
2039212Sgibbs * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2139212Sgibbs * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2239212Sgibbs * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2339212Sgibbs * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2439212Sgibbs * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2539212Sgibbs * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2639212Sgibbs * SUCH DAMAGE.
2739212Sgibbs *
2850477Speter * $FreeBSD: stable/11/sys/cam/cam_periph.h 355341 2019-12-03 16:52:39Z mav $
2939212Sgibbs */
3039212Sgibbs
3139212Sgibbs#ifndef _CAM_CAM_PERIPH_H
3239212Sgibbs#define _CAM_CAM_PERIPH_H 1
3339212Sgibbs
3439212Sgibbs#include <sys/queue.h>
35168876Sscottl#include <cam/cam_sim.h>
3639212Sgibbs
3755206Speter#ifdef _KERNEL
38256843Smav#include <sys/taskqueue.h>
3939212Sgibbs
40248874Smarius#include <cam/cam_xpt.h>
41248874Smarius
42111979Sphkstruct devstat;
43111979Sphk
4460168Sn_hibmaextern struct cam_periph *xpt_periph;
4558972Sn_hibma
4672119Speterextern struct periph_driver **periph_drivers;
4772119Spetervoid periphdriver_register(void *);
48316139Smavint periphdriver_unregister(void *);
49203108Smavvoid periphdriver_init(int level);
5039212Sgibbs
5172119Speter#include <sys/module.h>
5272119Speter#define PERIPHDRIVER_DECLARE(name, driver) \
5372119Speter	static int name ## _modevent(module_t mod, int type, void *data) \
5472119Speter	{ \
5572119Speter		switch (type) { \
5672119Speter		case MOD_LOAD: \
5772119Speter			periphdriver_register(data); \
5872119Speter			break; \
5972119Speter		case MOD_UNLOAD: \
60316139Smav			return (periphdriver_unregister(data)); \
61132199Sphk		default: \
62132199Sphk			return EOPNOTSUPP; \
6372119Speter		} \
6472119Speter		return 0; \
6572119Speter	} \
6672119Speter	static moduledata_t name ## _mod = { \
6772119Speter		#name, \
6872119Speter		name ## _modevent, \
6972119Speter		(void *)&driver \
7072119Speter	}; \
7172119Speter	DECLARE_MODULE(name, name ## _mod, SI_SUB_DRIVERS, SI_ORDER_ANY); \
7272119Speter	MODULE_DEPEND(name, cam, 1, 1, 1)
7372119Speter
74316139Smav/*
75316139Smav * Callback informing the peripheral driver it can perform it's
76316139Smav * initialization since the XPT is now fully initialized.
77316139Smav */
78316139Smavtypedef void (periph_init_t)(void);
7939212Sgibbs
80316139Smav/*
81316139Smav * Callback requesting the peripheral driver to remove its instances
82316139Smav * and shutdown, if possible.
83316139Smav */
84316139Smavtypedef int (periph_deinit_t)(void);
85316139Smav
8639212Sgibbsstruct periph_driver {
87316139Smav	periph_init_t		*init;
88316139Smav	char			*driver_name;
8960938Sjake	TAILQ_HEAD(,cam_periph)	 units;
9039212Sgibbs	u_int			 generation;
91198708Smav	u_int			 flags;
92198708Smav#define CAM_PERIPH_DRV_EARLY		0x01
93316139Smav	periph_deinit_t		*deinit;
9439212Sgibbs};
9539212Sgibbs
9639212Sgibbstypedef enum {
97136132Sscottl	CAM_PERIPH_BIO
9839212Sgibbs} cam_periph_type;
9939212Sgibbs
100249585Sgabor/* Generically useful offsets into the peripheral private area */
10139212Sgibbs#define ppriv_ptr0 periph_priv.entries[0].ptr
10239212Sgibbs#define ppriv_ptr1 periph_priv.entries[1].ptr
10339212Sgibbs#define ppriv_field0 periph_priv.entries[0].field
10439212Sgibbs#define ppriv_field1 periph_priv.entries[1].field
10539212Sgibbs
10639212Sgibbstypedef void		periph_start_t (struct cam_periph *periph,
10739212Sgibbs					union ccb *start_ccb);
10839212Sgibbstypedef cam_status	periph_ctor_t (struct cam_periph *periph,
10939212Sgibbs				       void *arg);
11040603Skentypedef void		periph_oninv_t (struct cam_periph *periph);
11139212Sgibbstypedef void		periph_dtor_t (struct cam_periph *periph);
11239212Sgibbsstruct cam_periph {
11339212Sgibbs	periph_start_t		*periph_start;
11440603Sken	periph_oninv_t		*periph_oninval;
11539212Sgibbs	periph_dtor_t		*periph_dtor;
11639212Sgibbs	char			*periph_name;
11739212Sgibbs	struct cam_path		*path;	/* Compiled path to device */
11839212Sgibbs	void			*softc;
119168752Sscottl	struct cam_sim		*sim;
12039212Sgibbs	u_int32_t		 unit_number;
12139212Sgibbs	cam_periph_type		 type;
12239212Sgibbs	u_int32_t		 flags;
12339212Sgibbs#define CAM_PERIPH_RUNNING		0x01
12439212Sgibbs#define CAM_PERIPH_LOCKED		0x02
12539212Sgibbs#define CAM_PERIPH_LOCK_WANTED		0x04
12639212Sgibbs#define CAM_PERIPH_INVALID		0x08
12739212Sgibbs#define CAM_PERIPH_NEW_DEV_FOUND	0x10
12840318Sken#define CAM_PERIPH_RECOVERY_INPROG	0x20
129256843Smav#define CAM_PERIPH_RUN_TASK		0x40
130230000Sken#define CAM_PERIPH_FREE			0x80
131256552Smav#define CAM_PERIPH_ANNOUNCED		0x100
132355341Smav#define CAM_PERIPH_RECOVERY_WAIT	0x200
133355341Smav#define CAM_PERIPH_RECOVERY_WAIT_FAILED	0x400
134256843Smav	uint32_t		 scheduled_priority;
135256843Smav	uint32_t		 immediate_priority;
136256843Smav	int			 periph_allocating;
137256843Smav	int			 periph_allocated;
13839212Sgibbs	u_int32_t		 refcount;
13960938Sjake	SLIST_HEAD(, ccb_hdr)	 ccb_list;	/* For "immediate" requests */
14060938Sjake	SLIST_ENTRY(cam_periph)  periph_links;
14160938Sjake	TAILQ_ENTRY(cam_periph)  unit_links;
14239212Sgibbs	ac_callback_t		*deferred_callback;
14339212Sgibbs	ac_code			 deferred_ac;
144256843Smav	struct task		 periph_run_task;
14539212Sgibbs};
14639212Sgibbs
14739212Sgibbs#define CAM_PERIPH_MAXMAPS	2
14839212Sgibbs
14939212Sgibbsstruct cam_periph_map_info {
15039212Sgibbs	int		num_bufs_used;
151346758Smav	void		*orig[CAM_PERIPH_MAXMAPS];
15239212Sgibbs	struct buf	*bp[CAM_PERIPH_MAXMAPS];
15339212Sgibbs};
15439212Sgibbs
15540603Skencam_status cam_periph_alloc(periph_ctor_t *periph_ctor,
15640603Sken			    periph_oninv_t *periph_oninvalidate,
15740603Sken			    periph_dtor_t *periph_dtor,
15840603Sken			    periph_start_t *periph_start,
15958111Sn_hibma			    char *name, cam_periph_type type, struct cam_path *,
16058111Sn_hibma			    ac_callback_t *, ac_code, void *arg);
16139212Sgibbsstruct cam_periph *cam_periph_find(struct cam_path *path, char *name);
162223081Sgibbsint		cam_periph_list(struct cam_path *, struct sbuf *);
16339212Sgibbscam_status	cam_periph_acquire(struct cam_periph *periph);
164260541Smavvoid		cam_periph_doacquire(struct cam_periph *periph);
16539212Sgibbsvoid		cam_periph_release(struct cam_periph *periph);
166186319Straszvoid		cam_periph_release_locked(struct cam_periph *periph);
167230000Skenvoid		cam_periph_release_locked_buses(struct cam_periph *periph);
168168752Sscottlint		cam_periph_hold(struct cam_periph *periph, int priority);
169168752Sscottlvoid		cam_periph_unhold(struct cam_periph *periph);
17039212Sgibbsvoid		cam_periph_invalidate(struct cam_periph *periph);
17139212Sgibbsint		cam_periph_mapmem(union ccb *ccb,
172288420Smav				  struct cam_periph_map_info *mapinfo,
173288420Smav				  u_int maxmap);
17439212Sgibbsvoid		cam_periph_unmapmem(union ccb *ccb,
17539212Sgibbs				    struct cam_periph_map_info *mapinfo);
17639212Sgibbsunion ccb	*cam_periph_getccb(struct cam_periph *periph,
17739212Sgibbs				   u_int32_t priority);
17839212Sgibbsint		cam_periph_runccb(union ccb *ccb,
17939212Sgibbs				  int (*error_routine)(union ccb *ccb,
18039212Sgibbs						       cam_flags camflags,
18139212Sgibbs						       u_int32_t sense_flags),
18239212Sgibbs				  cam_flags camflags, u_int32_t sense_flags,
18339212Sgibbs				  struct devstat *ds);
184194627Sscottlint		cam_periph_ioctl(struct cam_periph *periph, u_long cmd,
18539212Sgibbs				 caddr_t addr,
18639212Sgibbs				 int (*error_routine)(union ccb *ccb,
18739212Sgibbs						      cam_flags camflags,
18839212Sgibbs						      u_int32_t sense_flags));
18947412Sgibbsvoid		cam_freeze_devq(struct cam_path *path);
19039212Sgibbsu_int32_t	cam_release_devq(struct cam_path *path, u_int32_t relsim_flags,
191203108Smav				 u_int32_t opening_reduction, u_int32_t arg,
19239212Sgibbs				 int getcount_only);
19347412Sgibbsvoid		cam_periph_async(struct cam_periph *periph, u_int32_t code,
19447412Sgibbs		 		 struct cam_path *path, void *arg);
19547412Sgibbsvoid		cam_periph_bus_settle(struct cam_periph *periph,
19647412Sgibbs				      u_int bus_settle_ms);
19747412Sgibbsvoid		cam_periph_freeze_after_event(struct cam_periph *periph,
19847412Sgibbs					      struct timeval* event_time,
19947412Sgibbs					      u_int duration_ms);
20039212Sgibbsint		cam_periph_error(union ccb *ccb, cam_flags camflags,
20139212Sgibbs				 u_int32_t sense_flags, union ccb *save_ccb);
20239212Sgibbs
203256843Smavstatic __inline struct mtx *
204256843Smavcam_periph_mtx(struct cam_periph *periph)
205168876Sscottl{
206256843Smav	return (xpt_path_mtx(periph->path));
207168876Sscottl}
208168876Sscottl
209256843Smav#define cam_periph_owned(periph)					\
210256843Smav	mtx_owned(xpt_path_mtx((periph)->path))
211168876Sscottl
212256843Smav#define cam_periph_lock(periph)						\
213256843Smav	mtx_lock(xpt_path_mtx((periph)->path))
214200180Smav
215256843Smav#define cam_periph_unlock(periph)					\
216256843Smav	mtx_unlock(xpt_path_mtx((periph)->path))
217223081Sgibbs
218256843Smav#define cam_periph_assert(periph, what)					\
219256843Smav	mtx_assert(xpt_path_mtx((periph)->path), (what))
220256843Smav
221256843Smav#define cam_periph_sleep(periph, chan, priority, wmesg, timo)		\
222256843Smav	xpt_path_sleep((periph)->path, (chan), (priority), (wmesg), (timo))
223256843Smav
224248868Smavstatic inline struct cam_periph *
225248868Smavcam_periph_acquire_first(struct periph_driver *driver)
226248868Smav{
227248868Smav	struct cam_periph *periph;
228248868Smav
229248868Smav	xpt_lock_buses();
230248868Smav	periph = TAILQ_FIRST(&driver->units);
231248868Smav	while (periph != NULL && (periph->flags & CAM_PERIPH_INVALID) != 0)
232248868Smav		periph = TAILQ_NEXT(periph, unit_links);
233248868Smav	if (periph != NULL)
234248868Smav		periph->refcount++;
235248868Smav	xpt_unlock_buses();
236248868Smav	return (periph);
237248868Smav}
238248868Smav
239248868Smavstatic inline struct cam_periph *
240248868Smavcam_periph_acquire_next(struct cam_periph *pperiph)
241248868Smav{
242248868Smav	struct cam_periph *periph = pperiph;
243248868Smav
244256843Smav	cam_periph_assert(pperiph, MA_NOTOWNED);
245248868Smav	xpt_lock_buses();
246248868Smav	do {
247248868Smav		periph = TAILQ_NEXT(periph, unit_links);
248248868Smav	} while (periph != NULL && (periph->flags & CAM_PERIPH_INVALID) != 0);
249248868Smav	if (periph != NULL)
250248868Smav		periph->refcount++;
251248868Smav	xpt_unlock_buses();
252248868Smav	cam_periph_release(pperiph);
253248868Smav	return (periph);
254248868Smav}
255248868Smav
256248868Smav#define CAM_PERIPH_FOREACH(periph, driver)				\
257248868Smav	for ((periph) = cam_periph_acquire_first(driver);		\
258248868Smav	    (periph) != NULL;						\
259248868Smav	    (periph) = cam_periph_acquire_next(periph))
260248868Smav
26155206Speter#endif /* _KERNEL */
26239212Sgibbs#endif /* _CAM_CAM_PERIPH_H */
263