Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/i2c When loaded as a non-built-in module, make sure ...
details: https://anonhg.NetBSD.org/src/rev/415dad9cb44e
branches: trunk
changeset: 342157:415dad9cb44e
user: pgoyette <pgoyette%NetBSD.org@localhost>
date: Thu Dec 10 05:33:28 2015 +0000
description:
When loaded as a non-built-in module, make sure we attach the cdevsw.
Without this, the i2c bus works but userland programs (such as
i2cscan(8)) cannot open /dev/iic*.
While we're here, add a ref-count to make sure that the device doesn't
get detached while it is open.
diffstat:
sys/dev/i2c/i2c.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 63 insertions(+), 5 deletions(-)
diffs (137 lines):
diff -r 666175df3698 -r 415dad9cb44e sys/dev/i2c/i2c.c
--- a/sys/dev/i2c/i2c.c Thu Dec 10 05:29:41 2015 +0000
+++ b/sys/dev/i2c/i2c.c Thu Dec 10 05:33:28 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: i2c.c,v 1.49 2015/04/13 22:26:20 pgoyette Exp $ */
+/* $NetBSD: i2c.c,v 1.50 2015/12/10 05:33:28 pgoyette Exp $ */
/*
* Copyright (c) 2003 Wasabi Systems, Inc.
@@ -40,7 +40,7 @@
#endif
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: i2c.c,v 1.49 2015/04/13 22:26:20 pgoyette Exp $");
+__KERNEL_RCSID(0, "$NetBSD: i2c.c,v 1.50 2015/12/10 05:33:28 pgoyette Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -54,6 +54,8 @@
#include <sys/kernel.h>
#include <sys/fcntl.h>
#include <sys/module.h>
+#include <sys/once.h>
+#include <sys/mutex.h>
#include <dev/i2c/i2cvar.h>
@@ -73,6 +75,13 @@
static dev_type_close(iic_close);
static dev_type_ioctl(iic_ioctl);
+int iic_init(void);
+
+kmutex_t iic_mtx;
+int iic_refcnt;
+
+ONCE_DECL(iic_once);
+
const struct cdevsw iic_cdevsw = {
.d_open = iic_open,
.d_close = iic_close,
@@ -475,8 +484,13 @@
{
struct iic_softc *sc = device_lookup_private(&iic_cd, minor(dev));
- if (sc == NULL)
+ mutex_enter(&iic_mtx);
+ if (sc == NULL) {
+ mutex_exit(&iic_mtx);
return ENXIO;
+ }
+ iic_refcnt++;
+ mutex_exit(&iic_mtx);
return 0;
}
@@ -484,6 +498,11 @@
static int
iic_close(dev_t dev, int flag, int fmt, lwp_t *l)
{
+
+ mutex_enter(&iic_mtx);
+ iic_refcnt--;
+ mutex_exit(&iic_mtx);
+
return 0;
}
@@ -579,27 +598,66 @@
#include "ioconf.c"
#endif
+int
+iic_init(void)
+{
+
+ mutex_init(&iic_mtx, MUTEX_DEFAULT, IPL_NONE);
+ iic_refcnt = 0;
+ return 0;
+}
+
static int
iic_modcmd(modcmd_t cmd, void *opaque)
{
+#ifdef _MODULE
+ int bmajor, cmajor;
+#endif
int error;
error = 0;
switch (cmd) {
case MODULE_CMD_INIT:
+ RUN_ONCE(&iic_once, iic_init);
+
#ifdef _MODULE
+ mutex_enter(&iic_mtx);
+ bmajor = cmajor = -1;
+ error = devsw_attach("iic", NULL, &bmajor,
+ &iic_cdevsw, &cmajor);
+ if (error != 0) {
+ mutex_exit(&iic_mtx);
+ break;
+ }
error = config_init_component(cfdriver_ioconf_iic,
cfattach_ioconf_iic, cfdata_ioconf_iic);
- if (error)
+ if (error) {
aprint_error("%s: unable to init component\n",
iic_cd.cd_name);
+ (void)devsw_detach(NULL, &iic_cdevsw);
+ }
+ mutex_exit(&iic_mtx);
#endif
break;
case MODULE_CMD_FINI:
+ mutex_enter(&iic_mtx);
+ if (iic_refcnt != 0) {
+ mutex_exit(&iic_mtx);
+ return EBUSY;
+ }
#ifdef _MODULE
- config_fini_component(cfdriver_ioconf_iic,
+ error = config_fini_component(cfdriver_ioconf_iic,
cfattach_ioconf_iic, cfdata_ioconf_iic);
+ if (error != 0) {
+ mutex_exit(&iic_mtx);
+ break;
+ }
+ error = devsw_detach(NULL, &iic_cdevsw);
+ if (error != 0)
+ config_init_component(cfdriver_ioconf_iic,
+ cfattach_ioconf_iic, cfdata_ioconf_iic);
#endif
+ mutex_exit(&iic_mtx);
break;
default:
error = ENOTTY;
Home |
Main Index |
Thread Index |
Old Index