Index: share/man/man9/module.9 =================================================================== --- share/man/man9/module.9 +++ share/man/man9/module.9 @@ -28,12 +28,18 @@ .\" .\" $FreeBSD$ .\" -.Dd February 12, 2018 +.Dd May 27, 2019 .Dt MODULE 9 .Os .Sh NAME .Nm module .Nd structure describing a kernel module +.Sh SYNOPSIS +.In sys/param.h +.In sys/kernel.h +.In sys/module.h +.Ft int +.Fn modevent_nop "module_t" "int" "void *" .Sh DESCRIPTION Each module in the kernel is described by a .Vt module_t @@ -47,6 +53,11 @@ .Xr DECLARE_MODULE 9 macro registers the module with the system. +.Xr DRIVER_MODULE 9 +is a convenience wrapper around +.Fn DECLARE_MODULE +for device drivers. +Modules only need one. .Pp When the module is loaded, the event handler function is called with the @@ -65,7 +76,7 @@ .Fa what is set to .Dv MOD_UNLOAD . -If the module returns non-zero to this, the unload will not happen. +If the module returns non-zero to this, unload fails. .Pp The difference between .Dv MOD_QUIESCE @@ -75,8 +86,9 @@ .Dv MOD_QUIESCE if it is currently in use, whereas .Dv MOD_UNLOAD -should only fail if it is impossible to unload the module, for instance -because there are memory references to the module which cannot be revoked. +should only fail if it is impossible to unload the module. +For instance, because there are memory references to the module which cannot be +revoked. .Pp When the system is shutting down, .Fa what @@ -87,6 +99,11 @@ .Er EOPNOTSUPP for unsupported and unrecognized values of .Fa what . +.Pp +.Fn modevent_nop +is provided as a helper routine for simple modules. +It does nothing and returns zero in response to all valid events. +It returns EOPTNOTSUPP in response to invalid events. .Sh EXAMPLES .Bd -literal #include Index: sys/kern/kern_module.c =================================================================== --- sys/kern/kern_module.c +++ sys/kern/kern_module.c @@ -66,7 +66,7 @@ static void module_shutdown(void *, int); static int -modevent_nop(module_t mod, int what, void *arg) +modevent_no_unload(module_t mod, int what, void *arg) { switch(what) { @@ -79,6 +79,26 @@ } } +int +modevent_nop(module_t mod __unused, int type, void *unused __unused) +{ + int error; + + switch (type) { + case MOD_LOAD: + case MOD_QUIESCE: + case MOD_UNLOAD: + case MOD_SHUTDOWN: + error = 0; + break; + default: + error = EOPNOTSUPP; + break; + } + + return (error); +} + static void module_init(void *arg) { @@ -168,7 +188,7 @@ newmod->id = nextid++; newmod->name = (char *)(newmod + 1); strcpy(newmod->name, data->name); - newmod->handler = data->evhand ? data->evhand : modevent_nop; + newmod->handler = data->evhand ? data->evhand : modevent_no_unload; newmod->arg = data->priv; bzero(&newmod->data, sizeof(newmod->data)); TAILQ_INSERT_TAIL(&modules, newmod, link); Index: sys/sys/module.h =================================================================== --- sys/sys/module.h +++ sys/sys/module.h @@ -52,6 +52,13 @@ typedef struct module *module_t; typedef int (*modeventhand_t)(module_t, int /* modeventtype_t */, void *); +/* + * A module can use this to ignore all valid module events. (In contrast, a + * NULL eventhandler prevents module unload with EBUSY, and returns EOPNOTSUPP + * for QUIESCE and SHUTDOWN.) + */ +int modevent_nop(module_t, int, void *); + /* * Struct for registering modules statically via SYSINIT. */