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