diff options
author | Matthew Blecker <matthewb@chromium.org> | 2020-05-15 23:45:55 -0700 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-05-19 01:17:52 +0000 |
commit | 825289a97d5341128c9baab650b9d9d8b4ff7c7b (patch) | |
tree | bee88a61b860aa341e0825ccd2981ca97b830d1c /extra | |
parent | c40fdee1c634403769d77a928f5bd28a14bce702 (diff) | |
download | chrome-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/Makefile | 11 | ||||
-rwxr-xr-x | extra/i2c_pseudo/check_stream_open.sh | 23 | ||||
-rw-r--r-- | extra/i2c_pseudo/i2c-pseudo.c | 13 |
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; |