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>