[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250520082435.2255639-3-tzungbi@kernel.org>
Date: Tue, 20 May 2025 08:24:29 +0000
From: Tzung-Bi Shih <tzungbi@...nel.org>
To: bleung@...omium.org,
brendan.higgins@...ux.dev,
davidgow@...gle.com
Cc: tzungbi@...nel.org,
rmoar@...gle.com,
rostedt@...dmis.org,
mhiramat@...nel.org,
naveen@...nel.org,
anil.s.keshavamurthy@...el.com,
davem@...emloft.net,
chrome-platform@...ts.linux.dev,
linux-kselftest@...r.kernel.org,
kunit-dev@...glegroups.com,
linux-trace-kernel@...r.kernel.org,
linux-kernel@...r.kernel.org
Subject: [RFC PATCH 2/7] platform/chrome: kunit: cros_ec_i2c: Add tests with ftrace stub
For running the tests:
$ ./tools/testing/kunit/kunit.py run \
--arch=x86_64 \
--kconfig_add CONFIG_CHROME_PLATFORMS=y \
--kconfig_add CONFIG_CROS_EC=y \
--kconfig_add CONFIG_FTRACE=y \
--kconfig_add CONFIG_FUNCTION_TRACER=y \
--kconfig_add CONFIG_MODULES=y \
--kconfig_add CONFIG_DEBUG_KERNEL=y \
--kconfig_add CONFIG_KALLSYMS_ALL=y \
--kconfig_add CONFIG_LIVEPATCH=y \
--kconfig_add CONFIG_KUNIT_FTRACE_STUBS=y \
--kconfig_add CONFIG_I2C=y \
--kconfig_add CONFIG_CROS_EC_I2C=y \
--kconfig_add CONFIG_CROS_KUNIT_EC_I2C_TEST=y \
cros_ec_i2c*
Signed-off-by: Tzung-Bi Shih <tzungbi@...nel.org>
---
drivers/platform/chrome/Kconfig | 9 +
drivers/platform/chrome/Makefile | 1 +
drivers/platform/chrome/cros_ec_i2c_test.c | 479 +++++++++++++++++++++
3 files changed, 489 insertions(+)
create mode 100644 drivers/platform/chrome/cros_ec_i2c_test.c
diff --git a/drivers/platform/chrome/Kconfig b/drivers/platform/chrome/Kconfig
index 10941ac37305..5e0b44fb7ca7 100644
--- a/drivers/platform/chrome/Kconfig
+++ b/drivers/platform/chrome/Kconfig
@@ -327,4 +327,13 @@ config CROS_KUNIT_EC_PROTO_TEST
help
Kunit tests for ChromeOS EC protocol.
+config CROS_KUNIT_EC_I2C_TEST
+ tristate "Kunit tests for ChromeOS EC over I2C" if !KUNIT_ALL_TESTS
+ depends on KUNIT && CROS_EC
+ default KUNIT_ALL_TESTS
+ depends on KUNIT_FTRACE_STUBS
+ depends on CROS_EC_I2C
+ help
+ Kunit tests for ChromeOS EC over I2C.
+
endif # CHROMEOS_PLATFORMS
diff --git a/drivers/platform/chrome/Makefile b/drivers/platform/chrome/Makefile
index b981a1bb5bd8..9808f25aea38 100644
--- a/drivers/platform/chrome/Makefile
+++ b/drivers/platform/chrome/Makefile
@@ -44,3 +44,4 @@ obj-$(CONFIG_WILCO_EC) += wilco_ec/
# Kunit test cases
obj-$(CONFIG_CROS_KUNIT_EC_PROTO_TEST) += cros_kunit_proto_test.o
cros_kunit_proto_test-objs := cros_ec_proto_test_util.o cros_ec_proto_test.o
+obj-$(CONFIG_CROS_KUNIT_EC_I2C_TEST) += cros_ec_i2c_test.o
diff --git a/drivers/platform/chrome/cros_ec_i2c_test.c b/drivers/platform/chrome/cros_ec_i2c_test.c
new file mode 100644
index 000000000000..3a7f1a17d82d
--- /dev/null
+++ b/drivers/platform/chrome/cros_ec_i2c_test.c
@@ -0,0 +1,479 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Kunit tests for ChromeOS Embedded Controller I2C interface.
+ */
+#include <kunit/test.h>
+#include <kunit/ftrace_stub.h>
+
+#include <linux/i2c.h>
+#include <linux/platform_data/cros_ec_proto.h>
+#include <linux/sched.h>
+
+#include "cros_ec.h"
+
+#define BUFSIZE 128
+#define I2C_ADDR 0x06
+
+struct cros_ec_i2c_test_priv {
+ struct i2c_adapter *fake_adap;
+ struct i2c_client *client;
+
+ int fake_cros_ec_register_called;
+ struct cros_ec_device *ec_dev;
+
+ int fake_cros_ec_unregister_called;
+
+ struct i2c_msg *i2c_msgs;
+ int i2c_msg_num;
+ int fake_i2c_xfer_res;
+ int fake_i2c_xfer_len;
+ u8 *fake_i2c_xfer_data;
+ u8 fake_i2c_xfer_sum;
+ int fake_i2c_xfer_ret;
+};
+
+static int fake_cros_ec_register(struct cros_ec_device *ec_dev)
+{
+ struct kunit *test = current->kunit_test;
+ struct cros_ec_i2c_test_priv *priv = test->priv;
+
+ priv->fake_cros_ec_register_called += 1;
+
+ priv->ec_dev = ec_dev;
+ priv->ec_dev->din_size = BUFSIZE;
+ priv->ec_dev->din = kunit_kmalloc(test, priv->ec_dev->din_size, GFP_KERNEL);
+ KUNIT_ASSERT_NOT_NULL(test, priv->ec_dev->din);
+ priv->ec_dev->dout_size = BUFSIZE;
+ priv->ec_dev->dout = kunit_kmalloc(test, priv->ec_dev->dout_size, GFP_KERNEL);
+ KUNIT_ASSERT_NOT_NULL(test, priv->ec_dev->dout);
+ return 0;
+}
+
+static void fake_cros_ec_unregister(struct cros_ec_device *ec_dev)
+{
+ struct kunit *test = current->kunit_test;
+ struct cros_ec_i2c_test_priv *priv = test->priv;
+
+ priv->fake_cros_ec_unregister_called += 1;
+}
+
+static int fake_cros_ec_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
+{
+ struct kunit *test = current->kunit_test;
+ struct cros_ec_i2c_test_priv *priv = test->priv;
+ int i;
+
+ priv->i2c_msgs = kunit_kmalloc_array(test, sizeof(struct i2c_msg), num, GFP_KERNEL);
+ KUNIT_ASSERT_NOT_NULL(test, priv->i2c_msgs);
+
+ for (i = 0; i < num; ++i) {
+ memcpy(priv->i2c_msgs + i, msgs + i, sizeof(struct i2c_msg));
+
+ priv->i2c_msgs[i].buf = kunit_kmalloc(test, msgs[i].len, GFP_KERNEL);
+ KUNIT_ASSERT_NOT_NULL(test, priv->i2c_msgs[i].buf);
+ memcpy(priv->i2c_msgs[i].buf, msgs[i].buf, msgs[i].len);
+
+ if (msgs[i].flags == I2C_M_RD) {
+ msgs[i].buf[0] = priv->fake_i2c_xfer_res;
+ msgs[i].buf[1] = priv->fake_i2c_xfer_len;
+
+ if (priv->fake_i2c_xfer_data)
+ memcpy(&msgs[i].buf[2], priv->fake_i2c_xfer_data,
+ priv->fake_i2c_xfer_len);
+
+ msgs[i].buf[priv->fake_i2c_xfer_len + 2] = priv->fake_i2c_xfer_sum;
+ }
+ }
+ priv->i2c_msg_num = num;
+
+ return priv->fake_i2c_xfer_ret;
+}
+
+static u32 fake_cros_ec_i2c_functionality(struct i2c_adapter *adap)
+{
+ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
+}
+
+static const struct i2c_algorithm fake_cros_ec_i2c_algorithm = {
+ .master_xfer = fake_cros_ec_i2c_xfer,
+ .functionality = fake_cros_ec_i2c_functionality,
+};
+
+static int cros_ec_i2c_test_init(struct kunit *test)
+{
+ struct cros_ec_i2c_test_priv *priv;
+ static const struct i2c_board_info board_info = {
+ I2C_BOARD_INFO("cros-ec-i2c", I2C_ADDR),
+ };
+
+ kunit_activate_ftrace_stub(test, cros_ec_register, fake_cros_ec_register);
+ kunit_activate_ftrace_stub(test, cros_ec_unregister, fake_cros_ec_unregister);
+
+ priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL);
+ KUNIT_ASSERT_NOT_NULL(test, priv);
+ test->priv = priv;
+
+ priv->fake_adap = kunit_kzalloc(test, sizeof(*priv->fake_adap), GFP_KERNEL);
+ KUNIT_ASSERT_NOT_NULL(test, priv->fake_adap);
+
+ priv->fake_adap->owner = THIS_MODULE;
+ strscpy(priv->fake_adap->name, "cros-ec-i2c-test");
+ priv->fake_adap->algo = &fake_cros_ec_i2c_algorithm;
+ priv->fake_adap->retries = 3;
+
+ KUNIT_ASSERT_EQ(test, i2c_add_adapter(priv->fake_adap), 0);
+
+ priv->client = i2c_new_client_device(priv->fake_adap, &board_info);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->client);
+ KUNIT_EXPECT_EQ(test, priv->client->addr, I2C_ADDR);
+
+ KUNIT_EXPECT_EQ(test, priv->fake_cros_ec_register_called, 1);
+ KUNIT_ASSERT_NOT_NULL(test, priv->ec_dev);
+ KUNIT_EXPECT_EQ(test, priv->fake_cros_ec_unregister_called, 0);
+ return 0;
+}
+
+static void cros_ec_i2c_test_exit(struct kunit *test)
+{
+ struct cros_ec_i2c_test_priv *priv = test->priv;
+
+ i2c_unregister_device(priv->client);
+ KUNIT_EXPECT_EQ(test, priv->fake_cros_ec_unregister_called, 1);
+
+ i2c_del_adapter(priv->fake_adap);
+
+ kunit_deactivate_ftrace_stub(test, cros_ec_register);
+ kunit_deactivate_ftrace_stub(test, cros_ec_unregister);
+}
+
+static int cros_ec_i2c_test_cmd_xfer_init(struct kunit *test)
+{
+ struct cros_ec_i2c_test_priv *priv;
+
+ cros_ec_i2c_test_init(test);
+ priv = test->priv;
+ priv->ec_dev->proto_version = 2;
+ return 0;
+}
+
+static void cros_ec_i2c_test_cmd_xfer_normal(struct kunit *test)
+{
+ struct cros_ec_i2c_test_priv *priv = test->priv;
+ struct cros_ec_command *msg;
+ int ret, i;
+ u8 sum;
+
+ msg = kunit_kmalloc(test, sizeof(*msg) + 2 /* max(outsize, insize) */, GFP_KERNEL);
+ KUNIT_ASSERT_NOT_NULL(test, msg);
+ msg->version = 0x1000;
+ msg->command = 0x1001;
+ msg->outsize = 2;
+ msg->insize = 1;
+ msg->data[0] = 0xbe;
+ msg->data[1] = 0xef;
+
+ priv->fake_i2c_xfer_res = 0;
+ priv->fake_i2c_xfer_data = kunit_kmalloc(test, msg->insize, GFP_KERNEL);
+ KUNIT_ASSERT_NOT_NULL(test, priv->fake_i2c_xfer_data);
+ priv->fake_i2c_xfer_data[0] = 0xaa;
+ priv->fake_i2c_xfer_len = msg->insize;
+ priv->fake_i2c_xfer_ret = 2 /* # of i2c_msg */;
+ sum = priv->fake_i2c_xfer_res + priv->fake_i2c_xfer_len + priv->fake_i2c_xfer_data[0];
+ priv->fake_i2c_xfer_sum = sum;
+
+ ret = priv->ec_dev->cmd_xfer(priv->ec_dev, msg);
+ KUNIT_EXPECT_EQ(test, ret, 1 /* insize */);
+ KUNIT_EXPECT_EQ(test, msg->result, 0);
+ KUNIT_EXPECT_EQ(test, msg->data[0], 0xaa);
+
+ KUNIT_EXPECT_EQ(test, priv->i2c_msg_num, 2);
+ /*
+ * Validate output message only which is supposed to be received by EC devices.
+ */
+ KUNIT_EXPECT_EQ(test, priv->i2c_msgs[0].addr, I2C_ADDR);
+ KUNIT_EXPECT_EQ(test, priv->i2c_msgs[0].flags, 0);
+ /*
+ * Total length of the message: EC_MSG_TX_HEADER_BYTES (version, command, length) +
+ * outsize + EC_MSG_TX_TRAILER_BYTES (checksum).
+ */
+ KUNIT_EXPECT_EQ(test, priv->i2c_msgs[0].len, EC_MSG_TX_PROTO_BYTES + 2 /* outsize */);
+ KUNIT_EXPECT_EQ(test, priv->i2c_msgs[0].buf[0], (u8)(EC_CMD_VERSION0 + 0x1000));
+ KUNIT_EXPECT_EQ(test, priv->i2c_msgs[0].buf[1], (u8)0x1001);
+ KUNIT_EXPECT_EQ(test, priv->i2c_msgs[0].buf[2], 2 /* outsize */);
+ for (sum = 0, i = 0; i < EC_MSG_TX_HEADER_BYTES + 2 /* outsize */; ++i)
+ sum += priv->i2c_msgs[0].buf[i];
+ KUNIT_EXPECT_EQ(test,
+ priv->i2c_msgs[0].buf[EC_MSG_TX_HEADER_BYTES + 2 /* outsize */], sum);
+}
+
+static void cros_ec_i2c_test_cmd_xfer_error(struct kunit *test)
+{
+ struct cros_ec_i2c_test_priv *priv = test->priv;
+ struct cros_ec_command msg = {};
+ int ret;
+
+ priv->fake_i2c_xfer_ret = -EBUSY;
+ ret = priv->ec_dev->cmd_xfer(priv->ec_dev, &msg);
+ KUNIT_EXPECT_EQ(test, ret, -EBUSY);
+
+ priv->fake_i2c_xfer_ret = 1;
+ ret = priv->ec_dev->cmd_xfer(priv->ec_dev, &msg);
+ KUNIT_EXPECT_EQ(test, ret, -EIO);
+
+ priv->fake_i2c_xfer_ret = 2 /* # of i2c_msg */;
+ priv->fake_i2c_xfer_res = EC_RES_IN_PROGRESS;
+ ret = priv->ec_dev->cmd_xfer(priv->ec_dev, &msg);
+ KUNIT_EXPECT_EQ(test, ret, -EAGAIN);
+}
+
+static void cros_ec_i2c_test_cmd_xfer_response_too_long(struct kunit *test)
+{
+ struct cros_ec_i2c_test_priv *priv = test->priv;
+ struct cros_ec_command msg = {};
+ int ret;
+
+ priv->fake_i2c_xfer_res = 0;
+ priv->fake_i2c_xfer_data = kunit_kmalloc(test, 1, GFP_KERNEL);
+ KUNIT_ASSERT_NOT_NULL(test, priv->fake_i2c_xfer_data);
+ priv->fake_i2c_xfer_len = msg.insize + 1; /* make it greater than msg.insize */
+ priv->fake_i2c_xfer_ret = 2 /* # of i2c_msg */;
+
+ ret = priv->ec_dev->cmd_xfer(priv->ec_dev, &msg);
+ KUNIT_EXPECT_EQ(test, ret, -ENOSPC);
+}
+
+static void cros_ec_i2c_test_cmd_xfer_response_bad_checksum(struct kunit *test)
+{
+ struct cros_ec_i2c_test_priv *priv = test->priv;
+ struct cros_ec_command msg = {};
+ int ret;
+
+ priv->fake_i2c_xfer_ret = 2 /* # of i2c_msg */;
+ priv->fake_i2c_xfer_sum = (u8)0xbad;
+
+ ret = priv->ec_dev->cmd_xfer(priv->ec_dev, &msg);
+ KUNIT_EXPECT_EQ(test, ret, -EBADMSG);
+}
+
+static struct kunit_case cros_ec_i2c_test_cmd_xfer_cases[] = {
+ KUNIT_CASE(cros_ec_i2c_test_cmd_xfer_normal),
+ KUNIT_CASE(cros_ec_i2c_test_cmd_xfer_error),
+ KUNIT_CASE(cros_ec_i2c_test_cmd_xfer_response_too_long),
+ KUNIT_CASE(cros_ec_i2c_test_cmd_xfer_response_bad_checksum),
+ {},
+};
+
+static struct kunit_suite cros_ec_i2c_test_cmd_xfer_suite = {
+ .name = "cros_ec_i2c_test_cmd_xfer_suite",
+ .init = cros_ec_i2c_test_cmd_xfer_init,
+ .exit = cros_ec_i2c_test_exit,
+ .test_cases = cros_ec_i2c_test_cmd_xfer_cases,
+};
+
+static int cros_ec_i2c_test_pkt_xfer_init(struct kunit *test)
+{
+ struct cros_ec_i2c_test_priv *priv;
+
+ cros_ec_i2c_test_init(test);
+ priv = test->priv;
+ priv->ec_dev->proto_version = 3;
+ return 0;
+}
+
+static void cros_ec_i2c_test_pkt_xfer_normal(struct kunit *test)
+{
+ struct cros_ec_i2c_test_priv *priv = test->priv;
+ struct cros_ec_command *msg;
+ struct ec_host_request *request;
+ struct ec_host_response *response;
+ int ret, i;
+ u8 sum;
+
+ msg = kunit_kmalloc(test, sizeof(*msg) + 2 /* max(outsize, insize) */, GFP_KERNEL);
+ KUNIT_ASSERT_NOT_NULL(test, msg);
+ msg->version = 0x1000;
+ msg->command = 0x1001;
+ msg->outsize = 2;
+ msg->insize = 1;
+ msg->data[0] = 0xbe;
+ msg->data[1] = 0xef;
+
+ priv->fake_i2c_xfer_res = 0;
+ priv->fake_i2c_xfer_len = sizeof(*response) + msg->insize;
+ priv->fake_i2c_xfer_data = kunit_kzalloc(test, priv->fake_i2c_xfer_len, GFP_KERNEL);
+ KUNIT_ASSERT_NOT_NULL(test, priv->fake_i2c_xfer_data);
+ response = (struct ec_host_response *)priv->fake_i2c_xfer_data;
+ response->struct_version = EC_HOST_RESPONSE_VERSION;
+ response->data_len = msg->insize;
+ priv->fake_i2c_xfer_data[sizeof(*response)] = 0xaa;
+ priv->fake_i2c_xfer_ret = 2 /* # of i2c_msg */;
+ for (sum = 0, i = 0; i < priv->fake_i2c_xfer_len; ++i)
+ sum += priv->fake_i2c_xfer_data[i];
+ response->checksum = -sum;
+
+ ret = priv->ec_dev->pkt_xfer(priv->ec_dev, msg);
+ KUNIT_EXPECT_EQ(test, ret, 1 /* insize */);
+ KUNIT_EXPECT_EQ(test, msg->result, 0);
+ KUNIT_EXPECT_EQ(test, msg->data[0], 0xaa);
+
+ KUNIT_EXPECT_EQ(test, priv->i2c_msg_num, 2);
+ /*
+ * Validate output message only which is supposed to be received by EC devices.
+ */
+ KUNIT_EXPECT_EQ(test, priv->i2c_msgs[0].addr, I2C_ADDR);
+ KUNIT_EXPECT_EQ(test, priv->i2c_msgs[0].flags, 0);
+ /*
+ * Total length of the message: sizeof(struct ec_host_request_i2c) + outsize.
+ * The test can't access struct ec_host_request_i2c directly (in cros_ec_i2c.c).
+ * However, it is a {u8 + struct ec_host_request} struct.
+ */
+ KUNIT_EXPECT_EQ(test, priv->i2c_msgs[0].len, 1 + sizeof(*request) + 2 /* outsize */);
+ /*
+ * i2c_msgs[0].buf is a struct ec_host_request_i2c. Again, the test can't access the
+ * struct directly. Access the u8 and struct ec_host_request separately.
+ */
+ KUNIT_EXPECT_EQ(test, priv->i2c_msgs[0].buf[0], EC_COMMAND_PROTOCOL_3);
+ request = (struct ec_host_request *)&priv->i2c_msgs[0].buf[1];
+ KUNIT_EXPECT_EQ(test, request->struct_version, EC_HOST_REQUEST_VERSION);
+ KUNIT_EXPECT_EQ(test, request->command, 0x1001);
+ KUNIT_EXPECT_EQ(test, request->command_version, (u8)0x1000);
+ KUNIT_EXPECT_EQ(test, request->data_len, 2 /* outsize */);
+ for (sum = 0, i = 0; i < sizeof(*request); ++i)
+ sum += ((u8 *)request)[i];
+ sum += 0xbe + 0xef;
+ KUNIT_EXPECT_EQ(test, sum, 0);
+}
+
+static void cros_ec_i2c_test_pkt_xfer_msg_too_long(struct kunit *test)
+{
+ struct cros_ec_i2c_test_priv *priv = test->priv;
+ struct cros_ec_command msg = {
+ .insize = 10,
+ .outsize = 10,
+ };
+ int ret;
+
+ priv->ec_dev->din_size = 0;
+ ret = priv->ec_dev->pkt_xfer(priv->ec_dev, &msg);
+ KUNIT_EXPECT_EQ(test, ret, -EINVAL);
+
+ priv->ec_dev->din_size = BUFSIZE;
+ priv->ec_dev->dout_size = 0;
+ ret = priv->ec_dev->pkt_xfer(priv->ec_dev, &msg);
+ KUNIT_EXPECT_EQ(test, ret, -EINVAL);
+}
+
+static void cros_ec_i2c_test_pkt_xfer_error(struct kunit *test)
+{
+ struct cros_ec_i2c_test_priv *priv = test->priv;
+ struct cros_ec_command msg = {};
+ int ret;
+
+ priv->fake_i2c_xfer_ret = -EBUSY;
+ ret = priv->ec_dev->pkt_xfer(priv->ec_dev, &msg);
+ KUNIT_EXPECT_EQ(test, ret, -EBUSY);
+
+ priv->fake_i2c_xfer_ret = 1;
+ ret = priv->ec_dev->pkt_xfer(priv->ec_dev, &msg);
+ KUNIT_EXPECT_EQ(test, ret, -EIO);
+}
+
+static void cros_ec_i2c_test_pkt_xfer_in_progress(struct kunit *test)
+{
+ struct cros_ec_i2c_test_priv *priv = test->priv;
+ struct cros_ec_command msg = {};
+ int ret;
+
+ priv->fake_i2c_xfer_res = EC_RES_IN_PROGRESS;
+ priv->fake_i2c_xfer_ret = 2 /* # of i2c_msg */;
+ ret = priv->ec_dev->pkt_xfer(priv->ec_dev, &msg);
+ KUNIT_EXPECT_EQ(test, ret, -EAGAIN);
+}
+
+static void cros_ec_i2c_test_pkt_xfer_to_v2_proto(struct kunit *test)
+{
+ struct cros_ec_i2c_test_priv *priv = test->priv;
+ struct cros_ec_command msg = {};
+ int ret;
+
+ priv->fake_i2c_xfer_res = EC_RES_INVALID_COMMAND;
+ priv->fake_i2c_xfer_ret = 2 /* # of i2c_msg */;
+ ret = priv->ec_dev->pkt_xfer(priv->ec_dev, &msg);
+ KUNIT_EXPECT_EQ(test, ret, -EPROTONOSUPPORT);
+}
+
+static void cros_ec_i2c_test_pkt_xfer_response_too_short(struct kunit *test)
+{
+ struct cros_ec_i2c_test_priv *priv = test->priv;
+ struct cros_ec_command msg = {};
+ int ret;
+
+ priv->fake_i2c_xfer_len = sizeof(struct ec_host_response) - 1; /* make it shorter */
+ priv->fake_i2c_xfer_ret = 2 /* # of i2c_msg */;
+ ret = priv->ec_dev->pkt_xfer(priv->ec_dev, &msg);
+ KUNIT_EXPECT_EQ(test, ret, -EBADMSG);
+}
+
+static void cros_ec_i2c_test_pkt_xfer_response_too_long(struct kunit *test)
+{
+ struct cros_ec_i2c_test_priv *priv = test->priv;
+ struct cros_ec_command msg = {};
+ struct ec_host_response *response;
+ int ret;
+
+ priv->fake_i2c_xfer_len = sizeof(*response);
+ priv->fake_i2c_xfer_data = kunit_kzalloc(test, priv->fake_i2c_xfer_len, GFP_KERNEL);
+ KUNIT_ASSERT_NOT_NULL(test, priv->fake_i2c_xfer_data);
+ response = (struct ec_host_response *)priv->fake_i2c_xfer_data;
+ response->struct_version = EC_HOST_RESPONSE_VERSION;
+ response->data_len = 100;
+ priv->fake_i2c_xfer_ret = 2 /* # of i2c_msg */;
+
+ ret = priv->ec_dev->pkt_xfer(priv->ec_dev, &msg);
+ KUNIT_EXPECT_EQ(test, ret, -EMSGSIZE);
+}
+
+static void cros_ec_i2c_test_pkt_xfer_bad_checksum(struct kunit *test)
+{
+ struct cros_ec_i2c_test_priv *priv = test->priv;
+ struct cros_ec_command msg = {};
+ struct ec_host_response *response;
+ int ret;
+
+ priv->fake_i2c_xfer_len = sizeof(*response);
+ priv->fake_i2c_xfer_data = kunit_kzalloc(test, priv->fake_i2c_xfer_len, GFP_KERNEL);
+ KUNIT_ASSERT_NOT_NULL(test, priv->fake_i2c_xfer_data);
+ response = (struct ec_host_response *)priv->fake_i2c_xfer_data;
+ response->struct_version = EC_HOST_RESPONSE_VERSION;
+ response->checksum = (u8)0xbad;
+ priv->fake_i2c_xfer_ret = 2 /* # of i2c_msg */;
+
+ ret = priv->ec_dev->pkt_xfer(priv->ec_dev, &msg);
+ KUNIT_EXPECT_EQ(test, ret, -EBADMSG);
+}
+
+static struct kunit_case cros_ec_i2c_test_pkt_xfer_cases[] = {
+ KUNIT_CASE(cros_ec_i2c_test_pkt_xfer_normal),
+ KUNIT_CASE(cros_ec_i2c_test_pkt_xfer_msg_too_long),
+ KUNIT_CASE(cros_ec_i2c_test_pkt_xfer_error),
+ KUNIT_CASE(cros_ec_i2c_test_pkt_xfer_in_progress),
+ KUNIT_CASE(cros_ec_i2c_test_pkt_xfer_to_v2_proto),
+ KUNIT_CASE(cros_ec_i2c_test_pkt_xfer_response_too_short),
+ KUNIT_CASE(cros_ec_i2c_test_pkt_xfer_response_too_long),
+ KUNIT_CASE(cros_ec_i2c_test_pkt_xfer_bad_checksum),
+ {},
+};
+
+static struct kunit_suite cros_ec_i2c_test_pkt_xfer_suite = {
+ .name = "cros_ec_i2c_test_pkt_xfer_suite",
+ .init = cros_ec_i2c_test_pkt_xfer_init,
+ .exit = cros_ec_i2c_test_exit,
+ .test_cases = cros_ec_i2c_test_pkt_xfer_cases,
+};
+
+kunit_test_suites(
+ &cros_ec_i2c_test_cmd_xfer_suite,
+ &cros_ec_i2c_test_pkt_xfer_suite,
+);
+
+MODULE_LICENSE("GPL");
--
2.49.0.1101.gccaa498523-goog
Powered by blists - more mailing lists