summaryrefslogtreecommitdiff
path: root/extra
diff options
context:
space:
mode:
authorMatthew Blecker <matthewb@chromium.org>2020-05-15 23:45:55 -0700
committerCommit Bot <commit-bot@chromium.org>2020-05-19 01:17:52 +0000
commit825289a97d5341128c9baab650b9d9d8b4ff7c7b (patch)
treebee88a61b860aa341e0825ccd2981ca97b830d1c /extra
parentc40fdee1c634403769d77a928f5bd28a14bce702 (diff)
downloadchrome-ec-825289a97d5341128c9baab650b9d9d8b4ff7c7b.tar.gz
i2c-pseudo: Fall back on nonseekable_open when stream_open is unavailable.
The FROMLIST revision of i2c-pseudo is targeted at the newest Linux versions, which have new stream_open function and it is preferred for a pure I/O stream device. However updating to the FROMLIST i2c-pseudo broke compilation with older kernels that lack stream_open. Since Linux kernel versions as old as 4.18 are still in common use among Chrome OS developers, this fixes compatibility by checking for nonseekable_open and stream_open symbols. nonseekable_open is only used when stream_open is not found and nonseekable_open is found. Otherwise stream_open is used. BRANCH=none BUG=none TEST=With Linux 4.18 and Linux 5.2: $ make $ # With 4.18 matches nonseekable_open, with 5.2 matches stream_open. $ strings i2c-pseudo.ko | grep -E -m1 '^(nonseekable_open|stream_open)$' $ make clean $ ./install Signed-off-by: Matthew Blecker <matthewb@chromium.org> Change-Id: I62c44b1b63e7c4c6a9683be547baa341747f5efa Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2205294 Reviewed-by: Harry Cutts <hcutts@chromium.org>
Diffstat (limited to 'extra')
-rw-r--r--extra/i2c_pseudo/Makefile11
-rwxr-xr-xextra/i2c_pseudo/check_stream_open.sh23
-rw-r--r--extra/i2c_pseudo/i2c-pseudo.c13
3 files changed, 46 insertions, 1 deletions
diff --git a/extra/i2c_pseudo/Makefile b/extra/i2c_pseudo/Makefile
index c8dcb1e3b4..f7fda6e2de 100644
--- a/extra/i2c_pseudo/Makefile
+++ b/extra/i2c_pseudo/Makefile
@@ -1,9 +1,20 @@
+# Copyright 2020 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+#
+# Makefile for i2c-pseudo module. Typical usage:
+# $ make
+# $ sudo make modules_install
+# $ make clean
+
obj-m := i2c-pseudo.o
.PHONY: all
all: modules
+CFLAGS_i2c-pseudo.o += "-DHAVE_STREAM_OPEN=$(shell "$M"/check_stream_open.sh)"
+
.DEFAULT:
$(MAKE) -C /lib/modules/$(shell uname -r)/build \
M=$(shell pwd) \
diff --git a/extra/i2c_pseudo/check_stream_open.sh b/extra/i2c_pseudo/check_stream_open.sh
new file mode 100755
index 0000000000..da802cb282
--- /dev/null
+++ b/extra/i2c_pseudo/check_stream_open.sh
@@ -0,0 +1,23 @@
+#!/bin/sh
+#
+# Copyright 2020 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+#
+# This checks whether stream_open symbol is available from the target kernel.
+#
+# Output meanings:
+# -1 : stream_open is not available
+# 0 : unknown whether or not stream_open is available
+# 1 : stream_open is available
+
+symbols="$(< "/lib/modules/$(uname -r)/build/Module.symvers" \
+ awk '{print $2}' | grep -E '^(nonseekable_open|stream_open)$')"
+
+if echo "${symbols}" | grep -q '^stream_open$'; then
+ echo 1
+elif echo "${symbols}" | grep -q '^nonseekable_open$'; then
+ echo -1
+else
+ echo 0
+fi
diff --git a/extra/i2c_pseudo/i2c-pseudo.c b/extra/i2c_pseudo/i2c-pseudo.c
index 69fc9dbc52..bbe702a14c 100644
--- a/extra/i2c_pseudo/i2c-pseudo.c
+++ b/extra/i2c_pseudo/i2c-pseudo.c
@@ -2205,8 +2205,19 @@ static int i2cp_cdev_open(struct inode *inodep, struct file *filep)
/* Is there any way to find this through @inodep? */
this_pseudo = i2cp_device;
- /* I2C pseudo adapter controllers are not seekable. */
+ /*
+ * HAVE_STREAM_OPEN value meanings:
+ * -1 : stream_open() is not available
+ * 0 : unknown if stream_open() is or is not available
+ * 1 : stream_open() is available
+ */
+#if HAVE_STREAM_OPEN >= 0
+ /* I2C pseudo adapter controllers are non-seekable pure I/O streams. */
stream_open(inodep, filep);
+#else
+ /* I2C pseudo adapter controllers are not seekable. */
+ nonseekable_open(inodep, filep);
+#endif
/* Refuse fsnotify events. Modeled after /dev/ptmx implementation. */
filep->f_mode |= FMODE_NONOTIFY;