OASIS Mailing List ArchivesView the OASIS mailing list archive below
or browse/search using MarkMail.

 


Help: OASIS Mailing Lists Help | MarkMail Help

virtio-comment message

[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]


Subject: [PATCH 1/6] virtio-scsi: Maintain scsi device spec in separate file


Move virtio-scsi device specification to its own file similar to
recent virtio devices.

Fixes: https://github.com/oasis-tcs/virtio-spec/issues/153
Signed-off-by: Parav Pandit <parav@nvidia.com>
---
 content.tex     | 711 +-----------------------------------------------
 virtio-scsi.tex | 711 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 712 insertions(+), 710 deletions(-)
 create mode 100644 virtio-scsi.tex

diff --git a/content.tex b/content.tex
index 96f4723..1652165 100644
--- a/content.tex
+++ b/content.tex
@@ -6822,716 +6822,7 @@ \subsubsection{Free Page Reporting}\label{sec:Device Types / Memory Balloon Devi
 MUST NOT modify the the content of a reported page to a value other than
 \field{poison_val}.
 
-\section{SCSI Host Device}\label{sec:Device Types / SCSI Host Device}
-
-The virtio SCSI host device groups together one or more virtual
-logical units (such as disks), and allows communicating to them
-using the SCSI protocol. An instance of the device represents a
-SCSI host to which many targets and LUNs are attached.
-
-The virtio SCSI device services two kinds of requests:
-\begin{itemize}
-\item command requests for a logical unit;
-
-\item task management functions related to a logical unit, target or
-  command.
-\end{itemize}
-
-The device is also able to send out notifications about added and
-removed logical units. Together, these capabilities provide a
-SCSI transport protocol that uses virtqueues as the transfer
-medium. In the transport protocol, the virtio driver acts as the
-initiator, while the virtio SCSI host provides one or more
-targets that receive and process the requests.
-
-This section relies on definitions from \hyperref[intro:SAM]{SAM}.
-
-\subsection{Device ID}\label{sec:Device Types / SCSI Host Device / Device ID}
-  8
-
-\subsection{Virtqueues}\label{sec:Device Types / SCSI Host Device / Virtqueues}
-
-\begin{description}
-\item[0] controlq
-\item[1] eventq
-\item[2\ldots n] request queues
-\end{description}
-
-\subsection{Feature bits}\label{sec:Device Types / SCSI Host Device / Feature bits}
-
-\begin{description}
-\item[VIRTIO_SCSI_F_INOUT (0)] A single request can include both
-    device-readable and device-writable data buffers.
-
-\item[VIRTIO_SCSI_F_HOTPLUG (1)] The host SHOULD enable reporting of
-    hot-plug and hot-unplug events for LUNs and targets on the SCSI bus.
-    The guest SHOULD handle hot-plug and hot-unplug events.
-
-\item[VIRTIO_SCSI_F_CHANGE (2)] The host will report changes to LUN
-    parameters via a VIRTIO_SCSI_T_PARAM_CHANGE event; the guest
-    SHOULD handle them.
-
-\item[VIRTIO_SCSI_F_T10_PI (3)] The extended fields for T10 protection
-    information (DIF/DIX) are included in the SCSI request header.
-\end{description}
-
-\subsection{Device configuration layout}\label{sec:Device Types / SCSI Host Device / Device configuration layout}
-
-  All fields of this configuration are always available.
-
-\begin{lstlisting}
-struct virtio_scsi_config {
-        le32 num_queues;
-        le32 seg_max;
-        le32 max_sectors;
-        le32 cmd_per_lun;
-        le32 event_info_size;
-        le32 sense_size;
-        le32 cdb_size;
-        le16 max_channel;
-        le16 max_target;
-        le32 max_lun;
-};
-\end{lstlisting}
-
-\begin{description}
-\item[\field{num_queues}] is the total number of request virtqueues exposed by
-    the device. The driver MAY use only one request queue,
-    or it can use more to achieve better performance.
-
-\item[\field{seg_max}] is the maximum number of segments that can be in a
-    command. A bidirectional command can include \field{seg_max} input
-    segments and \field{seg_max} output segments.
-
-\item[\field{max_sectors}] is a hint to the driver about the maximum transfer
-    size to use.
-
-\item[\field{cmd_per_lun}] tells the driver the maximum number of
-    linked commands it can send to one LUN.
-
-\item[\field{event_info_size}] is the maximum size that the device will fill
-    for buffers that the driver places in the eventq. It is
-    written by the device depending on the set of negotiated
-    features.
-
-\item[\field{sense_size}] is the maximum size of the sense data that the
-    device will write. The default value is written by the device
-    and MUST be 96, but the driver can modify it. It is
-    restored to the default when the device is reset.
-
-\item[\field{cdb_size}] is the maximum size of the CDB that the driver will
-    write. The default value is written by the device and MUST
-    be 32, but the driver can likewise modify it. It is
-    restored to the default when the device is reset.
-
-\item[\field{max_channel}, \field{max_target} and \field{max_lun}] can be
-    used by the driver as hints to constrain scanning the logical units
-    on the host to channel/target/logical unit numbers that are less than
-    or equal to the value of the fields.  \field{max_channel} SHOULD
-    be zero.  \field{max_target} SHOULD be less than or equal to 255.
-    \field{max_lun} SHOULD be less than or equal to 16383.
-\end{description}
-
-\drivernormative{\subsubsection}{Device configuration layout}{Device Types / SCSI Host Device / Device configuration layout}
-
-The driver MUST NOT write to device configuration fields other than
-\field{sense_size} and \field{cdb_size}.
-
-The driver MUST NOT send more than \field{cmd_per_lun} linked commands
-to one LUN, and MUST NOT send more than the virtqueue size number of
-linked commands to one LUN.
-
-\devicenormative{\subsubsection}{Device configuration layout}{Device Types / SCSI Host Device / Device configuration layout}
-
-On reset, the device MUST set \field{sense_size} to 96 and
-\field{cdb_size} to 32.
-
-\subsubsection{Legacy Interface: Device configuration layout}\label{sec:Device Types / SCSI Host Device / Device configuration layout / Legacy Interface: Device configuration layout}
-When using the legacy interface, transitional devices and drivers
-MUST format the fields in struct virtio_scsi_config
-according to the native endian of the guest rather than
-(necessarily when not using the legacy interface) little-endian.
-
-\devicenormative{\subsection}{Device Initialization}{Device Types / SCSI Host Device / Device Initialization}
-
-On initialization the driver SHOULD first discover the
-device's virtqueues.
-
-If the driver uses the eventq, the driver SHOULD place at least one
-buffer in the eventq.
-
-The driver MAY immediately issue requests\footnote{For example, INQUIRY
-or REPORT LUNS.} or task management functions\footnote{For example, I_T
-RESET.}.
-
-\subsection{Device Operation}\label{sec:Device Types / SCSI Host Device / Device Operation}
-
-Device operation consists of operating request queues, the control
-queue and the event queue.
-
-\paragraph{Legacy Interface: Device Operation}\label{sec:Device
-Types / SCSI Host Device / Device Operation / Legacy
-Interface: Device Operation}
-When using the legacy interface, the driver SHOULD ignore the
-used length values.
-\begin{note}
-Historically, devices put the total descriptor length,
-or the total length of device-writable buffers there,
-even when only part of the buffers were actually written.
-\end{note}
-
-\subsubsection{Device Operation: Request Queues}\label{sec:Device Types / SCSI Host Device / Device Operation / Device Operation: Request Queues}
-
-The driver queues requests to an arbitrary request queue, and
-they are used by the device on that same queue. It is the
-responsibility of the driver to ensure strict request ordering
-for commands placed on different queues, because they will be
-consumed with no order constraints.
-
-Requests have the following format:
-
-\begin{lstlisting}
-struct virtio_scsi_req_cmd {
-        // Device-readable part
-        u8 lun[8];
-        le64 id;
-        u8 task_attr;
-        u8 prio;
-        u8 crn;
-        u8 cdb[cdb_size];
-        // The next three fields are only present if VIRTIO_SCSI_F_T10_PI
-        // is negotiated.
-        le32 pi_bytesout;
-        le32 pi_bytesin;
-        u8 pi_out[pi_bytesout];
-        u8 dataout[];
-
-        // Device-writable part
-        le32 sense_len;
-        le32 residual;
-        le16 status_qualifier;
-        u8 status;
-        u8 response;
-        u8 sense[sense_size];
-        // The next field is only present if VIRTIO_SCSI_F_T10_PI
-        // is negotiated
-        u8 pi_in[pi_bytesin];
-        u8 datain[];
-};
-
-
-/* command-specific response values */
-#define VIRTIO_SCSI_S_OK                0
-#define VIRTIO_SCSI_S_OVERRUN           1
-#define VIRTIO_SCSI_S_ABORTED           2
-#define VIRTIO_SCSI_S_BAD_TARGET        3
-#define VIRTIO_SCSI_S_RESET             4
-#define VIRTIO_SCSI_S_BUSY              5
-#define VIRTIO_SCSI_S_TRANSPORT_FAILURE 6
-#define VIRTIO_SCSI_S_TARGET_FAILURE    7
-#define VIRTIO_SCSI_S_NEXUS_FAILURE     8
-#define VIRTIO_SCSI_S_FAILURE           9
-
-/* task_attr */
-#define VIRTIO_SCSI_S_SIMPLE            0
-#define VIRTIO_SCSI_S_ORDERED           1
-#define VIRTIO_SCSI_S_HEAD              2
-#define VIRTIO_SCSI_S_ACA               3
-\end{lstlisting}
-
-\field{lun} addresses the REPORT LUNS well-known logical unit, or
-a target and logical unit in the virtio-scsi device's SCSI domain.
-When used to address the REPORT LUNS logical unit, \field{lun} is 0xC1,
-0x01 and six zero bytes.  The virtio-scsi device SHOULD implement the
-REPORT LUNS well-known logical unit.
-
-When used to address a target and logical unit, the only supported format
-for \field{lun} is: first byte set to 1, second byte set to target,
-third and fourth byte representing a single level LUN structure, followed
-by four zero bytes. With this representation, a virtio-scsi device can
-serve up to 256 targets and 16384 LUNs per target.  The device MAY also
-support having a well-known logical units in the third and fourth byte.
-
-\field{id} is the command identifier (``tag'').
-
-\field{task_attr} defines the task attribute as in the table above, but
-all task attributes MAY be mapped to SIMPLE by the device.  Some commands
-are defined by SCSI standards as "implicit head of queue"; for such
-commands, all task attributes MAY also be mapped to HEAD OF QUEUE.
-Drivers and applications SHOULD NOT send a command with the ORDERED
-task attribute if the command has an implicit HEAD OF QUEUE attribute,
-because whether the ORDERED task attribute is honored is vendor-specific.
-
-\field{crn} may also be provided by clients, but is generally expected
-to be 0. The maximum CRN value defined by the protocol is 255, since
-CRN is stored in an 8-bit integer.
-
-The CDB is included in \field{cdb} and its size, \field{cdb_size},
-is taken from the configuration space.
-
-All of these fields are defined in \hyperref[intro:SAM]{SAM} and are
-always device-readable.
-
-\field{pi_bytesout} determines the size of the \field{pi_out} field
-in bytes.  If it is nonzero, the \field{pi_out} field contains outgoing
-protection information for write operations.  \field{pi_bytesin} determines
-the size of the \field{pi_in} field in the device-writable section, in bytes.
-All three fields are only present if VIRTIO_SCSI_F_T10_PI has been negotiated.
-
-The remainder of the device-readable part is the data output buffer,
-\field{dataout}.
-
-\field{sense} and subsequent fields are always device-writable. \field{sense_len}
-indicates the number of bytes actually written to the sense
-buffer.
-
-\field{residual} indicates the residual size,
-calculated as ``data_length - number_of_transferred_bytes'', for
-read or write operations. For bidirectional commands, the
-number_of_transferred_bytes includes both read and written bytes.
-A \field{residual} that is less than the size of \field{datain} means that
-\field{dataout} was processed entirely. A \field{residual} that
-exceeds the size of \field{datain} means that \field{dataout} was
-processed partially and \field{datain} was not processed at
-all.
-
-If the \field{pi_bytesin} is nonzero, the \field{pi_in} field contains
-incoming protection information for read operations.  \field{pi_in} is
-only present if VIRTIO_SCSI_F_T10_PI has been negotiated\footnote{There
-  is no separate residual size for \field{pi_bytesout} and
-  \field{pi_bytesin}.  It can be computed from the \field{residual} field,
-  the size of the data integrity information per sector, and the sizes
-  of \field{pi_out}, \field{pi_in}, \field{dataout} and \field{datain}.}.
-
-The remainder of the device-writable part is the data input buffer,
-\field{datain}.
-
-
-\devicenormative{\paragraph}{Device Operation: Request Queues}{Device Types / SCSI Host Device / Device Operation / Device Operation: Request Queues}
-
-The device MUST write the \field{status} byte as the status code as
-defined in \hyperref[intro:SAM]{SAM}.
-
-The device MUST write the \field{response} byte as one of the following:
-
-\begin{description}
-
-\item[VIRTIO_SCSI_S_OK] when the request was completed and the \field{status}
-  byte is filled with a SCSI status code (not necessarily
-  ``GOOD'').
-
-\item[VIRTIO_SCSI_S_OVERRUN] if the content of the CDB (such as the
-  allocation length, parameter length or transfer size) requires
-  more data than is available in the datain and dataout buffers.
-
-\item[VIRTIO_SCSI_S_ABORTED] if the request was cancelled due to an
-  ABORT TASK or ABORT TASK SET task management function.
-
-\item[VIRTIO_SCSI_S_BAD_TARGET] if the request was never processed
-  because the target indicated by \field{lun} does not exist.
-
-\item[VIRTIO_SCSI_S_RESET] if the request was cancelled due to a bus
-  or device reset (including a task management function).
-
-\item[VIRTIO_SCSI_S_TRANSPORT_FAILURE] if the request failed due to a
-  problem in the connection between the host and the target
-  (severed link).
-
-\item[VIRTIO_SCSI_S_TARGET_FAILURE] if the target is suffering a
-  failure and to tell the driver not to retry on other paths.
-
-\item[VIRTIO_SCSI_S_NEXUS_FAILURE] if the nexus is suffering a failure
-  but retrying on other paths might yield a different result.
-
-\item[VIRTIO_SCSI_S_BUSY] if the request failed but retrying on the
-  same path is likely to work.
-
-\item[VIRTIO_SCSI_S_FAILURE] for other host or driver error. In
-  particular, if neither \field{dataout} nor \field{datain} is empty, and the
-  VIRTIO_SCSI_F_INOUT feature has not been negotiated, the
-  request will be immediately returned with a response equal to
-  VIRTIO_SCSI_S_FAILURE.
-\end{description}
-
-All commands must be completed before the virtio-scsi device is
-reset or unplugged.  The device MAY choose to abort them, or if
-it does not do so MUST pick the VIRTIO_SCSI_S_FAILURE response.
-
-\drivernormative{\paragraph}{Device Operation: Request Queues}{Device Types / SCSI Host Device / Device Operation / Device Operation: Request Queues}
-
-\field{task_attr}, \field{prio} and \field{crn} SHOULD be zero.
-
-Upon receiving a VIRTIO_SCSI_S_TARGET_FAILURE response, the driver
-SHOULD NOT retry the request on other paths.
-
-\paragraph{Legacy Interface: Device Operation: Request Queues}\label{sec:Device Types / SCSI Host Device / Device Operation / Device Operation: Request Queues / Legacy Interface: Device Operation: Request Queues}
-When using the legacy interface, transitional devices and drivers
-MUST format the fields in struct virtio_scsi_req_cmd
-according to the native endian of the guest rather than
-(necessarily when not using the legacy interface) little-endian.
-
-\subsubsection{Device Operation: controlq}\label{sec:Device Types / SCSI Host Device / Device Operation / Device Operation: controlq}
-
-The controlq is used for other SCSI transport operations.
-Requests have the following format:
-
-{
-\lstset{escapechar=\$}
-\begin{lstlisting}
-struct virtio_scsi_ctrl {
-        le32 type;
-$\ldots$
-        u8 response;
-};
-
-/* response values valid for all commands */
-#define VIRTIO_SCSI_S_OK                       0
-#define VIRTIO_SCSI_S_BAD_TARGET               3
-#define VIRTIO_SCSI_S_BUSY                     5
-#define VIRTIO_SCSI_S_TRANSPORT_FAILURE        6
-#define VIRTIO_SCSI_S_TARGET_FAILURE           7
-#define VIRTIO_SCSI_S_NEXUS_FAILURE            8
-#define VIRTIO_SCSI_S_FAILURE                  9
-#define VIRTIO_SCSI_S_INCORRECT_LUN            12
-\end{lstlisting}
-}
-
-The \field{type} identifies the remaining fields.
-
-The following commands are defined:
-
-\begin{itemize}
-\item Task management function.
-\begin{lstlisting}
-#define VIRTIO_SCSI_T_TMF                      0
-
-#define VIRTIO_SCSI_T_TMF_ABORT_TASK           0
-#define VIRTIO_SCSI_T_TMF_ABORT_TASK_SET       1
-#define VIRTIO_SCSI_T_TMF_CLEAR_ACA            2
-#define VIRTIO_SCSI_T_TMF_CLEAR_TASK_SET       3
-#define VIRTIO_SCSI_T_TMF_I_T_NEXUS_RESET      4
-#define VIRTIO_SCSI_T_TMF_LOGICAL_UNIT_RESET   5
-#define VIRTIO_SCSI_T_TMF_QUERY_TASK           6
-#define VIRTIO_SCSI_T_TMF_QUERY_TASK_SET       7
-
-struct virtio_scsi_ctrl_tmf {
-        // Device-readable part
-        le32 type;
-        le32 subtype;
-        u8   lun[8];
-        le64 id;
-        // Device-writable part
-        u8   response;
-};
-
-/* command-specific response values */
-#define VIRTIO_SCSI_S_FUNCTION_COMPLETE        0
-#define VIRTIO_SCSI_S_FUNCTION_SUCCEEDED       10
-#define VIRTIO_SCSI_S_FUNCTION_REJECTED        11
-\end{lstlisting}
-
-  The \field{type} is VIRTIO_SCSI_T_TMF; \field{subtype} defines which
-  task management function. All
-  fields except \field{response} are filled by the driver.
-
-  Other fields which are irrelevant for the requested TMF
-  are ignored but they are still present. \field{lun}
-  is in the same format specified for request queues; the
-  single level LUN is ignored when the task management function
-  addresses a whole I_T nexus. When relevant, the value of \field{id}
-  is matched against the id values passed on the requestq.
-
-  The outcome of the task management function is written by the
-  device in \field{response}. The command-specific response
-  values map 1-to-1 with those defined in \hyperref[intro:SAM]{SAM}.
-
-  Task management function can affect the response value for commands that
-  are in the request queue and have not been completed yet.  For example,
-  the device MUST complete all active commands on a logical unit
-  or target (possibly with a VIRTIO_SCSI_S_RESET response code)
-  upon receiving a "logical unit reset" or "I_T nexus reset" TMF.
-  Similarly, the device MUST complete the selected commands (possibly
-  with a VIRTIO_SCSI_S_ABORTED response code) upon receiving an "abort
-  task" or "abort task set" TMF.  Such effects MUST take place before
-  the TMF itself is successfully completed, and the device MUST use
-  memory barriers appropriately in order to ensure that the driver sees
-  these writes in the correct order.
-
-\item Asynchronous notification query.
-\begin{lstlisting}
-#define VIRTIO_SCSI_T_AN_QUERY                    1
-
-struct virtio_scsi_ctrl_an {
-    // Device-readable part
-    le32 type;
-    u8   lun[8];
-    le32 event_requested;
-    // Device-writable part
-    le32 event_actual;
-    u8   response;
-};
-
-#define VIRTIO_SCSI_EVT_ASYNC_OPERATIONAL_CHANGE  2
-#define VIRTIO_SCSI_EVT_ASYNC_POWER_MGMT          4
-#define VIRTIO_SCSI_EVT_ASYNC_EXTERNAL_REQUEST    8
-#define VIRTIO_SCSI_EVT_ASYNC_MEDIA_CHANGE        16
-#define VIRTIO_SCSI_EVT_ASYNC_MULTI_HOST          32
-#define VIRTIO_SCSI_EVT_ASYNC_DEVICE_BUSY         64
-\end{lstlisting}
-
-  By sending this command, the driver asks the device which
-  events the given LUN can report, as described in paragraphs 6.6
-  and A.6 of \hyperref[intro:SCSI MMC]{SCSI MMC}. The driver writes the
-  events it is interested in into \field{event_requested}; the device
-  responds by writing the events that it supports into
-  \field{event_actual}.
-
-  The \field{type} is VIRTIO_SCSI_T_AN_QUERY. \field{lun} and \field{event_requested}
-  are written by the driver. \field{event_actual} and \field{response}
-  fields are written by the device.
-
-  No command-specific values are defined for the \field{response} byte.
-
-\item Asynchronous notification subscription.
-\begin{lstlisting}
-#define VIRTIO_SCSI_T_AN_SUBSCRIBE                2
-
-struct virtio_scsi_ctrl_an {
-        // Device-readable part
-        le32 type;
-        u8   lun[8];
-        le32 event_requested;
-        // Device-writable part
-        le32 event_actual;
-        u8   response;
-};
-\end{lstlisting}
-
-  By sending this command, the driver asks the specified LUN to
-  report events for its physical interface, again as described in
-   \hyperref[intro:SCSI MMC]{SCSI MMC}. The driver writes the events it is
-  interested in into \field{event_requested}; the device responds by
-  writing the events that it supports into \field{event_actual}.
-
-  Event types are the same as for the asynchronous notification
-  query message.
-
-  The \field{type} is VIRTIO_SCSI_T_AN_SUBSCRIBE. \field{lun} and
-  \field{event_requested} are written by the driver.
-  \field{event_actual} and \field{response} are written by the device.
-
-  No command-specific values are defined for the response byte.
-\end{itemize}
-
-\paragraph{Legacy Interface: Device Operation: controlq}\label{sec:Device Types / SCSI Host Device / Device Operation / Device Operation: controlq / Legacy Interface: Device Operation: controlq}
-
-When using the legacy interface, transitional devices and drivers
-MUST format the fields in struct virtio_scsi_ctrl, struct
-virtio_scsi_ctrl_tmf, struct virtio_scsi_ctrl_an and struct
-virtio_scsi_ctrl_an
-according to the native endian of the guest rather than
-(necessarily when not using the legacy interface) little-endian.
-
-
-\subsubsection{Device Operation: eventq}\label{sec:Device Types / SCSI Host Device / Device Operation / Device Operation: eventq}
-
-The eventq is populated by the driver for the device to report information on logical
-units that are attached to it. In general, the device will not
-queue events to cope with an empty eventq, and will end up
-dropping events if it finds no buffer ready. However, when
-reporting events for many LUNs (e.g. when a whole target
-disappears), the device can throttle events to avoid dropping
-them. For this reason, placing 10-15 buffers on the event queue
-is sufficient.
-
-Buffers returned by the device on the eventq will be referred to
-as ``events'' in the rest of this section. Events have the
-following format:
-
-\begin{lstlisting}
-#define VIRTIO_SCSI_T_EVENTS_MISSED   0x80000000
-
-struct virtio_scsi_event {
-        // Device-writable part
-        le32 event;
-        u8  lun[8];
-        le32 reason;
-};
-\end{lstlisting}
-
-The devices sets bit 31 in \field{event} to report lost events
-due to missing buffers.
-
-The meaning of \field{reason} depends on the
-contents of \field{event}. The following events are defined:
-
-\begin{itemize}
-\item No event.
-\begin{lstlisting}
-#define VIRTIO_SCSI_T_NO_EVENT         0
-\end{lstlisting}
-
-  This event is fired in the following cases:
-
-\begin{itemize}
-\item When the device detects in the eventq a buffer that is
-    shorter than what is indicated in the configuration field, it
-    MAY use it immediately and put this dummy value in \field{event}.
-    A well-written driver will never observe this
-    situation.
-
-\item When events are dropped, the device MAY signal this event as
-    soon as the drivers makes a buffer available, in order to
-    request action from the driver. In this case, of course, this
-    event will be reported with the VIRTIO_SCSI_T_EVENTS_MISSED
-    flag.
-\end{itemize}
-
-\item Transport reset
-\begin{lstlisting}
-#define VIRTIO_SCSI_T_TRANSPORT_RESET  1
-
-#define VIRTIO_SCSI_EVT_RESET_HARD         0
-#define VIRTIO_SCSI_EVT_RESET_RESCAN       1
-#define VIRTIO_SCSI_EVT_RESET_REMOVED      2
-\end{lstlisting}
-
-  By sending this event, the device signals that a logical unit
-  on a target has been reset, including the case of a new device
-  appearing or disappearing on the bus. The device fills in all
-  fields. \field{event} is set to
-  VIRTIO_SCSI_T_TRANSPORT_RESET. \field{lun} addresses a
-  logical unit in the SCSI host.
-
-  The \field{reason} value is one of the three \#define values appearing
-  above:
-
-  \begin{description}
-  \item[VIRTIO_SCSI_EVT_RESET_REMOVED] (``LUN/target removed'') is used
-    if the target or logical unit is no longer able to receive
-    commands.
-
-  \item[VIRTIO_SCSI_EVT_RESET_HARD] (``LUN hard reset'') is used if the
-    logical unit has been reset, but is still present.
-
-  \item[VIRTIO_SCSI_EVT_RESET_RESCAN] (``rescan LUN/target'') is used if
-    a target or logical unit has just appeared on the device.
-  \end{description}
-
-  The ``removed'' and ``rescan'' events can happen when
-  VIRTIO_SCSI_F_HOTPLUG feature was negotiated; when sent for LUN 0,
-  they MAY apply to the entire target so the driver can ask the
-  initiator to rescan the target to detect this.
-
-  Events will also be reported via sense codes (this obviously
-  does not apply to newly appeared buses or targets, since the
-  application has never discovered them):
-
-  \begin{itemize}
-  \item ``LUN/target removed'' maps to sense key ILLEGAL REQUEST, asc
-    0x25, ascq 0x00 (LOGICAL UNIT NOT SUPPORTED)
-
-  \item ``LUN hard reset'' maps to sense key UNIT ATTENTION, asc 0x29
-    (POWER ON, RESET OR BUS DEVICE RESET OCCURRED)
-
-  \item ``rescan LUN/target'' maps to sense key UNIT ATTENTION, asc
-    0x3f, ascq 0x0e (REPORTED LUNS DATA HAS CHANGED)
-  \end{itemize}
-
-  The preferred way to detect transport reset is always to use
-  events, because sense codes are only seen by the driver when it
-  sends a SCSI command to the logical unit or target. However, in
-  case events are dropped, the initiator will still be able to
-  synchronize with the actual state of the controller if the
-  driver asks the initiator to rescan of the SCSI bus. During the
-  rescan, the initiator will be able to observe the above sense
-  codes, and it will process them as if it the driver had
-  received the equivalent event.
-
-  \item Asynchronous notification
-\begin{lstlisting}
-#define VIRTIO_SCSI_T_ASYNC_NOTIFY     2
-\end{lstlisting}
-
-  By sending this event, the device signals that an asynchronous
-  event was fired from a physical interface.
-
-  All fields are written by the device. \field{event} is set to
-  VIRTIO_SCSI_T_ASYNC_NOTIFY. \field{lun} addresses a logical
-  unit in the SCSI host. \field{reason} is a subset of the
-  events that the driver has subscribed to via the ``Asynchronous
-  notification subscription'' command.
-
-  \item LUN parameter change
-\begin{lstlisting}
-#define VIRTIO_SCSI_T_PARAM_CHANGE  3
-\end{lstlisting}
-
-  By sending this event, the device signals a change in the configuration parameters
-  of a logical unit, for example the capacity or cache mode.
-  \field{event} is set to VIRTIO_SCSI_T_PARAM_CHANGE.
-  \field{lun} addresses a logical unit in the SCSI host.
-
-  The same event SHOULD also be reported as a unit attention condition.
-  \field{reason} contains the additional sense code and additional sense code qualifier,
-  respectively in bits 0\ldots 7 and 8\ldots 15.
-  \begin{note}
-  For example, a change in capacity will be reported as asc 0x2a, ascq 0x09
-  (CAPACITY DATA HAS CHANGED).
-  \end{note}
-
-  For MMC devices (inquiry type 5) there would be some overlap between this
-  event and the asynchronous notification event, so for simplicity the host never
-  reports this event for MMC devices.
-\end{itemize}
-
-\drivernormative{\paragraph}{Device Operation: eventq}{Device Types / SCSI Host Device / Device Operation / Device Operation: eventq}
-
-The driver SHOULD keep the eventq populated with buffers.  These
-buffers MUST be device-writable, and SHOULD be at least
-\field{event_info_size} bytes long, and MUST be at least the size of
-struct virtio_scsi_event.
-
-If \field{event} has bit 31 set, the driver SHOULD
-poll the logical units for unit attention conditions, and/or do
-whatever form of bus scan is appropriate for the guest operating
-system and SHOULD poll for asynchronous events manually using SCSI commands.
-
-When receiving a VIRTIO_SCSI_T_TRANSPORT_RESET message with
-\field{reason} set to VIRTIO_SCSI_EVT_RESET_REMOVED or
-VIRTIO_SCSI_EVT_RESET_RESCAN for LUN 0, the driver SHOULD ask the
-initiator to rescan the target, in order to detect the case when an
-entire target has appeared or disappeared.
-
-\devicenormative{\paragraph}{Device Operation: eventq}{Device Types / SCSI Host Device / Device Operation / Device Operation: eventq}
-
-The device MUST set bit 31 in \field{event} if events were lost due to
-missing buffers, and it MAY use a VIRTIO_SCSI_T_NO_EVENT event to report
-this.
-
-The device MUST NOT send VIRTIO_SCSI_T_TRANSPORT_RESET messages
-with \field{reason} set to VIRTIO_SCSI_EVT_RESET_REMOVED or
-VIRTIO_SCSI_EVT_RESET_RESCAN unless VIRTIO_SCSI_F_HOTPLUG was negotiated.
-
-The device MUST NOT report VIRTIO_SCSI_T_PARAM_CHANGE for MMC devices.
-
-\paragraph{Legacy Interface: Device Operation: eventq}\label{sec:Device Types / SCSI Host Device / Device Operation / Device Operation: eventq / Legacy Interface: Device Operation: eventq}
-When using the legacy interface, transitional devices and drivers
-MUST format the fields in struct virtio_scsi_event
-according to the native endian of the guest rather than
-(necessarily when not using the legacy interface) little-endian.
-
-\subsubsection{Legacy Interface: Framing Requirements}\label{sec:Device
-Types / SCSI Host Device / Legacy Interface: Framing Requirements}
-
-When using legacy interfaces, transitional drivers which have not
-negotiated VIRTIO_F_ANY_LAYOUT MUST use a single descriptor for the
-\field{lun}, \field{id}, \field{task_attr}, \field{prio},
-\field{crn} and \field{cdb} fields, and MUST only use a single
-descriptor for the \field{sense_len}, \field{residual},
-\field{status_qualifier}, \field{status}, \field{response} and
-\field{sense} fields.
-
+\input{virtio-scsi.tex}
 \input{virtio-gpu.tex}
 \input{virtio-input.tex}
 \input{virtio-crypto.tex}
diff --git a/virtio-scsi.tex b/virtio-scsi.tex
new file mode 100644
index 0000000..df83607
--- /dev/null
+++ b/virtio-scsi.tex
@@ -0,0 +1,711 @@
+\section{SCSI Host Device}\label{sec:Device Types / SCSI Host Device}
+
+The virtio SCSI host device groups together one or more virtual
+logical units (such as disks), and allows communicating to them
+using the SCSI protocol. An instance of the device represents a
+SCSI host to which many targets and LUNs are attached.
+
+The virtio SCSI device services two kinds of requests:
+\begin{itemize}
+\item command requests for a logical unit;
+
+\item task management functions related to a logical unit, target or
+  command.
+\end{itemize}
+
+The device is also able to send out notifications about added and
+removed logical units. Together, these capabilities provide a
+SCSI transport protocol that uses virtqueues as the transfer
+medium. In the transport protocol, the virtio driver acts as the
+initiator, while the virtio SCSI host provides one or more
+targets that receive and process the requests.
+
+This section relies on definitions from \hyperref[intro:SAM]{SAM}.
+
+\subsection{Device ID}\label{sec:Device Types / SCSI Host Device / Device ID}
+  8
+
+\subsection{Virtqueues}\label{sec:Device Types / SCSI Host Device / Virtqueues}
+
+\begin{description}
+\item[0] controlq
+\item[1] eventq
+\item[2\ldots n] request queues
+\end{description}
+
+\subsection{Feature bits}\label{sec:Device Types / SCSI Host Device / Feature bits}
+
+\begin{description}
+\item[VIRTIO_SCSI_F_INOUT (0)] A single request can include both
+    device-readable and device-writable data buffers.
+
+\item[VIRTIO_SCSI_F_HOTPLUG (1)] The host SHOULD enable reporting of
+    hot-plug and hot-unplug events for LUNs and targets on the SCSI bus.
+    The guest SHOULD handle hot-plug and hot-unplug events.
+
+\item[VIRTIO_SCSI_F_CHANGE (2)] The host will report changes to LUN
+    parameters via a VIRTIO_SCSI_T_PARAM_CHANGE event; the guest
+    SHOULD handle them.
+
+\item[VIRTIO_SCSI_F_T10_PI (3)] The extended fields for T10 protection
+    information (DIF/DIX) are included in the SCSI request header.
+\end{description}
+
+\subsection{Device configuration layout}\label{sec:Device Types / SCSI Host Device / Device configuration layout}
+
+  All fields of this configuration are always available.
+
+\begin{lstlisting}
+struct virtio_scsi_config {
+        le32 num_queues;
+        le32 seg_max;
+        le32 max_sectors;
+        le32 cmd_per_lun;
+        le32 event_info_size;
+        le32 sense_size;
+        le32 cdb_size;
+        le16 max_channel;
+        le16 max_target;
+        le32 max_lun;
+};
+\end{lstlisting}
+
+\begin{description}
+\item[\field{num_queues}] is the total number of request virtqueues exposed by
+    the device. The driver MAY use only one request queue,
+    or it can use more to achieve better performance.
+
+\item[\field{seg_max}] is the maximum number of segments that can be in a
+    command. A bidirectional command can include \field{seg_max} input
+    segments and \field{seg_max} output segments.
+
+\item[\field{max_sectors}] is a hint to the driver about the maximum transfer
+    size to use.
+
+\item[\field{cmd_per_lun}] tells the driver the maximum number of
+    linked commands it can send to one LUN.
+
+\item[\field{event_info_size}] is the maximum size that the device will fill
+    for buffers that the driver places in the eventq. It is
+    written by the device depending on the set of negotiated
+    features.
+
+\item[\field{sense_size}] is the maximum size of the sense data that the
+    device will write. The default value is written by the device
+    and MUST be 96, but the driver can modify it. It is
+    restored to the default when the device is reset.
+
+\item[\field{cdb_size}] is the maximum size of the CDB that the driver will
+    write. The default value is written by the device and MUST
+    be 32, but the driver can likewise modify it. It is
+    restored to the default when the device is reset.
+
+\item[\field{max_channel}, \field{max_target} and \field{max_lun}] can be
+    used by the driver as hints to constrain scanning the logical units
+    on the host to channel/target/logical unit numbers that are less than
+    or equal to the value of the fields.  \field{max_channel} SHOULD
+    be zero.  \field{max_target} SHOULD be less than or equal to 255.
+    \field{max_lun} SHOULD be less than or equal to 16383.
+\end{description}
+
+\drivernormative{\subsubsection}{Device configuration layout}{Device Types / SCSI Host Device / Device configuration layout}
+
+The driver MUST NOT write to device configuration fields other than
+\field{sense_size} and \field{cdb_size}.
+
+The driver MUST NOT send more than \field{cmd_per_lun} linked commands
+to one LUN, and MUST NOT send more than the virtqueue size number of
+linked commands to one LUN.
+
+\devicenormative{\subsubsection}{Device configuration layout}{Device Types / SCSI Host Device / Device configuration layout}
+
+On reset, the device MUST set \field{sense_size} to 96 and
+\field{cdb_size} to 32.
+
+\subsubsection{Legacy Interface: Device configuration layout}\label{sec:Device Types / SCSI Host Device / Device configuration layout / Legacy Interface: Device configuration layout}
+When using the legacy interface, transitional devices and drivers
+MUST format the fields in struct virtio_scsi_config
+according to the native endian of the guest rather than
+(necessarily when not using the legacy interface) little-endian.
+
+\devicenormative{\subsection}{Device Initialization}{Device Types / SCSI Host Device / Device Initialization}
+
+On initialization the driver SHOULD first discover the
+device's virtqueues.
+
+If the driver uses the eventq, the driver SHOULD place at least one
+buffer in the eventq.
+
+The driver MAY immediately issue requests\footnote{For example, INQUIRY
+or REPORT LUNS.} or task management functions\footnote{For example, I_T
+RESET.}.
+
+\subsection{Device Operation}\label{sec:Device Types / SCSI Host Device / Device Operation}
+
+Device operation consists of operating request queues, the control
+queue and the event queue.
+
+\paragraph{Legacy Interface: Device Operation}\label{sec:Device
+Types / SCSI Host Device / Device Operation / Legacy
+Interface: Device Operation}
+When using the legacy interface, the driver SHOULD ignore the
+used length values.
+\begin{note}
+Historically, devices put the total descriptor length,
+or the total length of device-writable buffers there,
+even when only part of the buffers were actually written.
+\end{note}
+
+\subsubsection{Device Operation: Request Queues}\label{sec:Device Types / SCSI Host Device / Device Operation / Device Operation: Request Queues}
+
+The driver queues requests to an arbitrary request queue, and
+they are used by the device on that same queue. It is the
+responsibility of the driver to ensure strict request ordering
+for commands placed on different queues, because they will be
+consumed with no order constraints.
+
+Requests have the following format:
+
+\begin{lstlisting}
+struct virtio_scsi_req_cmd {
+        // Device-readable part
+        u8 lun[8];
+        le64 id;
+        u8 task_attr;
+        u8 prio;
+        u8 crn;
+        u8 cdb[cdb_size];
+        // The next three fields are only present if VIRTIO_SCSI_F_T10_PI
+        // is negotiated.
+        le32 pi_bytesout;
+        le32 pi_bytesin;
+        u8 pi_out[pi_bytesout];
+        u8 dataout[];
+
+        // Device-writable part
+        le32 sense_len;
+        le32 residual;
+        le16 status_qualifier;
+        u8 status;
+        u8 response;
+        u8 sense[sense_size];
+        // The next field is only present if VIRTIO_SCSI_F_T10_PI
+        // is negotiated
+        u8 pi_in[pi_bytesin];
+        u8 datain[];
+};
+
+
+/* command-specific response values */
+#define VIRTIO_SCSI_S_OK                0
+#define VIRTIO_SCSI_S_OVERRUN           1
+#define VIRTIO_SCSI_S_ABORTED           2
+#define VIRTIO_SCSI_S_BAD_TARGET        3
+#define VIRTIO_SCSI_S_RESET             4
+#define VIRTIO_SCSI_S_BUSY              5
+#define VIRTIO_SCSI_S_TRANSPORT_FAILURE 6
+#define VIRTIO_SCSI_S_TARGET_FAILURE    7
+#define VIRTIO_SCSI_S_NEXUS_FAILURE     8
+#define VIRTIO_SCSI_S_FAILURE           9
+
+/* task_attr */
+#define VIRTIO_SCSI_S_SIMPLE            0
+#define VIRTIO_SCSI_S_ORDERED           1
+#define VIRTIO_SCSI_S_HEAD              2
+#define VIRTIO_SCSI_S_ACA               3
+\end{lstlisting}
+
+\field{lun} addresses the REPORT LUNS well-known logical unit, or
+a target and logical unit in the virtio-scsi device's SCSI domain.
+When used to address the REPORT LUNS logical unit, \field{lun} is 0xC1,
+0x01 and six zero bytes.  The virtio-scsi device SHOULD implement the
+REPORT LUNS well-known logical unit.
+
+When used to address a target and logical unit, the only supported format
+for \field{lun} is: first byte set to 1, second byte set to target,
+third and fourth byte representing a single level LUN structure, followed
+by four zero bytes. With this representation, a virtio-scsi device can
+serve up to 256 targets and 16384 LUNs per target.  The device MAY also
+support having a well-known logical units in the third and fourth byte.
+
+\field{id} is the command identifier (``tag'').
+
+\field{task_attr} defines the task attribute as in the table above, but
+all task attributes MAY be mapped to SIMPLE by the device.  Some commands
+are defined by SCSI standards as "implicit head of queue"; for such
+commands, all task attributes MAY also be mapped to HEAD OF QUEUE.
+Drivers and applications SHOULD NOT send a command with the ORDERED
+task attribute if the command has an implicit HEAD OF QUEUE attribute,
+because whether the ORDERED task attribute is honored is vendor-specific.
+
+\field{crn} may also be provided by clients, but is generally expected
+to be 0. The maximum CRN value defined by the protocol is 255, since
+CRN is stored in an 8-bit integer.
+
+The CDB is included in \field{cdb} and its size, \field{cdb_size},
+is taken from the configuration space.
+
+All of these fields are defined in \hyperref[intro:SAM]{SAM} and are
+always device-readable.
+
+\field{pi_bytesout} determines the size of the \field{pi_out} field
+in bytes.  If it is nonzero, the \field{pi_out} field contains outgoing
+protection information for write operations.  \field{pi_bytesin} determines
+the size of the \field{pi_in} field in the device-writable section, in bytes.
+All three fields are only present if VIRTIO_SCSI_F_T10_PI has been negotiated.
+
+The remainder of the device-readable part is the data output buffer,
+\field{dataout}.
+
+\field{sense} and subsequent fields are always device-writable. \field{sense_len}
+indicates the number of bytes actually written to the sense
+buffer.
+
+\field{residual} indicates the residual size,
+calculated as ``data_length - number_of_transferred_bytes'', for
+read or write operations. For bidirectional commands, the
+number_of_transferred_bytes includes both read and written bytes.
+A \field{residual} that is less than the size of \field{datain} means that
+\field{dataout} was processed entirely. A \field{residual} that
+exceeds the size of \field{datain} means that \field{dataout} was
+processed partially and \field{datain} was not processed at
+all.
+
+If the \field{pi_bytesin} is nonzero, the \field{pi_in} field contains
+incoming protection information for read operations.  \field{pi_in} is
+only present if VIRTIO_SCSI_F_T10_PI has been negotiated\footnote{There
+  is no separate residual size for \field{pi_bytesout} and
+  \field{pi_bytesin}.  It can be computed from the \field{residual} field,
+  the size of the data integrity information per sector, and the sizes
+  of \field{pi_out}, \field{pi_in}, \field{dataout} and \field{datain}.}.
+
+The remainder of the device-writable part is the data input buffer,
+\field{datain}.
+
+
+\devicenormative{\paragraph}{Device Operation: Request Queues}{Device Types / SCSI Host Device / Device Operation / Device Operation: Request Queues}
+
+The device MUST write the \field{status} byte as the status code as
+defined in \hyperref[intro:SAM]{SAM}.
+
+The device MUST write the \field{response} byte as one of the following:
+
+\begin{description}
+
+\item[VIRTIO_SCSI_S_OK] when the request was completed and the \field{status}
+  byte is filled with a SCSI status code (not necessarily
+  ``GOOD'').
+
+\item[VIRTIO_SCSI_S_OVERRUN] if the content of the CDB (such as the
+  allocation length, parameter length or transfer size) requires
+  more data than is available in the datain and dataout buffers.
+
+\item[VIRTIO_SCSI_S_ABORTED] if the request was cancelled due to an
+  ABORT TASK or ABORT TASK SET task management function.
+
+\item[VIRTIO_SCSI_S_BAD_TARGET] if the request was never processed
+  because the target indicated by \field{lun} does not exist.
+
+\item[VIRTIO_SCSI_S_RESET] if the request was cancelled due to a bus
+  or device reset (including a task management function).
+
+\item[VIRTIO_SCSI_S_TRANSPORT_FAILURE] if the request failed due to a
+  problem in the connection between the host and the target
+  (severed link).
+
+\item[VIRTIO_SCSI_S_TARGET_FAILURE] if the target is suffering a
+  failure and to tell the driver not to retry on other paths.
+
+\item[VIRTIO_SCSI_S_NEXUS_FAILURE] if the nexus is suffering a failure
+  but retrying on other paths might yield a different result.
+
+\item[VIRTIO_SCSI_S_BUSY] if the request failed but retrying on the
+  same path is likely to work.
+
+\item[VIRTIO_SCSI_S_FAILURE] for other host or driver error. In
+  particular, if neither \field{dataout} nor \field{datain} is empty, and the
+  VIRTIO_SCSI_F_INOUT feature has not been negotiated, the
+  request will be immediately returned with a response equal to
+  VIRTIO_SCSI_S_FAILURE.
+\end{description}
+
+All commands must be completed before the virtio-scsi device is
+reset or unplugged.  The device MAY choose to abort them, or if
+it does not do so MUST pick the VIRTIO_SCSI_S_FAILURE response.
+
+\drivernormative{\paragraph}{Device Operation: Request Queues}{Device Types / SCSI Host Device / Device Operation / Device Operation: Request Queues}
+
+\field{task_attr}, \field{prio} and \field{crn} SHOULD be zero.
+
+Upon receiving a VIRTIO_SCSI_S_TARGET_FAILURE response, the driver
+SHOULD NOT retry the request on other paths.
+
+\paragraph{Legacy Interface: Device Operation: Request Queues}\label{sec:Device Types / SCSI Host Device / Device Operation / Device Operation: Request Queues / Legacy Interface: Device Operation: Request Queues}
+When using the legacy interface, transitional devices and drivers
+MUST format the fields in struct virtio_scsi_req_cmd
+according to the native endian of the guest rather than
+(necessarily when not using the legacy interface) little-endian.
+
+\subsubsection{Device Operation: controlq}\label{sec:Device Types / SCSI Host Device / Device Operation / Device Operation: controlq}
+
+The controlq is used for other SCSI transport operations.
+Requests have the following format:
+
+{
+\lstset{escapechar=\$}
+\begin{lstlisting}
+struct virtio_scsi_ctrl {
+        le32 type;
+$\ldots$
+        u8 response;
+};
+
+/* response values valid for all commands */
+#define VIRTIO_SCSI_S_OK                       0
+#define VIRTIO_SCSI_S_BAD_TARGET               3
+#define VIRTIO_SCSI_S_BUSY                     5
+#define VIRTIO_SCSI_S_TRANSPORT_FAILURE        6
+#define VIRTIO_SCSI_S_TARGET_FAILURE           7
+#define VIRTIO_SCSI_S_NEXUS_FAILURE            8
+#define VIRTIO_SCSI_S_FAILURE                  9
+#define VIRTIO_SCSI_S_INCORRECT_LUN            12
+\end{lstlisting}
+}
+
+The \field{type} identifies the remaining fields.
+
+The following commands are defined:
+
+\begin{itemize}
+\item Task management function.
+\begin{lstlisting}
+#define VIRTIO_SCSI_T_TMF                      0
+
+#define VIRTIO_SCSI_T_TMF_ABORT_TASK           0
+#define VIRTIO_SCSI_T_TMF_ABORT_TASK_SET       1
+#define VIRTIO_SCSI_T_TMF_CLEAR_ACA            2
+#define VIRTIO_SCSI_T_TMF_CLEAR_TASK_SET       3
+#define VIRTIO_SCSI_T_TMF_I_T_NEXUS_RESET      4
+#define VIRTIO_SCSI_T_TMF_LOGICAL_UNIT_RESET   5
+#define VIRTIO_SCSI_T_TMF_QUERY_TASK           6
+#define VIRTIO_SCSI_T_TMF_QUERY_TASK_SET       7
+
+struct virtio_scsi_ctrl_tmf {
+        // Device-readable part
+        le32 type;
+        le32 subtype;
+        u8   lun[8];
+        le64 id;
+        // Device-writable part
+        u8   response;
+};
+
+/* command-specific response values */
+#define VIRTIO_SCSI_S_FUNCTION_COMPLETE        0
+#define VIRTIO_SCSI_S_FUNCTION_SUCCEEDED       10
+#define VIRTIO_SCSI_S_FUNCTION_REJECTED        11
+\end{lstlisting}
+
+  The \field{type} is VIRTIO_SCSI_T_TMF; \field{subtype} defines which
+  task management function. All
+  fields except \field{response} are filled by the driver.
+
+  Other fields which are irrelevant for the requested TMF
+  are ignored but they are still present. \field{lun}
+  is in the same format specified for request queues; the
+  single level LUN is ignored when the task management function
+  addresses a whole I_T nexus. When relevant, the value of \field{id}
+  is matched against the id values passed on the requestq.
+
+  The outcome of the task management function is written by the
+  device in \field{response}. The command-specific response
+  values map 1-to-1 with those defined in \hyperref[intro:SAM]{SAM}.
+
+  Task management function can affect the response value for commands that
+  are in the request queue and have not been completed yet.  For example,
+  the device MUST complete all active commands on a logical unit
+  or target (possibly with a VIRTIO_SCSI_S_RESET response code)
+  upon receiving a "logical unit reset" or "I_T nexus reset" TMF.
+  Similarly, the device MUST complete the selected commands (possibly
+  with a VIRTIO_SCSI_S_ABORTED response code) upon receiving an "abort
+  task" or "abort task set" TMF.  Such effects MUST take place before
+  the TMF itself is successfully completed, and the device MUST use
+  memory barriers appropriately in order to ensure that the driver sees
+  these writes in the correct order.
+
+\item Asynchronous notification query.
+\begin{lstlisting}
+#define VIRTIO_SCSI_T_AN_QUERY                    1
+
+struct virtio_scsi_ctrl_an {
+    // Device-readable part
+    le32 type;
+    u8   lun[8];
+    le32 event_requested;
+    // Device-writable part
+    le32 event_actual;
+    u8   response;
+};
+
+#define VIRTIO_SCSI_EVT_ASYNC_OPERATIONAL_CHANGE  2
+#define VIRTIO_SCSI_EVT_ASYNC_POWER_MGMT          4
+#define VIRTIO_SCSI_EVT_ASYNC_EXTERNAL_REQUEST    8
+#define VIRTIO_SCSI_EVT_ASYNC_MEDIA_CHANGE        16
+#define VIRTIO_SCSI_EVT_ASYNC_MULTI_HOST          32
+#define VIRTIO_SCSI_EVT_ASYNC_DEVICE_BUSY         64
+\end{lstlisting}
+
+  By sending this command, the driver asks the device which
+  events the given LUN can report, as described in paragraphs 6.6
+  and A.6 of \hyperref[intro:SCSI MMC]{SCSI MMC}. The driver writes the
+  events it is interested in into \field{event_requested}; the device
+  responds by writing the events that it supports into
+  \field{event_actual}.
+
+  The \field{type} is VIRTIO_SCSI_T_AN_QUERY. \field{lun} and \field{event_requested}
+  are written by the driver. \field{event_actual} and \field{response}
+  fields are written by the device.
+
+  No command-specific values are defined for the \field{response} byte.
+
+\item Asynchronous notification subscription.
+\begin{lstlisting}
+#define VIRTIO_SCSI_T_AN_SUBSCRIBE                2
+
+struct virtio_scsi_ctrl_an {
+        // Device-readable part
+        le32 type;
+        u8   lun[8];
+        le32 event_requested;
+        // Device-writable part
+        le32 event_actual;
+        u8   response;
+};
+\end{lstlisting}
+
+  By sending this command, the driver asks the specified LUN to
+  report events for its physical interface, again as described in
+   \hyperref[intro:SCSI MMC]{SCSI MMC}. The driver writes the events it is
+  interested in into \field{event_requested}; the device responds by
+  writing the events that it supports into \field{event_actual}.
+
+  Event types are the same as for the asynchronous notification
+  query message.
+
+  The \field{type} is VIRTIO_SCSI_T_AN_SUBSCRIBE. \field{lun} and
+  \field{event_requested} are written by the driver.
+  \field{event_actual} and \field{response} are written by the device.
+
+  No command-specific values are defined for the response byte.
+\end{itemize}
+
+\paragraph{Legacy Interface: Device Operation: controlq}\label{sec:Device Types / SCSI Host Device / Device Operation / Device Operation: controlq / Legacy Interface: Device Operation: controlq}
+
+When using the legacy interface, transitional devices and drivers
+MUST format the fields in struct virtio_scsi_ctrl, struct
+virtio_scsi_ctrl_tmf, struct virtio_scsi_ctrl_an and struct
+virtio_scsi_ctrl_an
+according to the native endian of the guest rather than
+(necessarily when not using the legacy interface) little-endian.
+
+
+\subsubsection{Device Operation: eventq}\label{sec:Device Types / SCSI Host Device / Device Operation / Device Operation: eventq}
+
+The eventq is populated by the driver for the device to report information on logical
+units that are attached to it. In general, the device will not
+queue events to cope with an empty eventq, and will end up
+dropping events if it finds no buffer ready. However, when
+reporting events for many LUNs (e.g. when a whole target
+disappears), the device can throttle events to avoid dropping
+them. For this reason, placing 10-15 buffers on the event queue
+is sufficient.
+
+Buffers returned by the device on the eventq will be referred to
+as ``events'' in the rest of this section. Events have the
+following format:
+
+\begin{lstlisting}
+#define VIRTIO_SCSI_T_EVENTS_MISSED   0x80000000
+
+struct virtio_scsi_event {
+        // Device-writable part
+        le32 event;
+        u8  lun[8];
+        le32 reason;
+};
+\end{lstlisting}
+
+The devices sets bit 31 in \field{event} to report lost events
+due to missing buffers.
+
+The meaning of \field{reason} depends on the
+contents of \field{event}. The following events are defined:
+
+\begin{itemize}
+\item No event.
+\begin{lstlisting}
+#define VIRTIO_SCSI_T_NO_EVENT         0
+\end{lstlisting}
+
+  This event is fired in the following cases:
+
+\begin{itemize}
+\item When the device detects in the eventq a buffer that is
+    shorter than what is indicated in the configuration field, it
+    MAY use it immediately and put this dummy value in \field{event}.
+    A well-written driver will never observe this
+    situation.
+
+\item When events are dropped, the device MAY signal this event as
+    soon as the drivers makes a buffer available, in order to
+    request action from the driver. In this case, of course, this
+    event will be reported with the VIRTIO_SCSI_T_EVENTS_MISSED
+    flag.
+\end{itemize}
+
+\item Transport reset
+\begin{lstlisting}
+#define VIRTIO_SCSI_T_TRANSPORT_RESET  1
+
+#define VIRTIO_SCSI_EVT_RESET_HARD         0
+#define VIRTIO_SCSI_EVT_RESET_RESCAN       1
+#define VIRTIO_SCSI_EVT_RESET_REMOVED      2
+\end{lstlisting}
+
+  By sending this event, the device signals that a logical unit
+  on a target has been reset, including the case of a new device
+  appearing or disappearing on the bus. The device fills in all
+  fields. \field{event} is set to
+  VIRTIO_SCSI_T_TRANSPORT_RESET. \field{lun} addresses a
+  logical unit in the SCSI host.
+
+  The \field{reason} value is one of the three \#define values appearing
+  above:
+
+  \begin{description}
+  \item[VIRTIO_SCSI_EVT_RESET_REMOVED] (``LUN/target removed'') is used
+    if the target or logical unit is no longer able to receive
+    commands.
+
+  \item[VIRTIO_SCSI_EVT_RESET_HARD] (``LUN hard reset'') is used if the
+    logical unit has been reset, but is still present.
+
+  \item[VIRTIO_SCSI_EVT_RESET_RESCAN] (``rescan LUN/target'') is used if
+    a target or logical unit has just appeared on the device.
+  \end{description}
+
+  The ``removed'' and ``rescan'' events can happen when
+  VIRTIO_SCSI_F_HOTPLUG feature was negotiated; when sent for LUN 0,
+  they MAY apply to the entire target so the driver can ask the
+  initiator to rescan the target to detect this.
+
+  Events will also be reported via sense codes (this obviously
+  does not apply to newly appeared buses or targets, since the
+  application has never discovered them):
+
+  \begin{itemize}
+  \item ``LUN/target removed'' maps to sense key ILLEGAL REQUEST, asc
+    0x25, ascq 0x00 (LOGICAL UNIT NOT SUPPORTED)
+
+  \item ``LUN hard reset'' maps to sense key UNIT ATTENTION, asc 0x29
+    (POWER ON, RESET OR BUS DEVICE RESET OCCURRED)
+
+  \item ``rescan LUN/target'' maps to sense key UNIT ATTENTION, asc
+    0x3f, ascq 0x0e (REPORTED LUNS DATA HAS CHANGED)
+  \end{itemize}
+
+  The preferred way to detect transport reset is always to use
+  events, because sense codes are only seen by the driver when it
+  sends a SCSI command to the logical unit or target. However, in
+  case events are dropped, the initiator will still be able to
+  synchronize with the actual state of the controller if the
+  driver asks the initiator to rescan of the SCSI bus. During the
+  rescan, the initiator will be able to observe the above sense
+  codes, and it will process them as if it the driver had
+  received the equivalent event.
+
+  \item Asynchronous notification
+\begin{lstlisting}
+#define VIRTIO_SCSI_T_ASYNC_NOTIFY     2
+\end{lstlisting}
+
+  By sending this event, the device signals that an asynchronous
+  event was fired from a physical interface.
+
+  All fields are written by the device. \field{event} is set to
+  VIRTIO_SCSI_T_ASYNC_NOTIFY. \field{lun} addresses a logical
+  unit in the SCSI host. \field{reason} is a subset of the
+  events that the driver has subscribed to via the ``Asynchronous
+  notification subscription'' command.
+
+  \item LUN parameter change
+\begin{lstlisting}
+#define VIRTIO_SCSI_T_PARAM_CHANGE  3
+\end{lstlisting}
+
+  By sending this event, the device signals a change in the configuration parameters
+  of a logical unit, for example the capacity or cache mode.
+  \field{event} is set to VIRTIO_SCSI_T_PARAM_CHANGE.
+  \field{lun} addresses a logical unit in the SCSI host.
+
+  The same event SHOULD also be reported as a unit attention condition.
+  \field{reason} contains the additional sense code and additional sense code qualifier,
+  respectively in bits 0\ldots 7 and 8\ldots 15.
+  \begin{note}
+  For example, a change in capacity will be reported as asc 0x2a, ascq 0x09
+  (CAPACITY DATA HAS CHANGED).
+  \end{note}
+
+  For MMC devices (inquiry type 5) there would be some overlap between this
+  event and the asynchronous notification event, so for simplicity the host never
+  reports this event for MMC devices.
+\end{itemize}
+
+\drivernormative{\paragraph}{Device Operation: eventq}{Device Types / SCSI Host Device / Device Operation / Device Operation: eventq}
+
+The driver SHOULD keep the eventq populated with buffers.  These
+buffers MUST be device-writable, and SHOULD be at least
+\field{event_info_size} bytes long, and MUST be at least the size of
+struct virtio_scsi_event.
+
+If \field{event} has bit 31 set, the driver SHOULD
+poll the logical units for unit attention conditions, and/or do
+whatever form of bus scan is appropriate for the guest operating
+system and SHOULD poll for asynchronous events manually using SCSI commands.
+
+When receiving a VIRTIO_SCSI_T_TRANSPORT_RESET message with
+\field{reason} set to VIRTIO_SCSI_EVT_RESET_REMOVED or
+VIRTIO_SCSI_EVT_RESET_RESCAN for LUN 0, the driver SHOULD ask the
+initiator to rescan the target, in order to detect the case when an
+entire target has appeared or disappeared.
+
+\devicenormative{\paragraph}{Device Operation: eventq}{Device Types / SCSI Host Device / Device Operation / Device Operation: eventq}
+
+The device MUST set bit 31 in \field{event} if events were lost due to
+missing buffers, and it MAY use a VIRTIO_SCSI_T_NO_EVENT event to report
+this.
+
+The device MUST NOT send VIRTIO_SCSI_T_TRANSPORT_RESET messages
+with \field{reason} set to VIRTIO_SCSI_EVT_RESET_REMOVED or
+VIRTIO_SCSI_EVT_RESET_RESCAN unless VIRTIO_SCSI_F_HOTPLUG was negotiated.
+
+The device MUST NOT report VIRTIO_SCSI_T_PARAM_CHANGE for MMC devices.
+
+\paragraph{Legacy Interface: Device Operation: eventq}\label{sec:Device Types / SCSI Host Device / Device Operation / Device Operation: eventq / Legacy Interface: Device Operation: eventq}
+When using the legacy interface, transitional devices and drivers
+MUST format the fields in struct virtio_scsi_event
+according to the native endian of the guest rather than
+(necessarily when not using the legacy interface) little-endian.
+
+\subsubsection{Legacy Interface: Framing Requirements}\label{sec:Device
+Types / SCSI Host Device / Legacy Interface: Framing Requirements}
+
+When using legacy interfaces, transitional drivers which have not
+negotiated VIRTIO_F_ANY_LAYOUT MUST use a single descriptor for the
+\field{lun}, \field{id}, \field{task_attr}, \field{prio},
+\field{crn} and \field{cdb} fields, and MUST only use a single
+descriptor for the \field{sense_len}, \field{residual},
+\field{status_qualifier}, \field{status}, \field{response} and
+\field{sense} fields.
+
+
-- 
2.26.2



[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]