[PATCH v5] i2c: virtio: add a virtio i2c frontend driver

Subsystems: i2c subsystem, i2c subsystem host drivers, the rest, virtio core, virtio i2c driver

STALE1986d

8 messages, 4 authors, 2021-03-03 · open the first message on its own page

[PATCH v5] i2c: virtio: add a virtio i2c frontend driver

From: Jie Deng <hidden>
Date: 2021-03-01 06:44:03

Add an I2C bus driver for virtio para-virtualization.

The controller can be emulated by the backend driver in
any device model software by following the virtio protocol.

The device specification can be found on
https://lists.oasis-open.org/archives/virtio-comment/202101/msg00008.html.

By following the specification, people may implement different
backend drivers to emulate different controllers according to
their needs.

Co-developed-by: Conghui Chen <redacted>
Signed-off-by: Conghui Chen <redacted>
Signed-off-by: Jie Deng <redacted>
---
 drivers/i2c/busses/Kconfig      |  11 ++
 drivers/i2c/busses/Makefile     |   3 +
 drivers/i2c/busses/i2c-virtio.c | 281 ++++++++++++++++++++++++++++++++++++++++
 include/uapi/linux/virtio_i2c.h |  56 ++++++++
 include/uapi/linux/virtio_ids.h |   1 +
 5 files changed, 352 insertions(+)
 create mode 100644 drivers/i2c/busses/i2c-virtio.c
 create mode 100644 include/uapi/linux/virtio_i2c.h
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 05ebf75..0860395 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -21,6 +21,17 @@ config I2C_ALI1535
 	  This driver can also be built as a module.  If so, the module
 	  will be called i2c-ali1535.
 
+config I2C_VIRTIO
+	tristate "Virtio I2C Adapter"
+	depends on VIRTIO
+	help
+	  If you say yes to this option, support will be included for the virtio
+	  I2C adapter driver. The hardware can be emulated by any device model
+	  software according to the virtio protocol.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called i2c-virtio.
+
 config I2C_ALI1563
 	tristate "ALI 1563"
 	depends on PCI
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index 615f35e..b88da08 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -6,6 +6,9 @@
 # ACPI drivers
 obj-$(CONFIG_I2C_SCMI)		+= i2c-scmi.o
 
+# VIRTIO I2C host controller driver
+obj-$(CONFIG_I2C_VIRTIO)	+= i2c-virtio.o
+
 # PC SMBus host controller drivers
 obj-$(CONFIG_I2C_ALI1535)	+= i2c-ali1535.o
 obj-$(CONFIG_I2C_ALI1563)	+= i2c-ali1563.o
