xref: /DragonOS/kernel/src/driver/virtio/transport.rs (revision 1ea2daad8121b77ed704e6d7c3a09f478147441d)
1 use virtio_drivers::transport::Transport;
2 
3 use crate::exception::HardwareIrqNumber;
4 
5 use super::{transport_mmio::VirtIOMmioTransport, transport_pci::PciTransport};
6 
7 pub enum VirtIOTransport {
8     Pci(PciTransport),
9     Mmio(VirtIOMmioTransport),
10 }
11 
12 impl VirtIOTransport {
13     pub fn irq(&self) -> Option<HardwareIrqNumber> {
14         match self {
15             VirtIOTransport::Mmio(transport) => Some(transport.irq()),
16             _ => None,
17         }
18     }
19 }
20 
21 impl core::fmt::Debug for VirtIOTransport {
22     fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
23         match self {
24             VirtIOTransport::Pci(_) => write!(f, "VirtIOTransport::Pci"),
25             VirtIOTransport::Mmio(_) => write!(f, "VirtIOTransport::Mmio"),
26         }
27     }
28 }
29 
30 impl Transport for VirtIOTransport {
31     #[inline(always)]
32     fn finish_init(&mut self) {
33         match self {
34             VirtIOTransport::Pci(transport) => transport.finish_init(),
35             VirtIOTransport::Mmio(transport) => transport.finish_init(),
36         }
37     }
38 
39     #[inline(always)]
40     fn device_type(&self) -> virtio_drivers::transport::DeviceType {
41         match self {
42             VirtIOTransport::Pci(transport) => transport.device_type(),
43             VirtIOTransport::Mmio(transport) => transport.device_type(),
44         }
45     }
46 
47     #[inline(always)]
48     fn read_device_features(&mut self) -> u64 {
49         match self {
50             VirtIOTransport::Pci(transport) => transport.read_device_features(),
51             VirtIOTransport::Mmio(transport) => transport.read_device_features(),
52         }
53     }
54 
55     #[inline(always)]
56     fn write_driver_features(&mut self, driver_features: u64) {
57         match self {
58             VirtIOTransport::Pci(transport) => transport.write_driver_features(driver_features),
59             VirtIOTransport::Mmio(transport) => transport.write_driver_features(driver_features),
60         }
61     }
62 
63     #[inline(always)]
64     fn max_queue_size(&mut self, queue: u16) -> u32 {
65         match self {
66             VirtIOTransport::Pci(transport) => transport.max_queue_size(queue),
67             VirtIOTransport::Mmio(transport) => transport.max_queue_size(queue),
68         }
69     }
70 
71     #[inline(always)]
72     fn notify(&mut self, queue: u16) {
73         match self {
74             VirtIOTransport::Pci(transport) => transport.notify(queue),
75             VirtIOTransport::Mmio(transport) => transport.notify(queue),
76         }
77     }
78 
79     #[inline(always)]
80     fn get_status(&self) -> virtio_drivers::transport::DeviceStatus {
81         match self {
82             VirtIOTransport::Pci(transport) => transport.get_status(),
83             VirtIOTransport::Mmio(transport) => transport.get_status(),
84         }
85     }
86 
87     #[inline(always)]
88     fn set_status(&mut self, status: virtio_drivers::transport::DeviceStatus) {
89         match self {
90             VirtIOTransport::Pci(transport) => transport.set_status(status),
91             VirtIOTransport::Mmio(transport) => transport.set_status(status),
92         }
93     }
94 
95     #[inline(always)]
96     fn set_guest_page_size(&mut self, guest_page_size: u32) {
97         match self {
98             VirtIOTransport::Pci(transport) => transport.set_guest_page_size(guest_page_size),
99             VirtIOTransport::Mmio(transport) => transport.set_guest_page_size(guest_page_size),
100         }
101     }
102 
103     #[inline(always)]
104     fn requires_legacy_layout(&self) -> bool {
105         match self {
106             VirtIOTransport::Pci(transport) => transport.requires_legacy_layout(),
107             VirtIOTransport::Mmio(transport) => transport.requires_legacy_layout(),
108         }
109     }
110 
111     #[inline(always)]
112     fn queue_set(
113         &mut self,
114         queue: u16,
115         size: u32,
116         descriptors: virtio_drivers::PhysAddr,
117         driver_area: virtio_drivers::PhysAddr,
118         device_area: virtio_drivers::PhysAddr,
119     ) {
120         match self {
121             VirtIOTransport::Pci(transport) => {
122                 transport.queue_set(queue, size, descriptors, driver_area, device_area)
123             }
124             VirtIOTransport::Mmio(transport) => {
125                 transport.queue_set(queue, size, descriptors, driver_area, device_area)
126             }
127         }
128     }
129 
130     #[inline(always)]
131     fn queue_unset(&mut self, queue: u16) {
132         match self {
133             VirtIOTransport::Pci(transport) => transport.queue_unset(queue),
134             VirtIOTransport::Mmio(transport) => transport.queue_unset(queue),
135         }
136     }
137 
138     #[inline(always)]
139     fn queue_used(&mut self, queue: u16) -> bool {
140         match self {
141             VirtIOTransport::Pci(transport) => transport.queue_used(queue),
142             VirtIOTransport::Mmio(transport) => transport.queue_used(queue),
143         }
144     }
145 
146     #[inline(always)]
147     fn ack_interrupt(&mut self) -> bool {
148         match self {
149             VirtIOTransport::Pci(transport) => transport.ack_interrupt(),
150             VirtIOTransport::Mmio(transport) => transport.ack_interrupt(),
151         }
152     }
153 
154     #[inline(always)]
155     fn config_space<T: 'static>(&self) -> virtio_drivers::Result<core::ptr::NonNull<T>> {
156         match self {
157             VirtIOTransport::Pci(transport) => transport.config_space(),
158             VirtIOTransport::Mmio(transport) => transport.config_space(),
159         }
160     }
161 }
162