Subject: LKM problem
To: None <current-users@netbsd.org>
From: Christian Groessler <cpg@aladdin.de>
List: current-users
Date: 02/06/2004 20:39:57
Hi,

I'm trying to write a simple LKM.
Now I have the problem, that when the LKM_E_LOAD command fails, the
system gets into an inconsistent state.
The module is not loaded, but modload thinks it is:


# modstat
Type    Id   Offset Loadaddr Size Info     Rev Module Name
# modload testlkm.o
modload: error initializing module: Device not configured
# modstat
Type    Id   Offset Loadaddr Size Info     Rev Module Name
# modload testlkm.o
modload: error initializing module: File exists
# uname -a
NetBSD bronze 1.6ZH NetBSD 1.6ZH (BRONZE) #0: Thu Jan 22 22:55:24 CET 2004  chris@langhals:/local/netbsdsrc/src/sys/arch/i386/compile/BRONZE i386


regards,
chris



----------------------------------------
/*
 * test lkm
 */

#include <sys/cdefs.h>
#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/systm.h>
#include <sys/conf.h>
#include <sys/mount.h>
#include <sys/exec.h>
#include <sys/lkm.h>
#include <sys/file.h>
#include <sys/errno.h>
#include <sys/kernel.h>
#include <sys/device.h>
#include <sys/proc.h>


static int testlkm_open(dev_t dev, int flag, int mode, struct proc *p);
static int testlkm_close(dev_t dev, int flag, int mode, struct proc *p);
static int testlkm_ioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p);

/*
 * global data
 */

dev_type_open(testlkm_open);
dev_type_close(testlkm_close);
dev_type_ioctl(testlkm_ioctl);

const struct cdevsw testlkm_cdevsw = {
        testlkm_open, testlkm_close, noread, nowrite, testlkm_ioctl,
        nostop, notty, nopoll, nommap, nokqfilter,
};


MOD_DEV("testlkm", "testlkm", NULL, -1, &testlkm_cdevsw, -1)


static int
testlkm_lkm(struct lkm_table *lkmtp, int cmd)
{
        int error = 0;

        switch (cmd) {
        case LKM_E_LOAD:
                return ENXIO;
                /*break;*/
        case LKM_E_UNLOAD:
                break;
        case LKM_E_STAT:
                error = lkmdispatch(lkmtp, cmd);
                break;
        }
        return (error);
}

/*
 * testlkm_lkmentry
 * External entry point.
 */
int testlkm_lkmentry (struct lkm_table *lkmtp, int cmd, int ver)
{

        DISPATCH(lkmtp, cmd, ver, testlkm_lkm, testlkm_lkm, lkm_nofunc);
}


/*
 * open function
 */
static int testlkm_open(dev_t dev, int flag, int mode, struct proc *p)
{
    return ENXIO;
}


/*
 * close function
 */
static int testlkm_close(dev_t dev, int flag, int mode, struct proc *p)
{
    return ENXIO;
}


/*
 * ioctl function
 */
static int testlkm_ioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
{
    return ENXIO;
}
----------------------------------------