diff --git a/drivers/i2c/busses/i2c-virtio.c b/drivers/i2c/busses/i2c-virtio.c
new file mode 100644
index 0000000..8c8bc95
--- /dev/null
+++ b/drivers/i2c/busses/i2c-virtio.c
@@ -0,0 +1,281 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Virtio I2C Bus Driver
+ *
+ * Copyright (c) 2021 Intel Corporation. All rights reserved.
+ */
+
+#include <linux/acpi.h>
+#include <linux/completion.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/io.h>
+#include <linux/jiffies.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/wait.h>
+
+#include <linux/virtio.h>
+#include <linux/virtio_i2c.h>
+
+/**
+ * struct virtio_i2c - virtio I2C data
+ * @vdev: virtio device for this controller
+ * @completion: completion of virtio I2C message
+ * @adap: I2C adapter for this controller
+ * @i2c_lock: lock for virtqueue processing
+ * @vq: the virtio virtqueue for communication
+ */
+struct virtio_i2c {
+	struct virtio_device *vdev;
+	struct completion completion;
+	struct i2c_adapter adap;
+	struct mutex i2c_lock;
+	struct virtqueue *vq;
+};
+
+static void virtio_i2c_msg_done(struct virtqueue *vq)
+{
+	struct virtio_i2c *vi = vq->vdev->priv;
+
+	complete(&vi->completion);
+}
+
+static int virtio_i2c_send_reqs(struct virtqueue *vq,
+				struct virtio_i2c_req *reqs,
+				struct i2c_msg *msgs, int nr)
+{
+	struct scatterlist *sgs[3], out_hdr, msg_buf, in_hdr;
+	int i, outcnt, incnt, err = 0;
+	u8 *buf;
+
+	for (i = 0; i < nr; i++) {
+		if (!msgs[i].len)
+			break;
+
+		reqs[i].out_hdr.addr = cpu_to_le16(msgs[i].addr << 1);
+
+		if (i != nr - 1)
+			reqs[i].out_hdr.flags |= VIRTIO_I2C_FLAGS_FAIL_NEXT;
+
+		outcnt = incnt = 0;
+		sg_init_one(&out_hdr, &reqs[i].out_hdr, sizeof(reqs[i].out_hdr));
+		sgs[outcnt++] = &out_hdr;
+
+		buf = kzalloc(msgs[i].len, GFP_KERNEL);
+		if (!buf)
+			break;
+
+		if (msgs[i].flags & I2C_M_RD) {
+			reqs[i].read_buf = buf;
+			sg_init_one(&msg_buf, reqs[i].read_buf, msgs[i].len);
+			sgs[outcnt + incnt++] = &msg_buf;
+		} else {
+			reqs[i].write_buf = buf;
+			memcpy(reqs[i].write_buf, msgs[i].buf, msgs[i].len);
+			sg_init_one(&msg_buf, reqs[i].write_buf, msgs[i].len);
+			sgs[outcnt++] = &msg_buf;
+		}
+
+		sg_init_one(&in_hdr, &reqs[i].in_hdr, sizeof(reqs[i].in_hdr));
+		sgs[outcnt + incnt++] = &in_hdr;
+
+		err = virtqueue_add_sgs(vq, sgs, outcnt, incnt, &reqs[i], GFP_KERNEL);
+		if (err < 0) {
+			pr_err("failed to add msg[%d] to virtqueue.\n", i);
+			if (msgs[i].flags & I2C_M_RD) {
+				kfree(reqs[i].read_buf);
+				reqs[i].read_buf = NULL;
+			} else {
+				kfree(reqs[i].write_buf);
+				reqs[i].write_buf = NULL;
+			}
+			break;
+		}
+	}
+
+	return i;
+}
+
+static int virtio_i2c_complete_reqs(struct virtqueue *vq,
+					struct virtio_i2c_req *reqs,
+					struct i2c_msg *msgs, int nr)
+{
+	struct virtio_i2c_req *req;
+	unsigned int len;
+	int i;
+
+	for (i = 0; i < nr; i++) {
+		req = (struct virtio_i2c_req *)virtqueue_get_buf(vq, &len);
+		if (!(req && req == &reqs[i])) {
+			pr_err("msg[%d]: addr=0x%x virtqueue error.\n", i, msgs[i].addr);
+			break;
+		}
+
+		if (req->in_hdr.status != VIRTIO_I2C_MSG_OK) {
+			pr_err("msg[%d]: addr=0x%x backend error.\n", i, msgs[i].addr);
+			break;
+		}
+
+		if (msgs[i].flags & I2C_M_RD) {
+			memcpy(msgs[i].buf, req->read_buf, msgs[i].len);
+			kfree(req->read_buf);
+			req->read_buf = NULL;
+		} else {
+			kfree(req->write_buf);
+			req->write_buf = NULL;
+		}
+	}
+
+	return i;
+}
+
+
+static int virtio_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
+{
+	struct virtio_i2c *vi = i2c_get_adapdata(adap);
+	struct virtqueue *vq = vi->vq;
+	struct virtio_i2c_req *reqs;
+	unsigned long time_left;
+	int ret, nr;
+
+	reqs = kcalloc(num, sizeof(*reqs), GFP_KERNEL);
+	if (!reqs)
+		return -ENOMEM;
+
+	mutex_lock(&vi->i2c_lock);
+
+	ret = virtio_i2c_send_reqs(vq, reqs, msgs, num);
+	if (ret == 0)
+		goto err_unlock_free;
+	else
+		nr = ret;
+
+	virtqueue_kick(vq);
+
+	time_left = wait_for_completion_timeout(&vi->completion, adap->timeout);
+	if (!time_left) {
+		dev_err(&adap->dev, "virtio i2c backend timeout.\n");
+		ret = -ETIMEDOUT;
+		goto err_unlock_free;
+	}
+
+	ret = virtio_i2c_complete_reqs(vq, reqs, msgs, nr);
+
+	reinit_completion(&vi->completion);
+
+err_unlock_free:
+	mutex_unlock(&vi->i2c_lock);
+	kfree(reqs);
+	return ret;
+}
+
+static void virtio_i2c_del_vqs(struct virtio_device *vdev)
+{
+	vdev->config->reset(vdev);
+	vdev->config->del_vqs(vdev);
+}
+
+static int virtio_i2c_setup_vqs(struct virtio_i2c *vi)
+{
+	struct virtio_device *vdev = vi->vdev;
+
+	vi->vq = virtio_find_single_vq(vdev, virtio_i2c_msg_done, "msg");
+	return PTR_ERR_OR_ZERO(vi->vq);
+}
+
+static u32 virtio_i2c_func(struct i2c_adapter *adap)
+{
+	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
+}
+
+static struct i2c_algorithm virtio_algorithm = {
+	.master_xfer = virtio_i2c_xfer,
+	.functionality = virtio_i2c_func,
+};
+
+static struct i2c_adapter virtio_adapter = {
+	.owner = THIS_MODULE,
+	.name = "Virtio I2C Adapter",
+	.class = I2C_CLASS_DEPRECATED,
+	.algo = &virtio_algorithm,
+};
+
+static int virtio_i2c_probe(struct virtio_device *vdev)
+{
+	struct device *pdev = vdev->dev.parent;
+	struct virtio_i2c *vi;
+	int ret;
+
+	vi = devm_kzalloc(&vdev->dev, sizeof(*vi), GFP_KERNEL);
+	if (!vi)
+		return -ENOMEM;
+
+	vdev->priv = vi;
+	vi->vdev = vdev;
+
+	mutex_init(&vi->i2c_lock);
+	init_completion(&vi->completion);
+
+	ret = virtio_i2c_setup_vqs(vi);
+	if (ret)
+		return ret;
+
+	vi->adap = virtio_adapter;
+	i2c_set_adapdata(&vi->adap, vi);
+	vi->adap.dev.parent = &vdev->dev;
+	/* Setup ACPI node for controlled devices which will be probed through ACPI */
+	ACPI_COMPANION_SET(&vi->adap.dev, ACPI_COMPANION(pdev));
+	vi->adap.timeout = HZ / 10;
+
+	ret = i2c_add_adapter(&vi->adap);
+	if (ret) {
+		virtio_i2c_del_vqs(vdev);
+		dev_err(&vdev->dev, "failed to add virtio-i2c adapter.\n");
+	}
+
+	return ret;
+}
+
+static void virtio_i2c_remove(struct virtio_device *vdev)
+{
+	struct virtio_i2c *vi = vdev->priv;
+
+	i2c_del_adapter(&vi->adap);
+	virtio_i2c_del_vqs(vdev);
+}
+
+static struct virtio_device_id id_table[] = {
+	{ VIRTIO_ID_I2C_ADPTER, VIRTIO_DEV_ANY_ID },
+	{}
+};
+MODULE_DEVICE_TABLE(virtio, id_table);
+
+static int __maybe_unused virtio_i2c_freeze(struct virtio_device *vdev)
+{
+	virtio_i2c_del_vqs(vdev);
+	return 0;
+}
+
+static int __maybe_unused virtio_i2c_restore(struct virtio_device *vdev)
+{
+	return virtio_i2c_setup_vqs(vdev->priv);
+}
+
+static struct virtio_driver virtio_i2c_driver = {
+	.id_table	= id_table,
+	.probe		= virtio_i2c_probe,
+	.remove		= virtio_i2c_remove,
+	.driver	= {
+		.name	= "i2c_virtio",
+	},
+#ifdef CONFIG_PM_SLEEP
+	.freeze = virtio_i2c_freeze,
+	.restore = virtio_i2c_restore,
+#endif
+};
+module_virtio_driver(virtio_i2c_driver);
+
+MODULE_DESCRIPTION("Virtio i2c bus driver");
+MODULE_LICENSE("GPL");
diff --git a/include/uapi/linux/virtio_i2c.h b/include/uapi/linux/virtio_i2c.h
new file mode 100644
index 0000000..92febf0
--- /dev/null
+++ b/include/uapi/linux/virtio_i2c.h
@@ -0,0 +1,56 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later WITH Linux-syscall-note */
+/*
+ * Definitions for virtio I2C Adpter
+ *
+ * Copyright (c) 2021 Intel Corporation. All rights reserved.
+ */
+
+#ifndef _UAPI_LINUX_VIRTIO_I2C_H
+#define _UAPI_LINUX_VIRTIO_I2C_H
+
+#include <linux/types.h>
+#include <linux/virtio_ids.h>
+#include <linux/virtio_config.h>
+
+/**
+ * struct virtio_i2c_out_hdr - the virtio I2C message OUT header
+ * @addr: the controlled device address
+ * @padding: used to pad to full dword
+ * @flags: used for feature extensibility
+ */
+struct virtio_i2c_out_hdr {
+	__le16 addr;
+	__le16 padding;
+	__le32 flags;
+};
+
+/* The bit 0 of the @virtio_i2c_out_hdr.@flags, used to group the requests */
+#define VIRTIO_I2C_FLAGS_FAIL_NEXT	0x00000001
+
+/**
+ * struct virtio_i2c_in_hdr - the virtio I2C message IN header
+ * @status: the processing result from the backend
+ */
+struct virtio_i2c_in_hdr {
+	u8 status;
+};
+
+/* The final status written by the device */
+#define VIRTIO_I2C_MSG_OK	0
+#define VIRTIO_I2C_MSG_ERR	1
+
+/**
+ * struct virtio_i2c_req - the virtio I2C request structure
+ * @out_hdr: the OUT header of the virtio I2C message
+ * @write_buf: contains one I2C segment being written to the device
+ * @read_buf: contains one I2C segment being read from the device
+ * @in_hdr: the IN header of the virtio I2C message
+ */
+struct virtio_i2c_req {
+	struct virtio_i2c_out_hdr out_hdr;
+	u8 *write_buf;
+	u8 *read_buf;
+	struct virtio_i2c_in_hdr in_hdr;
+};
+
+#endif /* _UAPI_LINUX_VIRTIO_I2C_H */
diff --git a/include/uapi/linux/virtio_ids.h b/include/uapi/linux/virtio_ids.h
index bc1c062..6ae32db 100644
--- a/include/uapi/linux/virtio_ids.h
+++ b/include/uapi/linux/virtio_ids.h
@@ -54,5 +54,6 @@
 #define VIRTIO_ID_FS			26 /* virtio filesystem */
 #define VIRTIO_ID_PMEM			27 /* virtio pmem */
 #define VIRTIO_ID_MAC80211_HWSIM	29 /* virtio mac80211-hwsim */
