138032Speter/*-
2168515Sgshapiro * Data structures and definitions for CAM peripheral ("type") drivers.
364562Sgshapiro *
438032Speter * Copyright (c) 1997, 1998 Justin T. Gibbs.
538032Speter * All rights reserved.
638032Speter *
738032Speter * Redistribution and use in source and binary forms, with or without
838032Speter * modification, are permitted provided that the following conditions
938032Speter * are met:
1038032Speter * 1. Redistributions of source code must retain the above copyright
1138032Speter *    notice, this list of conditions, and the following disclaimer,
1238032Speter *    without modification, immediately at the beginning of the file.
1338032Speter * 2. The name of the author may not be used to endorse or promote products
1464562Sgshapiro *    derived from this software without specific prior written permission.
1538032Speter *
16182352Sgshapiro * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1790792Sgshapiro * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18168515Sgshapiro * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19168515Sgshapiro * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
20168515Sgshapiro * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2190792Sgshapiro * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2264562Sgshapiro * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2364562Sgshapiro * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2464562Sgshapiro * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2594334Sgshapiro * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2664562Sgshapiro * SUCH DAMAGE.
2794334Sgshapiro *
2894334Sgshapiro * $FreeBSD: stable/11/sys/cam/cam_periph.h 355341 2019-12-03 16:52:39Z mav $
2994334Sgshapiro */
3038032Speter
3138032Speter#ifndef _CAM_CAM_PERIPH_H
3238032Speter#define _CAM_CAM_PERIPH_H 1
3338032Speter
3438032Speter#include <sys/queue.h>
3538032Speter#include <cam/cam_sim.h>
3638032Speter
3738032Speter#ifdef _KERNEL
3838032Speter#include <sys/taskqueue.h>
3938032Speter
4038032Speter#include <cam/cam_xpt.h>
4138032Speter
4238032Speterstruct devstat;
4338032Speter
4438032Speterextern struct cam_periph *xpt_periph;
4538032Speter
4638032Speterextern struct periph_driver **periph_drivers;
4790792Sgshapirovoid periphdriver_register(void *);
4838032Speterint periphdriver_unregister(void *);
4938032Spetervoid periphdriver_init(int level);
5038032Speter
5138032Speter#include <sys/module.h>
5238032Speter#define PERIPHDRIVER_DECLARE(name, driver) \
5338032Speter	static int name ## _modevent(module_t mod, int type, void *data) \
5438032Speter	{ \
5590792Sgshapiro		switch (type) { \
5690792Sgshapiro		case MOD_LOAD: \
5738032Speter			periphdriver_register(data); \
5838032Speter			break; \
5938032Speter		case MOD_UNLOAD: \
6038032Speter			return (periphdriver_unregister(data)); \
6138032Speter		default: \
6238032Speter			return EOPNOTSUPP; \
6338032Speter		} \
6490792Sgshapiro		return 0; \
6538032Speter	} \
6638032Speter	static moduledata_t name ## _mod = { \
6738032Speter		#name, \
6864562Sgshapiro		name ## _modevent, \
6938032Speter		(void *)&driver \
7038032Speter	}; \
7190792Sgshapiro	DECLARE_MODULE(name, name ## _mod, SI_SUB_DRIVERS, SI_ORDER_ANY); \
7238032Speter	MODULE_DEPEND(name, cam, 1, 1, 1)
7338032Speter
7438032Speter/*
7538032Speter * Callback informing the peripheral driver it can perform it's
7638032Speter * initialization since the XPT is now fully initialized.
7738032Speter */
7890792Sgshapirotypedef void (periph_init_t)(void);
7938032Speter
8090792Sgshapiro/*
8138032Speter * Callback requesting the peripheral driver to remove its instances
8264562Sgshapiro * and shutdown, if possible.
8338032Speter */
8438032Spetertypedef int (periph_deinit_t)(void);
8538032Speter
8638032Speterstruct periph_driver {
8738032Speter	periph_init_t		*init;
8838032Speter	char			*driver_name;
8938032Speter	TAILQ_HEAD(,cam_periph)	 units;
9038032Speter	u_int			 generation;
9190792Sgshapiro	u_int			 flags;
9238032Speter#define CAM_PERIPH_DRV_EARLY		0x01
9338032Speter	periph_deinit_t		*deinit;
9438032Speter};
9538032Speter
96168515Sgshapirotypedef enum {
97168515Sgshapiro	CAM_PERIPH_BIO
9838032Speter} cam_periph_type;
9938032Speter
10038032Speter/* Generically useful offsets into the peripheral private area */
10190792Sgshapiro#define ppriv_ptr0 periph_priv.entries[0].ptr
10264562Sgshapiro#define ppriv_ptr1 periph_priv.entries[1].ptr
10338032Speter#define ppriv_field0 periph_priv.entries[0].field
10438032Speter#define ppriv_field1 periph_priv.entries[1].field
10590792Sgshapiro
10638032Spetertypedef void		periph_start_t (struct cam_periph *periph,
10738032Speter					union ccb *start_ccb);
10890792Sgshapirotypedef cam_status	periph_ctor_t (struct cam_periph *periph,
10938032Speter				       void *arg);
11038032Spetertypedef void		periph_oninv_t (struct cam_periph *periph);
11138032Spetertypedef void		periph_dtor_t (struct cam_periph *periph);
11238032Speterstruct cam_periph {
11338032Speter	periph_start_t		*periph_start;
11438032Speter	periph_oninv_t		*periph_oninval;
11538032Speter	periph_dtor_t		*periph_dtor;
11638032Speter	char			*periph_name;
11738032Speter	struct cam_path		*path;	/* Compiled path to device */
11838032Speter	void			*softc;
11938032Speter	struct cam_sim		*sim;
12038032Speter	u_int32_t		 unit_number;
12138032Speter	cam_periph_type		 type;
12238032Speter	u_int32_t		 flags;
12338032Speter#define CAM_PERIPH_RUNNING		0x01
12438032Speter#define CAM_PERIPH_LOCKED		0x02
12538032Speter#define CAM_PERIPH_LOCK_WANTED		0x04
12690792Sgshapiro#define CAM_PERIPH_INVALID		0x08
12738032Speter#define CAM_PERIPH_NEW_DEV_FOUND	0x10
12838032Speter#define CAM_PERIPH_RECOVERY_INPROG	0x20
12938032Speter#define CAM_PERIPH_RUN_TASK		0x40
13038032Speter#define CAM_PERIPH_FREE			0x80
13138032Speter#define CAM_PERIPH_ANNOUNCED		0x100
13238032Speter#define CAM_PERIPH_RECOVERY_WAIT	0x200
13338032Speter#define CAM_PERIPH_RECOVERY_WAIT_FAILED	0x400
13438032Speter	uint32_t		 scheduled_priority;
13538032Speter	uint32_t		 immediate_priority;
13690792Sgshapiro	int			 periph_allocating;
13790792Sgshapiro	int			 periph_allocated;
13890792Sgshapiro	u_int32_t		 refcount;
13990792Sgshapiro	SLIST_HEAD(, ccb_hdr)	 ccb_list;	/* For "immediate" requests */
14090792Sgshapiro	SLIST_ENTRY(cam_periph)  periph_links;
14138032Speter	TAILQ_ENTRY(cam_periph)  unit_links;
14238032Speter	ac_callback_t		*deferred_callback;
14338032Speter	ac_code			 deferred_ac;
14438032Speter	struct task		 periph_run_task;
14538032Speter};
14638032Speter
14738032Speter#define CAM_PERIPH_MAXMAPS	2
14894334Sgshapiro
14990792Sgshapirostruct cam_periph_map_info {
15090792Sgshapiro	int		num_bufs_used;
15190792Sgshapiro	void		*orig[CAM_PERIPH_MAXMAPS];
15294334Sgshapiro	struct buf	*bp[CAM_PERIPH_MAXMAPS];
15394334Sgshapiro};
15494334Sgshapiro
15594334Sgshapirocam_status cam_periph_alloc(periph_ctor_t *periph_ctor,
15694334Sgshapiro			    periph_oninv_t *periph_oninvalidate,
15794334Sgshapiro			    periph_dtor_t *periph_dtor,
15894334Sgshapiro			    periph_start_t *periph_start,
15994334Sgshapiro			    char *name, cam_periph_type type, struct cam_path *,
16090792Sgshapiro			    ac_callback_t *, ac_code, void *arg);
16190792Sgshapirostruct cam_periph *cam_periph_find(struct cam_path *path, char *name);
16238032Speterint		cam_periph_list(struct cam_path *, struct sbuf *);
16338032Spetercam_status	cam_periph_acquire(struct cam_periph *periph);
16438032Spetervoid		cam_periph_doacquire(struct cam_periph *periph);
16538032Spetervoid		cam_periph_release(struct cam_periph *periph);
16638032Spetervoid		cam_periph_release_locked(struct cam_periph *periph);
16790792Sgshapirovoid		cam_periph_release_locked_buses(struct cam_periph *periph);
16864562Sgshapiroint		cam_periph_hold(struct cam_periph *periph, int priority);
16994334Sgshapirovoid		cam_periph_unhold(struct cam_periph *periph);
17094334Sgshapirovoid		cam_periph_invalidate(struct cam_periph *periph);
17194334Sgshapiroint		cam_periph_mapmem(union ccb *ccb,
17238032Speter				  struct cam_periph_map_info *mapinfo,
17394334Sgshapiro				  u_int maxmap);
17438032Spetervoid		cam_periph_unmapmem(union ccb *ccb,
17538032Speter				    struct cam_periph_map_info *mapinfo);
17690792Sgshapirounion ccb	*cam_periph_getccb(struct cam_periph *periph,
17790792Sgshapiro				   u_int32_t priority);
17890792Sgshapiroint		cam_periph_runccb(union ccb *ccb,
17990792Sgshapiro				  int (*error_routine)(union ccb *ccb,
18090792Sgshapiro						       cam_flags camflags,
18190792Sgshapiro						       u_int32_t sense_flags),
18290792Sgshapiro				  cam_flags camflags, u_int32_t sense_flags,
183168515Sgshapiro				  struct devstat *ds);
18490792Sgshapiroint		cam_periph_ioctl(struct cam_periph *periph, u_long cmd,
18590792Sgshapiro				 caddr_t addr,
18690792Sgshapiro				 int (*error_routine)(union ccb *ccb,
18790792Sgshapiro						      cam_flags camflags,
18890792Sgshapiro						      u_int32_t sense_flags));
18990792Sgshapirovoid		cam_freeze_devq(struct cam_path *path);
19090792Sgshapirou_int32_t	cam_release_devq(struct cam_path *path, u_int32_t relsim_flags,
19190792Sgshapiro				 u_int32_t opening_reduction, u_int32_t arg,
19290792Sgshapiro				 int getcount_only);
19390792Sgshapirovoid		cam_periph_async(struct cam_periph *periph, u_int32_t code,
19490792Sgshapiro		 		 struct cam_path *path, void *arg);
19590792Sgshapirovoid		cam_periph_bus_settle(struct cam_periph *periph,
19690792Sgshapiro				      u_int bus_settle_ms);
19790792Sgshapirovoid		cam_periph_freeze_after_event(struct cam_periph *periph,
19890792Sgshapiro					      struct timeval* event_time,
19990792Sgshapiro					      u_int duration_ms);
20090792Sgshapiroint		cam_periph_error(union ccb *ccb, cam_flags camflags,
20190792Sgshapiro				 u_int32_t sense_flags, union ccb *save_ccb);
20290792Sgshapiro
20390792Sgshapirostatic __inline struct mtx *
20490792Sgshapirocam_periph_mtx(struct cam_periph *periph)
20590792Sgshapiro{
20690792Sgshapiro	return (xpt_path_mtx(periph->path));
20790792Sgshapiro}
20890792Sgshapiro
20990792Sgshapiro#define cam_periph_owned(periph)					\
21038032Speter	mtx_owned(xpt_path_mtx((periph)->path))
21138032Speter
21238032Speter#define cam_periph_lock(periph)						\
21364562Sgshapiro	mtx_lock(xpt_path_mtx((periph)->path))
21438032Speter
21538032Speter#define cam_periph_unlock(periph)					\
21638032Speter	mtx_unlock(xpt_path_mtx((periph)->path))
21738032Speter
21838032Speter#define cam_periph_assert(periph, what)					\
21938032Speter	mtx_assert(xpt_path_mtx((periph)->path), (what))
220173340Sgshapiro
22138032Speter#define cam_periph_sleep(periph, chan, priority, wmesg, timo)		\
22238032Speter	xpt_path_sleep((periph)->path, (chan), (priority), (wmesg), (timo))
22390792Sgshapiro
22464562Sgshapirostatic inline struct cam_periph *
22538032Spetercam_periph_acquire_first(struct periph_driver *driver)
22638032Speter{
22738032Speter	struct cam_periph *periph;
22838032Speter
22938032Speter	xpt_lock_buses();
23038032Speter	periph = TAILQ_FIRST(&driver->units);
23138032Speter	while (periph != NULL && (periph->flags & CAM_PERIPH_INVALID) != 0)
23238032Speter		periph = TAILQ_NEXT(periph, unit_links);
23338032Speter	if (periph != NULL)
23490792Sgshapiro		periph->refcount++;
235132943Sgshapiro	xpt_unlock_buses();
23638032Speter	return (periph);
23738032Speter}
23864562Sgshapiro
23938032Speterstatic inline struct cam_periph *
24090792Sgshapirocam_periph_acquire_next(struct cam_periph *pperiph)
24190792Sgshapiro{
24238032Speter	struct cam_periph *periph = pperiph;
24338032Speter
24438032Speter	cam_periph_assert(pperiph, MA_NOTOWNED);
24590792Sgshapiro	xpt_lock_buses();
24690792Sgshapiro	do {
24790792Sgshapiro		periph = TAILQ_NEXT(periph, unit_links);
24838032Speter	} while (periph != NULL && (periph->flags & CAM_PERIPH_INVALID) != 0);
24938032Speter	if (periph != NULL)
25090792Sgshapiro		periph->refcount++;
25190792Sgshapiro	xpt_unlock_buses();
25290792Sgshapiro	cam_periph_release(pperiph);
25338032Speter	return (periph);
25438032Speter}
25538032Speter
25690792Sgshapiro#define CAM_PERIPH_FOREACH(periph, driver)				\
25738032Speter	for ((periph) = cam_periph_acquire_first(driver);		\
25838032Speter	    (periph) != NULL;						\
25990792Sgshapiro	    (periph) = cam_periph_acquire_next(periph))
26038032Speter
26190792Sgshapiro#endif /* _KERNEL */
26238032Speter#endif /* _CAM_CAM_PERIPH_H */
26394334Sgshapiro