diff options
Diffstat (limited to 'content.tex')
-rw-r--r-- | content.tex | 962 |
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 |