+#define VIRTIO_ID_I2C_ADPTER		34 /* virtio i2c adpter */
 
 #endif /* _LINUX_VIRTIO_IDS_H */
-- 
2.7.4

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

Re: [PATCH v5] i2c: virtio: add a virtio i2c frontend driver

From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Date: 2021-03-01 12:12:21

On Mon, Mar 01, 2021 at 02:41:35PM +0800, Jie Deng wrote:
Add an I2C bus driver for virtio para-virtualization.

The controller can be emulated by the backend driver in
any device model software by following the virtio protocol.

The device specification can be found on
https://lists.oasis-open.org/archives/virtio-comment/202101/msg00008.html.

By following the specification, people may implement different
backend drivers to emulate different controllers according to
their needs.
...
+		buf = kzalloc(msgs[i].len, GFP_KERNEL);
+		if (!buf)
+			break;
+
+		if (msgs[i].flags & I2C_M_RD) {
kzalloc()
+			reqs[i].read_buf = buf;
+			sg_init_one(&msg_buf, reqs[i].read_buf, msgs[i].len);
+			sgs[outcnt + incnt++] = &msg_buf;
+		} else {
+			reqs[i].write_buf = buf;
+			memcpy(reqs[i].write_buf, msgs[i].buf, msgs[i].len);
kmemdup() ?
+			sg_init_one(&msg_buf, reqs[i].write_buf, msgs[i].len);
+			sgs[outcnt++] = &msg_buf;
+		}
...
+
+
One blank line is enough.

