virtio_drivers/transport/
some.rs1use zerocopy::{FromBytes, Immutable, IntoBytes};
2
3use super::{mmio::MmioTransport, pci::PciTransport, DeviceStatus, DeviceType, Transport};
4use crate::{transport::InterruptStatus, PhysAddr, Result};
5
6#[derive(Debug)]
8pub enum SomeTransport<'a> {
9 Mmio(MmioTransport<'a>),
11 Pci(PciTransport),
13 #[cfg(target_arch = "x86_64")]
15 HypPci(super::x86_64::HypPciTransport),
16}
17
18impl<'a> From<MmioTransport<'a>> for SomeTransport<'a> {
19 fn from(mmio: MmioTransport<'a>) -> Self {
20 Self::Mmio(mmio)
21 }
22}
23
24impl From<PciTransport> for SomeTransport<'_> {
25 fn from(pci: PciTransport) -> Self {
26 Self::Pci(pci)
27 }
28}
29
30impl Transport for SomeTransport<'_> {
31 fn device_type(&self) -> DeviceType {
32 match self {
33 Self::Mmio(mmio) => mmio.device_type(),
34 Self::Pci(pci) => pci.device_type(),
35 #[cfg(target_arch = "x86_64")]
36 Self::HypPci(pci) => pci.device_type(),
37 }
38 }
39
40 fn read_device_features(&mut self) -> u64 {
41 match self {
42 Self::Mmio(mmio) => mmio.read_device_features(),
43 Self::Pci(pci) => pci.read_device_features(),
44 #[cfg(target_arch = "x86_64")]
45 Self::HypPci(pci) => pci.read_device_features(),
46 }
47 }
48
49 fn write_driver_features(&mut self, driver_features: u64) {
50 match self {
51 Self::Mmio(mmio) => mmio.write_driver_features(driver_features),
52 Self::Pci(pci) => pci.write_driver_features(driver_features),
53 #[cfg(target_arch = "x86_64")]
54 Self::HypPci(pci) => pci.write_driver_features(driver_features),
55 }
56 }
57
58 fn max_queue_size(&mut self, queue: u16) -> u32 {
59 match self {
60 Self::Mmio(mmio) => mmio.max_queue_size(queue),
61 Self::Pci(pci) => pci.max_queue_size(queue),
62 #[cfg(target_arch = "x86_64")]
63 Self::HypPci(pci) => pci.max_queue_size(queue),
64 }
65 }
66
67 fn notify(&mut self, queue: u16) {
68 match self {
69 Self::Mmio(mmio) => mmio.notify(queue),
70 Self::Pci(pci) => pci.notify(queue),
71 #[cfg(target_arch = "x86_64")]
72 Self::HypPci(pci) => pci.notify(queue),
73 }
74 }
75
76 fn get_status(&self) -> DeviceStatus {
77 match self {
78 Self::Mmio(mmio) => mmio.get_status(),
79 Self::Pci(pci) => pci.get_status(),
80 #[cfg(target_arch = "x86_64")]
81 Self::HypPci(pci) => pci.get_status(),
82 }
83 }
84
85 fn set_status(&mut self, status: DeviceStatus) {
86 match self {
87 Self::Mmio(mmio) => mmio.set_status(status),
88 Self::Pci(pci) => pci.set_status(status),
89 #[cfg(target_arch = "x86_64")]
90 Self::HypPci(pci) => pci.set_status(status),
91 }
92 }
93
94 fn set_guest_page_size(&mut self, guest_page_size: u32) {
95 match self {
96 Self::Mmio(mmio) => mmio.set_guest_page_size(guest_page_size),
97 Self::Pci(pci) => pci.set_guest_page_size(guest_page_size),
98 #[cfg(target_arch = "x86_64")]
99 Self::HypPci(pci) => pci.set_guest_page_size(guest_page_size),
100 }
101 }
102
103 fn requires_legacy_layout(&self) -> bool {
104 match self {
105 Self::Mmio(mmio) => mmio.requires_legacy_layout(),
106 Self::Pci(pci) => pci.requires_legacy_layout(),
107 #[cfg(target_arch = "x86_64")]
108 Self::HypPci(pci) => pci.requires_legacy_layout(),
109 }
110 }
111
112 fn queue_set(
113 &mut self,
114 queue: u16,
115 size: u32,
116 descriptors: PhysAddr,
117 driver_area: PhysAddr,
118 device_area: PhysAddr,
119 ) {
120 match self {
121 Self::Mmio(mmio) => mmio.queue_set(queue, size, descriptors, driver_area, device_area),
122 Self::Pci(pci) => pci.queue_set(queue, size, descriptors, driver_area, device_area),
123 #[cfg(target_arch = "x86_64")]
124 Self::HypPci(pci) => pci.queue_set(queue, size, descriptors, driver_area, device_area),
125 }
126 }
127
128 fn queue_unset(&mut self, queue: u16) {
129 match self {
130 Self::Mmio(mmio) => mmio.queue_unset(queue),
131 Self::Pci(pci) => pci.queue_unset(queue),
132 #[cfg(target_arch = "x86_64")]
133 Self::HypPci(pci) => pci.queue_unset(queue),
134 }
135 }
136
137 fn queue_used(&mut self, queue: u16) -> bool {
138 match self {
139 Self::Mmio(mmio) => mmio.queue_used(queue),
140 Self::Pci(pci) => pci.queue_used(queue),
141 #[cfg(target_arch = "x86_64")]
142 Self::HypPci(pci) => pci.queue_used(queue),
143 }
144 }
145
146 fn ack_interrupt(&mut self) -> InterruptStatus {
147 match self {
148 Self::Mmio(mmio) => mmio.ack_interrupt(),
149 Self::Pci(pci) => pci.ack_interrupt(),
150 #[cfg(target_arch = "x86_64")]
151 Self::HypPci(pci) => pci.ack_interrupt(),
152 }
153 }
154
155 fn read_config_generation(&self) -> u32 {
156 match self {
157 Self::Mmio(mmio) => mmio.read_config_generation(),
158 Self::Pci(pci) => pci.read_config_generation(),
159 #[cfg(target_arch = "x86_64")]
160 Self::HypPci(pci) => pci.read_config_generation(),
161 }
162 }
163
164 fn read_config_space<T: FromBytes + IntoBytes>(&self, offset: usize) -> Result<T> {
165 match self {
166 Self::Mmio(mmio) => mmio.read_config_space(offset),
167 Self::Pci(pci) => pci.read_config_space(offset),
168 #[cfg(target_arch = "x86_64")]
169 Self::HypPci(pci) => pci.read_config_space(offset),
170 }
171 }
172
173 fn write_config_space<T: IntoBytes + Immutable>(
174 &mut self,
175 offset: usize,
176 value: T,
177 ) -> Result<()> {
178 match self {
179 Self::Mmio(mmio) => mmio.write_config_space(offset, value),
180 Self::Pci(pci) => pci.write_config_space(offset, value),
181 #[cfg(target_arch = "x86_64")]
182 Self::HypPci(pci) => pci.write_config_space(offset, value),
183 }
184 }
185}