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