1*97f8debdSpgoyette /* $NetBSD: lua.c,v 1.28 2022/03/31 19:30:17 pgoyette Exp $ */
258881ebfSmbalmer
358881ebfSmbalmer /*
4d191c429Smbalmer * Copyright (c) 2011 - 2017 by Marc Balmer <mbalmer@NetBSD.org>.
5ba791a5eSlneto * Copyright (c) 2014 by Lourival Vieira Neto <lneto@NetBSD.org>.
658881ebfSmbalmer * All rights reserved.
758881ebfSmbalmer *
858881ebfSmbalmer * Redistribution and use in source and binary forms, with or without
958881ebfSmbalmer * modification, are permitted provided that the following conditions
1058881ebfSmbalmer * are met:
1158881ebfSmbalmer * 1. Redistributions of source code must retain the above copyright
1258881ebfSmbalmer * notice, this list of conditions and the following disclaimer.
1358881ebfSmbalmer * 2. Redistributions in binary form must reproduce the above copyright
1458881ebfSmbalmer * notice, this list of conditions and the following disclaimer in the
1558881ebfSmbalmer * documentation and/or other materials provided with the distribution.
1658881ebfSmbalmer * 3. The name of the Author may not be used to endorse or promote products
1758881ebfSmbalmer * derived from this software without specific prior written permission.
1858881ebfSmbalmer *
1958881ebfSmbalmer * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
2058881ebfSmbalmer * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2158881ebfSmbalmer * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2258881ebfSmbalmer * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2358881ebfSmbalmer * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2458881ebfSmbalmer * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2558881ebfSmbalmer * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2658881ebfSmbalmer * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2758881ebfSmbalmer * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2858881ebfSmbalmer * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2958881ebfSmbalmer * SUCH DAMAGE.
3058881ebfSmbalmer */
3158881ebfSmbalmer
3258881ebfSmbalmer /* Lua device driver */
3358881ebfSmbalmer
3458881ebfSmbalmer #include <sys/param.h>
3558881ebfSmbalmer #include <sys/fcntl.h>
3658881ebfSmbalmer #include <sys/conf.h>
3758881ebfSmbalmer #include <sys/condvar.h>
3858881ebfSmbalmer #include <sys/device.h>
3958881ebfSmbalmer #include <sys/ioctl.h>
40b345b17fSmbalmer #include <sys/kmem.h>
4158881ebfSmbalmer #include <sys/lock.h>
4258881ebfSmbalmer #include <sys/lua.h>
4358881ebfSmbalmer #include <sys/module.h>
4458881ebfSmbalmer #include <sys/mutex.h>
4558881ebfSmbalmer #include <sys/namei.h>
4658881ebfSmbalmer #include <sys/queue.h>
4758881ebfSmbalmer #include <sys/sysctl.h>
4858881ebfSmbalmer #include <sys/vnode.h>
49ba791a5eSlneto #include <sys/cpu.h>
5058881ebfSmbalmer
5158881ebfSmbalmer #include <lauxlib.h>
5258881ebfSmbalmer
5358881ebfSmbalmer #include "luavar.h"
5458881ebfSmbalmer
5558881ebfSmbalmer struct lua_softc {
5658881ebfSmbalmer device_t sc_dev;
5758881ebfSmbalmer
5858881ebfSmbalmer kmutex_t sc_lock;
5958881ebfSmbalmer kcondvar_t sc_inuse_cv;
6058881ebfSmbalmer bool sc_inuse;
6158881ebfSmbalmer
6258881ebfSmbalmer /* Locking access to state queues */
6358881ebfSmbalmer kmutex_t sc_state_lock;
6458881ebfSmbalmer kcondvar_t sc_state_cv;
6558881ebfSmbalmer bool sc_state;
6658881ebfSmbalmer
6758881ebfSmbalmer struct sysctllog *sc_log;
6858881ebfSmbalmer };
6958881ebfSmbalmer
7058881ebfSmbalmer static device_t sc_self;
7158881ebfSmbalmer static bool lua_autoload_on = true;
7258881ebfSmbalmer static bool lua_require_on = true;
7358881ebfSmbalmer static bool lua_bytecode_on = false;
7458881ebfSmbalmer static int lua_verbose;
7558881ebfSmbalmer static int lua_max_instr;
7658881ebfSmbalmer
779c8bf6eeSrin static LIST_HEAD(, lua_state) lua_states =
789c8bf6eeSrin LIST_HEAD_INITIALIZER(lua_states);
799c8bf6eeSrin static LIST_HEAD(, lua_module) lua_modules =
809c8bf6eeSrin LIST_HEAD_INITIALIZER(lua_modules);
8158881ebfSmbalmer
8258881ebfSmbalmer static int lua_match(device_t, cfdata_t, void *);
8358881ebfSmbalmer static void lua_attach(device_t, device_t, void *);
8458881ebfSmbalmer static int lua_detach(device_t, int);
8558881ebfSmbalmer static klua_State *klua_find(const char *);
8658881ebfSmbalmer static const char *lua_reader(lua_State *, void *, size_t *);
8758881ebfSmbalmer static void lua_maxcount(lua_State *, lua_Debug *);
8858881ebfSmbalmer
8958881ebfSmbalmer static int lua_require(lua_State *);
9058881ebfSmbalmer
9158881ebfSmbalmer CFATTACH_DECL_NEW(lua, sizeof(struct lua_softc),
9258881ebfSmbalmer lua_match, lua_attach, lua_detach, NULL);
9358881ebfSmbalmer
9458881ebfSmbalmer dev_type_open(luaopen);
9558881ebfSmbalmer dev_type_close(luaclose);
9658881ebfSmbalmer dev_type_ioctl(luaioctl);
9758881ebfSmbalmer
9858881ebfSmbalmer const struct cdevsw lua_cdevsw = {
99a68f9396Sdholland .d_open = luaopen,
100a68f9396Sdholland .d_close = luaclose,
101a68f9396Sdholland .d_read = noread,
102a68f9396Sdholland .d_write = nowrite,
103a68f9396Sdholland .d_ioctl = luaioctl,
104a68f9396Sdholland .d_stop = nostop,
105a68f9396Sdholland .d_tty = notty,
106a68f9396Sdholland .d_poll = nopoll,
107a68f9396Sdholland .d_mmap = nommap,
108a68f9396Sdholland .d_kqfilter = nokqfilter,
109f9228f42Sdholland .d_discard = nodiscard,
110a68f9396Sdholland .d_flag = D_OTHER | D_MPSAFE
11158881ebfSmbalmer };
11258881ebfSmbalmer
11358881ebfSmbalmer struct lua_loadstate {
11458881ebfSmbalmer struct vnode *vp;
11558881ebfSmbalmer size_t size;
11658881ebfSmbalmer off_t off;
11758881ebfSmbalmer };
11858881ebfSmbalmer
11958881ebfSmbalmer extern struct cfdriver lua_cd;
12058881ebfSmbalmer
12158881ebfSmbalmer static int
lua_match(device_t parent,cfdata_t match,void * aux)12258881ebfSmbalmer lua_match(device_t parent, cfdata_t match, void *aux)
12358881ebfSmbalmer {
12458881ebfSmbalmer return 1;
12558881ebfSmbalmer }
12658881ebfSmbalmer
12758881ebfSmbalmer static void
lua_attach(device_t parent,device_t self,void * aux)12858881ebfSmbalmer lua_attach(device_t parent, device_t self, void *aux)
12958881ebfSmbalmer {
13058881ebfSmbalmer struct lua_softc *sc;
13158881ebfSmbalmer const struct sysctlnode *node;
13258881ebfSmbalmer
13358881ebfSmbalmer if (sc_self)
13458881ebfSmbalmer return;
13558881ebfSmbalmer
13658881ebfSmbalmer sc = device_private(self);
13758881ebfSmbalmer sc->sc_dev = self;
13858881ebfSmbalmer sc_self = self;
13958881ebfSmbalmer
14058881ebfSmbalmer mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_VM);
14158881ebfSmbalmer cv_init(&sc->sc_inuse_cv, "luactl");
14258881ebfSmbalmer
14358881ebfSmbalmer mutex_init(&sc->sc_state_lock, MUTEX_DEFAULT, IPL_VM);
14458881ebfSmbalmer cv_init(&sc->sc_state_cv, "luastate");
14558881ebfSmbalmer
146b8f12c7fSmaya if (!pmf_device_register(self, NULL, NULL))
147b8f12c7fSmaya aprint_error_dev(self, "couldn't establish power handler\n");
14858881ebfSmbalmer
14958881ebfSmbalmer /* Sysctl to provide some control over behaviour */
15058881ebfSmbalmer sysctl_createv(&sc->sc_log, 0, NULL, &node,
15158881ebfSmbalmer CTLFLAG_OWNDESC,
15258881ebfSmbalmer CTLTYPE_NODE, "lua",
15358881ebfSmbalmer SYSCTL_DESCR("Lua options"),
15458881ebfSmbalmer NULL, 0, NULL, 0,
15558881ebfSmbalmer CTL_KERN, CTL_CREATE, CTL_EOL);
15658881ebfSmbalmer
15758881ebfSmbalmer if (node == NULL) {
158d21ffc75Smsaitoh aprint_error(": can't create sysctl node\n");
15958881ebfSmbalmer return;
16058881ebfSmbalmer }
16158881ebfSmbalmer
16258881ebfSmbalmer /*
16358881ebfSmbalmer * XXX Some of the sysctl values must not be changed after the
16458881ebfSmbalmer * securelevel has been raised.
16558881ebfSmbalmer */
16658881ebfSmbalmer sysctl_createv(&sc->sc_log, 0, &node, NULL,
16758881ebfSmbalmer CTLFLAG_READWRITE | CTLFLAG_OWNDESC,
16858881ebfSmbalmer CTLTYPE_BOOL, "require",
16958881ebfSmbalmer SYSCTL_DESCR("Enable the require command"),
17058881ebfSmbalmer NULL, 0, &lua_require_on, 0,
17158881ebfSmbalmer CTL_CREATE, CTL_EOL);
17258881ebfSmbalmer
17358881ebfSmbalmer sysctl_createv(&sc->sc_log, 0, &node, NULL,
17458881ebfSmbalmer CTLFLAG_READWRITE | CTLFLAG_OWNDESC,
17558881ebfSmbalmer CTLTYPE_BOOL, "autoload",
17658881ebfSmbalmer SYSCTL_DESCR("Enable automatic load of modules"),
17758881ebfSmbalmer NULL, 0, &lua_autoload_on, 0,
17858881ebfSmbalmer CTL_CREATE, CTL_EOL);
17958881ebfSmbalmer
18058881ebfSmbalmer sysctl_createv(&sc->sc_log, 0, &node, NULL,
18158881ebfSmbalmer CTLFLAG_READWRITE | CTLFLAG_OWNDESC,
18258881ebfSmbalmer CTLTYPE_BOOL, "bytecode",
18358881ebfSmbalmer SYSCTL_DESCR("Enable loading of bytecode"),
18458881ebfSmbalmer NULL, 0, &lua_bytecode_on, 0,
18558881ebfSmbalmer CTL_CREATE, CTL_EOL);
18658881ebfSmbalmer
18758881ebfSmbalmer sysctl_createv(&sc->sc_log, 0, &node, NULL,
18858881ebfSmbalmer CTLFLAG_READWRITE | CTLFLAG_OWNDESC,
18958881ebfSmbalmer CTLTYPE_INT, "verbose",
19058881ebfSmbalmer SYSCTL_DESCR("Enable verbose output"),
19158881ebfSmbalmer NULL, 0, &lua_verbose, 0,
19258881ebfSmbalmer CTL_CREATE, CTL_EOL);
19358881ebfSmbalmer
19458881ebfSmbalmer sysctl_createv(&sc->sc_log, 0, &node, NULL,
19558881ebfSmbalmer CTLFLAG_READWRITE | CTLFLAG_OWNDESC,
19658881ebfSmbalmer CTLTYPE_INT, "maxcount",
19758881ebfSmbalmer SYSCTL_DESCR("Limit maximum instruction count"),
19858881ebfSmbalmer NULL, 0, &lua_max_instr, 0,
19958881ebfSmbalmer CTL_CREATE, CTL_EOL);
20058881ebfSmbalmer
2014ab4902eSlneto aprint_normal_dev(self, "%s\n", LUA_COPYRIGHT);
20258881ebfSmbalmer }
20358881ebfSmbalmer
20458881ebfSmbalmer static int
lua_detach(device_t self,int flags)20558881ebfSmbalmer lua_detach(device_t self, int flags)
20658881ebfSmbalmer {
20758881ebfSmbalmer struct lua_softc *sc;
20858881ebfSmbalmer struct lua_state *s;
20958881ebfSmbalmer
21058881ebfSmbalmer sc = device_private(self);
21158881ebfSmbalmer pmf_device_deregister(self);
21258881ebfSmbalmer
21358881ebfSmbalmer if (sc->sc_log != NULL) {
21458881ebfSmbalmer sysctl_teardown(&sc->sc_log);
21558881ebfSmbalmer sc->sc_log = NULL;
21658881ebfSmbalmer }
21758881ebfSmbalmer
21858881ebfSmbalmer /* Traverse the list of states and close them */
21958881ebfSmbalmer while ((s = LIST_FIRST(&lua_states)) != NULL) {
22058881ebfSmbalmer LIST_REMOVE(s, lua_next);
22158881ebfSmbalmer klua_close(s->K);
22258881ebfSmbalmer if (lua_verbose)
22358881ebfSmbalmer device_printf(self, "state %s destroyed\n",
22458881ebfSmbalmer s->lua_name);
225b345b17fSmbalmer kmem_free(s, sizeof(struct lua_state));
22658881ebfSmbalmer }
22758881ebfSmbalmer mutex_destroy(&sc->sc_lock);
22858881ebfSmbalmer cv_destroy(&sc->sc_inuse_cv);
22958881ebfSmbalmer mutex_destroy(&sc->sc_state_lock);
23058881ebfSmbalmer cv_destroy(&sc->sc_state_cv);
23158881ebfSmbalmer sc_self = NULL;
23258881ebfSmbalmer return 0;
23358881ebfSmbalmer }
23458881ebfSmbalmer
23558881ebfSmbalmer int
luaopen(dev_t dev,int flag,int mode,struct lwp * l)23658881ebfSmbalmer luaopen(dev_t dev, int flag, int mode, struct lwp *l)
23758881ebfSmbalmer {
23858881ebfSmbalmer struct lua_softc *sc;
2393b5eeb2bSmbalmer int error = 0;
24058881ebfSmbalmer
24158881ebfSmbalmer if (minor(dev) > 0)
24258881ebfSmbalmer return ENXIO;
24358881ebfSmbalmer
24458881ebfSmbalmer sc = device_lookup_private(&lua_cd, minor(dev));
24558881ebfSmbalmer if (sc == NULL)
24658881ebfSmbalmer return ENXIO;
24758881ebfSmbalmer
24858881ebfSmbalmer mutex_enter(&sc->sc_lock);
24958881ebfSmbalmer while (sc->sc_inuse == true) {
25058881ebfSmbalmer error = cv_wait_sig(&sc->sc_inuse_cv, &sc->sc_lock);
25158881ebfSmbalmer if (error)
25258881ebfSmbalmer break;
25358881ebfSmbalmer }
25458881ebfSmbalmer if (!error)
25558881ebfSmbalmer sc->sc_inuse = true;
25658881ebfSmbalmer mutex_exit(&sc->sc_lock);
25758881ebfSmbalmer
25858881ebfSmbalmer if (error)
25958881ebfSmbalmer return error;
26058881ebfSmbalmer return 0;
26158881ebfSmbalmer }
26258881ebfSmbalmer
26358881ebfSmbalmer int
luaclose(dev_t dev,int flag,int mode,struct lwp * l)26458881ebfSmbalmer luaclose(dev_t dev, int flag, int mode, struct lwp *l)
26558881ebfSmbalmer {
26658881ebfSmbalmer struct lua_softc *sc;
26758881ebfSmbalmer
26858881ebfSmbalmer if (minor(dev) > 0)
26958881ebfSmbalmer return ENXIO;
27058881ebfSmbalmer sc = device_lookup_private(&lua_cd, minor(dev));
27158881ebfSmbalmer mutex_enter(&sc->sc_lock);
27258881ebfSmbalmer sc->sc_inuse = false;
27358881ebfSmbalmer cv_signal(&sc->sc_inuse_cv);
27458881ebfSmbalmer mutex_exit(&sc->sc_lock);
27558881ebfSmbalmer return 0;
27658881ebfSmbalmer }
27758881ebfSmbalmer
27858881ebfSmbalmer int
luaioctl(dev_t dev,u_long cmd,void * data,int flag,struct lwp * l)27958881ebfSmbalmer luaioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
28058881ebfSmbalmer {
28158881ebfSmbalmer struct lua_softc *sc;
28258881ebfSmbalmer struct lua_info *info;
28358881ebfSmbalmer struct lua_create *create;
28458881ebfSmbalmer struct lua_require *require;
28558881ebfSmbalmer struct lua_load *load;
28658881ebfSmbalmer struct lua_state *s;
28758881ebfSmbalmer struct lua_module *m;
28858881ebfSmbalmer kauth_cred_t cred;
289723d09ceSdholland struct vnode *vp;
29058881ebfSmbalmer struct pathbuf *pb;
29158881ebfSmbalmer struct vattr va;
29258881ebfSmbalmer struct lua_loadstate ls;
29363f6d58fSmartin struct lua_state_info *states;
29458881ebfSmbalmer int error, n;
29558881ebfSmbalmer klua_State *K;
29658881ebfSmbalmer
29758881ebfSmbalmer sc = device_lookup_private(&lua_cd, minor(dev));
29858881ebfSmbalmer if (!device_is_active(sc->sc_dev))
29958881ebfSmbalmer return EBUSY;
30058881ebfSmbalmer
30158881ebfSmbalmer switch (cmd) {
30258881ebfSmbalmer case LUAINFO:
30358881ebfSmbalmer info = data;
30458881ebfSmbalmer if (info->states == NULL) {
30558881ebfSmbalmer info->num_states = 0;
30658881ebfSmbalmer LIST_FOREACH(s, &lua_states, lua_next)
30758881ebfSmbalmer info->num_states++;
30858881ebfSmbalmer } else {
30958881ebfSmbalmer n = 0;
31058881ebfSmbalmer LIST_FOREACH(s, &lua_states, lua_next) {
31158881ebfSmbalmer if (n > info->num_states)
31258881ebfSmbalmer break;
31358881ebfSmbalmer n++;
31458881ebfSmbalmer }
31558881ebfSmbalmer info->num_states = n;
31663f6d58fSmartin states = kmem_alloc(sizeof(*states) * n, KM_SLEEP);
31763f6d58fSmartin if (copyin(info->states, states, sizeof(*states) * n)
31863f6d58fSmartin == 0) {
31963f6d58fSmartin n = 0;
32063f6d58fSmartin LIST_FOREACH(s, &lua_states, lua_next) {
32163f6d58fSmartin if (n > info->num_states)
32263f6d58fSmartin break;
32363f6d58fSmartin strcpy(states[n].name, s->lua_name);
32463f6d58fSmartin strcpy(states[n].desc, s->lua_desc);
32563f6d58fSmartin states[n].user = s->K->ks_user;
32663f6d58fSmartin n++;
32763f6d58fSmartin }
32863f6d58fSmartin copyout(states, info->states,
32963f6d58fSmartin sizeof(*states) * n);
33063f6d58fSmartin kmem_free(states, sizeof(*states) * n);
33163f6d58fSmartin }
33258881ebfSmbalmer }
33358881ebfSmbalmer break;
33458881ebfSmbalmer case LUACREATE:
33558881ebfSmbalmer create = data;
33658881ebfSmbalmer
33758881ebfSmbalmer if (*create->name == '_') {
33858881ebfSmbalmer if (lua_verbose)
33958881ebfSmbalmer device_printf(sc->sc_dev, "names of user "
34058881ebfSmbalmer "created states must not begin with '_'");
34158881ebfSmbalmer return ENXIO;
34258881ebfSmbalmer }
34358881ebfSmbalmer LIST_FOREACH(s, &lua_states, lua_next)
34458881ebfSmbalmer if (!strcmp(s->lua_name, create->name)) {
34558881ebfSmbalmer if (lua_verbose)
34658881ebfSmbalmer device_printf(sc->sc_dev,
34758881ebfSmbalmer "state %s exists\n", create->name);
34858881ebfSmbalmer return EBUSY;
34958881ebfSmbalmer }
35058881ebfSmbalmer
351ba791a5eSlneto K = kluaL_newstate(create->name, create->desc, IPL_NONE);
35258881ebfSmbalmer
35358881ebfSmbalmer if (K == NULL)
35458881ebfSmbalmer return ENOMEM;
3553c246ec0Smbalmer
3563c246ec0Smbalmer K->ks_user = true;
3573c246ec0Smbalmer
35858881ebfSmbalmer if (lua_verbose)
35958881ebfSmbalmer device_printf(sc->sc_dev, "state %s created\n",
36058881ebfSmbalmer create->name);
36158881ebfSmbalmer break;
36258881ebfSmbalmer case LUADESTROY:
36358881ebfSmbalmer create = data;
36458881ebfSmbalmer
36558881ebfSmbalmer K = klua_find(create->name);
36658881ebfSmbalmer
36758881ebfSmbalmer if (K != NULL && (K->ks_user == true)) {
36858881ebfSmbalmer klua_close(K);
36958881ebfSmbalmer return 0;
37058881ebfSmbalmer }
37158881ebfSmbalmer return EBUSY;
37258881ebfSmbalmer case LUAREQUIRE: /* 'require' a module in a State */
37358881ebfSmbalmer require = data;
37458881ebfSmbalmer LIST_FOREACH(s, &lua_states, lua_next)
3757093afb2Ssalazar if (!strcmp(s->lua_name, require->state)) {
3767093afb2Ssalazar LIST_FOREACH(m, &s->lua_modules, mod_next)
3777093afb2Ssalazar if (!strcmp(m->mod_name, require->module))
3787093afb2Ssalazar return ENXIO;
37958881ebfSmbalmer LIST_FOREACH(m, &lua_modules, mod_next)
38058881ebfSmbalmer if (!strcmp(m->mod_name,
38158881ebfSmbalmer require->module)) {
38258881ebfSmbalmer if (lua_verbose)
38358881ebfSmbalmer device_printf(
38458881ebfSmbalmer sc->sc_dev,
38558881ebfSmbalmer "requiring module "
38658881ebfSmbalmer "%s to state %s\n",
38758881ebfSmbalmer m->mod_name,
38858881ebfSmbalmer s->lua_name);
389ba791a5eSlneto klua_lock(s->K);
39026258645Slneto luaL_requiref(
39126258645Slneto s->K->L,
39226258645Slneto m->mod_name,
39326258645Slneto m->open,
39426258645Slneto 1);
395ba791a5eSlneto klua_unlock(s->K);
39658881ebfSmbalmer m->refcount++;
39758881ebfSmbalmer LIST_INSERT_HEAD(
39858881ebfSmbalmer &s->lua_modules, m,
39958881ebfSmbalmer mod_next);
40058881ebfSmbalmer return 0;
40158881ebfSmbalmer }
4027093afb2Ssalazar }
40358881ebfSmbalmer return ENXIO;
40458881ebfSmbalmer case LUALOAD:
40558881ebfSmbalmer load = data;
40658881ebfSmbalmer if (strrchr(load->path, '/') == NULL)
40758881ebfSmbalmer return ENXIO;
40858881ebfSmbalmer
40958881ebfSmbalmer LIST_FOREACH(s, &lua_states, lua_next)
41058881ebfSmbalmer if (!strcmp(s->lua_name, load->state)) {
41158881ebfSmbalmer if (lua_verbose)
41258881ebfSmbalmer device_printf(sc->sc_dev,
41358881ebfSmbalmer "loading %s into state %s\n",
41458881ebfSmbalmer load->path, s->lua_name);
41558881ebfSmbalmer cred = kauth_cred_get();
41658881ebfSmbalmer pb = pathbuf_create(load->path);
41758881ebfSmbalmer if (pb == NULL)
41858881ebfSmbalmer return ENOMEM;
419723d09ceSdholland error = vn_open(NULL, pb, NOCHROOT, FREAD, 0,
420723d09ceSdholland &vp, NULL, NULL);
421e67dab8dSriastradh pathbuf_destroy(pb);
42258881ebfSmbalmer if (error) {
42358881ebfSmbalmer if (lua_verbose)
42458881ebfSmbalmer device_printf(sc->sc_dev,
42558881ebfSmbalmer "error vn_open %d\n",
42658881ebfSmbalmer error);
42758881ebfSmbalmer return error;
42858881ebfSmbalmer }
429723d09ceSdholland error = VOP_GETATTR(vp, &va,
43058881ebfSmbalmer kauth_cred_get());
43158881ebfSmbalmer if (error) {
432723d09ceSdholland VOP_UNLOCK(vp);
433723d09ceSdholland vn_close(vp, FREAD,
43458881ebfSmbalmer kauth_cred_get());
43558881ebfSmbalmer if (lua_verbose)
43658881ebfSmbalmer device_printf(sc->sc_dev,
43758881ebfSmbalmer "erro VOP_GETATTR %d\n",
43858881ebfSmbalmer error);
43958881ebfSmbalmer return error;
44058881ebfSmbalmer }
44158881ebfSmbalmer if (va.va_type != VREG) {
442723d09ceSdholland VOP_UNLOCK(vp);
443723d09ceSdholland vn_close(vp, FREAD,
44458881ebfSmbalmer kauth_cred_get());
44558881ebfSmbalmer return EINVAL;
44658881ebfSmbalmer }
447723d09ceSdholland ls.vp = vp;
44858881ebfSmbalmer ls.off = 0L;
44958881ebfSmbalmer ls.size = va.va_size;
450723d09ceSdholland VOP_UNLOCK(vp);
451ba791a5eSlneto klua_lock(s->K);
45258881ebfSmbalmer error = lua_load(s->K->L, lua_reader, &ls,
4534ab4902eSlneto strrchr(load->path, '/') + 1, "bt");
454723d09ceSdholland vn_close(vp, FREAD, cred);
45558881ebfSmbalmer switch (error) {
45658881ebfSmbalmer case 0: /* no error */
45758881ebfSmbalmer break;
45858881ebfSmbalmer case LUA_ERRSYNTAX:
45958881ebfSmbalmer if (lua_verbose)
46058881ebfSmbalmer device_printf(sc->sc_dev,
46158881ebfSmbalmer "syntax error\n");
462ba791a5eSlneto klua_unlock(s->K);
46358881ebfSmbalmer return EINVAL;
46458881ebfSmbalmer case LUA_ERRMEM:
46558881ebfSmbalmer if (lua_verbose)
46658881ebfSmbalmer device_printf(sc->sc_dev,
46758881ebfSmbalmer "memory error\n");
468ba791a5eSlneto klua_unlock(s->K);
46958881ebfSmbalmer return ENOMEM;
47058881ebfSmbalmer default:
47158881ebfSmbalmer if (lua_verbose)
47258881ebfSmbalmer device_printf(sc->sc_dev,
47358881ebfSmbalmer "load error %d: %s\n",
47458881ebfSmbalmer error,
47558881ebfSmbalmer lua_tostring(s->K->L, -1));
476ba791a5eSlneto klua_unlock(s->K);
47758881ebfSmbalmer return EINVAL;
47858881ebfSmbalmer }
47958881ebfSmbalmer if (lua_max_instr > 0)
48058881ebfSmbalmer lua_sethook(s->K->L, lua_maxcount,
48158881ebfSmbalmer LUA_MASKCOUNT, lua_max_instr);
48258881ebfSmbalmer error = lua_pcall(s->K->L, 0, LUA_MULTRET, 0);
48358881ebfSmbalmer if (error) {
48458881ebfSmbalmer if (lua_verbose) {
48558881ebfSmbalmer device_printf(sc->sc_dev,
48658881ebfSmbalmer "execution error: %s\n",
48758881ebfSmbalmer lua_tostring(s->K->L, -1));
48858881ebfSmbalmer }
489ba791a5eSlneto klua_unlock(s->K);
49058881ebfSmbalmer return EINVAL;
49158881ebfSmbalmer }
492ba791a5eSlneto klua_unlock(s->K);
49358881ebfSmbalmer return 0;
49458881ebfSmbalmer }
49558881ebfSmbalmer return ENXIO;
49658881ebfSmbalmer }
49758881ebfSmbalmer return 0;
49858881ebfSmbalmer }
49958881ebfSmbalmer
50058881ebfSmbalmer static int
lua_require(lua_State * L)50158881ebfSmbalmer lua_require(lua_State *L)
50258881ebfSmbalmer {
50358881ebfSmbalmer struct lua_state *s;
50458881ebfSmbalmer struct lua_module *m, *md;
50558881ebfSmbalmer const char *module;
50658881ebfSmbalmer char name[MAXPATHLEN];
50758881ebfSmbalmer
50858881ebfSmbalmer module = lua_tostring(L, -1);
50958881ebfSmbalmer md = NULL;
51058881ebfSmbalmer LIST_FOREACH(m, &lua_modules, mod_next)
51158881ebfSmbalmer if (!strcmp(m->mod_name, module)) {
51258881ebfSmbalmer md = m;
51358881ebfSmbalmer break;
51458881ebfSmbalmer }
51558881ebfSmbalmer
51658881ebfSmbalmer if (md == NULL && lua_autoload_on && strchr(module, '/') == NULL) {
51758881ebfSmbalmer snprintf(name, sizeof name, "lua%s", module);
51858881ebfSmbalmer if (lua_verbose)
51958881ebfSmbalmer device_printf(sc_self, "autoload %s\n", name);
520c1f5fe0aSmbalmer module_autoload(name, MODULE_CLASS_MISC);
52158881ebfSmbalmer LIST_FOREACH(m, &lua_modules, mod_next)
52258881ebfSmbalmer if (!strcmp(m->mod_name, module)) {
52358881ebfSmbalmer md = m;
52458881ebfSmbalmer break;
52558881ebfSmbalmer }
52658881ebfSmbalmer }
52758881ebfSmbalmer
52858881ebfSmbalmer if (md != NULL)
52958881ebfSmbalmer LIST_FOREACH(s, &lua_states, lua_next)
53058881ebfSmbalmer if (s->K->L == L) {
53158881ebfSmbalmer if (lua_verbose)
53258881ebfSmbalmer device_printf(sc_self,
53358881ebfSmbalmer "require module %s\n",
53458881ebfSmbalmer md->mod_name);
53526258645Slneto luaL_requiref(L, md->mod_name, md->open, 0);
53626258645Slneto
537934d80f7Smbalmer LIST_FOREACH(m, &s->lua_modules, mod_next)
538934d80f7Smbalmer if (m == md)
539934d80f7Smbalmer return 1;
540934d80f7Smbalmer
54158881ebfSmbalmer md->refcount++;
54258881ebfSmbalmer LIST_INSERT_HEAD(&s->lua_modules, md, mod_next);
5434ab4902eSlneto return 1;
54458881ebfSmbalmer }
54558881ebfSmbalmer
54658881ebfSmbalmer lua_pushstring(L, "module not found");
54758881ebfSmbalmer return lua_error(L);
54858881ebfSmbalmer }
54958881ebfSmbalmer
550ba791a5eSlneto typedef struct {
551ba791a5eSlneto size_t size;
55246895156Srin } alloc_header_t;
553ba791a5eSlneto
554ba791a5eSlneto static void *
lua_alloc(void * ud,void * ptr,size_t osize,size_t nsize)55558881ebfSmbalmer lua_alloc(void *ud, void *ptr, size_t osize, size_t nsize)
55658881ebfSmbalmer {
557ba791a5eSlneto void *nptr = NULL;
558b345b17fSmbalmer
55946895156Srin /*
56046895156Srin * Make sure that buffers allocated by lua_alloc() are aligned to
56146895156Srin * 8-byte boundaries as done by kmem_alloc(9).
56246895156Srin */
56346895156Srin const size_t hdr_size = roundup(sizeof(alloc_header_t), 8);
564ba791a5eSlneto alloc_header_t *hdr = (alloc_header_t *) ((char *) ptr - hdr_size);
565ba791a5eSlneto
566ba791a5eSlneto if (nsize == 0) { /* freeing */
56758881ebfSmbalmer if (ptr != NULL)
568ba791a5eSlneto kmem_intr_free(hdr, hdr->size);
569ba791a5eSlneto } else if (ptr != NULL && nsize <= hdr->size - hdr_size) /* shrinking */
570ba791a5eSlneto return ptr; /* don't need to reallocate */
571ba791a5eSlneto else { /* creating or expanding */
572ba791a5eSlneto km_flag_t sleep = cpu_intr_p() || cpu_softintr_p() ?
573ba791a5eSlneto KM_NOSLEEP : KM_SLEEP;
574ba791a5eSlneto
575ba791a5eSlneto size_t alloc_size = nsize + hdr_size;
576ba791a5eSlneto alloc_header_t *nhdr = kmem_intr_alloc(alloc_size, sleep);
577ba791a5eSlneto if (nhdr == NULL) /* failed to allocate */
578ba791a5eSlneto return NULL;
579ba791a5eSlneto
580ba791a5eSlneto nhdr->size = alloc_size;
581ba791a5eSlneto nptr = (void *) ((char *) nhdr + hdr_size);
582ba791a5eSlneto
583ba791a5eSlneto if (ptr != NULL) { /* expanding */
584ba791a5eSlneto memcpy(nptr, ptr, osize);
585ba791a5eSlneto kmem_intr_free(hdr, hdr->size);
586b345b17fSmbalmer }
587b345b17fSmbalmer }
588b345b17fSmbalmer return nptr;
58958881ebfSmbalmer }
59058881ebfSmbalmer
59158881ebfSmbalmer static const char *
lua_reader(lua_State * L,void * data,size_t * size)59258881ebfSmbalmer lua_reader(lua_State *L, void *data, size_t *size)
59358881ebfSmbalmer {
59458881ebfSmbalmer struct lua_loadstate *ls;
59558881ebfSmbalmer static char buf[1024];
59658881ebfSmbalmer size_t rsiz;
59758881ebfSmbalmer
59858881ebfSmbalmer ls = data;
59958881ebfSmbalmer if (ls->size < sizeof(buf))
60058881ebfSmbalmer rsiz = ls->size;
60158881ebfSmbalmer else
60258881ebfSmbalmer rsiz = sizeof(buf);
60358881ebfSmbalmer vn_rdwr(UIO_READ, ls->vp, buf, rsiz, ls->off, UIO_SYSSPACE,
60458881ebfSmbalmer 0, curlwp->l_cred, NULL, curlwp);
60558881ebfSmbalmer if (ls->off == 0L && lua_bytecode_on == false && buf[0] == 0x1b) {
60658881ebfSmbalmer *size = 0L;
60758881ebfSmbalmer lua_pushstring(L, "loading of bytecode is not allowed");
60858881ebfSmbalmer lua_error(L);
60958881ebfSmbalmer return NULL;
61058881ebfSmbalmer } else {
61158881ebfSmbalmer *size = rsiz;
61258881ebfSmbalmer ls->off += *size;
61358881ebfSmbalmer ls->size -= *size;
61458881ebfSmbalmer }
61558881ebfSmbalmer return buf;
61658881ebfSmbalmer }
61758881ebfSmbalmer
61858881ebfSmbalmer static void
lua_maxcount(lua_State * L,lua_Debug * d)61958881ebfSmbalmer lua_maxcount(lua_State *L, lua_Debug *d)
62058881ebfSmbalmer {
62158881ebfSmbalmer lua_pushstring(L, "maximum instruction count exceeded");
62258881ebfSmbalmer lua_error(L);
62358881ebfSmbalmer }
62458881ebfSmbalmer
62558881ebfSmbalmer int
klua_mod_register(const char * name,lua_CFunction open)6264e28dab9Slneto klua_mod_register(const char *name, lua_CFunction open)
62758881ebfSmbalmer {
62858881ebfSmbalmer struct lua_module *m;
62958881ebfSmbalmer
63058881ebfSmbalmer LIST_FOREACH(m, &lua_modules, mod_next)
63158881ebfSmbalmer if (!strcmp(m->mod_name, name))
63258881ebfSmbalmer return EBUSY;
633b345b17fSmbalmer m = kmem_zalloc(sizeof(struct lua_module), KM_SLEEP);
63458881ebfSmbalmer strlcpy(m->mod_name, name, LUA_MAX_MODNAME);
63558881ebfSmbalmer m->open = open;
63658881ebfSmbalmer m->refcount = 0;
63758881ebfSmbalmer LIST_INSERT_HEAD(&lua_modules, m, mod_next);
63858881ebfSmbalmer if (lua_verbose)
63958881ebfSmbalmer device_printf(sc_self, "registered lua module %s\n", name);
64058881ebfSmbalmer return 0;
64158881ebfSmbalmer }
64258881ebfSmbalmer
64358881ebfSmbalmer int
klua_mod_unregister(const char * name)6444e28dab9Slneto klua_mod_unregister(const char *name)
64558881ebfSmbalmer {
64658881ebfSmbalmer struct lua_module *m;
64758881ebfSmbalmer
64858881ebfSmbalmer LIST_FOREACH(m, &lua_modules, mod_next)
64958881ebfSmbalmer if (!strcmp(m->mod_name, name)) {
65058881ebfSmbalmer if (m->refcount == 0) {
65158881ebfSmbalmer LIST_REMOVE(m, mod_next);
652b345b17fSmbalmer kmem_free(m, sizeof(struct lua_module));
65358881ebfSmbalmer if (lua_verbose)
65458881ebfSmbalmer device_printf(sc_self,
65558881ebfSmbalmer "unregistered lua module %s\n",
65658881ebfSmbalmer name);
65758881ebfSmbalmer return 0;
65858881ebfSmbalmer } else
65958881ebfSmbalmer return EBUSY;
66058881ebfSmbalmer }
66158881ebfSmbalmer return 0;
66258881ebfSmbalmer }
66358881ebfSmbalmer
66458881ebfSmbalmer klua_State *
klua_newstate(lua_Alloc f,void * ud,const char * name,const char * desc,int ipl)665ba791a5eSlneto klua_newstate(lua_Alloc f, void *ud, const char *name, const char *desc,
666ba791a5eSlneto int ipl)
66758881ebfSmbalmer {
66858881ebfSmbalmer klua_State *K;
66958881ebfSmbalmer struct lua_state *s;
67058881ebfSmbalmer struct lua_softc *sc;
6713b5eeb2bSmbalmer int error = 0;
67258881ebfSmbalmer
673b345b17fSmbalmer s = kmem_zalloc(sizeof(struct lua_state), KM_SLEEP);
67458881ebfSmbalmer sc = device_private(sc_self);
67558881ebfSmbalmer mutex_enter(&sc->sc_state_lock);
67658881ebfSmbalmer while (sc->sc_state == true) {
67758881ebfSmbalmer error = cv_wait_sig(&sc->sc_state_cv, &sc->sc_state_lock);
67858881ebfSmbalmer if (error)
67958881ebfSmbalmer break;
68058881ebfSmbalmer }
68158881ebfSmbalmer if (!error)
68258881ebfSmbalmer sc->sc_state = true;
68358881ebfSmbalmer mutex_exit(&sc->sc_state_lock);
68458881ebfSmbalmer
6854bb71db0Schristos if (error) {
6864bb71db0Schristos kmem_free(s, sizeof(struct lua_state));
68758881ebfSmbalmer return NULL;
6884bb71db0Schristos }
68958881ebfSmbalmer
690b345b17fSmbalmer K = kmem_zalloc(sizeof(klua_State), KM_SLEEP);
69158881ebfSmbalmer K->L = lua_newstate(f, ud);
69258881ebfSmbalmer K->ks_user = false;
69358881ebfSmbalmer if (K->L == NULL) {
694b345b17fSmbalmer kmem_free(K, sizeof(klua_State));
69558881ebfSmbalmer K = NULL;
69658881ebfSmbalmer goto finish;
69758881ebfSmbalmer }
69858881ebfSmbalmer
69958881ebfSmbalmer strlcpy(s->lua_name, name, MAX_LUA_NAME);
70058881ebfSmbalmer strlcpy(s->lua_desc, desc, MAX_LUA_DESC);
70158881ebfSmbalmer s->K = K;
70258881ebfSmbalmer
70358881ebfSmbalmer if (lua_require_on || lua_autoload_on) {
70458881ebfSmbalmer lua_pushcfunction(K->L, lua_require);
70558881ebfSmbalmer lua_setglobal(K->L, "require");
70658881ebfSmbalmer }
70758881ebfSmbalmer LIST_INSERT_HEAD(&lua_states, s, lua_next);
70858881ebfSmbalmer
709ba791a5eSlneto mutex_init(&K->ks_lock, MUTEX_DEFAULT, ipl);
71058881ebfSmbalmer
71158881ebfSmbalmer finish:
71258881ebfSmbalmer mutex_enter(&sc->sc_state_lock);
71358881ebfSmbalmer sc->sc_state = false;
71458881ebfSmbalmer cv_signal(&sc->sc_state_cv);
71558881ebfSmbalmer mutex_exit(&sc->sc_state_lock);
71658881ebfSmbalmer return K;
71758881ebfSmbalmer }
71858881ebfSmbalmer
719ba791a5eSlneto inline klua_State *
kluaL_newstate(const char * name,const char * desc,int ipl)720ba791a5eSlneto kluaL_newstate(const char *name, const char *desc, int ipl)
721ba791a5eSlneto {
722ba791a5eSlneto return klua_newstate(lua_alloc, NULL, name, desc, ipl);
723ba791a5eSlneto }
724ba791a5eSlneto
72558881ebfSmbalmer void
klua_close(klua_State * K)72658881ebfSmbalmer klua_close(klua_State *K)
72758881ebfSmbalmer {
7289c8bf6eeSrin struct lua_state *s, *ns;
72958881ebfSmbalmer struct lua_softc *sc;
73058881ebfSmbalmer struct lua_module *m;
7313b5eeb2bSmbalmer int error = 0;
73258881ebfSmbalmer
733433f0999Smbalmer /* XXX consider registering a handler instead of a fixed name. */
73458881ebfSmbalmer lua_getglobal(K->L, "onClose");
73558881ebfSmbalmer if (lua_isfunction(K->L, -1))
73658881ebfSmbalmer lua_pcall(K->L, -1, 0, 0);
73758881ebfSmbalmer
73858881ebfSmbalmer sc = device_private(sc_self);
73958881ebfSmbalmer mutex_enter(&sc->sc_state_lock);
74058881ebfSmbalmer while (sc->sc_state == true) {
74158881ebfSmbalmer error = cv_wait_sig(&sc->sc_state_cv, &sc->sc_state_lock);
74258881ebfSmbalmer if (error)
74358881ebfSmbalmer break;
74458881ebfSmbalmer }
74558881ebfSmbalmer if (!error)
74658881ebfSmbalmer sc->sc_state = true;
74758881ebfSmbalmer mutex_exit(&sc->sc_state_lock);
74858881ebfSmbalmer
74958881ebfSmbalmer if (error)
75058881ebfSmbalmer return; /* Nothing we can do... */
75158881ebfSmbalmer
7529c8bf6eeSrin LIST_FOREACH_SAFE(s, &lua_states, lua_next, ns)
75358881ebfSmbalmer if (s->K == K) {
75458881ebfSmbalmer LIST_REMOVE(s, lua_next);
75558881ebfSmbalmer LIST_FOREACH(m, &s->lua_modules, mod_next)
75658881ebfSmbalmer m->refcount--;
757b345b17fSmbalmer kmem_free(s, sizeof(struct lua_state));
75858881ebfSmbalmer }
75958881ebfSmbalmer
76058881ebfSmbalmer lua_close(K->L);
76158881ebfSmbalmer mutex_destroy(&K->ks_lock);
762b345b17fSmbalmer kmem_free(K, sizeof(klua_State));
76358881ebfSmbalmer
76458881ebfSmbalmer mutex_enter(&sc->sc_state_lock);
76558881ebfSmbalmer sc->sc_state = false;
76658881ebfSmbalmer cv_signal(&sc->sc_state_cv);
76758881ebfSmbalmer mutex_exit(&sc->sc_state_lock);
76858881ebfSmbalmer }
76958881ebfSmbalmer
77058881ebfSmbalmer static klua_State *
klua_find(const char * name)77158881ebfSmbalmer klua_find(const char *name)
77258881ebfSmbalmer {
77358881ebfSmbalmer struct lua_state *s;
77458881ebfSmbalmer struct lua_softc *sc;
77558881ebfSmbalmer klua_State *K;
7763b5eeb2bSmbalmer int error = 0;
77758881ebfSmbalmer
77858881ebfSmbalmer K = NULL;
77958881ebfSmbalmer sc = device_private(sc_self);
78058881ebfSmbalmer mutex_enter(&sc->sc_state_lock);
78158881ebfSmbalmer while (sc->sc_state == true) {
78258881ebfSmbalmer error = cv_wait_sig(&sc->sc_state_cv, &sc->sc_state_lock);
78358881ebfSmbalmer if (error)
78458881ebfSmbalmer break;
78558881ebfSmbalmer }
78658881ebfSmbalmer if (!error)
78758881ebfSmbalmer sc->sc_state = true;
78858881ebfSmbalmer mutex_exit(&sc->sc_state_lock);
78958881ebfSmbalmer
79058881ebfSmbalmer if (error)
79158881ebfSmbalmer return NULL;
79258881ebfSmbalmer
79358881ebfSmbalmer LIST_FOREACH(s, &lua_states, lua_next)
79458881ebfSmbalmer if (!strcmp(s->lua_name, name)) {
79558881ebfSmbalmer K = s->K;
79658881ebfSmbalmer break;
79758881ebfSmbalmer }
79858881ebfSmbalmer
79958881ebfSmbalmer mutex_enter(&sc->sc_state_lock);
80058881ebfSmbalmer sc->sc_state = false;
80158881ebfSmbalmer cv_signal(&sc->sc_state_cv);
80258881ebfSmbalmer mutex_exit(&sc->sc_state_lock);
80358881ebfSmbalmer return K;
80458881ebfSmbalmer }
80558881ebfSmbalmer
806ba791a5eSlneto inline void
klua_lock(klua_State * K)80758881ebfSmbalmer klua_lock(klua_State *K)
80858881ebfSmbalmer {
80958881ebfSmbalmer mutex_enter(&K->ks_lock);
81058881ebfSmbalmer }
81158881ebfSmbalmer
812ba791a5eSlneto inline void
klua_unlock(klua_State * K)81358881ebfSmbalmer klua_unlock(klua_State *K)
81458881ebfSmbalmer {
81558881ebfSmbalmer mutex_exit(&K->ks_lock);
81658881ebfSmbalmer }
81758881ebfSmbalmer
81858881ebfSmbalmer MODULE(MODULE_CLASS_MISC, lua, NULL);
81958881ebfSmbalmer
82058881ebfSmbalmer #ifdef _MODULE
82158881ebfSmbalmer static const struct cfiattrdata luabus_iattrdata = {
82258881ebfSmbalmer "luabus", 0, { { NULL, NULL, 0 },}
82358881ebfSmbalmer };
824433f0999Smbalmer
82558881ebfSmbalmer static const struct cfiattrdata *const lua_attrs[] = {
82658881ebfSmbalmer &luabus_iattrdata, NULL
82758881ebfSmbalmer };
828433f0999Smbalmer
82958881ebfSmbalmer CFDRIVER_DECL(lua, DV_DULL, lua_attrs);
83058881ebfSmbalmer extern struct cfattach lua_ca;
83158881ebfSmbalmer static int lualoc[] = {
83258881ebfSmbalmer -1,
83358881ebfSmbalmer -1,
83458881ebfSmbalmer -1
83558881ebfSmbalmer };
836433f0999Smbalmer
83758881ebfSmbalmer static struct cfdata lua_cfdata[] = {
83858881ebfSmbalmer {
83958881ebfSmbalmer .cf_name = "lua",
84058881ebfSmbalmer .cf_atname = "lua",
84158881ebfSmbalmer .cf_unit = 0,
84258881ebfSmbalmer .cf_fstate = FSTATE_STAR,
84358881ebfSmbalmer .cf_loc = lualoc,
84458881ebfSmbalmer .cf_flags = 0,
84558881ebfSmbalmer .cf_pspec = NULL,
84658881ebfSmbalmer },
84758881ebfSmbalmer { NULL, NULL, 0, FSTATE_NOTFOUND, NULL, 0, NULL }
84858881ebfSmbalmer };
84958881ebfSmbalmer #endif
85058881ebfSmbalmer
85158881ebfSmbalmer static int
lua_modcmd(modcmd_t cmd,void * opaque)85258881ebfSmbalmer lua_modcmd(modcmd_t cmd, void *opaque)
85358881ebfSmbalmer {
85458881ebfSmbalmer #ifdef _MODULE
85558881ebfSmbalmer devmajor_t cmajor, bmajor;
85658881ebfSmbalmer int error = 0;
85758881ebfSmbalmer
85858881ebfSmbalmer cmajor = bmajor = NODEVMAJOR;
85958881ebfSmbalmer #endif
86058881ebfSmbalmer switch (cmd) {
86158881ebfSmbalmer case MODULE_CMD_INIT:
86258881ebfSmbalmer #ifdef _MODULE
863*97f8debdSpgoyette error = devsw_attach(lua_cd.cd_name, NULL, &bmajor,
864*97f8debdSpgoyette &lua_cdevsw, &cmajor);
865*97f8debdSpgoyette if (error) {
866*97f8debdSpgoyette aprint_error("%s: unable to register devsw\n",
867*97f8debdSpgoyette lua_cd.cd_name);
86858881ebfSmbalmer return error;
869*97f8debdSpgoyette }
870*97f8debdSpgoyette
871*97f8debdSpgoyette error = config_cfdriver_attach(&lua_cd);
872*97f8debdSpgoyette if (error) {
873*97f8debdSpgoyette devsw_detach(NULL, &lua_cdevsw);
874*97f8debdSpgoyette return error;
875*97f8debdSpgoyette }
87658881ebfSmbalmer
87758881ebfSmbalmer error = config_cfattach_attach(lua_cd.cd_name,
87858881ebfSmbalmer &lua_ca);
87958881ebfSmbalmer if (error) {
88058881ebfSmbalmer config_cfdriver_detach(&lua_cd);
881*97f8debdSpgoyette devsw_detach(NULL, &lua_cdevsw);
88258881ebfSmbalmer aprint_error("%s: unable to register cfattach\n",
88358881ebfSmbalmer lua_cd.cd_name);
88458881ebfSmbalmer return error;
88558881ebfSmbalmer }
88658881ebfSmbalmer error = config_cfdata_attach(lua_cfdata, 1);
88758881ebfSmbalmer if (error) {
88858881ebfSmbalmer config_cfattach_detach(lua_cd.cd_name,
88958881ebfSmbalmer &lua_ca);
89058881ebfSmbalmer config_cfdriver_detach(&lua_cd);
891*97f8debdSpgoyette devsw_detach(NULL, &lua_cdevsw);
89258881ebfSmbalmer aprint_error("%s: unable to register cfdata\n",
89358881ebfSmbalmer lua_cd.cd_name);
89458881ebfSmbalmer return error;
89558881ebfSmbalmer }
89658881ebfSmbalmer config_attach_pseudo(lua_cfdata);
89758881ebfSmbalmer #endif
89858881ebfSmbalmer return 0;
89958881ebfSmbalmer case MODULE_CMD_FINI:
90058881ebfSmbalmer #ifdef _MODULE
90158881ebfSmbalmer error = config_cfdata_detach(lua_cfdata);
90258881ebfSmbalmer if (error)
90358881ebfSmbalmer return error;
90458881ebfSmbalmer
90558881ebfSmbalmer config_cfattach_detach(lua_cd.cd_name, &lua_ca);
90658881ebfSmbalmer config_cfdriver_detach(&lua_cd);
90758881ebfSmbalmer devsw_detach(NULL, &lua_cdevsw);
90858881ebfSmbalmer #endif
90958881ebfSmbalmer return 0;
91058881ebfSmbalmer case MODULE_CMD_AUTOUNLOAD:
91158881ebfSmbalmer /* no auto-unload */
91258881ebfSmbalmer return EBUSY;
91358881ebfSmbalmer default:
91458881ebfSmbalmer return ENOTTY;
91558881ebfSmbalmer }
91658881ebfSmbalmer }
917