virtio: i2c: Allow zero-length transactions
v6 cover virtio: i2c: Allow zero-length transactions
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(-)
Signature · 1 line
2.31.1.272.g89b43f80a514
PATCH v6 1/2 virtio: i2c: No need to have separate read-write buffers
The virtio I2C protocol allows to contain multiple read-write requests in a single I2C transaction using the VIRTIO_I2C_FLAGS_FAIL_NEXT flag, where each request contains a header, buffer and status.
There is no need to pass both read and write buffers in a single request, as we have a better way of combining requests into a single I2C transaction. Moreover, this also limits the transactions to two buffers, one for read operation and one for write. By using VIRTIO_I2C_FLAGS_FAIL_NEXT, we don't have any such limits.
Remove support for multiple buffers within a single request.
--- virtio-i2c.tex | 54 +++++++++++++++++++------------------------------- 1 file changed, 20 insertions(+), 34 deletions(-)
virtio-i2c.tex +20 -34
@@ -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}
@@ -89,11 +88,8 @@ \subsubsection{Device Operation: Request Queue}\label{sec:Device Types / I2C Ada 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 contains one segment of an I2C transaction +being read from or written to the device. 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 +99,18 @@ \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 ``length of \field{read_buf}''>0 and ``length of \field{write_buf}''=0, -the request is called read 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 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 +128,8 @@ \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 use \field{read_buf} if the final \field{status} returned -from the device is VIRTIO_I2C_MSG_ERR. +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 queue the requests in order if multiple requests are going to be sent at a time.
@@ -160,11 +144,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.
Signature · 1 line
2.31.1.272.g89b43f80a514
PATCH v6 2/2 virtio: i2c: Allow zero-length transactions
In reply to Viresh KumarThe 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.
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.
--- virtio-i2c.tex | 42 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 39 insertions(+), 3 deletions(-)
virtio-i2c.tex +39 -3
@@ -17,7 +17,21 @@ \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} + +\begin{note} +The \field{VIRTIO_I2C_FLAGS_M_RD} flag was not present in the initial +implementation of the specification and the direction of the transfer (read or +write) was inferred from the permissions (read-only or write-only) of the +buffer itself. There is no need of having backwards compatibility for the older +specification and so the \field{VIRTIO_I2C_FLAGS_FAIL_NEXT} feature is made +mandatory. The driver should abort negotiation with the device, if the device +doesn't offer this feature. +\end{note} \subsection{Device configuration layout}\label{sec:Device Types / I2C Adapter Device / Device configuration layout}
@@ -83,13 +97,20 @@ \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. + If \field{VIRTIO_I2C_FLAGS_M_RD} bit is set in the \field{flags}, then the + request is called a read request. If \field{VIRTIO_I2C_FLAGS_M_RD} bit is + unset in the \field{flags}, then the request is called a write request. \end{description} Other bits of \field{flags} are currently reserved as zero for future feature extensibility. -The \field{buf} of the request contains one segment of an I2C transaction -being read from or written to the device. +The \field{buf} is optional and will not be present for a zero-length request, +like the SMBus "Quick" command. The \field{buf} 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.
@@ -124,13 +145,25 @@ \subsubsection{Device Operation: Operation Status}\label{sec:Device Types / I2C \drivernormative{\subsubsection}{Device Operation}{Device Types / I2C Adapter Device / Device Operation} +A driver MUST accept the \field{VIRTIO_I2C_F_ZERO_LENGTH_REQUEST} feature and +MUST abort negotiation with the device, if the device doesn't offer this +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. +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 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.
@@ -141,6 +174,9 @@ \subsubsection{Device Operation: Operation Status}\label{sec:Device Types / I2C \devicenormative{\subsubsection}{Device Operation}{Device Types / I2C Adapter Device / Device Operation} +A device MUST offer the \field{VIRTIO_I2C_F_ZERO_LENGTH_REQUEST} feature and +MUST reject any driver that doesn't negotiate this feature. + A device SHOULD keep consistent behaviors with the hardware as described in \hyperref[intro:I2C]{I2C}.
Signature · 1 line
2.31.1.272.g89b43f80a514