Hi,
Arnd suggested (over IRC) to split this into two patches for better readability
and so here is a resend. The eventual specification hasn't changed at all.
V4->V5:
- Split into two patches.
V3->V4:
- Add a new mandatory feature flag.
V2->V3:
- Add conformance clauses that require that the flag is consistent with the
buffer.
V1->V2:
- Name the buffer-less request as zero-length request.
------
I did try to follow the discussion you guys had during V4, where we added
support for multiple buffers for the same request, which I think is unnecessary
now, after introduction of the VIRTIO_I2C_FLAGS_FAIL_NEXT flag.
https://lists.oasis-open.org/archives/virtio-comment/202011/msg00005.html
And so starting this discussion again, because we need to support stuff
like: i2cdetect -q <i2c-bus-number>, which issues a zero-length SMBus
Quick command.
Viresh Kumar (2):
virtio: i2c: No need to have separate read-write buffers
virtio: i2c: Allow zero-length transactions
virtio-i2c.tex | 76 ++++++++++++++++++++++++++++++--------------------
1 file changed, 45 insertions(+), 31 deletions(-)
--
2.31.1.272.g89b43f80a514
Hi,
This patchset simplifies the protocol and allows zero-length transactions, which
are required to support stuff like: i2cdetect -q <i2c-bus-number>, which issues
a zero-length SMBus Quick command.
V5->V6:
- s/SMBus Quick/the SMBus "Quick" command/
- Add a footnote and reword/rearrange few parts for more clarity.
V4->V5:
- Split into two patches.
V3->V4:
- Add a new mandatory feature flag.
V2->V3:
- Add conformance clauses that require that the flag is consistent with the
buffer.
V1->V2:
- Name the buffer-less request as zero-length request.
--
Viresh
Viresh Kumar (2):
virtio: i2c: No need to have separate read-write buffers
virtio: i2c: Allow zero-length transactions
virtio-i2c.tex | 90 +++++++++++++++++++++++++++++++-------------------
1 file changed, 56 insertions(+), 34 deletions(-)
--
2.31.1.272.g89b43f80a514
The I2C protocol allows zero-length requests with no data, like the
SMBus Quick command, where the command is inferred based on the
read/write flag itself.
In order to allow such a request, allocate another bit,
VIRTIO_I2C_FLAGS_M_RD(1), in the flags to pass the request type, as read
or write. This was earlier done using the read/write permission to the
buffer itself.
This still won't work well if multiple buffers are passed for the same
request, i.e. the write-read requests, as the VIRTIO_I2C_FLAGS_M_RD flag
can only be used with a single buffer.
Coming back to it, there is no need to send multiple buffers with a
single request. All we need, is a way to group several requests
together, which we can already do based on the
VIRTIO_I2C_FLAGS_FAIL_NEXT flag.
Remove support for multiple buffers within a single request.
Add a new feature flag for zero length requests and make it mandatory
for it to be implemented, so we don't need to drag the old
implementation around.
Fixes: https://github.com/oasis-tcs/virtio-spec/issues/112
Signed-off-by: Viresh Kumar <viresh.kumar(a)linaro.org>
---
V3->V4:
- Add a new mandatory feature flag.
V2->V3:
- Add conformance clauses that require that the flag is consistent with the
buffer.
V1->V2:
- Name the buffer-less request as zero-length request.
Hi Guys,
I did try to follow the discussion you guys had during V4, where we added
support for multiple buffers for the same request, which I think is unnecessary
now, after introduction of the VIRTIO_I2C_FLAGS_FAIL_NEXT flag.
https://lists.oasis-open.org/archives/virtio-comment/202011/msg00005.html
And so starting this discussion again, because we need to support stuff
like: i2cdetect -q <i2c-bus-number>, which issues a zero-length SMBus
Quick command.
---
virtio-i2c.tex | 76 ++++++++++++++++++++++++++++++--------------------
1 file changed, 45 insertions(+), 31 deletions(-)
diff --git a/virtio-i2c.tex b/virtio-i2c.tex
index 949d75f44158..0e73348963ce 100644
--- a/virtio-i2c.tex
+++ b/virtio-i2c.tex
@@ -17,7 +17,11 @@ \subsection{Virtqueues}\label{sec:Device Types / I2C Adapter Device / Virtqueues
\subsection{Feature bits}\label{sec:Device Types / I2C Adapter Device / Feature bits}
-None currently defined.
+\begin{description}
+\item[VIRTIO_I2C_F_ZERO_LENGTH_REQUEST (0)] The device supports zero-length I2C
+request and \field{VIRTIO_I2C_FLAGS_M_RD} flag. It is mandatory to implement
+this feature.
+\end{description}
\subsection{Device configuration layout}\label{sec:Device Types / I2C Adapter Device / Device configuration layout}
@@ -54,8 +58,7 @@ \subsubsection{Device Operation: Request Queue}\label{sec:Device Types / I2C Ada
\begin{lstlisting}
struct virtio_i2c_req {
struct virtio_i2c_out_hdr out_hdr;
- u8 write_buf[];
- u8 read_buf[];
+ u8 buf[];
struct virtio_i2c_in_hdr in_hdr;
};
\end{lstlisting}
@@ -84,16 +87,16 @@ \subsubsection{Device Operation: Request Queue}\label{sec:Device Types / I2C Ada
and sets it on the other requests. If this bit is set and a device fails
to process the current request, it needs to fail the next request instead
of attempting to execute it.
+
+\item[VIRTIO_I2C_FLAGS_M_RD(1)] is used to mark the request as READ or WRITE.
\end{description}
Other bits of \field{flags} are currently reserved as zero for future feature
extensibility.
-The \field{write_buf} of the request contains one segment of an I2C transaction
-being written to the device.
-
-The \field{read_buf} of the request contains one segment of an I2C transaction
-being read from the device.
+The \field{buf} of the request is optional and contains one segment of an I2C
+transaction being read from or written to the device, based on the value of the
+\field{VIRTIO_I2C_FLAGS_M_RD} bit in the \field{flags} field.
The final \field{status} byte of the request is written by the device: either
VIRTIO_I2C_MSG_OK for success or VIRTIO_I2C_MSG_ERR for error.
@@ -103,27 +106,27 @@ \subsubsection{Device Operation: Request Queue}\label{sec:Device Types / I2C Ada
#define VIRTIO_I2C_MSG_ERR 1
\end{lstlisting}
-If ``length of \field{read_buf}''=0 and ``length of \field{write_buf}''>0,
-the request is called write request.
+If \field{VIRTIO_I2C_FLAGS_M_RD} bit is set in the \field{flags}, then the
+request is called a read request.
-If ``length of \field{read_buf}''>0 and ``length of \field{write_buf}''=0,
-the request is called read request.
+If \field{VIRTIO_I2C_FLAGS_M_RD} bit is unset in the \field{flags}, then the
+request is called a write request.
-If ``length of \field{read_buf}''>0 and ``length of \field{write_buf}''>0,
-the request is called write-read request. It means an I2C write segment followed
-by a read segment. Usually, the write segment provides the number of an I2C
-controlled device register to be read.
+The \field{buf} is optional and will not be present for a zero-length request,
+like SMBus Quick.
-The case when ``length of \field{write_buf}''=0, and at the same time,
-``length of \field{read_buf}''=0 doesn't make any sense.
+The virtio I2C protocol supports write-read requests, i.e. an I2C write segment
+followed by a read segment (usually, the write segment provides the number of an
+I2C controlled device register to be read), by grouping a list of requests
+together using the \field{VIRTIO_I2C_FLAGS_FAIL_NEXT} flag.
\subsubsection{Device Operation: Operation Status}\label{sec:Device Types / I2C Adapter Device / Device Operation: Operation Status}
-\field{addr}, \field{flags}, ``length of \field{write_buf}'' and ``length of \field{read_buf}''
-are determined by the driver, while \field{status} is determined by the processing
-of the device. A driver puts the data written to the device into \field{write_buf}, while
-a device puts the data of the corresponding length into \field{read_buf} according to the
-request of the driver.
+\field{addr}, \field{flags}, and ``length of \field{buf}'' are determined by the
+driver, while \field{status} is determined by the processing of the device. A
+driver, for a write request, puts the data to be written to the device into the
+\field{buf}, while a device, for a read request, puts the data read from device
+into the \field{buf} according to the request from the driver.
A driver may send one request or multiple requests to the device at a time.
The requests in the virtqueue are both queued and processed in order.
@@ -137,15 +140,22 @@ \subsubsection{Device Operation: Operation Status}\label{sec:Device Types / I2C
\drivernormative{\subsubsection}{Device Operation}{Device Types / I2C Adapter Device / Device Operation}
+A driver SHOULD implement the VIRTIO_I2C_F_ZERO_LENGTH_REQUEST feature.
+
A driver MUST set \field{addr} and \field{flags} before sending the request.
A driver MUST set the reserved bits of \field{flags} to be zero.
-The driver MUST NOT send a request with ``length of \field{write_buf}''=0 and
-``length of \field{read_buf}''=0 at the same time.
+A driver MUST NOT send the \field{buf}, for a zero-length request.
+
+A driver MUST NOT use \field{buf}, for a read request, if the final
+\field{status} returned from the device is VIRTIO_I2C_MSG_ERR.
+
+A driver MUST set the \field{VIRTIO_I2C_FLAGS_M_RD} flag for a read operation,
+where the buffer is write-only for the device.
-A driver MUST NOT use \field{read_buf} if the final \field{status} returned
-from the device is VIRTIO_I2C_MSG_ERR.
+A driver MUST NOT set the \field{VIRTIO_I2C_FLAGS_M_RD} flag for a write
+operation, where the buffer is read-only for the device.
A driver MUST queue the requests in order if multiple requests are going to
be sent at a time.
@@ -157,14 +167,18 @@ \subsubsection{Device Operation: Operation Status}\label{sec:Device Types / I2C
\devicenormative{\subsubsection}{Device Operation}{Device Types / I2C Adapter Device / Device Operation}
+A device SHOULD implement the VIRTIO_I2C_F_ZERO_LENGTH_REQUEST feature.
+
A device SHOULD keep consistent behaviors with the hardware as described in
\hyperref[intro:I2C]{I2C}.
-A device MUST NOT change the value of \field{addr}, reserved bits of \field{flags}
-and \field{write_buf}.
+A device MUST NOT change the value of \field{addr}, and reserved bits of
+\field{flags}.
+
+A device MUST not change the value of the \field{buf} for a write request.
-A device MUST place one I2C segment of the corresponding length into \field{read_buf}
-according the driver's request.
+A device MUST place one I2C segment of the ``length of \field{buf}'', for the
+read request, into the \field{buf} according the driver's request.
A device MUST guarantee the requests in the virtqueue being processed in order
if multiple requests are received at a time.
--
2.31.1.272.g89b43f80a514
On 05. 10. 21 7:31, Manish DUBEY wrote:
> Hello Team,
>
> Hope you are doing well.
>
> We have some users in ST environment being subscribed to your Mailing list. After few days they use to get an email stating that "Your membership in the mailing list has been disabled due to excessive bounces"..
>
> We have verified at our end and didn't find any bounce back email getting generated. To investigate the case, could you please share couple of sample bounce back (NDR) email received by you from ST environment. The NDR may help us to investigate the cause of bounce back email getting generated.
>
> If possible, we can schedule a call as well to discuss the case. Feel free to share your availability to discuss the case and we can share a Teams invite accordingly.
> Awaiting your response.
It seems like a DMARC verification issue on your side:
Oct 5 07:29:12 alsa0 postfix/smtp[23459]: AFEC9839:
to=<arnaud.pouliquen(a)foss.st.com>,
relay=mxa-00178001.gslb.pphosted.com[185.132.182.106]:25, delay=51,
delays=50/0.19/0.48/0.33, dsn=5.7.0, status=bounced (host
mxa-00178001.gslb.pphosted.com[185.132.182.106] said: 550 5.7.0 Local Policy
Violation - DMARC Reject (in reply to end of DATA command))
Jaroslav
--
Jaroslav Kysela <perex(a)perex.cz>
Linux Sound Maintainer; ALSA Project; Red Hat, Inc.
Currently the GPIO Aggregator does not support interrupts. This means
that kernel drivers going from a GPIO to an IRQ using gpiod_to_irq(),
and userspace applications using line events do not work.
Add interrupt support by providing a gpio_chip.to_irq() callback, which
just calls into the parent GPIO controller.
Note that this does not implement full interrupt controller (irq_chip)
support, so using e.g. gpio-keys with "interrupts" instead of "gpios"
still does not work.
Signed-off-by: Geert Uytterhoeven <geert+renesas(a)glider.be>
---
I would prefer to avoid implementing irq_chip support, until there is a
real use case for this.
This has been tested with gpio-keys and gpiomon on the Koelsch
development board:
- gpio-keys, using a DT overlay[1]:
$ overlay add r8a7791-koelsch-keyboard-controlled-led
$ echo gpio-aggregator > /sys/devices/platform/frobnicator/driver_override
$ echo frobnicator > /sys/bus/platform/drivers/gpio-aggregator/bind
$ gpioinfo frobnicator
gpiochip12 - 3 lines:
line 0: "light" "light" output active-high [used]
line 1: "on" "On" input active-low [used]
line 2: "off" "Off" input active-low [used]
$ echo 255 > /sys/class/leds/light/brightness
$ echo 0 > /sys/class/leds/light/brightness
$ evtest /dev/input/event0
- gpiomon, using the GPIO sysfs API:
$ echo keyboard > /sys/bus/platform/drivers/gpio-keys/unbind
$ echo e6055800.gpio 2,6 > /sys/bus/platform/drivers/gpio-aggregator/new_device
$ gpiomon gpiochip12 0 1
[1] "ARM: dts: koelsch: Add overlay for keyboard-controlled LED"
https://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers.git/c…
---
drivers/gpio/gpio-aggregator.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/drivers/gpio/gpio-aggregator.c b/drivers/gpio/gpio-aggregator.c
index 34e35b64dcdc0581..2ff867d2a3630d3b 100644
--- a/drivers/gpio/gpio-aggregator.c
+++ b/drivers/gpio/gpio-aggregator.c
@@ -374,6 +374,13 @@ static int gpio_fwd_set_config(struct gpio_chip *chip, unsigned int offset,
return gpiod_set_config(fwd->descs[offset], config);
}
+static int gpio_fwd_to_irq(struct gpio_chip *chip, unsigned int offset)
+{
+ struct gpiochip_fwd *fwd = gpiochip_get_data(chip);
+
+ return gpiod_to_irq(fwd->descs[offset]);
+}
+
/**
* gpiochip_fwd_create() - Create a new GPIO forwarder
* @dev: Parent device pointer
@@ -414,7 +421,8 @@ static struct gpiochip_fwd *gpiochip_fwd_create(struct device *dev,
for (i = 0; i < ngpios; i++) {
struct gpio_chip *parent = gpiod_to_chip(descs[i]);
- dev_dbg(dev, "%u => gpio-%d\n", i, desc_to_gpio(descs[i]));
+ dev_dbg(dev, "%u => gpio %d irq %d\n", i,
+ desc_to_gpio(descs[i]), gpiod_to_irq(descs[i]));
if (gpiod_cansleep(descs[i]))
chip->can_sleep = true;
@@ -432,6 +440,7 @@ static struct gpiochip_fwd *gpiochip_fwd_create(struct device *dev,
chip->get_multiple = gpio_fwd_get_multiple_locked;
chip->set = gpio_fwd_set;
chip->set_multiple = gpio_fwd_set_multiple_locked;
+ chip->to_irq = gpio_fwd_to_irq;
chip->base = -1;
chip->ngpio = ngpios;
fwd->descs = descs;
--
2.25.1
Hi,
One of the goals of Project Stratos is to enable hypervisor agnostic
backends so we can enable as much re-use of code as possible and avoid
repeating ourselves. This is the flip side of the front end where
multiple front-end implementations are required - one per OS, assuming
you don't just want Linux guests. The resultant guests are trivially
movable between hypervisors modulo any abstracted paravirt type
interfaces.
In my original thumb nail sketch of a solution I envisioned vhost-user
daemons running in a broadly POSIX like environment. The interface to
the daemon is fairly simple requiring only some mapped memory and some
sort of signalling for events (on Linux this is eventfd). The idea was a
stub binary would be responsible for any hypervisor specific setup and
then launch a common binary to deal with the actual virtqueue requests
themselves.
Since that original sketch we've seen an expansion in the sort of ways
backends could be created. There is interest in encapsulating backends
in RTOSes or unikernels for solutions like SCMI. There interest in Rust
has prompted ideas of using the trait interface to abstract differences
away as well as the idea of bare-metal Rust backends.
We have a card (STR-12) called "Hypercall Standardisation" which
calls for a description of the APIs needed from the hypervisor side to
support VirtIO guests and their backends. However we are some way off
from that at the moment as I think we need to at least demonstrate one
portable backend before we start codifying requirements. To that end I
want to think about what we need for a backend to function.
Configuration
=============
In the type-2 setup this is typically fairly simple because the host
system can orchestrate the various modules that make up the complete
system. In the type-1 case (or even type-2 with delegated service VMs)
we need some sort of mechanism to inform the backend VM about key
details about the system:
- where virt queue memory is in it's address space
- how it's going to receive (interrupt) and trigger (kick) events
- what (if any) resources the backend needs to connect to
Obviously you can elide over configuration issues by having static
configurations and baking the assumptions into your guest images however
this isn't scalable in the long term. The obvious solution seems to be
extending a subset of Device Tree data to user space but perhaps there
are other approaches?
Before any virtio transactions can take place the appropriate memory
mappings need to be made between the FE guest and the BE guest.
Currently the whole of the FE guests address space needs to be visible
to whatever is serving the virtio requests. I can envision 3 approaches:
* BE guest boots with memory already mapped
This would entail the guest OS knowing where in it's Guest Physical
Address space is already taken up and avoiding clashing. I would assume
in this case you would want a standard interface to userspace to then
make that address space visible to the backend daemon.
* BE guests boots with a hypervisor handle to memory
The BE guest is then free to map the FE's memory to where it wants in
the BE's guest physical address space. To activate the mapping will
require some sort of hypercall to the hypervisor. I can see two options
at this point:
- expose the handle to userspace for daemon/helper to trigger the
mapping via existing hypercall interfaces. If using a helper you
would have a hypervisor specific one to avoid the daemon having to
care too much about the details or push that complexity into a
compile time option for the daemon which would result in different
binaries although a common source base.
- expose a new kernel ABI to abstract the hypercall differences away
in the guest kernel. In this case the userspace would essentially
ask for an abstract "map guest N memory to userspace ptr" and let
the kernel deal with the different hypercall interfaces. This of
course assumes the majority of BE guests would be Linux kernels and
leaves the bare-metal/unikernel approaches to their own devices.
Operation
=========
The core of the operation of VirtIO is fairly simple. Once the
vhost-user feature negotiation is done it's a case of receiving update
events and parsing the resultant virt queue for data. The vhost-user
specification handles a bunch of setup before that point, mostly to
detail where the virt queues are set up FD's for memory and event
communication. This is where the envisioned stub process would be
responsible for getting the daemon up and ready to run. This is
currently done inside a big VMM like QEMU but I suspect a modern
approach would be to use the rust-vmm vhost crate. It would then either
communicate with the kernel's abstracted ABI or be re-targeted as a
build option for the various hypervisors.
One question is how to best handle notification and kicks. The existing
vhost-user framework uses eventfd to signal the daemon (although QEMU
is quite capable of simulating them when you use TCG). Xen has it's own
IOREQ mechanism. However latency is an important factor and having
events go through the stub would add quite a lot.
Could we consider the kernel internally converting IOREQ messages from
the Xen hypervisor to eventfd events? Would this scale with other kernel
hypercall interfaces?
So any thoughts on what directions are worth experimenting with?
--
Alex Bennée
The I2C protocol allows zero-length requests with no data, like the
SMBus Quick command, where the command is inferred based on the
read/write flag itself.
In order to allow such a request, allocate another bit,
VIRTIO_I2C_FLAGS_M_RD(1), in the flags to pass the request type, as read
or write. This was earlier done using the read/write permission to the
buffer itself.
This still won't work well if multiple buffers are passed for the same
request, i.e. the write-read requests, as the VIRTIO_I2C_FLAGS_M_RD flag
can only be used with a single buffer.
Coming back to it, there is no need to send multiple buffers with a
single request. All we need, is a way to group several requests
together, which we can already do based on the
VIRTIO_I2C_FLAGS_FAIL_NEXT flag.
Remove support for multiple buffers within a single request.
Since we are at very early stage of development currently, we can do
these modifications without addition of new features or versioning of
the protocol.
Signed-off-by: Viresh Kumar <viresh.kumar(a)linaro.org>
---
V2->V3:
- Add conformance clauses that require that the flag is consistent with the
buffer.
V1->V2:
- Name the buffer-less request as zero-length request.
Hi Guys,
I did try to follow the discussion you guys had during V4, where we added
support for multiple buffers for the same request, which I think is unnecessary
now, after introduction of the VIRTIO_I2C_FLAGS_FAIL_NEXT flag.
https://lists.oasis-open.org/archives/virtio-comment/202011/msg00005.html
And so starting this discussion again, because we need to support stuff
like: i2cdetect -q <i2c-bus-number>, which issues a zero-length SMBus
Quick command.
---
virtio-i2c.tex | 66 +++++++++++++++++++++++++++-----------------------
1 file changed, 36 insertions(+), 30 deletions(-)
diff --git a/virtio-i2c.tex b/virtio-i2c.tex
index 949d75f44158..c7335372a8bb 100644
--- a/virtio-i2c.tex
+++ b/virtio-i2c.tex
@@ -54,8 +54,7 @@ \subsubsection{Device Operation: Request Queue}\label{sec:Device Types / I2C Ada
\begin{lstlisting}
struct virtio_i2c_req {
struct virtio_i2c_out_hdr out_hdr;
- u8 write_buf[];
- u8 read_buf[];
+ u8 buf[];
struct virtio_i2c_in_hdr in_hdr;
};
\end{lstlisting}
@@ -84,16 +83,16 @@ \subsubsection{Device Operation: Request Queue}\label{sec:Device Types / I2C Ada
and sets it on the other requests. If this bit is set and a device fails
to process the current request, it needs to fail the next request instead
of attempting to execute it.
+
+\item[VIRTIO_I2C_FLAGS_M_RD(1)] is used to mark the request as READ or WRITE.
\end{description}
Other bits of \field{flags} are currently reserved as zero for future feature
extensibility.
-The \field{write_buf} of the request contains one segment of an I2C transaction
-being written to the device.
-
-The \field{read_buf} of the request contains one segment of an I2C transaction
-being read from the device.
+The \field{buf} of the request is optional and contains one segment of an I2C
+transaction being read from or written to the device, based on the value of the
+\field{VIRTIO_I2C_FLAGS_M_RD} bit in the \field{flags} field.
The final \field{status} byte of the request is written by the device: either
VIRTIO_I2C_MSG_OK for success or VIRTIO_I2C_MSG_ERR for error.
@@ -103,27 +102,27 @@ \subsubsection{Device Operation: Request Queue}\label{sec:Device Types / I2C Ada
#define VIRTIO_I2C_MSG_ERR 1
\end{lstlisting}
-If ``length of \field{read_buf}''=0 and ``length of \field{write_buf}''>0,
-the request is called write request.
+If \field{VIRTIO_I2C_FLAGS_M_RD} bit is set in the \field{flags}, then the
+request is called a read request.
-If ``length of \field{read_buf}''>0 and ``length of \field{write_buf}''=0,
-the request is called read request.
+If \field{VIRTIO_I2C_FLAGS_M_RD} bit is unset in the \field{flags}, then the
+request is called a write request.
-If ``length of \field{read_buf}''>0 and ``length of \field{write_buf}''>0,
-the request is called write-read request. It means an I2C write segment followed
-by a read segment. Usually, the write segment provides the number of an I2C
-controlled device register to be read.
+The \field{buf} is optional and will not be present for a zero-length request,
+like SMBus Quick.
-The case when ``length of \field{write_buf}''=0, and at the same time,
-``length of \field{read_buf}''=0 doesn't make any sense.
+The virtio I2C protocol supports write-read requests, i.e. an I2C write segment
+followed by a read segment (usually, the write segment provides the number of an
+I2C controlled device register to be read), by grouping a list of requests
+together using the \field{VIRTIO_I2C_FLAGS_FAIL_NEXT} flag.
\subsubsection{Device Operation: Operation Status}\label{sec:Device Types / I2C Adapter Device / Device Operation: Operation Status}
-\field{addr}, \field{flags}, ``length of \field{write_buf}'' and ``length of \field{read_buf}''
-are determined by the driver, while \field{status} is determined by the processing
-of the device. A driver puts the data written to the device into \field{write_buf}, while
-a device puts the data of the corresponding length into \field{read_buf} according to the
-request of the driver.
+\field{addr}, \field{flags}, and ``length of \field{buf}'' are determined by the
+driver, while \field{status} is determined by the processing of the device. A
+driver, for a write request, puts the data to be written to the device into the
+\field{buf}, while a device, for a read request, puts the data read from device
+into the \field{buf} according to the request from the driver.
A driver may send one request or multiple requests to the device at a time.
The requests in the virtqueue are both queued and processed in order.
@@ -141,11 +140,16 @@ \subsubsection{Device Operation: Operation Status}\label{sec:Device Types / I2C
A driver MUST set the reserved bits of \field{flags} to be zero.
-The driver MUST NOT send a request with ``length of \field{write_buf}''=0 and
-``length of \field{read_buf}''=0 at the same time.
+A driver MUST NOT send the \field{buf}, for a zero-length request.
+
+A driver MUST NOT use \field{buf}, for a read request, if the final
+\field{status} returned from the device is VIRTIO_I2C_MSG_ERR.
-A driver MUST NOT use \field{read_buf} if the final \field{status} returned
-from the device is VIRTIO_I2C_MSG_ERR.
+A driver MUST set the \field{VIRTIO_I2C_FLAGS_M_RD} flag for a read operation,
+where the buffer is write-only for the device.
+
+A driver MUST NOT set the \field{VIRTIO_I2C_FLAGS_M_RD} flag for a write
+operation, where the buffer is read-only for the device.
A driver MUST queue the requests in order if multiple requests are going to
be sent at a time.
@@ -160,11 +164,13 @@ \subsubsection{Device Operation: Operation Status}\label{sec:Device Types / I2C
A device SHOULD keep consistent behaviors with the hardware as described in
\hyperref[intro:I2C]{I2C}.
-A device MUST NOT change the value of \field{addr}, reserved bits of \field{flags}
-and \field{write_buf}.
+A device MUST NOT change the value of \field{addr}, and reserved bits of
+\field{flags}.
+
+A device MUST not change the value of the \field{buf} for a write request.
-A device MUST place one I2C segment of the corresponding length into \field{read_buf}
-according the driver's request.
+A device MUST place one I2C segment of the ``length of \field{buf}'', for the
+read request, into the \field{buf} according the driver's request.
A device MUST guarantee the requests in the virtqueue being processed in order
if multiple requests are received at a time.
--
2.31.1.272.g89b43f80a514