...

+	ret = virtio_i2c_send_reqs(vq, reqs, msgs, num);
+	if (ret == 0)
+		goto err_unlock_free;
+	else
Redundant.
+		nr = ret;
-- 
With Best Regards,
Andy Shevchenko


_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

Re: [PATCH v5] i2c: virtio: add a virtio i2c frontend driver

From: Arnd Bergmann <arnd@arndb.de>
Date: 2021-03-01 15:22:58

On Mon, Mar 1, 2021 at 7:41 AM Jie Deng [off-list ref] wrote:
quoted hunk
--- /dev/null
+++ b/include/uapi/linux/virtio_i2c.h
@@ -0,0 +1,56 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later WITH Linux-syscall-note */
+/*
+ * Definitions for virtio I2C Adpter
+ *
+ * Copyright (c) 2021 Intel Corporation. All rights reserved.
+ */
+
+#ifndef _UAPI_LINUX_VIRTIO_I2C_H
+#define _UAPI_LINUX_VIRTIO_I2C_H
Why is this a uapi header? Can't this all be moved into the driver
itself?
+/**
+ * struct virtio_i2c_req - the virtio I2C request structure
+ * @out_hdr: the OUT header of the virtio I2C message
+ * @write_buf: contains one I2C segment being written to the device
+ * @read_buf: contains one I2C segment being read from the device
+ * @in_hdr: the IN header of the virtio I2C message
+ */
+struct virtio_i2c_req {
+       struct virtio_i2c_out_hdr out_hdr;
+       u8 *write_buf;
+       u8 *read_buf;
+       struct virtio_i2c_in_hdr in_hdr;
+};
In particular, this structure looks like it is only ever usable between
the transfer functions in the driver itself, it is shared with neither
user space nor the virtio host side.

       Arnd
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

