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:
parent
ad526ef003
commit
07b62696b9
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue