Add support for loading pseudo-device drivers. Try to autoload modules from

specs_open routine. If devsw_open fail, get driver name with devsw_getname
routine and autoload module.

For now only dm drivervcan be loaded, other pseudo drivers needs more work.

Ok by ad@.
This commit is contained in:
haad 2009-02-02 14:00:27 +00:00
parent ad526ef003
commit 07b62696b9
3 changed files with 99 additions and 8 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: subr_devsw.c,v 1.25 2009/02/02 11:19:29 enami Exp $ */
/* $NetBSD: subr_devsw.c,v 1.26 2009/02/02 14:00:27 haad Exp $ */
/*-
* Copyright (c) 2001, 2002, 2007, 2008 The NetBSD Foundation, Inc.
@ -69,7 +69,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: subr_devsw.c,v 1.25 2009/02/02 11:19:29 enami Exp $");
__KERNEL_RCSID(0, "$NetBSD: subr_devsw.c,v 1.26 2009/02/02 14:00:27 haad Exp $");
#include <sys/param.h>
#include <sys/conf.h>
@ -458,6 +458,56 @@ devsw_blk2name(devmajor_t bmajor)
return (name);
}
/*
* Convert char major number to device driver name.
*/
const char*
cdevsw_getname(devmajor_t major)
{
const char *name;
int i;
name = NULL;
if (major < 0)
return (NULL);
mutex_enter(&device_lock);
for (i = 0 ; i < max_devsw_convs; i++) {
if (devsw_conv[i].d_cmajor == major) {
name = devsw_conv[i].d_name;
break;
}
}
mutex_exit(&device_lock);
return (name);
}
/*
* Convert block major number to device driver name.
*/
const char*
bdevsw_getname(devmajor_t major)
{
const char *name;
int i;
name = NULL;
if (major < 0)
return (NULL);
mutex_enter(&device_lock);
for (i = 0 ; i < max_devsw_convs; i++) {
if (devsw_conv[i].d_bmajor == major) {
name = devsw_conv[i].d_name;
break;
}
}
mutex_exit(&device_lock);
return (name);
}
/*
* Convert from device name to block major number.
*

View File

@ -1,4 +1,4 @@
/* $NetBSD: spec_vnops.c,v 1.121 2009/01/11 02:45:54 christos Exp $ */
/* $NetBSD: spec_vnops.c,v 1.122 2009/02/02 14:00:27 haad Exp $ */
/*-
* Copyright (c) 2008 The NetBSD Foundation, Inc.
@ -58,7 +58,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: spec_vnops.c,v 1.121 2009/01/11 02:45:54 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: spec_vnops.c,v 1.122 2009/02/02 14:00:27 haad Exp $");
#include <sys/param.h>
#include <sys/proc.h>
@ -79,6 +79,7 @@ __KERNEL_RCSID(0, "$NetBSD: spec_vnops.c,v 1.121 2009/01/11 02:45:54 christos Ex
#include <sys/tty.h>
#include <sys/kauth.h>
#include <sys/fstrans.h>
#include <sys/module.h>
#include <miscfs/genfs/genfs.h>
#include <miscfs/specfs/specdev.h>
@ -353,12 +354,17 @@ spec_open(void *v)
specnode_t *sn;
specdev_t *sd;
u_int gen;
const char *name;
l = curlwp;
vp = ap->a_vp;
dev = vp->v_rdev;
sn = vp->v_specnode;
sd = sn->sn_dev;
name = NULL;
gen = 0;
/*
* Don't allow open if fs is mounted -nodev.
*/
@ -398,7 +404,22 @@ spec_open(void *v)
if (cdev_type(dev) == D_TTY)
vp->v_vflag |= VV_ISTTY;
VOP_UNLOCK(vp, 0);
error = cdev_open(dev, ap->a_mode, S_IFCHR, l);
do {
gen = module_gen;
error = cdev_open(dev, ap->a_mode, S_IFCHR, l);
if (error != ENXIO)
break;
/* Get device name from devsw_conv array */
if ((name = cdevsw_getname(major(dev))) == NULL)
break;
/* Try to autoload device module */
mutex_enter(&module_lock);
(void) module_autoload(name, MODULE_CLASS_DRIVER);
mutex_exit(&module_lock);
} while (gen != module_gen);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
break;
@ -425,8 +446,26 @@ spec_open(void *v)
sd->sd_opencnt = 1;
sd->sd_bdevvp = vp;
mutex_exit(&device_lock);
do {
gen = module_gen;
error = bdev_open(dev, ap->a_mode, S_IFBLK, l);
if (error != ENXIO)
break;
/* Get device name from devsw_conv array */
if ((name = bdevsw_getname(major(dev))) == NULL)
break;
VOP_UNLOCK(vp, 0);
/* Try to autoload device module */
mutex_enter(&module_lock);
(void) module_autoload(name, MODULE_CLASS_DRIVER);
mutex_exit(&module_lock);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
} while (gen != module_gen);
error = bdev_open(dev, ap->a_mode, S_IFBLK, l);
break;
case VNON:

View File

@ -1,4 +1,4 @@
/* $NetBSD: conf.h,v 1.133 2009/01/20 18:20:48 drochner Exp $ */
/* $NetBSD: conf.h,v 1.134 2009/02/02 14:00:27 haad Exp $ */
/*-
* Copyright (c) 1990, 1993
@ -238,6 +238,8 @@ struct devsw_conv {
#ifdef _KERNEL
void devsw_init(void);
const char *devsw_blk2name(devmajor_t);
const char *cdevsw_getname(devmajor_t);
const char *bdevsw_getname(devmajor_t);
devmajor_t devsw_name2blk(const char *, char *, size_t);
devmajor_t devsw_name2chr(const char *, char *, size_t);
dev_t devsw_chr2blk(dev_t);