Re: [PATCH v5] i2c: virtio: add a virtio i2c frontend driver

From: Jie Deng <hidden>
Date: 2021-03-02 02:42:25

On 2021/3/1 23:19, Arnd Bergmann wrote:
On Mon, Mar 1, 2021 at 7:41 AM Jie Deng [off-list ref] wrote:
quoted
--- /dev/null
+++ b/include/uapi/linux/virtio_i2c.h
@@ -0,0 +1,56 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later WITH Linux-syscall-note */
+/*
+ * Definitions for virtio I2C Adpter
+ *
+ * Copyright (c) 2021 Intel Corporation. All rights reserved.
+ */
+
+#ifndef _UAPI_LINUX_VIRTIO_I2C_H
+#define _UAPI_LINUX_VIRTIO_I2C_H
Why is this a uapi header? Can't this all be moved into the driver
itself?
quoted
+/**
+ * struct virtio_i2c_req - the virtio I2C request structure
+ * @out_hdr: the OUT header of the virtio I2C message
+ * @write_buf: contains one I2C segment being written to the device
+ * @read_buf: contains one I2C segment being read from the device
+ * @in_hdr: the IN header of the virtio I2C message
+ */
+struct virtio_i2c_req {
+       struct virtio_i2c_out_hdr out_hdr;
+       u8 *write_buf;
+       u8 *read_buf;
+       struct virtio_i2c_in_hdr in_hdr;
+};
In particular, this structure looks like it is only ever usable between
the transfer functions in the driver itself, it is shared with neither
user space nor the virtio host side.

        Arnd
Please check this link.

https://lists.linuxfoundation.org/pipermail/virtualization/2020-October/050222.html

Jason/Stefan, could you please double confirm about the following ?

**************************************************************************
quoted
quoted
quoted
quoted
/I think following definition in uAPI for the status is enough. />>>>>/There is no need to provide a "u8" status in the structure. />>>>>//>>>>>//* The final status written by the device */ />>>>>/#define VIRTIO_I2C_MSG_OK    0 />>>>>/#define VIRTIO_I2C_MSG_ERR    1 />>>>>//>>>>>/You can see an example in virtio_blk. />>>>>//>>>>>/In the spec: />>>>>//>>>>>/struct virtio_blk_req { />>>>>/le32 type; />>>>>/le32 reserved; />>>>>/le64 sector; />>>>>/u8 data[]; />>>>>/u8 status; />>>>>/}; />>>>>//>>>>>/In virtio_blk.h, there is only following definitions. />>>>>//>>>>>/#define VIRTIO_BLK_S_OK        0 />>>>>/#define VIRTIO_BLK_S_IOERR    1 />>>>>/#define VIRTIO_BLK_S_UNSUPP    2 />>>>>//>>>>//>>>>/virtio-blk is a bad example, it's just too late to fix. For any new />>>>/introduced uAPI it should be a complete one. />>>>//>>>>/Thanks />>>>//>>>/I checked a relatively new device "virtio_fs". />>>/I found following definition in spec but not in uAPI also. />>>//>>>/struct virtio_fs_req { />>>/// Device -readable part />>>/struct fuse_in_header in; />>>/u8 datain[]; />>>/// Device -writable part />>>/struct fuse_out_header out; />>>/u8 dataout[]; />>>/}; />>>//>>>/So is this also a bad example which has not been fixed yet. />>//>>//>>/Cc Stefan for the answer. />>//>>//>>>/Or what's your mean about "complete" here ? Is there any definition />>>/about "complete uAPI" ? />>//>>//>>/My understanding it should contain all the fields defined in the />>/virtio spec. />>//>>/Thanks />>//>/OK. I noticed this isn't strictly implemented in the current virtio />/codes. />/I'm not sure if this is already a consensus. I will follow it if this />/is the opinion of the majority. /
Please do that, this forces us to maintain uABI compatibility which is
what Linux try to maintain for ever.

