1 use super::transport_pci::PciTransport;
2 use super::virtio_impl::HalImpl;
3 use crate::driver::net::virtio_net::virtio_net;
4 use crate::driver::pci::pci::PciDeviceStructureGeneralDevice;
5 use crate::driver::pci::pci::{
6 get_pci_device_structure_mut, PciDeviceStructure, PCI_DEVICE_LINKEDLIST,
7 };
8 use crate::libs::rwlock::RwLockWriteGuard;
9 use crate::{kdebug, kerror, kwarn};
10 use alloc::{boxed::Box, collections::LinkedList};
11 use virtio_drivers::transport::{DeviceType, Transport};
12 const NETWORK_CLASS: u8 = 0x2;
13 const ETHERNET_SUBCLASS: u8 = 0x0;
14
15 //Virtio设备寻找过程中出现的问题
16 enum VirtioError {
17 VirtioNetNotFound,
18 NetDeviceNotFound,
19 }
20
21 /// @brief 寻找并加载所有virtio设备的驱动(目前只有virtio-net,但其他virtio设备也可添加)(for c)
22 #[no_mangle]
rs_virtio_probe()23 pub extern "C" fn rs_virtio_probe() {
24 virtio_probe();
25 }
26
27 ///@brief 寻找并加载所有virtio设备的驱动(目前只有virtio-net,但其他virtio设备也可添加)
virtio_probe()28 pub fn virtio_probe() {
29 let mut list = PCI_DEVICE_LINKEDLIST.write();
30 if let Ok(virtio_list) = virtio_device_search(&mut list) {
31 for virtio_device in virtio_list {
32 match PciTransport::new::<HalImpl>(virtio_device) {
33 Ok(mut transport) => {
34 kdebug!(
35 "Detected virtio PCI device with device type {:?}, features {:#018x}",
36 transport.device_type(),
37 transport.read_device_features(),
38 );
39 virtio_device_init(transport);
40 }
41 Err(err) => {
42 kerror!("Pci transport create failed because of error: {}", err);
43 }
44 }
45 }
46 } else {
47 kerror!("Error occured when finding virtio device!");
48 }
49 }
50
51 ///@brief 为virtio设备寻找对应的驱动进行初始化
virtio_device_init(transport: impl Transport + 'static)52 fn virtio_device_init(transport: impl Transport + 'static) {
53 match transport.device_type() {
54 DeviceType::Block => {
55 kwarn!("Not support virtio_block device for now");
56 }
57 DeviceType::GPU => {
58 kwarn!("Not support virtio_gpu device for now");
59 }
60 DeviceType::Input => {
61 kwarn!("Not support virtio_input device for now");
62 }
63 DeviceType::Network => virtio_net(transport),
64 t => {
65 kwarn!("Unrecognized virtio device: {:?}", t);
66 }
67 }
68 }
69
70 /// @brief 寻找所有的virtio设备
71 /// @param list 链表的写锁
72 /// @return Result<LinkedList<&'a mut Pci_Device_Structure_General_Device>, VirtioError> 成功则返回包含所有virtio设备结构体的可变引用的链表,失败则返回err
73 /// 该函数主要是为其他virtio设备预留支持
virtio_device_search<'a>( list: &'a mut RwLockWriteGuard<'_, LinkedList<Box<dyn PciDeviceStructure>>>, ) -> Result<LinkedList<&'a mut PciDeviceStructureGeneralDevice>, VirtioError>74 fn virtio_device_search<'a>(
75 list: &'a mut RwLockWriteGuard<'_, LinkedList<Box<dyn PciDeviceStructure>>>,
76 ) -> Result<LinkedList<&'a mut PciDeviceStructureGeneralDevice>, VirtioError> {
77 let mut virtio_list: LinkedList<&mut PciDeviceStructureGeneralDevice> = LinkedList::new();
78 let virtio_net_device = get_virtio_net_device(list)?;
79 virtio_list.push_back(virtio_net_device);
80 Ok(virtio_list)
81 }
82
83 /// @brief 寻找virtio-net设备
84 /// @param list 链表的写锁
85 /// @return Result<&'a mut Pci_Device_Structure_General_Device, VirtioError> 成功则返回virtio设备结构体的可变引用,失败则返回err
get_virtio_net_device<'a>( list: &'a mut RwLockWriteGuard<'_, LinkedList<Box<dyn PciDeviceStructure>>>, ) -> Result<&'a mut PciDeviceStructureGeneralDevice, VirtioError>86 fn get_virtio_net_device<'a>(
87 list: &'a mut RwLockWriteGuard<'_, LinkedList<Box<dyn PciDeviceStructure>>>,
88 ) -> Result<&'a mut PciDeviceStructureGeneralDevice, VirtioError> {
89 let result = get_pci_device_structure_mut(list, NETWORK_CLASS, ETHERNET_SUBCLASS);
90 if result.is_empty() {
91 return Err(VirtioError::NetDeviceNotFound);
92 }
93 for device in result {
94 let standard_device = device.as_standard_device_mut().unwrap();
95 let header = &standard_device.common_header;
96 if header.vendor_id == 0x1AF4
97 && header.device_id >= 0x1000
98 && header.device_id <= 0x103F
99 && standard_device.subsystem_id == 1
100 {
101 return Ok(standard_device);
102 }
103 }
104 Err(VirtioError::VirtioNetNotFound)
105 }
106