virtio_drivers/transport/
mod.rs
1#[cfg(test)]
4pub mod fake;
5pub mod mmio;
6pub mod pci;
7
8use crate::{PhysAddr, Result, PAGE_SIZE};
9use bitflags::{bitflags, Flags};
10use core::{fmt::Debug, ops::BitAnd, ptr::NonNull};
11use log::debug;
12
13pub trait Transport {
15 fn device_type(&self) -> DeviceType;
17
18 fn read_device_features(&mut self) -> u64;
20
21 fn write_driver_features(&mut self, driver_features: u64);
23
24 fn max_queue_size(&mut self, queue: u16) -> u32;
26
27 fn notify(&mut self, queue: u16);
29
30 fn get_status(&self) -> DeviceStatus;
32
33 fn set_status(&mut self, status: DeviceStatus);
35
36 fn set_guest_page_size(&mut self, guest_page_size: u32);
38
39 fn requires_legacy_layout(&self) -> bool;
43
44 fn queue_set(
46 &mut self,
47 queue: u16,
48 size: u32,
49 descriptors: PhysAddr,
50 driver_area: PhysAddr,
51 device_area: PhysAddr,
52 );
53
54 fn queue_unset(&mut self, queue: u16);
56
57 fn queue_used(&mut self, queue: u16) -> bool;
59
60 fn ack_interrupt(&mut self) -> bool;
64
65 fn begin_init<F: Flags<Bits = u64> + BitAnd<Output = F> + Debug>(
71 &mut self,
72 supported_features: F,
73 ) -> F {
74 self.set_status(DeviceStatus::empty());
75 self.set_status(DeviceStatus::ACKNOWLEDGE | DeviceStatus::DRIVER);
76
77 let device_features = F::from_bits_truncate(self.read_device_features());
78 debug!("Device features: {:?}", device_features);
79 let negotiated_features = device_features & supported_features;
80 self.write_driver_features(negotiated_features.bits());
81
82 self.set_status(
83 DeviceStatus::ACKNOWLEDGE | DeviceStatus::DRIVER | DeviceStatus::FEATURES_OK,
84 );
85
86 self.set_guest_page_size(PAGE_SIZE as u32);
87
88 negotiated_features
89 }
90
91 fn finish_init(&mut self) {
93 self.set_status(
94 DeviceStatus::ACKNOWLEDGE
95 | DeviceStatus::DRIVER
96 | DeviceStatus::FEATURES_OK
97 | DeviceStatus::DRIVER_OK,
98 );
99 }
100
101 fn config_space<T: 'static>(&self) -> Result<NonNull<T>>;
103}
104
105bitflags! {
106 #[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
108 pub struct DeviceStatus: u32 {
109 const ACKNOWLEDGE = 1;
112
113 const DRIVER = 2;
115
116 const FAILED = 128;
121
122 const FEATURES_OK = 8;
125
126 const DRIVER_OK = 4;
128
129 const DEVICE_NEEDS_RESET = 64;
132 }
133}
134
135#[repr(u8)]
137#[derive(Clone, Copy, Debug, Eq, PartialEq)]
138#[allow(missing_docs)]
139pub enum DeviceType {
140 Invalid = 0,
141 Network = 1,
142 Block = 2,
143 Console = 3,
144 EntropySource = 4,
145 MemoryBallooning = 5,
146 IoMemory = 6,
147 Rpmsg = 7,
148 ScsiHost = 8,
149 _9P = 9,
150 Mac80211 = 10,
151 RprocSerial = 11,
152 VirtioCAIF = 12,
153 MemoryBalloon = 13,
154 GPU = 16,
155 Timer = 17,
156 Input = 18,
157 Socket = 19,
158 Crypto = 20,
159 SignalDistributionModule = 21,
160 Pstore = 22,
161 IOMMU = 23,
162 Memory = 24,
163 Sound = 25,
164}
165
166impl From<u32> for DeviceType {
167 fn from(virtio_device_id: u32) -> Self {
168 match virtio_device_id {
169 1 => DeviceType::Network,
170 2 => DeviceType::Block,
171 3 => DeviceType::Console,
172 4 => DeviceType::EntropySource,
173 5 => DeviceType::MemoryBalloon,
174 6 => DeviceType::IoMemory,
175 7 => DeviceType::Rpmsg,
176 8 => DeviceType::ScsiHost,
177 9 => DeviceType::_9P,
178 10 => DeviceType::Mac80211,
179 11 => DeviceType::RprocSerial,
180 12 => DeviceType::VirtioCAIF,
181 13 => DeviceType::MemoryBalloon,
182 16 => DeviceType::GPU,
183 17 => DeviceType::Timer,
184 18 => DeviceType::Input,
185 19 => DeviceType::Socket,
186 20 => DeviceType::Crypto,
187 21 => DeviceType::SignalDistributionModule,
188 22 => DeviceType::Pstore,
189 23 => DeviceType::IOMMU,
190 24 => DeviceType::Memory,
191 25 => DeviceType::Sound,
192 _ => DeviceType::Invalid,
193 }
194 }
195}
196
197impl From<u16> for DeviceType {
198 fn from(virtio_device_id: u16) -> Self {
199 u32::from(virtio_device_id).into()
200 }
201}
202
203impl From<u8> for DeviceType {
204 fn from(virtio_device_id: u8) -> Self {
205 u32::from(virtio_device_id).into()
206 }
207}