******************************************************************************

Re: [PATCH v5] i2c: virtio: add a virtio i2c frontend driver

From: Jie Deng <hidden>
Date: 2021-03-02 08:35:34

On 2021/3/1 20:07, Andy Shevchenko wrote:
On Mon, Mar 01, 2021 at 02:41:35PM +0800, Jie Deng wrote:
quoted
Add an I2C bus driver for virtio para-virtualization.

The controller can be emulated by the backend driver in
any device model software by following the virtio protocol.

The device specification can be found on
https://lists.oasis-open.org/archives/virtio-comment/202101/msg00008.html.

By following the specification, people may implement different
backend drivers to emulate different controllers according to
their needs.
...
quoted
+		buf = kzalloc(msgs[i].len, GFP_KERNEL);
+		if (!buf)
+			break;
+
+		if (msgs[i].flags & I2C_M_RD) {
kzalloc()
quoted
+			reqs[i].read_buf = buf;
+			sg_init_one(&msg_buf, reqs[i].read_buf, msgs[i].len);
+			sgs[outcnt + incnt++] = &msg_buf;
+		} else {
+			reqs[i].write_buf = buf;
+			memcpy(reqs[i].write_buf, msgs[i].buf, msgs[i].len);
kmemdup() ?
Do you mean using "kzalloc" in the if condition and "kmemdup" in the 
else condition ?
Then we have to check the NULL twice which is also not good.
quoted
+			sg_init_one(&msg_buf, reqs[i].write_buf, msgs[i].len);
+			sgs[outcnt++] = &msg_buf;
+		}
...
quoted
+
+
One blank line is enough.
Will fix it. Thank you.
...

quoted
+	ret = virtio_i2c_send_reqs(vq, reqs, msgs, num);
+	if (ret == 0)
+		goto err_unlock_free;
+	else
Redundant.
Good catch !
quoted
+		nr = ret;
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

Re: [PATCH v5] i2c: virtio: add a virtio i2c frontend driver

From: Stefan Hajnoczi <stefanha@redhat.com>
Date: 2021-03-02 10:11:13

