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