150107Smsmith/*- 250107Smsmith * Copyright (c) 1999 Michael Smith <msmith@freebsd.org> 350107Smsmith * All rights reserved. 450107Smsmith * 550107Smsmith * Redistribution and use in source and binary forms, with or without 650107Smsmith * modification, are permitted provided that the following conditions 750107Smsmith * are met: 850107Smsmith * 1. Redistributions of source code must retain the above copyright 950107Smsmith * notice, this list of conditions and the following disclaimer. 1050107Smsmith * 2. Redistributions in binary form must reproduce the above copyright 1150107Smsmith * notice, this list of conditions and the following disclaimer in the 1250107Smsmith * documentation and/or other materials provided with the distribution. 1350107Smsmith * 1450107Smsmith * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1550107Smsmith * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1650107Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1750107Smsmith * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1850107Smsmith * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1950107Smsmith * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2050107Smsmith * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2150107Smsmith * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2250107Smsmith * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2350107Smsmith * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2450107Smsmith * SUCH DAMAGE. 2550107Smsmith * 2650477Speter * $FreeBSD: stable/10/sys/sys/eventhandler.h 307253 2016-10-14 03:11:31Z sephe $ 2750107Smsmith */ 2850107Smsmith 2967535Sjhb#ifndef SYS_EVENTHANDLER_H 3067535Sjhb#define SYS_EVENTHANDLER_H 3167535Sjhb 3293615Salfred#include <sys/lock.h> 33112111Sjhb#include <sys/ktr.h> 34112111Sjhb#include <sys/mutex.h> 3550107Smsmith#include <sys/queue.h> 3650107Smsmith 3795193Smarkmstruct eventhandler_entry { 3895193Smarkm TAILQ_ENTRY(eventhandler_entry) ee_link; 3995193Smarkm int ee_priority; 40112111Sjhb#define EHE_DEAD_PRIORITY (-1) 4195193Smarkm void *ee_arg; 4250107Smsmith}; 4350107Smsmith 44205345Sbz#ifdef VIMAGE 45205345Sbzstruct eventhandler_entry_vimage { 46205345Sbz void (* func)(void); /* Original function registered. */ 47205345Sbz void *ee_arg; /* Original argument registered. */ 48205345Sbz void *sparep[2]; 49205345Sbz}; 50205345Sbz#endif 51205345Sbz 5295193Smarkmstruct eventhandler_list { 5395193Smarkm char *el_name; 5495193Smarkm int el_flags; 55112111Sjhb#define EHL_INITTED (1<<0) 56112111Sjhb u_int el_runcount; 57112111Sjhb struct mtx el_lock; 5895193Smarkm TAILQ_ENTRY(eventhandler_list) el_link; 5995193Smarkm TAILQ_HEAD(,eventhandler_entry) el_entries; 6050107Smsmith}; 6150107Smsmith 6250107Smsmithtypedef struct eventhandler_entry *eventhandler_tag; 6350107Smsmith 64112111Sjhb#define EHL_LOCK(p) mtx_lock(&(p)->el_lock) 65112111Sjhb#define EHL_UNLOCK(p) mtx_unlock(&(p)->el_lock) 66112111Sjhb#define EHL_LOCK_ASSERT(p, x) mtx_assert(&(p)->el_lock, x) 6793615Salfred 68112111Sjhb/* 69112111Sjhb * Macro to invoke the handlers for a given event. 70112111Sjhb */ 71112111Sjhb#define _EVENTHANDLER_INVOKE(name, list, ...) do { \ 72112111Sjhb struct eventhandler_entry *_ep; \ 73112111Sjhb struct eventhandler_entry_ ## name *_t; \ 74112111Sjhb \ 75112111Sjhb KASSERT((list)->el_flags & EHL_INITTED, \ 76112111Sjhb ("eventhandler_invoke: running non-inited list")); \ 77112111Sjhb EHL_LOCK_ASSERT((list), MA_OWNED); \ 78112111Sjhb (list)->el_runcount++; \ 79112111Sjhb KASSERT((list)->el_runcount > 0, \ 80112111Sjhb ("eventhandler_invoke: runcount overflow")); \ 81112111Sjhb CTR0(KTR_EVH, "eventhandler_invoke(\"" __STRING(name) "\")"); \ 82112111Sjhb TAILQ_FOREACH(_ep, &((list)->el_entries), ee_link) { \ 83112111Sjhb if (_ep->ee_priority != EHE_DEAD_PRIORITY) { \ 84112111Sjhb EHL_UNLOCK((list)); \ 85112111Sjhb _t = (struct eventhandler_entry_ ## name *)_ep; \ 86112111Sjhb CTR1(KTR_EVH, "eventhandler_invoke: executing %p", \ 87112111Sjhb (void *)_t->eh_func); \ 88112111Sjhb _t->eh_func(_ep->ee_arg , ## __VA_ARGS__); \ 89112111Sjhb EHL_LOCK((list)); \ 90112111Sjhb } \ 91112111Sjhb } \ 92112111Sjhb KASSERT((list)->el_runcount > 0, \ 93112111Sjhb ("eventhandler_invoke: runcount underflow")); \ 94112111Sjhb (list)->el_runcount--; \ 95112111Sjhb if ((list)->el_runcount == 0) \ 96112111Sjhb eventhandler_prune_list(list); \ 97112111Sjhb EHL_UNLOCK((list)); \ 98112111Sjhb} while (0) 99112111Sjhb 10050107Smsmith/* 10166205Smsmith * Slow handlers are entirely dynamic; lists are created 10250107Smsmith * when entries are added to them, and thus have no concept of "owner", 10350107Smsmith * 10466205Smsmith * Slow handlers need to be declared, but do not need to be defined. The 10550107Smsmith * declaration must be in scope wherever the handler is to be invoked. 10650107Smsmith */ 10795193Smarkm#define EVENTHANDLER_DECLARE(name, type) \ 10895193Smarkmstruct eventhandler_entry_ ## name \ 10995193Smarkm{ \ 11095193Smarkm struct eventhandler_entry ee; \ 11195193Smarkm type eh_func; \ 11295193Smarkm}; \ 11356093Sbdestruct __hack 11450107Smsmith 115167905Snjl#define EVENTHANDLER_DEFINE(name, func, arg, priority) \ 116167905Snjl static eventhandler_tag name ## _tag; \ 117167905Snjl static void name ## _evh_init(void *ctx) \ 118167905Snjl { \ 119167905Snjl name ## _tag = EVENTHANDLER_REGISTER(name, func, ctx, \ 120167905Snjl priority); \ 121167905Snjl } \ 122167905Snjl SYSINIT(name ## _evh_init, SI_SUB_CONFIGURE, SI_ORDER_ANY, \ 123177253Srwatson name ## _evh_init, arg); \ 124167905Snjl struct __hack 125167905Snjl 126100111Smarkm#define EVENTHANDLER_INVOKE(name, ...) \ 12795193Smarkmdo { \ 12895193Smarkm struct eventhandler_list *_el; \ 12995193Smarkm \ 130112111Sjhb if ((_el = eventhandler_find_list(#name)) != NULL) \ 131112111Sjhb _EVENTHANDLER_INVOKE(name, _el , ## __VA_ARGS__); \ 13256093Sbde} while (0) 13350107Smsmith 13495193Smarkm#define EVENTHANDLER_REGISTER(name, func, arg, priority) \ 13595193Smarkm eventhandler_register(NULL, #name, func, arg, priority) 13650107Smsmith 13795193Smarkm#define EVENTHANDLER_DEREGISTER(name, tag) \ 13895193Smarkmdo { \ 13995193Smarkm struct eventhandler_list *_el; \ 14095193Smarkm \ 14195193Smarkm if ((_el = eventhandler_find_list(#name)) != NULL) \ 14295193Smarkm eventhandler_deregister(_el, tag); \ 14356093Sbde} while(0) 14450107Smsmith 14550107Smsmith 146112111Sjhbeventhandler_tag eventhandler_register(struct eventhandler_list *list, 147138439Sjkoshy const char *name, void *func, void *arg, int priority); 148112111Sjhbvoid eventhandler_deregister(struct eventhandler_list *list, 149112111Sjhb eventhandler_tag tag); 150138439Sjkoshystruct eventhandler_list *eventhandler_find_list(const char *name); 151112111Sjhbvoid eventhandler_prune_list(struct eventhandler_list *list); 15250107Smsmith 153205345Sbz#ifdef VIMAGE 154205345Sbztypedef void (*vimage_iterator_func_t)(void *, ...); 155205345Sbz 156205345Sbzeventhandler_tag vimage_eventhandler_register(struct eventhandler_list *list, 157205345Sbz const char *name, void *func, void *arg, int priority, 158205345Sbz vimage_iterator_func_t); 159205345Sbz#endif 160205345Sbz 16150107Smsmith/* 16250107Smsmith * Standard system event queues. 16350107Smsmith */ 16450107Smsmith 165112563Sjhb/* Generic priority levels */ 166112563Sjhb#define EVENTHANDLER_PRI_FIRST 0 167112563Sjhb#define EVENTHANDLER_PRI_ANY 10000 168112563Sjhb#define EVENTHANDLER_PRI_LAST 20000 169112563Sjhb 17050107Smsmith/* Shutdown events */ 17192719Salfredtypedef void (*shutdown_fn)(void *, int); 17250107Smsmith 173112563Sjhb#define SHUTDOWN_PRI_FIRST EVENTHANDLER_PRI_FIRST 174112563Sjhb#define SHUTDOWN_PRI_DEFAULT EVENTHANDLER_PRI_ANY 175112565Sjhb#define SHUTDOWN_PRI_LAST EVENTHANDLER_PRI_LAST 17650107Smsmith 17750107SmsmithEVENTHANDLER_DECLARE(shutdown_pre_sync, shutdown_fn); /* before fs sync */ 17850107SmsmithEVENTHANDLER_DECLARE(shutdown_post_sync, shutdown_fn); /* after fs sync */ 17950107SmsmithEVENTHANDLER_DECLARE(shutdown_final, shutdown_fn); 18050107Smsmith 181220647Sjkim/* Power state change events */ 182220647Sjkimtypedef void (*power_change_fn)(void *); 183220647SjkimEVENTHANDLER_DECLARE(power_resume, power_change_fn); 184220647SjkimEVENTHANDLER_DECLARE(power_suspend, power_change_fn); 185282750SavgEVENTHANDLER_DECLARE(power_suspend_early, power_change_fn); 186220647Sjkim 187107136Sjeff/* Low memory event */ 188107136Sjefftypedef void (*vm_lowmem_handler_t)(void *, int); 189112563Sjhb#define LOWMEM_PRI_DEFAULT EVENTHANDLER_PRI_FIRST 190107136SjeffEVENTHANDLER_DECLARE(vm_lowmem, vm_lowmem_handler_t); 19166205Smsmith 192178016Ssam/* Root mounted event */ 193178016Ssamtypedef void (*mountroot_handler_t)(void *); 194178016SsamEVENTHANDLER_DECLARE(mountroot, mountroot_handler_t); 195178016Ssam 196253158Smarcel/* File system mount events */ 197253158Smarcelstruct mount; 198253158Smarcelstruct vnode; 199253158Smarcelstruct thread; 200253158Smarceltypedef void (*vfs_mounted_notify_fn)(void *, struct mount *, struct vnode *, 201253158Smarcel struct thread *); 202253158Smarceltypedef void (*vfs_unmounted_notify_fn)(void *, struct mount *, 203253158Smarcel struct thread *); 204253158SmarcelEVENTHANDLER_DECLARE(vfs_mounted, vfs_mounted_notify_fn); 205253158SmarcelEVENTHANDLER_DECLARE(vfs_unmounted, vfs_unmounted_notify_fn); 206253158Smarcel 207180510Sjfv/* VLAN state change events */ 208180510Sjfvstruct ifnet; 209180510Sjfvtypedef void (*vlan_config_fn)(void *, struct ifnet *, uint16_t); 210180510Sjfvtypedef void (*vlan_unconfig_fn)(void *, struct ifnet *, uint16_t); 211180510SjfvEVENTHANDLER_DECLARE(vlan_config, vlan_config_fn); 212180510SjfvEVENTHANDLER_DECLARE(vlan_unconfig, vlan_unconfig_fn); 213180510Sjfv 214192313Ssam/* BPF attach/detach events */ 215192313Ssamstruct ifnet; 216192763Ssamtypedef void (*bpf_track_fn)(void *, struct ifnet *, int /* dlt */, 217192763Ssam int /* 1 =>'s attach */); 218192313SsamEVENTHANDLER_DECLARE(bpf_track, bpf_track_fn); 219192313Ssam 220126940Speter/* 221126940Speter * Process events 222126941Speter * process_fork and exit handlers are called without Giant. 223126941Speter * exec handlers are called with Giant, but that is by accident. 224126940Speter */ 225112564Sjhbstruct proc; 226161302Snetchildstruct image_params; 227112564Sjhb 228112564Sjhbtypedef void (*exitlist_fn)(void *, struct proc *); 229112564Sjhbtypedef void (*forklist_fn)(void *, struct proc *, struct proc *, int); 230161302Snetchildtypedef void (*execlist_fn)(void *, struct proc *, struct image_params *); 231173631Srrstypedef void (*proc_ctor_fn)(void *, struct proc *); 232173631Srrstypedef void (*proc_dtor_fn)(void *, struct proc *); 233173631Srrstypedef void (*proc_init_fn)(void *, struct proc *); 234173631Srrstypedef void (*proc_fini_fn)(void *, struct proc *); 235173631SrrsEVENTHANDLER_DECLARE(process_ctor, proc_ctor_fn); 236173631SrrsEVENTHANDLER_DECLARE(process_dtor, proc_dtor_fn); 237173631SrrsEVENTHANDLER_DECLARE(process_init, proc_init_fn); 238173631SrrsEVENTHANDLER_DECLARE(process_fini, proc_fini_fn); 239112564SjhbEVENTHANDLER_DECLARE(process_exit, exitlist_fn); 240112564SjhbEVENTHANDLER_DECLARE(process_fork, forklist_fn); 241112564SjhbEVENTHANDLER_DECLARE(process_exec, execlist_fn); 242112564Sjhb 243204552Salfred/* 244204552Salfred * application dump event 245204552Salfred */ 246204552Salfredtypedef void (*app_coredump_start_fn)(void *, struct thread *, char *name); 247204552Salfredtypedef void (*app_coredump_progress_fn)(void *, struct thread *td, int byte_count); 248204552Salfredtypedef void (*app_coredump_finish_fn)(void *, struct thread *td); 249204552Salfredtypedef void (*app_coredump_error_fn)(void *, struct thread *td, char *msg, ...); 250204552Salfred 251204552SalfredEVENTHANDLER_DECLARE(app_coredump_start, app_coredump_start_fn); 252204552SalfredEVENTHANDLER_DECLARE(app_coredump_progress, app_coredump_progress_fn); 253204552SalfredEVENTHANDLER_DECLARE(app_coredump_finish, app_coredump_finish_fn); 254204552SalfredEVENTHANDLER_DECLARE(app_coredump_error, app_coredump_error_fn); 255204552Salfred 256173631Srrstypedef void (*thread_ctor_fn)(void *, struct thread *); 257173631Srrstypedef void (*thread_dtor_fn)(void *, struct thread *); 258173631Srrstypedef void (*thread_fini_fn)(void *, struct thread *); 259173631Srrstypedef void (*thread_init_fn)(void *, struct thread *); 260173631SrrsEVENTHANDLER_DECLARE(thread_ctor, thread_ctor_fn); 261173631SrrsEVENTHANDLER_DECLARE(thread_dtor, thread_dtor_fn); 262173631SrrsEVENTHANDLER_DECLARE(thread_init, thread_init_fn); 263173631SrrsEVENTHANDLER_DECLARE(thread_fini, thread_fini_fn); 264173631Srrs 265157927Spstypedef void (*uma_zone_chfn)(void *); 266157927SpsEVENTHANDLER_DECLARE(nmbclusters_change, uma_zone_chfn); 267243631SandreEVENTHANDLER_DECLARE(nmbufs_change, uma_zone_chfn); 268157927SpsEVENTHANDLER_DECLARE(maxsockets_change, uma_zone_chfn); 269161302Snetchild 270254309Smarkj/* Kernel linker file load and unload events */ 271254266Smarkjstruct linker_file; 272254309Smarkjtypedef void (*kld_load_fn)(void *, struct linker_file *); 273254813Smarkjtypedef void (*kld_unload_fn)(void *, const char *, caddr_t, size_t); 274254813Smarkjtypedef void (*kld_unload_try_fn)(void *, struct linker_file *, int *); 275254309SmarkjEVENTHANDLER_DECLARE(kld_load, kld_load_fn); 276254309SmarkjEVENTHANDLER_DECLARE(kld_unload, kld_unload_fn); 277254813SmarkjEVENTHANDLER_DECLARE(kld_unload_try, kld_unload_try_fn); 278254266Smarkj 279262861Sjhb/* Generic graphics framebuffer interface */ 280262861Sjhbstruct fb_info; 281262861Sjhbtypedef void (*register_framebuffer_fn)(void *, struct fb_info *); 282262861Sjhbtypedef void (*unregister_framebuffer_fn)(void *, struct fb_info *); 283262861SjhbEVENTHANDLER_DECLARE(register_framebuffer, register_framebuffer_fn); 284262861SjhbEVENTHANDLER_DECLARE(unregister_framebuffer, unregister_framebuffer_fn); 285262861Sjhb 286307253Ssephe/* Veto ada attachment */ 287307253Ssephestruct cam_path; 288307253Ssephestruct ata_params; 289307253Ssephetypedef void (*ada_probe_veto_fn)(void *, struct cam_path *, 290307253Ssephe struct ata_params *, int *); 291307253SsepheEVENTHANDLER_DECLARE(ada_probe_veto, ada_probe_veto_fn); 292307253Ssephe 29350107Smsmith#endif /* SYS_EVENTHANDLER_H */ 294