virtio/devices/virtio_gpu/messages/
ctrl_header.rs1use super::super::helpers::{bytes_from_iter, copy_to_iter};
6use kernel::ErrorCode;
7
8#[derive(Debug, Copy, Clone, PartialEq, Eq)]
9#[repr(u32)]
10#[allow(dead_code)]
11pub enum CtrlType {
12 CmdGetDisplayInfo = 0x0100,
14 CmdResourceCreate2d,
15 CmdResourceUref,
16 CmdSetScanout,
17 CmdResourceFlush,
18 CmdTransferToHost2d,
19 CmdResourceAttachBacking,
20 CmdResourceDetachBacking,
21 CmdGetCapsetInfo,
22 CmdGetCapset,
23 CmdGetEdid,
24
25 CmdUpdateCursor = 0x0300,
27 CmdMoveCursor,
28
29 RespOkNoData = 0x1100,
31 RespOkDisplayInfo,
32 RespOkCapsetInfo,
33 RespOkCapset,
34 RespOkEdid,
35
36 RespErrUnspec = 0x1200,
38 RespErrOutOfMemory,
39 RespErrInvalidScanoutId,
40 RespErrInvalidResourceId,
41 RespErrInvalidContextId,
42 RespErrInvalidParameter,
43}
44
45impl TryFrom<u32> for CtrlType {
46 type Error = ();
47
48 fn try_from(int: u32) -> Result<Self, Self::Error> {
49 match int {
50 v if v == CtrlType::CmdGetDisplayInfo as u32 => Ok(CtrlType::CmdGetDisplayInfo),
52 v if v == CtrlType::CmdResourceCreate2d as u32 => Ok(CtrlType::CmdResourceCreate2d),
53 v if v == CtrlType::CmdResourceUref as u32 => Ok(CtrlType::CmdResourceUref),
54 v if v == CtrlType::CmdSetScanout as u32 => Ok(CtrlType::CmdSetScanout),
55 v if v == CtrlType::CmdResourceFlush as u32 => Ok(CtrlType::CmdResourceFlush),
56 v if v == CtrlType::CmdTransferToHost2d as u32 => Ok(CtrlType::CmdTransferToHost2d),
57 v if v == CtrlType::CmdResourceAttachBacking as u32 => {
58 Ok(CtrlType::CmdResourceAttachBacking)
59 }
60 v if v == CtrlType::CmdResourceDetachBacking as u32 => {
61 Ok(CtrlType::CmdResourceDetachBacking)
62 }
63 v if v == CtrlType::CmdGetCapsetInfo as u32 => Ok(CtrlType::CmdGetCapsetInfo),
64 v if v == CtrlType::CmdGetCapset as u32 => Ok(CtrlType::CmdGetCapset),
65 v if v == CtrlType::CmdGetEdid as u32 => Ok(CtrlType::CmdGetEdid),
66
67 v if v == CtrlType::CmdUpdateCursor as u32 => Ok(CtrlType::CmdUpdateCursor),
69 v if v == CtrlType::CmdMoveCursor as u32 => Ok(CtrlType::CmdMoveCursor),
70
71 v if v == CtrlType::RespOkNoData as u32 => Ok(CtrlType::RespOkNoData),
73 v if v == CtrlType::RespOkDisplayInfo as u32 => Ok(CtrlType::RespOkDisplayInfo),
74 v if v == CtrlType::RespOkCapsetInfo as u32 => Ok(CtrlType::RespOkCapsetInfo),
75 v if v == CtrlType::RespOkCapset as u32 => Ok(CtrlType::RespOkCapset),
76 v if v == CtrlType::RespOkEdid as u32 => Ok(CtrlType::RespOkEdid),
77
78 v if v == CtrlType::RespErrUnspec as u32 => Ok(CtrlType::RespErrUnspec),
80 v if v == CtrlType::RespErrOutOfMemory as u32 => Ok(CtrlType::RespErrOutOfMemory),
81 v if v == CtrlType::RespErrInvalidScanoutId as u32 => {
82 Ok(CtrlType::RespErrInvalidScanoutId)
83 }
84 v if v == CtrlType::RespErrInvalidResourceId as u32 => {
85 Ok(CtrlType::RespErrInvalidResourceId)
86 }
87 v if v == CtrlType::RespErrInvalidContextId as u32 => {
88 Ok(CtrlType::RespErrInvalidContextId)
89 }
90 v if v == CtrlType::RespErrInvalidParameter as u32 => {
91 Ok(CtrlType::RespErrInvalidParameter)
92 }
93
94 _ => Err(()),
95 }
96 }
97}
98
99#[derive(Debug, Copy, Clone)]
100#[repr(C)]
101pub struct CtrlHeader {
102 pub ctrl_type: CtrlType,
103 pub flags: u32,
104 pub fence_id: u64,
105 pub ctx_id: u32,
106 pub padding: u32,
107}
108
109impl CtrlHeader {
110 pub const ENCODED_SIZE: usize = core::mem::size_of::<Self>();
111
112 pub fn write_to_byte_iter<'a>(
113 &self,
114 dst: &mut impl Iterator<Item = &'a mut u8>,
115 ) -> Result<(), ErrorCode> {
116 copy_to_iter(dst, u32::to_le_bytes(self.ctrl_type as u32).into_iter())?;
120 copy_to_iter(dst, u32::to_le_bytes(self.flags).into_iter())?;
121 copy_to_iter(dst, u64::to_le_bytes(self.fence_id).into_iter())?;
122 copy_to_iter(dst, u32::to_le_bytes(self.ctx_id).into_iter())?;
123 copy_to_iter(dst, u32::to_le_bytes(self.padding).into_iter())?;
124
125 Ok(())
126 }
127
128 pub fn from_byte_iter(src: &mut impl Iterator<Item = u8>) -> Result<Self, ErrorCode> {
129 let ctrl_type = CtrlType::try_from(u32::from_le_bytes(bytes_from_iter(src)?))
130 .map_err(|()| ErrorCode::INVAL)?;
131 let flags = u32::from_le_bytes(bytes_from_iter(src)?);
132 let fence_id = u64::from_le_bytes(bytes_from_iter(src)?);
133 let ctx_id = u32::from_le_bytes(bytes_from_iter(src)?);
134 let padding = u32::from_le_bytes(bytes_from_iter(src)?);
135
136 Ok(CtrlHeader {
137 ctrl_type,
138 flags,
139 fence_id,
140 ctx_id,
141 padding,
142 })
143 }
144}