Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 23 Jan 2018 23:30:19 +0000 (UTC)
From:      Ian Lepore <ian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r328307 - head/sys/dev/iicbus
Message-ID:  <201801232330.w0NNUJfn019643@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ian
Date: Tue Jan 23 23:30:19 2018
New Revision: 328307
URL: https://svnweb.freebsd.org/changeset/base/328307

Log:
  Fix a bug introduced with recursive bus ownership support in r321584.
  
  The recursive ownership support added in r321584 was unconditionally in
  effect all the time -- whenever a given i2c slave device instance tried to
  lock the i2c bus for exclusive use when it already owned the bus, the call
  returned immediately without waiting.  However, many i2c slave drivers use
  bus ownership to enforce that only a single thread at a time can be using
  the slave device.  The recursive locking changes broke this use case.
  
  Now there is a new flag, IIC_RECURSIVE, which can be mixed in with the
  other flags passed to iicbus_acquire_bus() to allow drivers to indicate
  when recursive locking is desired.  Using the flag implies that the driver
  is managing concurrent access to the device by different threads in some way.
  
  This immediately fixes all existing i2c slave drivers except for the two
  i2c RTC drivers which use the recursive locking feature; those will be
  fixed in a followup commit.

Modified:
  head/sys/dev/iicbus/iiconf.c
  head/sys/dev/iicbus/iiconf.h

Modified: head/sys/dev/iicbus/iiconf.c
==============================================================================
--- head/sys/dev/iicbus/iiconf.c	Tue Jan 23 22:48:06 2018	(r328306)
+++ head/sys/dev/iicbus/iiconf.c	Tue Jan 23 23:30:19 2018	(r328307)
@@ -84,7 +84,7 @@ iicbus_poll(struct iicbus_softc *sc, int how)
 	int error;
 
 	IICBUS_ASSERT_LOCKED(sc);
-	switch (how) {
+	switch (how & IIC_INTRWAIT) {
 	case IIC_WAIT | IIC_INTR:
 		error = mtx_sleep(sc, &sc->lock, IICPRI|PCATCH, "iicreq", 0);
 		break;
@@ -115,8 +115,14 @@ iicbus_request_bus(device_t bus, device_t dev, int how
 
 	IICBUS_LOCK(sc);
 
-	while (error == 0 && sc->owner != NULL && sc->owner != dev)
-		error = iicbus_poll(sc, how);
+	for (;;) {
+		if (sc->owner == NULL)
+			break;
+		if ((how & IIC_RECURSIVE) && sc->owner == dev)
+			break;
+		if ((error = iicbus_poll(sc, how)) != 0)
+			break;
+	}
 
 	if (error == 0) {
 		++sc->owncount;

Modified: head/sys/dev/iicbus/iiconf.h
==============================================================================
--- head/sys/dev/iicbus/iiconf.h	Tue Jan 23 22:48:06 2018	(r328306)
+++ head/sys/dev/iicbus/iiconf.h	Tue Jan 23 23:30:19 2018	(r328307)
@@ -39,13 +39,14 @@
 #define LSB 0x1
 
 /*
- * How tsleep() is called in iic_request_bus().
+ * Options affecting iicbus_request_bus()
  */
 #define IIC_DONTWAIT	0
 #define IIC_NOINTR	0
 #define IIC_WAIT	0x1
 #define IIC_INTR	0x2
 #define IIC_INTRWAIT	(IIC_INTR | IIC_WAIT)
+#define IIC_RECURSIVE	0x4
 
 /*
  * i2c modes



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201801232330.w0NNUJfn019643>