summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--content.tex962
1 files changed, 481 insertions, 481 deletions
diff --git a/content.tex b/content.tex
index 48698fc..456b167 100644
--- a/content.tex
+++ b/content.tex
@@ -156,12 +156,12 @@ space.
Thus drivers SHOULD read configuration space fields like so:
\begin{lstlisting}
- u32 before, after;
- do {
- before = get_config_generation(device);
- // read config entry/entries.
- after = get_config_generation(device);
- } while (after != before);
+u32 before, after;
+do {
+ before = get_config_generation(device);
+ // read config entry/entries.
+ after = get_config_generation(device);
+} while (after != before);
\end{lstlisting}
Note that configuration space uses the little-endian format
@@ -269,31 +269,31 @@ The bus-specific Queue Size field controls the total number of bytes
required for the virtqueue according to the following formula:
\begin{lstlisting}
- #define ALIGN(x) (((x) + PAGE_SIZE) & ~PAGE_SIZE)
- static inline unsigned vring_size(unsigned int qsz)
- {
- return ALIGN(sizeof(struct vring_desc)*qsz + sizeof(u16)*(3 + qsz))
- + ALIGN(sizeof(u16)*3 + sizeof(struct vring_used_elem)*qsz);
- }
+#define ALIGN(x) (((x) + PAGE_SIZE) & ~PAGE_SIZE)
+static inline unsigned vring_size(unsigned int qsz)
+{
+ return ALIGN(sizeof(struct vring_desc)*qsz + sizeof(u16)*(3 + qsz))
+ + ALIGN(sizeof(u16)*3 + sizeof(struct vring_used_elem)*qsz);
+}
\end{lstlisting}
This wastes some space with padding.
The legacy virtqueue layout structure therefore looks like this:
\begin{lstlisting}
- struct vring {
- // The actual descriptors (16 bytes each)
- struct vring_desc desc[ Queue Size ];
+struct vring {
+ // The actual descriptors (16 bytes each)
+ struct vring_desc desc[ Queue Size ];
- // A ring of available descriptor heads with free-running index.
- struct vring_avail avail;
+ // A ring of available descriptor heads with free-running index.
+ struct vring_avail avail;
- // Padding to the next PAGE_SIZE boundary.
- char pad[ Padding ];
+ // Padding to the next PAGE_SIZE boundary.
+ char pad[ Padding ];
- // A ring of used descriptor heads with free-running index.
- struct vring_used used;
- };
+ // A ring of used descriptor heads with free-running index.
+ struct vring_used used;
+};
\end{lstlisting}
\subsection{Legacy Interfaces: A Note on Virtqueue Endianness}\label{sec:Basic Facilities of a Virtio Device / Virtqueues / Legacy Interfaces: A Note on Virtqueue Endianness}
@@ -349,23 +349,23 @@ Drivers MUST NOT add a descriptor chain over than $2^{32}$ bytes long in total;
this implies that loops in the descriptor chain are forbidden!
\begin{lstlisting}
- struct vring_desc {
- /* Address (guest-physical). */
- le64 addr;
- /* Length. */
- le32 len;
-
- /* This marks a buffer as continuing via the next field. */
- #define VRING_DESC_F_NEXT 1
- /* This marks a buffer as write-only (otherwise read-only). */
- #define VRING_DESC_F_WRITE 2
- /* This means the buffer contains a list of buffer descriptors. */
- #define VRING_DESC_F_INDIRECT 4
- /* The flags as indicated above. */
- le16 flags;
- /* Next field if flags & NEXT */
- le16 next;
- };
+struct vring_desc {
+ /* Address (guest-physical). */
+ le64 addr;
+ /* Length. */
+ le32 len;
+
+/* This marks a buffer as continuing via the next field. */
+#define VRING_DESC_F_NEXT 1
+/* This marks a buffer as write-only (otherwise read-only). */
+#define VRING_DESC_F_WRITE 2
+/* This means the buffer contains a list of buffer descriptors. */
+#define VRING_DESC_F_INDIRECT 4
+ /* The flags as indicated above. */
+ le16 flags;
+ /* Next field if flags & NEXT */
+ le16 next;
+};
\end{lstlisting}
The number of descriptors in the table is defined by the queue size
@@ -390,10 +390,10 @@ The indirect table layout structure looks like this
which is a variable, so this code won't compile):
\begin{lstlisting}
- struct indirect_descriptor_table {
- /* The actual descriptors (16 bytes each) */
- struct vring_desc desc[len / 16];
- };
+struct indirect_descriptor_table {
+ /* The actual descriptors (16 bytes each) */
+ struct vring_desc desc[len / 16];
+};
\end{lstlisting}
The first indirect descriptor is located at start of the indirect
@@ -409,13 +409,13 @@ the device MUST ignore the write-only flag (flags\&VRING_DESC_F_WRITE) in the de
\subsection{The Virtqueue Available Ring}\label{sec:Basic Facilities of a Virtio Device / Virtqueues / The Virtqueue Available Ring}
\begin{lstlisting}
- struct vring_avail {
- #define VRING_AVAIL_F_NO_INTERRUPT 1
- le16 flags;
- le16 idx;
- le16 ring[ /* Queue Size */ ];
- le16 used_event; /* Only if VIRTIO_RING_F_EVENT_IDX */
- };
+struct vring_avail {
+#define VRING_AVAIL_F_NO_INTERRUPT 1
+ le16 flags;
+ le16 idx;
+ le16 ring[ /* Queue Size */ ];
+ le16 used_event; /* Only if VIRTIO_RING_F_EVENT_IDX */
+};
\end{lstlisting}
The driver uses the available ring to offer buffers to the
@@ -445,21 +445,21 @@ entirely.
\subsection{The Virtqueue Used Ring}\label{sec:Basic Facilities of a Virtio Device / Virtqueues / The Virtqueue Used Ring}
\begin{lstlisting}
- struct vring_used {
- #define VRING_USED_F_NO_NOTIFY 1
- le16 flags;
- le16 idx;
- struct vring_used_elem ring[ /* Queue Size */];
- le16 avail_event; /* Only if VIRTIO_RING_F_EVENT_IDX */
- };
-
- /* le32 is used here for ids for padding reasons. */
- struct vring_used_elem {
- /* Index of start of used descriptor chain. */
- le32 id;
- /* Total length of the descriptor chain which was used (written to) */
- le32 len;
- };
+struct vring_used {
+#define VRING_USED_F_NO_NOTIFY 1
+ le16 flags;
+ le16 idx;
+ struct vring_used_elem ring[ /* Queue Size */];
+ le16 avail_event; /* Only if VIRTIO_RING_F_EVENT_IDX */
+};
+
+/* le32 is used here for ids for padding reasons. */
+struct vring_used_elem {
+ /* Index of start of used descriptor chain. */
+ le32 id;
+ /* Total length of the descriptor chain which was used (written to) */
+ le32 len;
+};
\end{lstlisting}
The used ring is where the device returns buffers once it is done with
@@ -650,7 +650,7 @@ part of the buffer. A naive implementation would do the following (with the
appropriate conversion to-and-from little-endian assumed):
\begin{lstlisting}
- avail->ring[avail->idx % qsz] = head;
+avail->ring[avail->idx % qsz] = head;
\end{lstlisting}
However, in general the driver can add many descriptor chains before it updates
@@ -658,7 +658,7 @@ the “idx” field (at which point they become visible to the
device), so it is common to keep a counter of how many the driver has added:
\begin{lstlisting}
- avail->ring[(avail->idx + added++) % qsz] = head;
+avail->ring[(avail->idx + added++) % qsz] = head;
\end{lstlisting}
\subsubsection{Updating The Index Field}\label{sec:General Initialization And Device Operation / Device Operation / Supplying Buffers to The Device / Updating The Index Field}
@@ -673,7 +673,7 @@ The index field always increments, and the driver can let it wrap naturally at
65536:
\begin{lstlisting}
- avail->idx += added;
+avail->idx += added;
\end{lstlisting}
\subsubsection{Notifying The Device}\label{sec:General Initialization And Device Operation / Device Operation / Supplying Buffers to The Device / Notifying The Device}
@@ -698,7 +698,7 @@ giving the following algorithm for calculating whether a device needs
notification:
\begin{lstlisting}
- (u16)(new_idx - avail_event - 1) < (u16)(new_idx - old_idx)
+(u16)(new_idx - avail_event - 1) < (u16)(new_idx - old_idx)
\end{lstlisting}
\subsection{Receiving Used Buffers From The Device}\label{sec:General Initialization And Device Operation / Device Operation / Receiving Used Buffers From The Device}
@@ -727,7 +727,7 @@ buffer:
since the last update. The used_event field wraps naturally
at 65536 as well:
\begin{lstlisting}
- (u16)(new_idx - used_event - 1) < (u16)(new_idx - old_idx)
+(u16)(new_idx - used_event - 1) < (u16)(new_idx - old_idx)
\end{lstlisting}
\end{enumerate}
\end{enumerate}
@@ -743,21 +743,21 @@ last check and before enabling interrupts, an interrupt has been
suppressed by the device:
\begin{lstlisting}
- vring_disable_interrupts(vq);
+vring_disable_interrupts(vq);
- for (;;) {
- if (vq->last_seen_used != le16_to_cpu(vring->used.idx)) {
- vring_enable_interrupts(vq);
- mb();
+for (;;) {
+ if (vq->last_seen_used != le16_to_cpu(vring->used.idx)) {
+ vring_enable_interrupts(vq);
+ mb();
- if (vq->last_seen_used != le16_to_cpu(vring->used.idx))
- break;
- }
+ if (vq->last_seen_used != le16_to_cpu(vring->used.idx))
+ break;
+ }
- struct vring_used_elem *e = vring.used->ring[vq->last_seen_used%vsz];
- process_buffer(e);
- vq->last_seen_used++;
- }
+ struct vring_used_elem *e = vring.used->ring[vq->last_seen_used%vsz];
+ process_buffer(e);
+ vq->last_seen_used++;
+}
\end{lstlisting}
\subsection{Notification of Device Configuration Changes}\label{sec:General Initialization And Device Operation / Device Operation / Notification of Device Configuration Changes}
@@ -822,27 +822,27 @@ All multi-byte fields are little-endian.
Common configuration structure layout is documented below:
\begin{lstlisting}
- struct virtio_pci_common_cfg {
- /* About the whole device. */
- le32 device_feature_select; /* read-write */
- le32 device_feature; /* read-only */
- le32 driver_feature_select; /* read-write */
- le32 driver_feature; /* read-write */
- le16 msix_config; /* read-write */
- le16 num_queues; /* read-only */
- u8 device_status; /* read-write */
- u8 config_generation; /* read-only */
-
- /* About a specific virtqueue. */
- le16 queue_select; /* read-write */
- le16 queue_size; /* read-write, power of 2, or 0. */
- le16 queue_msix_vector; /* read-write */
- le16 queue_enable; /* read-write */
- le16 queue_notify_off; /* read-only */
- le64 queue_desc; /* read-write */
- le64 queue_avail; /* read-write */
- le64 queue_used; /* read-write */
- };
+struct virtio_pci_common_cfg {
+ /* About the whole device. */
+ le32 device_feature_select; /* read-write */
+ le32 device_feature; /* read-only */
+ le32 driver_feature_select; /* read-write */
+ le32 driver_feature; /* read-write */
+ le16 msix_config; /* read-write */
+ le16 num_queues; /* read-only */
+ u8 device_status; /* read-write */
+ u8 config_generation; /* read-only */
+
+ /* About a specific virtqueue. */
+ le16 queue_select; /* read-write */
+ le16 queue_size; /* read-write, power of 2, or 0. */
+ le16 queue_msix_vector; /* read-write */
+ le16 queue_enable; /* read-write */
+ le16 queue_notify_off; /* read-only */
+ le64 queue_desc; /* read-write */
+ le64 queue_avail; /* read-write */
+ le64 queue_used; /* read-write */
+};
\end{lstlisting}
\begin{description}
@@ -1030,16 +1030,16 @@ This virtio structure capability uses little-endian format; all bits are
read-only:
\begin{lstlisting}
- struct virtio_pci_cap {
- u8 cap_vndr; /* Generic PCI field: PCI_CAP_ID_VNDR */
- u8 cap_next; /* Generic PCI field: next ptr. */
- u8 cap_len; /* Generic PCI field: capability length */
- u8 cfg_type; /* Identifies the structure. */
- u8 bar; /* Where to find it. */
- u8 padding[3]; /* Pad to full dword. */
- le32 offset; /* Offset within bar. */
- le32 length; /* Length of the structure, in bytes. */
- };
+struct virtio_pci_cap {
+ u8 cap_vndr; /* Generic PCI field: PCI_CAP_ID_VNDR */
+ u8 cap_next; /* Generic PCI field: next ptr. */
+ u8 cap_len; /* Generic PCI field: capability length */
+ u8 cfg_type; /* Identifies the structure. */
+ u8 bar; /* Where to find it. */
+ u8 padding[3]; /* Pad to full dword. */
+ le32 offset; /* Offset within bar. */
+ le32 length; /* Length of the structure, in bytes. */
+};
\end{lstlisting}
This structure can optionally be followed by extra data, depending on
@@ -1077,16 +1077,16 @@ The fields are interpreted as follows:
identifies the structure, according to the following table.
\begin{lstlisting}
- /* Common configuration */
- #define VIRTIO_PCI_CAP_COMMON_CFG 1
- /* Notifications */
- #define VIRTIO_PCI_CAP_NOTIFY_CFG 2
- /* ISR Status */
- #define VIRTIO_PCI_CAP_ISR_CFG 3
- /* Device specific configuration */
- #define VIRTIO_PCI_CAP_DEVICE_CFG 4
- /* PCI configuration access */
- #define VIRTIO_PCI_CAP_PCI_CFG 5
+/* Common configuration */
+#define VIRTIO_PCI_CAP_COMMON_CFG 1
+/* Notifications */
+#define VIRTIO_PCI_CAP_NOTIFY_CFG 2
+/* ISR Status */
+#define VIRTIO_PCI_CAP_ISR_CFG 3
+/* Device specific configuration */
+#define VIRTIO_PCI_CAP_DEVICE_CFG 4
+/* PCI configuration access */
+#define VIRTIO_PCI_CAP_PCI_CFG 5
\end{lstlisting}
Any other value - reserved for future use. Drivers MUST
@@ -1136,10 +1136,10 @@ If cfg_type is VIRTIO_PCI_CAP_NOTIFY_CFG this structure is immediately followed
by additional fields:
\begin{lstlisting}
- struct virtio_pci_notify_cap {
- struct virtio_pci_cap cap;
- le32 notify_off_multiplier; /* Multiplier for queue_notify_off. */
- };
+struct virtio_pci_notify_cap {
+ struct virtio_pci_cap cap;
+ le32 notify_off_multiplier; /* Multiplier for queue_notify_off. */
+};
\end{lstlisting}
\begin{description}
@@ -1159,9 +1159,9 @@ If cfg_type is VIRTIO_PCI_CAP_PCI_CFG the fields bar, offset and length are RW
and this structure is immediately followed by an additional field:
\begin{lstlisting}
- struct virtio_pci_cfg_cap {
- __u8 pci_cfg_data[4]; /* Data for BAR access. */
- };
+struct virtio_pci_cfg_cap {
+ __u8 pci_cfg_data[4]; /* Data for BAR access. */
+};
\end{lstlisting}
\begin{description}
@@ -1233,8 +1233,8 @@ specific event type, unmap it by writing a special NO_VECTOR
value:
\begin{lstlisting}
- /* Vector value used to disable MSI for queue */
- #define VIRTIO_MSI_NO_VECTOR 0xffff
+/* Vector value used to disable MSI for queue */
+#define VIRTIO_MSI_NO_VECTOR 0xffff
\end{lstlisting}
Reading these registers returns vector mapped to a given event,
@@ -1374,12 +1374,12 @@ and interrupt(s) used. The suggested binding for systems using
flattened device trees is shown in this example:
\begin{lstlisting}
- // EXAMPLE: virtio_block device taking 256 bytes at 0x1e000, interrupt 42.
- virtio_block@1e000 {
- compatible = "virtio,mmio";
- reg = <0x1e000 0x100>;
- interrupts = <42>;
- }
+// EXAMPLE: virtio_block device taking 256 bytes at 0x1e000, interrupt 42.
+virtio_block@1e000 {
+ compatible = "virtio,mmio";
+ reg = <0x1e000 0x100>;
+ interrupts = <42>;
+}
\end{lstlisting}
\subsection{MMIO Device Register Layout}\label{sec:Virtio Transport Options / Virtio Over MMIO / MMIO Device Register Layout}
@@ -1875,18 +1875,18 @@ set of channel commands related to configuration and operation of
virtio:
\begin{lstlisting}
- #define CCW_CMD_SET_VQ 0x13
- #define CCW_CMD_VDEV_RESET 0x33
- #define CCW_CMD_SET_IND 0x43
- #define CCW_CMD_SET_CONF_IND 0x53
- #define CCW_CMD_SET_IND_ADAPTER 0x73
- #define CCW_CMD_READ_FEAT 0x12
- #define CCW_CMD_WRITE_FEAT 0x11
- #define CCW_CMD_READ_CONF 0x22
- #define CCW_CMD_WRITE_CONF 0x21
- #define CCW_CMD_WRITE_STATUS 0x31
- #define CCW_CMD_READ_VQ_CONF 0x32
- #define CCW_CMD_SET_VIRTIO_REV 0x83
+#define CCW_CMD_SET_VQ 0x13
+#define CCW_CMD_VDEV_RESET 0x33
+#define CCW_CMD_SET_IND 0x43
+#define CCW_CMD_SET_CONF_IND 0x53
+#define CCW_CMD_SET_IND_ADAPTER 0x73
+#define CCW_CMD_READ_FEAT 0x12
+#define CCW_CMD_WRITE_FEAT 0x11
+#define CCW_CMD_READ_CONF 0x22
+#define CCW_CMD_WRITE_CONF 0x21
+#define CCW_CMD_WRITE_STATUS 0x31
+#define CCW_CMD_READ_VQ_CONF 0x32
+#define CCW_CMD_SET_VIRTIO_REV 0x83
\end{lstlisting}
The virtio-ccw device acts like a normal channel device, as specified
@@ -1919,11 +1919,11 @@ the virtio-ccw transport it intends to drive the device with. It uses the
following communication structure:
\begin{lstlisting}
- struct virtio_rev_info {
- be16 revision;
- be16 length;
- u8 data[];
- };
+struct virtio_rev_info {
+ be16 revision;
+ be16 length;
+ u8 data[];
+};
\end{lstlisting}
revision contains the desired revision id, length the length of the
@@ -1991,10 +1991,10 @@ CCW_CMD_READ_VQ_CONF is issued by the driver to obtain information
about a queue. It uses the following structure for communicating:
\begin{lstlisting}
- struct vq_config_block {
- be16 index;
- be16 max_num;
- } __attribute__ ((packed));
+struct vq_config_block {
+ be16 index;
+ be16 max_num;
+} __attribute__ ((packed));
\end{lstlisting}
The requested number of buffers for queue index is returned in
@@ -2005,14 +2005,14 @@ device about the location used for its queue. The transmitted
structure is
\begin{lstlisting}
- struct vq_info_block {
- be64 desc;
- be32 res0;
- be16 index;
- be16 num;
- be64 avail;
- be64 used;
- } __attribute__ ((packed));
+struct vq_info_block {
+ be64 desc;
+ be32 res0;
+ be16 index;
+ be16 num;
+ be64 avail;
+ be64 used;
+} __attribute__ ((packed));
\end{lstlisting}
desc, avail and used contain the guest addresses for the descriptor table,
@@ -2026,12 +2026,12 @@ For a legacy driver or for a driver that selected revision 0,
CCW_CMD_SET_VQ uses the following communication block:
\begin{lstlisting}
- struct vq_info_block_legacy {
- be64 queue;
- be32 align;
- be16 index;
- be16 num;
- } __attribute__ ((packed));
+struct vq_info_block_legacy {
+ be64 queue;
+ be32 align;
+ be16 index;
+ be16 num;
+} __attribute__ ((packed));
\end{lstlisting}
queue contains the guest address for queue index, num the number of buffers
@@ -2051,13 +2051,13 @@ Descriptor Table & Available Ring (\ldots padding\ldots) & Used Ring \\
The calculation for total size is as follows:
\begin{lstlisting}
- #define ALIGN(x) (((x) + align) & ~align)
- static inline unsigned vring_size(unsigned int num)
- {
- return ALIGN(sizeof(struct vring_desc)*num
- + sizeof(u16)*(3 + num))
- + ALIGN(sizeof(u16)*3 + sizeof(struct vring_used_elem)*num);
- }
+#define ALIGN(x) (((x) + align) & ~align)
+static inline unsigned vring_size(unsigned int num)
+{
+ return ALIGN(sizeof(struct vring_desc)*num
+ + sizeof(u16)*(3 + num))
+ + ALIGN(sizeof(u16)*3 + sizeof(struct vring_used_elem)*num);
+}
\end{lstlisting}
\subsubsection{Communicating Status Information}\label{sec:Virtio Transport Options / Virtio over channel I/O / Device Initialization / Communicating Status Information}
@@ -2076,10 +2076,10 @@ The CCW commands dealing with features use the following
communication block:
\begin{lstlisting}
- struct virtio_feature_desc {
- le32 features;
- u8 index;
- } __attribute__ ((packed));
+struct virtio_feature_desc {
+ le32 features;
+ u8 index;
+} __attribute__ ((packed));
\end{lstlisting}
features are the 32 bits of features currently accessed, while
@@ -2164,12 +2164,12 @@ the driver uses the CCW_CMD_SET_IND_ADAPTER command with the following
payload:
\begin{lstlisting}
- struct virtio_thinint_area {
- be64 summary_indicator;
- be64 indicator;
- be64 bit_nr;
- u8 isc;
- } __attribute__ ((packed));
+struct virtio_thinint_area {
+ be64 summary_indicator;
+ be64 indicator;
+ be64 bit_nr;
+ u8 isc;
+} __attribute__ ((packed));
\end{lstlisting}
summary_indicator contains the guest address of the 8 bit summary
@@ -2271,9 +2271,9 @@ For each notification, the output value is returned in GPR2 and
should be passed in GPR4 for the next notification:
\begin{lstlisting}
- info->cookie = do_notify(schid,
- virtqueue_get_queue_index(vq),
- info->cookie);
+info->cookie = do_notify(schid,
+ virtqueue_get_queue_index(vq),
+ info->cookie);
\end{lstlisting}
\subsubsection{Resetting Devices}\label{sec:Virtio Transport Options / Virtio over channel I/O / Device Operation / Resetting Devices}
@@ -2423,8 +2423,8 @@ read-only bits are currently defined for the status field:
VIRTIO_NET_S_LINK_UP and VIRTIO_NET_S_ANNOUNCE.
\begin{lstlisting}
- #define VIRTIO_NET_S_LINK_UP 1
- #define VIRTIO_NET_S_ANNOUNCE 2
+#define VIRTIO_NET_S_LINK_UP 1
+#define VIRTIO_NET_S_ANNOUNCE 2
\end{lstlisting}
The following read-only field, max_virtqueue_pairs only exists if
@@ -2435,11 +2435,11 @@ and transmitq0..transmitqN respectively;
is negotiated. Legal values for this field are 1 to 0x8000.
\begin{lstlisting}
- struct virtio_net_config {
- u8 mac[6];
- le16 status;
- le16 max_virtqueue_pairs;
- };
+struct virtio_net_config {
+ u8 mac[6];
+ le16 status;
+ le16 max_virtqueue_pairs;
+};
\end{lstlisting}
\subsubsection{Legacy Interface: Device configuration layout}\label{sec:Device Types / Network Device / Device configuration layout / Legacy Interface: Device configuration layout}
@@ -2521,22 +2521,22 @@ placed in the receiveq0..receiveqN. In each case, the packet
itself is preceeded by a header:
\begin{lstlisting}
- struct virtio_net_hdr {
- #define VIRTIO_NET_HDR_F_NEEDS_CSUM 1
- u8 flags;
- #define VIRTIO_NET_HDR_GSO_NONE 0
- #define VIRTIO_NET_HDR_GSO_TCPV4 1
- #define VIRTIO_NET_HDR_GSO_UDP 3
- #define VIRTIO_NET_HDR_GSO_TCPV6 4
- #define VIRTIO_NET_HDR_GSO_ECN 0x80
- u8 gso_type;
- le16 hdr_len;
- le16 gso_size;
- le16 csum_start;
- le16 csum_offset;
- /* Only if VIRTIO_NET_F_MRG_RXBUF: */
- le16 num_buffers;
- };
+struct virtio_net_hdr {
+#define VIRTIO_NET_HDR_F_NEEDS_CSUM 1
+ u8 flags;
+#define VIRTIO_NET_HDR_GSO_NONE 0
+#define VIRTIO_NET_HDR_GSO_TCPV4 1
+#define VIRTIO_NET_HDR_GSO_UDP 3
+#define VIRTIO_NET_HDR_GSO_TCPV6 4
+#define VIRTIO_NET_HDR_GSO_ECN 0x80
+ u8 gso_type;
+ le16 hdr_len;
+ le16 gso_size;
+ le16 csum_start;
+ le16 csum_offset;
+/* Only if VIRTIO_NET_F_MRG_RXBUF: */
+ le16 num_buffers;
+};
\end{lstlisting}
The controlq is used to control device features such as
@@ -2691,16 +2691,16 @@ space.
All commands are of the following form:
\begin{lstlisting}
- struct virtio_net_ctrl {
- u8 class;
- u8 command;
- u8 command-specific-data[];
- u8 ack;
- };
-
- /* ack values */
- #define VIRTIO_NET_OK 0
- #define VIRTIO_NET_ERR 1
+struct virtio_net_ctrl {
+ u8 class;
+ u8 command;
+ u8 command-specific-data[];
+ u8 ack;
+};
+
+/* ack values */
+#define VIRTIO_NET_OK 0
+#define VIRTIO_NET_ERR 1
\end{lstlisting}
The class, command and command-specific-data are set by the
@@ -2720,9 +2720,9 @@ packets may still arrive.
\paragraph{Setting Promiscuous Mode}\label{sec:Device Types / Network Device / Device Operation / Control Virtqueue / Setting Promiscuous Mode}
\begin{lstlisting}
- #define VIRTIO_NET_CTRL_RX 0
- #define VIRTIO_NET_CTRL_RX_PROMISC 0
- #define VIRTIO_NET_CTRL_RX_ALLMULTI 1
+#define VIRTIO_NET_CTRL_RX 0
+ #define VIRTIO_NET_CTRL_RX_PROMISC 0
+ #define VIRTIO_NET_CTRL_RX_ALLMULTI 1
\end{lstlisting}
The class VIRTIO_NET_CTRL_RX has two commands:
@@ -2734,14 +2734,14 @@ off. The command-specific-data is one byte containing 0 (off) or
\paragraph{Setting MAC Address Filtering}\label{sec:Device Types / Network Device / Device Operation / Control Virtqueue / Setting MAC Address Filtering}
\begin{lstlisting}
- struct virtio_net_ctrl_mac {
- le32 entries;
- u8 macs[entries][ETH_ALEN];
- };
-
- #define VIRTIO_NET_CTRL_MAC 1
- #define VIRTIO_NET_CTRL_MAC_TABLE_SET 0
- #define VIRTIO_NET_CTRL_MAC_ADDR_SET 1
+struct virtio_net_ctrl_mac {
+ le32 entries;
+ u8 macs[entries][ETH_ALEN];
+};
+
+#define VIRTIO_NET_CTRL_MAC 1
+ #define VIRTIO_NET_CTRL_MAC_TABLE_SET 0
+ #define VIRTIO_NET_CTRL_MAC_ADDR_SET 1
\end{lstlisting}
The device can filter incoming packets by any number of destination
@@ -2794,9 +2794,9 @@ If the driver negotiates the VIRTION_NET_F_CTRL_VLAN feature, it
can control a VLAN filter table in the device.
\begin{lstlisting}
- #define VIRTIO_NET_CTRL_VLAN 2
- #define VIRTIO_NET_CTRL_VLAN_ADD 0
- #define VIRTIO_NET_CTRL_VLAN_DEL 1
+#define VIRTIO_NET_CTRL_VLAN 2
+ #define VIRTIO_NET_CTRL_VLAN_ADD 0
+ #define VIRTIO_NET_CTRL_VLAN_DEL 1
\end{lstlisting}
Both the VIRTIO_NET_CTRL_VLAN_ADD and VIRTIO_NET_CTRL_VLAN_DEL
@@ -2817,8 +2817,8 @@ network configuration (eg. tagged vlan) it is simplest to prod
the guest in this way).
\begin{lstlisting}
- #define VIRTIO_NET_CTRL_ANNOUNCE 3
- #define VIRTIO_NET_CTRL_ANNOUNCE_ACK 0
+#define VIRTIO_NET_CTRL_ANNOUNCE 3
+ #define VIRTIO_NET_CTRL_ANNOUNCE_ACK 0
\end{lstlisting}
The Driver needs to check VIRTIO_NET_S_ANNOUNCE bit in status
@@ -2848,14 +2848,14 @@ queue incoming packets into one of the multiple receiveq0..receiveqN
depending on the packet flow.
\begin{lstlisting}
- struct virtio_net_ctrl_mq {
- le16 virtqueue_pairs;
- };
-
- #define VIRTIO_NET_CTRL_MQ 4
- #define VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET 0
- #define VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MIN 1
- #define VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MAX 0x8000
+struct virtio_net_ctrl_mq {
+ le16 virtqueue_pairs;
+};
+
+#define VIRTIO_NET_CTRL_MQ 4
+ #define VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET 0
+ #define VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MIN 1
+ #define VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MAX 0x8000
\end{lstlisting}
Multiqueue is disabled by default. The driver enables multiqueue by
@@ -2894,16 +2894,16 @@ send control commands for dynamic offloads state configuration.
\subparagraph{Setting Offloads State}\label{sec:Device Types / Network Device / Device Operation / Control Virtqueue / Offloads State Configuration / Setting Offloads State}
\begin{lstlisting}
- le64 offloads;
+le64 offloads;
- #define VIRTIO_NET_F_GUEST_CSUM 1
- #define VIRTIO_NET_F_GUEST_TSO4 7
- #define VIRTIO_NET_F_GUEST_TSO6 8
- #define VIRTIO_NET_F_GUEST_ECN 9
- #define VIRTIO_NET_F_GUEST_UFO 10
+#define VIRTIO_NET_F_GUEST_CSUM 1
+#define VIRTIO_NET_F_GUEST_TSO4 7
+#define VIRTIO_NET_F_GUEST_TSO6 8
+#define VIRTIO_NET_F_GUEST_ECN 9
+#define VIRTIO_NET_F_GUEST_UFO 10
- #define VIRTIO_NET_CTRL_GUEST_OFFLOADS 5
- #define VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET 0
+#define VIRTIO_NET_CTRL_GUEST_OFFLOADS 5
+ #define VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET 0
\end{lstlisting}
The class VIRTIO_NET_CTRL_GUEST_OFFLOADS has one command:
@@ -2984,28 +2984,28 @@ present. The availability of the others all depend on various feature
bits as indicated above.
\begin{lstlisting}
- struct virtio_blk_config {
- le64 capacity;
- le32 size_max;
- le32 seg_max;
- struct virtio_blk_geometry {
- le16 cylinders;
- u8 heads;
- u8 sectors;
- } geometry;
- le32 blk_size;
- struct virtio_blk_topology {
- // # of logical blocks per physical block (log2)
- u8 physical_block_exp;
- // offset of first aligned logical block
- u8 alignment_offset;
- // suggested minimum I/O size in blocks
- le16 min_io_size;
- // optimal (suggested maximum) I/O size in blocks
- le32 opt_io_size;
- } topology;
- u8 reserved;
- };
+struct virtio_blk_config {
+ le64 capacity;
+ le32 size_max;
+ le32 seg_max;
+ struct virtio_blk_geometry {
+ le16 cylinders;
+ u8 heads;
+ u8 sectors;
+ } geometry;
+ le32 blk_size;
+ struct virtio_blk_topology {
+ // # of logical blocks per physical block (log2)
+ u8 physical_block_exp;
+ // offset of first aligned logical block
+ u8 alignment_offset;
+ // suggested minimum I/O size in blocks
+ le16 min_io_size;
+ // optimal (suggested maximum) I/O size in blocks
+ le32 opt_io_size;
+ } topology;
+ u8 reserved;
+};
\end{lstlisting}
@@ -3056,13 +3056,13 @@ The driver queues requests to the virtqueue, and they are used by
the device (not necessarily in order). Each request is of form:
\begin{lstlisting}
- struct virtio_blk_req {
- le32 type;
- le32 reserved;
- le64 sector;
- char data[][512];
- u8 status;
- };
+struct virtio_blk_req {
+ le32 type;
+ le32 reserved;
+ le64 sector;
+ char data[][512];
+ u8 status;
+};
\end{lstlisting}
The type of the request is either a read (VIRTIO_BLK_T_IN), a write
@@ -3072,10 +3072,10 @@ distinguish between them
}).
\begin{lstlisting}
- #define VIRTIO_BLK_T_IN 0
- #define VIRTIO_BLK_T_OUT 1
- #define VIRTIO_BLK_T_FLUSH 4
- #define VIRTIO_BLK_T_FLUSH_OUT 5
+#define VIRTIO_BLK_T_IN 0
+#define VIRTIO_BLK_T_OUT 1
+#define VIRTIO_BLK_T_FLUSH 4
+#define VIRTIO_BLK_T_FLUSH_OUT 5
\end{lstlisting}
The sector number indicates the offset (multiplied by 512) where
@@ -3087,9 +3087,9 @@ VIRTIO_BLK_S_OK for success, VIRTIO_BLK_S_IOERR for device or driver
error or VIRTIO_BLK_S_UNSUPP for a request unsupported by device:
\begin{lstlisting}
- #define VIRTIO_BLK_S_OK 0
- #define VIRTIO_BLK_S_IOERR 1
- #define VIRTIO_BLK_S_UNSUPP 2
+#define VIRTIO_BLK_S_OK 0
+#define VIRTIO_BLK_S_IOERR 1
+#define VIRTIO_BLK_S_UNSUPP 2
\end{lstlisting}
Any writes completed before the submission of the flush command should
@@ -3104,7 +3104,7 @@ is a hint about the relative priorities of requests to the device:
higher numbers indicate more important requests.
\begin{lstlisting}
- #define VIRTIO_BLK_T_BARRIER 0x80000000
+#define VIRTIO_BLK_T_BARRIER 0x80000000
\end{lstlisting}
If the device has VIRTIO_BLK_F_BARRIER
@@ -3120,21 +3120,21 @@ If the device has VIRTIO_BLK_F_SCSI feature, it can also support
scsi packet command requests, each of these requests is of form:
\begin{lstlisting}
- /* All fields are in guest's native endian. */
- struct virtio_scsi_pc_req {
- u32 type;
- u32 ioprio;
- u64 sector;
- char cmd[];
- char data[][512];
- #define SCSI_SENSE_BUFFERSIZE 96
- u8 sense[SCSI_SENSE_BUFFERSIZE];
- u32 errors;
- u32 data_len;
- u32 sense_len;
- u32 residual;
- u8 status;
- };
+/* All fields are in guest's native endian. */
+struct virtio_scsi_pc_req {
+ u32 type;
+ u32 ioprio;
+ u64 sector;
+ char cmd[];
+ char data[][512];
+#define SCSI_SENSE_BUFFERSIZE 96
+ u8 sense[SCSI_SENSE_BUFFERSIZE];
+ u32 errors;
+ u32 data_len;
+ u32 sense_len;
+ u32 residual;
+ u8 status;
+};
\end{lstlisting}
A request type can also be a scsi packet command (VIRTIO_BLK_T_SCSI_CMD or
@@ -3142,8 +3142,8 @@ VIRTIO_BLK_T_SCSI_CMD_OUT). The two types are equivalent, the device
does not distinguish between them:
\begin{lstlisting}
- #define VIRTIO_BLK_T_SCSI_CMD 2
- #define VIRTIO_BLK_T_SCSI_CMD_OUT 3
+#define VIRTIO_BLK_T_SCSI_CMD 2
+#define VIRTIO_BLK_T_SCSI_CMD_OUT 3
\end{lstlisting}
The cmd field is only present for scsi packet command requests,
@@ -3241,12 +3241,12 @@ data and outgoing characters are placed in the transmit queue.
acknowledging the feature.
\begin{lstlisting}
- struct virtio_console_config {
- le16 cols;
- le16 rows;
- le32 max_nr_ports;
- le32 emerg_wr;
- };
+struct virtio_console_config {
+ le16 cols;
+ le16 rows;
+ le32 max_nr_ports;
+ le32 emerg_wr;
+};
\end{lstlisting}
\subsubsection{Legacy Interface: Device configuration layout}\label{sec:Device Types / Console Device / Device configuration layout / Legacy Interface: Device configuration layout}
@@ -3318,21 +3318,21 @@ when a port is closed or hot-unplugged.
buffer and the events associated are:
\begin{lstlisting}
- struct virtio_console_control {
- le32 id; /* Port number */
- le16 event; /* The kind of control event */
- le16 value; /* Extra information for the event */
- };
-
- /* Some events for the internal messages (control packets) */
- #define VIRTIO_CONSOLE_DEVICE_READY 0
- #define VIRTIO_CONSOLE_PORT_ADD 1
- #define VIRTIO_CONSOLE_PORT_REMOVE 2
- #define VIRTIO_CONSOLE_PORT_READY 3
- #define VIRTIO_CONSOLE_CONSOLE_PORT 4
- #define VIRTIO_CONSOLE_RESIZE 5
- #define VIRTIO_CONSOLE_PORT_OPEN 6
- #define VIRTIO_CONSOLE_PORT_NAME 7
+struct virtio_console_control {
+ le32 id; /* Port number */
+ le16 event; /* The kind of control event */
+ le16 value; /* Extra information for the event */
+};
+
+/* Some events for the internal messages (control packets) */
+#define VIRTIO_CONSOLE_DEVICE_READY 0
+#define VIRTIO_CONSOLE_PORT_ADD 1
+#define VIRTIO_CONSOLE_PORT_REMOVE 2
+#define VIRTIO_CONSOLE_PORT_READY 3
+#define VIRTIO_CONSOLE_CONSOLE_PORT 4
+#define VIRTIO_CONSOLE_RESIZE 5
+#define VIRTIO_CONSOLE_PORT_OPEN 6
+#define VIRTIO_CONSOLE_PORT_NAME 7
\end{lstlisting}
\end{enumerate}
@@ -3408,10 +3408,10 @@ guest memory statistics to the host.
are always available.
\begin{lstlisting}
- struct virtio_balloon_config {
- le32 num_pages;
- le32 actual;
- };
+struct virtio_balloon_config {
+ le32 num_pages;
+ le32 actual;
+};
\end{lstlisting}
\subsubsection{Legacy Interface: Device configuration layout}\label{sec:Device Types / Memory Balloon Device / Device configuration layout / Legacy Interface: Device configuration layout}
@@ -3507,16 +3507,16 @@ as follows:
compatibility, unsupported statistics should be omitted.
\begin{lstlisting}
- struct virtio_balloon_stat {
- #define VIRTIO_BALLOON_S_SWAP_IN 0
- #define VIRTIO_BALLOON_S_SWAP_OUT 1
- #define VIRTIO_BALLOON_S_MAJFLT 2
- #define VIRTIO_BALLOON_S_MINFLT 3
- #define VIRTIO_BALLOON_S_MEMFREE 4
- #define VIRTIO_BALLOON_S_MEMTOT 5
- le16 tag;
- le64 val;
- } __attribute__((packed));
+struct virtio_balloon_stat {
+#define VIRTIO_BALLOON_S_SWAP_IN 0
+#define VIRTIO_BALLOON_S_SWAP_OUT 1
+#define VIRTIO_BALLOON_S_MAJFLT 2
+#define VIRTIO_BALLOON_S_MINFLT 3
+#define VIRTIO_BALLOON_S_MEMFREE 4
+#define VIRTIO_BALLOON_S_MEMTOT 5
+ le16 tag;
+ le64 val;
+} __attribute__((packed));
\end{lstlisting}
\paragraph{Legacy Interface: Memory Statistics}\label{sec:Device Types / Memory Balloon Device / Device Operation / Memory Statistics / Legacy Interface: Memory Statistics}
@@ -3598,18 +3598,18 @@ targets that receive and process the requests.
and cdb_size are writable by the driver.
\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;
- };
+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}
@@ -3682,43 +3682,43 @@ consumed with no order constraints.
Requests have the following format:
\begin{lstlisting}
- struct virtio_scsi_req_cmd {
- // Read-only
- u8 lun[8];
- le64 id;
- u8 task_attr;
- u8 prio;
- u8 crn;
- char cdb[cdb_size];
- char dataout[];
- // Write-only part
- le32 sense_len;
- le32 residual;
- le16 status_qualifier;
- u8 status;
- u8 response;
- u8 sense[sense_size];
- char 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
+struct virtio_scsi_req_cmd {
+ // Read-only
+ u8 lun[8];
+ le64 id;
+ u8 task_attr;
+ u8 prio;
+ u8 crn;
+ char cdb[cdb_size];
+ char dataout[];
+ // Write-only part
+ le32 sense_len;
+ le32 residual;
+ le16 status_qualifier;
+ u8 status;
+ u8 response;
+ u8 sense[sense_size];
+ char 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}
The lun field addresses a target and logical unit in the
@@ -3808,21 +3808,21 @@ The controlq is used for other SCSI transport operations.
Requests have the following format:
\begin{lstlisting}
- struct virtio_scsi_ctrl {
- le32 type;
- ...
- 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
+struct virtio_scsi_ctrl {
+ le32 type;
+...
+ 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 type identifies the remaining fields.
@@ -3831,32 +3831,32 @@ The following commands are defined:
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
- {
- // Read-only part
- le32 type;
- le32 subtype;
- u8 lun[8];
- le64 id;
- // Write-only 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
+#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
+{
+ // Read-only part
+ le32 type;
+ le32 subtype;
+ u8 lun[8];
+ le64 id;
+ // Write-only 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 type is VIRTIO_SCSI_T_TMF; the subtype field defines. All
@@ -3878,24 +3878,24 @@ The following commands are defined:
Asynchronous notification query
\begin{lstlisting}
- #define VIRTIO_SCSI_T_AN_QUERY 1
-
- struct virtio_scsi_ctrl_an {
- // Read-only part
- le32 type;
- u8 lun[8];
- le32 event_requested;
- // Write-only 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
+#define VIRTIO_SCSI_T_AN_QUERY 1
+
+struct virtio_scsi_ctrl_an {
+ // Read-only part
+ le32 type;
+ u8 lun[8];
+ le32 event_requested;
+ // Write-only 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
@@ -3913,17 +3913,17 @@ The following commands are defined:
Asynchronous notification subscription
\begin{lstlisting}
- #define VIRTIO_SCSI_T_AN_SUBSCRIBE 2
-
- struct virtio_scsi_ctrl_an {
- // Read-only part
- le32 type;
- u8 lun[8];
- le32 event_requested;
- // Write-only part
- le32 event_actual;
- u8 response;
- }
+#define VIRTIO_SCSI_T_AN_SUBSCRIBE 2
+
+struct virtio_scsi_ctrl_an {
+ // Read-only part
+ le32 type;
+ u8 lun[8];
+ le32 event_requested;
+ // Write-only part
+ le32 event_actual;
+ u8 response;
+}
\end{lstlisting}
By sending this command, the driver asks the specified LUN to
@@ -3972,14 +3972,14 @@ 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 {
- // Write-only part
- le32 event;
- u8 lun[8];
- le32 reason;
- }
+#define VIRTIO_SCSI_T_EVENTS_MISSED 0x80000000
+
+struct virtio_scsi_event {
+ // Write-only part
+ le32 event;
+ u8 lun[8];
+ le32 reason;
+}
\end{lstlisting}
If bit 31 is set in the event field, the device failed to report
@@ -3993,7 +3993,7 @@ contents of the event field. The following events are defined:
No event
\begin{lstlisting}
- #define VIRTIO_SCSI_T_NO_EVENT 0
+#define VIRTIO_SCSI_T_NO_EVENT 0
\end{lstlisting}
This event is fired in the following cases:
@@ -4014,11 +4014,11 @@ contents of the event field. The following events are defined:
Transport reset
\begin{lstlisting}
- #define VIRTIO_SCSI_T_TRANSPORT_RESET 1
+#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
+#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
@@ -4078,7 +4078,7 @@ contents of the event field. The following events are defined:
Asynchronous notification
\begin{lstlisting}
- #define VIRTIO_SCSI_T_ASYNC_NOTIFY 2
+#define VIRTIO_SCSI_T_ASYNC_NOTIFY 2
\end{lstlisting}
By sending this event, the device signals that an asynchronous
@@ -4095,7 +4095,7 @@ contents of the event field. The following events are defined:
LUN parameter change
\begin{lstlisting}
- #define VIRTIO_SCSI_T_PARAM_CHANGE 3
+#define VIRTIO_SCSI_T_PARAM_CHANGE 3
\end{lstlisting}
By sending this event, the device signals that the configuration parameters