hermit/drivers/vsock/
pci.rs1use crate::arch::pci::PciConfigRegion;
2use crate::drivers::pci::PciDevice;
3use crate::drivers::virtio::error::{self, VirtioError};
4use crate::drivers::virtio::transport::pci;
5use crate::drivers::virtio::transport::pci::{PciCap, UniCapsColl};
6use crate::drivers::vsock::{EventQueue, RxQueue, TxQueue, VirtioVsockDriver, VsockDevCfg};
7
8#[derive(Debug, Copy, Clone)]
12#[repr(C)]
13pub(crate) struct VsockDevCfgRaw {
14 pub guest_cid: u64,
17}
18
19impl VirtioVsockDriver {
20 fn map_cfg(cap: &PciCap) -> Option<VsockDevCfg> {
21 let dev_cfg = pci::map_dev_cfg::<VsockDevCfgRaw>(cap)?;
22
23 Some(VsockDevCfg {
24 raw: dev_cfg,
25 dev_id: cap.dev_id(),
26 features: virtio::vsock::F::empty(),
27 })
28 }
29
30 pub fn new(
33 caps_coll: UniCapsColl,
34 device: &PciDevice<PciConfigRegion>,
35 ) -> Result<Self, error::VirtioVsockError> {
36 let device_id = device.device_id();
37
38 let UniCapsColl {
39 com_cfg,
40 notif_cfg,
41 isr_cfg,
42 dev_cfg_list,
43 ..
44 } = caps_coll;
45
46 let Some(dev_cfg) = dev_cfg_list.iter().find_map(VirtioVsockDriver::map_cfg) else {
47 error!("No dev config. Aborting!");
48 return Err(error::VirtioVsockError::NoDevCfg(device_id));
49 };
50
51 Ok(VirtioVsockDriver {
52 dev_cfg,
53 com_cfg,
54 isr_stat: isr_cfg,
55 notif_cfg,
56 irq: device.get_irq().unwrap(),
57 event_vq: EventQueue::new(),
58 recv_vq: RxQueue::new(),
59 send_vq: TxQueue::new(),
60 })
61 }
62
63 pub(crate) fn init(
67 device: &PciDevice<PciConfigRegion>,
68 ) -> Result<VirtioVsockDriver, VirtioError> {
69 let mut drv = match pci::map_caps(device) {
70 Ok(caps) => match VirtioVsockDriver::new(caps, device) {
71 Ok(driver) => driver,
72 Err(vsock_err) => {
73 error!("Initializing new virtio socket device driver failed. Aborting!");
74 return Err(VirtioError::VsockDriver(vsock_err));
75 }
76 },
77 Err(err) => {
78 error!("Mapping capabilities failed. Aborting!");
79 return Err(err);
80 }
81 };
82
83 match drv.init_dev() {
84 Ok(()) => {
85 info!(
86 "Socket device with cid {:x}, has been initialized by driver!",
87 drv.dev_cfg.raw.guest_cid
88 );
89
90 Ok(drv)
91 }
92 Err(fs_err) => {
93 drv.set_failed();
94 Err(VirtioError::VsockDriver(fs_err))
95 }
96 }
97 }
98}