On Tue, Mar 02, 2021 at 10:42:06AM +0800, Jie Deng wrote:
On 2021/3/1 23:19, Arnd Bergmann wrote:
quoted
On Mon, Mar 1, 2021 at 7:41 AM Jie Deng [off-list ref] wrote:
quoted
--- /dev/null
+++ b/include/uapi/linux/virtio_i2c.h
@@ -0,0 +1,56 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later WITH Linux-syscall-note */
The uapi VIRTIO header files are BSD licensed so they can be easily used
by other projects (including other operating systems and hypervisors
that don't use Linux). Please see the license headers in
<linux/virtio_net.h> or <linux/virtio_blk.h>.
quoted
quoted
+/*
+ * Definitions for virtio I2C Adpter
+ *
+ * Copyright (c) 2021 Intel Corporation. All rights reserved.
+ */
+
+#ifndef _UAPI_LINUX_VIRTIO_I2C_H
+#define _UAPI_LINUX_VIRTIO_I2C_H
Why is this a uapi header? Can't this all be moved into the driver
itself?
Linux VIRTIO drivers provide a uapi header with structs and constants
that describe the device interface. This allows other software like
QEMU, other operating systems, etc to reuse these headers instead of
redefining everything.

These files should contain:
1. Device-specific feature bits (VIRTIO_<device>_F_<feature>)
2. VIRTIO Configuration Space layout (struct virtio_<device>_config)
3. Virtqueue request layout (struct virtio_<device>_<req/resp>)

For examples, see <linux/virtio_net.h> and <linux/virtio_blk.h>.
quoted
quoted
+/**
+ * struct virtio_i2c_req - the virtio I2C request structure
+ * @out_hdr: the OUT header of the virtio I2C message
+ * @write_buf: contains one I2C segment being written to the device
+ * @read_buf: contains one I2C segment being read from the device
+ * @in_hdr: the IN header of the virtio I2C message
+ */
+struct virtio_i2c_req {
+       struct virtio_i2c_out_hdr out_hdr;
+       u8 *write_buf;
+       u8 *read_buf;
+       struct virtio_i2c_in_hdr in_hdr;
+};
In particular, this structure looks like it is only ever usable between
the transfer functions in the driver itself, it is shared with neither
user space nor the virtio host side.
I agree. This struct is not part of the device interface. It's part of
the Linux driver implementation. This belongs inside the driver code and
not in include/uapi/ where public headers are located.

Stefan

Re: [PATCH v5] i2c: virtio: add a virtio i2c frontend driver

From: Arnd Bergmann <arnd@arndb.de>
Date: 2021-03-02 11:22:38

On Tue, Mar 2, 2021 at 10:51 AM Stefan Hajnoczi [off-list ref] wrote:
On Tue, Mar 02, 2021 at 10:42:06AM +0800, Jie Deng wrote:
quoted
quoted
quoted
+/*
+ * Definitions for virtio I2C Adpter
+ *
+ * Copyright (c) 2021 Intel Corporation. All rights reserved.
+ */
+
+#ifndef _UAPI_LINUX_VIRTIO_I2C_H
+#define _UAPI_LINUX_VIRTIO_I2C_H
Why is this a uapi header? Can't this all be moved into the driver
itself?
Linux VIRTIO drivers provide a uapi header with structs and constants
that describe the device interface. This allows other software like
QEMU, other operating systems, etc to reuse these headers instead of
redefining everything.

These files should contain:
1. Device-specific feature bits (VIRTIO_<device>_F_<feature>)
2. VIRTIO Configuration Space layout (struct virtio_<device>_config)
3. Virtqueue request layout (struct virtio_<device>_<req/resp>)

For examples, see <linux/virtio_net.h> and <linux/virtio_blk.h>.
Ok, makes sense. So it's not strictly uapi but just helpful for
virtio applications to reference these. I suppose it is slightly harder
when building qemu on other operating systems though, how does
it get these headers on BSD or Windows?

       Arnd
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

Re: [PATCH v5] i2c: virtio: add a virtio i2c frontend driver

From: Stefan Hajnoczi <stefanha@redhat.com>
Date: 2021-03-03 20:57:21

On Tue, Mar 02, 2021 at 11:54:02AM +0100, Arnd Bergmann wrote:
On Tue, Mar 2, 2021 at 10:51 AM Stefan Hajnoczi [off-list ref] wrote:
quoted
On Tue, Mar 02, 2021 at 10:42:06AM +0800, Jie Deng wrote:
quoted
quoted
quoted
+/*
+ * Definitions for virtio I2C Adpter
+ *
+ * Copyright (c) 2021 Intel Corporation. All rights reserved.
+ */
+
+#ifndef _UAPI_LINUX_VIRTIO_I2C_H
+#define _UAPI_LINUX_VIRTIO_I2C_H
Why is this a uapi header? Can't this all be moved into the driver
itself?
Linux VIRTIO drivers provide a uapi header with structs and constants
that describe the device interface. This allows other software like
QEMU, other operating systems, etc to reuse these headers instead of
redefining everything.

These files should contain:
1. Device-specific feature bits (VIRTIO_<device>_F_<feature>)
2. VIRTIO Configuration Space layout (struct virtio_<device>_config)
3. Virtqueue request layout (struct virtio_<device>_<req/resp>)

For examples, see <linux/virtio_net.h> and <linux/virtio_blk.h>.
Ok, makes sense. So it's not strictly uapi but just helpful for
virtio applications to reference these. I suppose it is slightly harder
when building qemu on other operating systems though, how does
it get these headers on BSD or Windows?
qemu.git imports Linux headers from time to time and can use them
instead of system headers:

  https://gitlab.com/qemu-project/qemu/-/blob/master/scripts/update-linux-headers.sh

Stefan
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help