virtio_accel_transport/bytes.rs
1//! Transport-owned byte access that is independent of backend error semantics.
2
3use core::fmt;
4
5/// Failure while accessing a validated transport byte region.
6#[derive(Clone, Copy, Debug, PartialEq, Eq)]
7pub enum ByteAccessError {
8 /// The requested logical range is outside the mapped region.
9 OutOfBounds,
10 /// Another live access currently owns the same bytes.
11 Busy,
12 /// Queue reset invalidated the region before access.
13 Reset,
14 /// The concrete transport can no longer access the mapped memory.
15 Access,
16}
17
18/// Bounded readable bytes exposed by a transport implementation.
19///
20/// Implementations may be segmented. Every operation is nonblocking and allocation-free.
21pub trait ReadableBytes: fmt::Debug {
22 /// Stable logical byte length.
23 fn len(&self) -> u64;
24
25 /// Whether this source contains no bytes.
26 fn is_empty(&self) -> bool {
27 self.len() == 0
28 }
29
30 /// Fill `target` from the exact logical range beginning at `offset`.
31 fn read_at(&self, offset: u64, target: &mut [u8]) -> Result<(), ByteAccessError>;
32
33 /// Borrow the complete source when the concrete mapping is contiguous and stable.
34 fn as_contiguous(&self) -> Option<&[u8]> {
35 None
36 }
37}
38
39/// Bounded writable bytes exposed by a transport implementation.
40///
41/// Implementations may be segmented. Every operation is nonblocking and allocation-free.
42pub trait WritableBytes: fmt::Debug {
43 /// Stable logical byte length.
44 fn len(&self) -> u64;
45
46 /// Whether this destination contains no bytes.
47 fn is_empty(&self) -> bool {
48 self.len() == 0
49 }
50
51 /// Write `source` to the exact logical range beginning at `offset`.
52 fn write_at(&mut self, offset: u64, source: &[u8]) -> Result<(), ByteAccessError>;
53
54 /// Borrow the complete destination when the concrete mapping is contiguous and stable.
55 fn as_contiguous_mut(&mut self) -> Option<&mut [u8]> {
56 None
57 }
58}
59
60/// Driver-owned byte access for one unpublished or reclaimed descriptor chain.
61///
62/// The readable side is written by the driver and later read by the device. The writable side is
63/// written by the device and may be read by the driver only after used-ring reclamation. Methods
64/// are nonblocking and allocation-free; queue ownership prevents calls while a chain is published.
65pub trait DriverChainBuffer: fmt::Debug {
66 /// Concrete transport byte-access failure.
67 type Error;
68
69 /// Total bytes readable by the device.
70 fn device_readable_len(&self) -> u64;
71
72 /// Total bytes writable by the device.
73 fn device_writable_len(&self) -> u64;
74
75 /// Write an exact logical range into the device-readable side.
76 fn write_device_readable(&mut self, offset: u64, source: &[u8]) -> Result<(), Self::Error>;
77
78 /// Read an exact logical range from the device-writable side after completion.
79 fn read_device_writable(&self, offset: u64, target: &mut [u8]) -> Result<(), Self::Error>;
80}
81
82impl ReadableBytes for [u8] {
83 fn len(&self) -> u64 {
84 self.len() as u64
85 }
86
87 fn read_at(&self, offset: u64, target: &mut [u8]) -> Result<(), ByteAccessError> {
88 let start = usize::try_from(offset).map_err(|_| ByteAccessError::OutOfBounds)?;
89 let end = start
90 .checked_add(target.len())
91 .ok_or(ByteAccessError::OutOfBounds)?;
92 let source = self.get(start..end).ok_or(ByteAccessError::OutOfBounds)?;
93 target.copy_from_slice(source);
94 Ok(())
95 }
96
97 fn as_contiguous(&self) -> Option<&[u8]> {
98 Some(self)
99 }
100}
101
102impl WritableBytes for [u8] {
103 fn len(&self) -> u64 {
104 self.len() as u64
105 }
106
107 fn write_at(&mut self, offset: u64, source: &[u8]) -> Result<(), ByteAccessError> {
108 let start = usize::try_from(offset).map_err(|_| ByteAccessError::OutOfBounds)?;
109 let end = start
110 .checked_add(source.len())
111 .ok_or(ByteAccessError::OutOfBounds)?;
112 let target = self
113 .get_mut(start..end)
114 .ok_or(ByteAccessError::OutOfBounds)?;
115 target.copy_from_slice(source);
116 Ok(())
117 }
118
119 fn as_contiguous_mut(&mut self) -> Option<&mut [u8]> {
120 Some(self)
121 }
122}