diff --git a/Cargo.lock b/Cargo.lock index 7c64a09..55b1672 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -165,6 +165,7 @@ dependencies = [ "clap_complete", "colored", "comfy-table", + "glob", "i18n-embed", "i18n-embed-fl", "libpci", diff --git a/Cargo.toml b/Cargo.toml index 52b1991..d1d96f4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,6 +19,7 @@ once_cell = { features = ["std"], default-features = false, version = "1" } i18n-embed = { version = "0.14", features = ["fluent-system", "desktop-requester"] } i18n-embed-fl = "0.8" rust-embed = { version = "8", features = ["debug-embed", "include-exclude"] } +glob = "0.3" [build-dependencies] clap = { features = ["derive"], version = "4" } diff --git a/src/data.rs b/src/data.rs index f107aea..64a586d 100644 --- a/src/data.rs +++ b/src/data.rs @@ -207,6 +207,25 @@ fn set_matching_profiles( } } +fn get_all_devices_from_gc_versions( + devices: &ListOfDevicesT, + hwd_gc_versions: &[(String, String)], + profile_gc_versions: &[String], +) -> Vec { + let mut found_indices = vec![]; + for (sysfs_busid, gc_version) in hwd_gc_versions { + if !profile_gc_versions.iter().any(|x| x == gc_version) { + continue; + } + if let Some(device_index) = + devices.iter().position(|device| &device.sysfs_busid == sysfs_busid) + { + found_indices.push(device_index); + } + } + found_indices +} + pub fn get_all_devices_of_profile(devices: &ListOfDevicesT, profile: &Profile) -> Vec { let mut found_indices = vec![]; @@ -228,6 +247,13 @@ pub fn get_all_devices_of_profile(devices: &ListOfDevicesT, profile: &Profile) - } } + if let Some(gc_versions) = &profile.gc_versions { + if let Some(hwd_gc_versions) = crate::misc::get_gc_versions() { + return get_all_devices_from_gc_versions(devices, &hwd_gc_versions, gc_versions); + } + return vec![]; + } + for hwd_id in profile.hwd_ids.iter() { let mut found_device = false; @@ -301,3 +327,503 @@ fn add_profile_sorted(profiles: &mut Vec>, new_profile: &Profile) { profiles.push(Arc::new(new_profile.clone())); profiles.sort_by(|lhs, rhs| rhs.priority.cmp(&lhs.priority)); } + +#[cfg(test)] +mod tests { + use crate::data; + use crate::device::Device; + + fn test_data() -> Vec { + vec![ + Device { + dev_type: "PCI".to_string(), + class_name: "Host bridge".to_string(), + device_name: "Cezanne Data Fabric; Function 5".to_string(), + vendor_name: "Advanced Micro Devices, Inc. [AMD]".to_string(), + class_id: "0600".to_string(), + device_id: "166f".to_string(), + vendor_id: "1022".to_string(), + sysfs_busid: "0000:00:18.5".to_string(), + sysfs_id: "".to_string(), + available_profiles: vec![], + installed_profiles: vec![], + }, + Device { + dev_type: "PCI".to_string(), + class_name: "Audio device".to_string(), + device_name: "Family 17h/19h HD Audio Controller".to_string(), + vendor_name: "Advanced Micro Devices, Inc. [AMD]".to_string(), + class_id: "0403".to_string(), + device_id: "15e3".to_string(), + vendor_id: "1022".to_string(), + sysfs_busid: "0000:08:00.6".to_string(), + sysfs_id: "".to_string(), + available_profiles: vec![], + installed_profiles: vec![], + }, + Device { + dev_type: "PCI".to_string(), + class_name: "SMBus".to_string(), + device_name: "FCH SMBus Controller".to_string(), + vendor_name: "Advanced Micro Devices, Inc. [AMD]".to_string(), + class_id: "0c05".to_string(), + device_id: "790b".to_string(), + vendor_id: "1022".to_string(), + sysfs_busid: "0000:00:14.0".to_string(), + sysfs_id: "".to_string(), + available_profiles: vec![], + installed_profiles: vec![], + }, + Device { + dev_type: "PCI".to_string(), + class_name: "Host bridge".to_string(), + device_name: "Cezanne Data Fabric; Function 7".to_string(), + vendor_name: "Advanced Micro Devices, Inc. [AMD]".to_string(), + class_id: "0600".to_string(), + device_id: "1671".to_string(), + vendor_id: "1022".to_string(), + sysfs_busid: "0000:00:18.7".to_string(), + sysfs_id: "".to_string(), + available_profiles: vec![], + installed_profiles: vec![], + }, + Device { + dev_type: "PCI".to_string(), + class_name: "Host bridge".to_string(), + device_name: "Renoir PCIe Dummy Host Bridge".to_string(), + vendor_name: "Advanced Micro Devices, Inc. [AMD]".to_string(), + class_id: "0600".to_string(), + device_id: "1632".to_string(), + vendor_id: "1022".to_string(), + sysfs_busid: "0000:00:02.0".to_string(), + sysfs_id: "".to_string(), + available_profiles: vec![], + installed_profiles: vec![], + }, + Device { + dev_type: "PCI".to_string(), + class_name: "Ethernet controller".to_string(), + device_name: "RTL8111/8168/8211/8411 PCI Express Gigabit Ethernet Controller" + .to_string(), + vendor_name: "Realtek Semiconductor Co., Ltd.".to_string(), + class_id: "0200".to_string(), + device_id: "8168".to_string(), + vendor_id: "10ec".to_string(), + sysfs_busid: "0000:04:00.0".to_string(), + sysfs_id: "".to_string(), + available_profiles: vec![], + installed_profiles: vec![], + }, + Device { + dev_type: "PCI".to_string(), + class_name: "PCI bridge".to_string(), + device_name: "Renoir/Cezanne PCIe GPP Bridge".to_string(), + vendor_name: "Advanced Micro Devices, Inc. [AMD]".to_string(), + class_id: "0604".to_string(), + device_id: "1634".to_string(), + vendor_id: "1022".to_string(), + sysfs_busid: "0000:00:02.2".to_string(), + sysfs_id: "".to_string(), + available_profiles: vec![], + installed_profiles: vec![], + }, + Device { + dev_type: "PCI".to_string(), + class_name: "Host bridge".to_string(), + device_name: "Cezanne Data Fabric; Function 0".to_string(), + vendor_name: "Advanced Micro Devices, Inc. [AMD]".to_string(), + class_id: "0600".to_string(), + device_id: "166a".to_string(), + vendor_id: "1022".to_string(), + sysfs_busid: "0000:00:18.0".to_string(), + sysfs_id: "".to_string(), + available_profiles: vec![], + installed_profiles: vec![], + }, + Device { + dev_type: "PCI".to_string(), + class_name: "Network controller".to_string(), + device_name: "RTL8852AE 802.11ax PCIe Wireless Network Adapter".to_string(), + vendor_name: "Realtek Semiconductor Co., Ltd.".to_string(), + class_id: "0280".to_string(), + device_id: "8852".to_string(), + vendor_id: "10ec".to_string(), + sysfs_busid: "0000:05:00.0".to_string(), + sysfs_id: "".to_string(), + available_profiles: vec![], + installed_profiles: vec![], + }, + Device { + dev_type: "PCI".to_string(), + class_name: "Audio device".to_string(), + device_name: "Renoir Radeon High Definition Audio Controller".to_string(), + vendor_name: "Advanced Micro Devices, Inc. [AMD/ATI]".to_string(), + class_id: "0403".to_string(), + device_id: "1637".to_string(), + vendor_id: "1002".to_string(), + sysfs_busid: "0000:08:00.1".to_string(), + sysfs_id: "".to_string(), + available_profiles: vec![], + installed_profiles: vec![], + }, + Device { + dev_type: "PCI".to_string(), + class_name: "PCI bridge".to_string(), + device_name: "Renoir PCIe GPP Bridge".to_string(), + vendor_name: "Advanced Micro Devices, Inc. [AMD]".to_string(), + class_id: "0604".to_string(), + device_id: "1633".to_string(), + vendor_id: "1022".to_string(), + sysfs_busid: "0000:00:01.1".to_string(), + sysfs_id: "".to_string(), + available_profiles: vec![], + installed_profiles: vec![], + }, + Device { + dev_type: "PCI".to_string(), + class_name: "Host bridge".to_string(), + device_name: "Cezanne Data Fabric; Function 2".to_string(), + vendor_name: "Advanced Micro Devices, Inc. [AMD]".to_string(), + class_id: "0600".to_string(), + device_id: "166c".to_string(), + vendor_id: "1022".to_string(), + sysfs_busid: "0000:00:18.2".to_string(), + sysfs_id: "".to_string(), + available_profiles: vec![], + installed_profiles: vec![], + }, + Device { + dev_type: "PCI".to_string(), + class_name: "USB controller".to_string(), + device_name: "Renoir/Cezanne USB 3.1".to_string(), + vendor_name: "Advanced Micro Devices, Inc. [AMD]".to_string(), + class_id: "0c03".to_string(), + device_id: "1639".to_string(), + vendor_id: "1022".to_string(), + sysfs_busid: "0000:08:00.3".to_string(), + sysfs_id: "".to_string(), + available_profiles: vec![], + installed_profiles: vec![], + }, + Device { + dev_type: "PCI".to_string(), + class_name: "SD Host controller".to_string(), + device_name: "GL9750 SD Host Controller".to_string(), + vendor_name: "Genesys Logic, Inc".to_string(), + class_id: "0805".to_string(), + device_id: "9750".to_string(), + vendor_id: "17a0".to_string(), + sysfs_busid: "0000:06:00.0".to_string(), + sysfs_id: "".to_string(), + available_profiles: vec![], + installed_profiles: vec![], + }, + Device { + dev_type: "PCI".to_string(), + class_name: "Host bridge".to_string(), + device_name: "Cezanne Data Fabric; Function 4".to_string(), + vendor_name: "Advanced Micro Devices, Inc. [AMD]".to_string(), + class_id: "0600".to_string(), + device_id: "166e".to_string(), + vendor_id: "1022".to_string(), + sysfs_busid: "0000:00:18.4".to_string(), + sysfs_id: "".to_string(), + available_profiles: vec![], + installed_profiles: vec![], + }, + Device { + dev_type: "PCI".to_string(), + class_name: "PCI bridge".to_string(), + device_name: "Renoir Internal PCIe GPP Bridge to Bus".to_string(), + vendor_name: "Advanced Micro Devices, Inc. [AMD]".to_string(), + class_id: "0604".to_string(), + device_id: "1635".to_string(), + vendor_id: "1022".to_string(), + sysfs_busid: "0000:00:08.1".to_string(), + sysfs_id: "".to_string(), + available_profiles: vec![], + installed_profiles: vec![], + }, + Device { + dev_type: "PCI".to_string(), + class_name: "Multimedia controller".to_string(), + device_name: "ACP/ACP3X/ACP6x Audio Coprocessor".to_string(), + vendor_name: "Advanced Micro Devices, Inc. [AMD]".to_string(), + class_id: "0480".to_string(), + device_id: "15e2".to_string(), + vendor_id: "1022".to_string(), + sysfs_busid: "0000:08:00.5".to_string(), + sysfs_id: "".to_string(), + available_profiles: vec![], + installed_profiles: vec![], + }, + Device { + dev_type: "PCI".to_string(), + class_name: "Host bridge".to_string(), + device_name: "Renoir/Cezanne Root Complex".to_string(), + vendor_name: "Advanced Micro Devices, Inc. [AMD]".to_string(), + class_id: "0600".to_string(), + device_id: "1630".to_string(), + vendor_id: "1022".to_string(), + sysfs_busid: "0000:00:00.0".to_string(), + sysfs_id: "".to_string(), + available_profiles: vec![], + installed_profiles: vec![], + }, + Device { + dev_type: "PCI".to_string(), + class_name: "Audio device".to_string(), + device_name: "Navi 10 HDMI Audio".to_string(), + vendor_name: "Advanced Micro Devices, Inc. [AMD/ATI]".to_string(), + class_id: "0403".to_string(), + device_id: "ab38".to_string(), + vendor_id: "1002".to_string(), + sysfs_busid: "0000:03:00.1".to_string(), + sysfs_id: "".to_string(), + available_profiles: vec![], + installed_profiles: vec![], + }, + Device { + dev_type: "PCI".to_string(), + class_name: "Host bridge".to_string(), + device_name: "Cezanne Data Fabric; Function 6".to_string(), + vendor_name: "Advanced Micro Devices, Inc. [AMD]".to_string(), + class_id: "0600".to_string(), + device_id: "1670".to_string(), + vendor_id: "1022".to_string(), + sysfs_busid: "0000:00:18.6".to_string(), + sysfs_id: "".to_string(), + available_profiles: vec![], + installed_profiles: vec![], + }, + Device { + dev_type: "PCI".to_string(), + class_name: "IOMMU".to_string(), + device_name: "Renoir/Cezanne IOMMU".to_string(), + vendor_name: "Advanced Micro Devices, Inc. [AMD]".to_string(), + class_id: "0806".to_string(), + device_id: "1631".to_string(), + vendor_id: "1022".to_string(), + sysfs_busid: "0000:00:00.2".to_string(), + sysfs_id: "".to_string(), + available_profiles: vec![], + installed_profiles: vec![], + }, + Device { + dev_type: "PCI".to_string(), + class_name: "Non-Volatile memory controller".to_string(), + device_name: "3400 NVMe SSD [Hendrix]".to_string(), + vendor_name: "Micron Technology Inc".to_string(), + class_id: "0108".to_string(), + device_id: "5407".to_string(), + vendor_id: "1344".to_string(), + sysfs_busid: "0000:07:00.0".to_string(), + sysfs_id: "".to_string(), + available_profiles: vec![], + installed_profiles: vec![], + }, + Device { + dev_type: "PCI".to_string(), + class_name: "PCI bridge".to_string(), + device_name: "Renoir/Cezanne PCIe GPP Bridge".to_string(), + vendor_name: "Advanced Micro Devices, Inc. [AMD]".to_string(), + class_id: "0604".to_string(), + device_id: "1634".to_string(), + vendor_id: "1022".to_string(), + sysfs_busid: "0000:00:02.1".to_string(), + sysfs_id: "".to_string(), + available_profiles: vec![], + installed_profiles: vec![], + }, + Device { + dev_type: "PCI".to_string(), + class_name: "PCI bridge".to_string(), + device_name: "Navi 10 XL Upstream Port of PCI Express Switch".to_string(), + vendor_name: "Advanced Micro Devices, Inc. [AMD/ATI]".to_string(), + class_id: "0604".to_string(), + device_id: "1478".to_string(), + vendor_id: "1002".to_string(), + sysfs_busid: "0000:01:00.0".to_string(), + sysfs_id: "".to_string(), + available_profiles: vec![], + installed_profiles: vec![], + }, + Device { + dev_type: "PCI".to_string(), + class_name: "ISA bridge".to_string(), + device_name: "FCH LPC Bridge".to_string(), + vendor_name: "Advanced Micro Devices, Inc. [AMD]".to_string(), + class_id: "0601".to_string(), + device_id: "790e".to_string(), + vendor_id: "1022".to_string(), + sysfs_busid: "0000:00:14.3".to_string(), + sysfs_id: "".to_string(), + available_profiles: vec![], + installed_profiles: vec![], + }, + Device { + dev_type: "PCI".to_string(), + class_name: "PCI bridge".to_string(), + device_name: "Renoir/Cezanne PCIe GPP Bridge".to_string(), + vendor_name: "Advanced Micro Devices, Inc. [AMD]".to_string(), + class_id: "0604".to_string(), + device_id: "1634".to_string(), + vendor_id: "1022".to_string(), + sysfs_busid: "0000:00:02.3".to_string(), + sysfs_id: "".to_string(), + available_profiles: vec![], + installed_profiles: vec![], + }, + Device { + dev_type: "PCI".to_string(), + class_name: "VGA compatible controller".to_string(), + device_name: "Cezanne [Radeon Vega Series / Radeon Vega Mobile Series]".to_string(), + vendor_name: "Advanced Micro Devices, Inc. [AMD/ATI]".to_string(), + class_id: "0300".to_string(), + device_id: "1638".to_string(), + vendor_id: "1002".to_string(), + sysfs_busid: "0000:08:00.0".to_string(), + sysfs_id: "".to_string(), + available_profiles: vec![], + installed_profiles: vec![], + }, + Device { + dev_type: "PCI".to_string(), + class_name: "Host bridge".to_string(), + device_name: "Renoir PCIe Dummy Host Bridge".to_string(), + vendor_name: "Advanced Micro Devices, Inc. [AMD]".to_string(), + class_id: "0600".to_string(), + device_id: "1632".to_string(), + vendor_id: "1022".to_string(), + sysfs_busid: "0000:00:01.0".to_string(), + sysfs_id: "".to_string(), + available_profiles: vec![], + installed_profiles: vec![], + }, + Device { + dev_type: "PCI".to_string(), + class_name: "PCI bridge".to_string(), + device_name: "Navi 10 XL Downstream Port of PCI Express Switch".to_string(), + vendor_name: "Advanced Micro Devices, Inc. [AMD/ATI]".to_string(), + class_id: "0604".to_string(), + device_id: "1479".to_string(), + vendor_id: "1002".to_string(), + sysfs_busid: "0000:02:00.0".to_string(), + sysfs_id: "".to_string(), + available_profiles: vec![], + installed_profiles: vec![], + }, + Device { + dev_type: "PCI".to_string(), + class_name: "Host bridge".to_string(), + device_name: "Cezanne Data Fabric; Function 1".to_string(), + vendor_name: "Advanced Micro Devices, Inc. [AMD]".to_string(), + class_id: "0600".to_string(), + device_id: "166b".to_string(), + vendor_id: "1022".to_string(), + sysfs_busid: "0000:00:18.1".to_string(), + sysfs_id: "".to_string(), + available_profiles: vec![], + installed_profiles: vec![], + }, + Device { + dev_type: "PCI".to_string(), + class_name: "Encryption controller".to_string(), + device_name: "Family 17h (Models 10h-1fh) Platform Security Processor".to_string(), + vendor_name: "Advanced Micro Devices, Inc. [AMD]".to_string(), + class_id: "1080".to_string(), + device_id: "15df".to_string(), + vendor_id: "1022".to_string(), + sysfs_busid: "0000:08:00.2".to_string(), + sysfs_id: "".to_string(), + available_profiles: vec![], + installed_profiles: vec![], + }, + Device { + dev_type: "PCI".to_string(), + class_name: "PCI bridge".to_string(), + device_name: "Renoir/Cezanne PCIe GPP Bridge".to_string(), + vendor_name: "Advanced Micro Devices, Inc. [AMD]".to_string(), + class_id: "0604".to_string(), + device_id: "1634".to_string(), + vendor_id: "1022".to_string(), + sysfs_busid: "0000:00:01.2".to_string(), + sysfs_id: "".to_string(), + available_profiles: vec![], + installed_profiles: vec![], + }, + Device { + dev_type: "PCI".to_string(), + class_name: "Host bridge".to_string(), + device_name: "Cezanne Data Fabric; Function 3".to_string(), + vendor_name: "Advanced Micro Devices, Inc. [AMD]".to_string(), + class_id: "0600".to_string(), + device_id: "166d".to_string(), + vendor_id: "1022".to_string(), + sysfs_busid: "0000:00:18.3".to_string(), + sysfs_id: "".to_string(), + available_profiles: vec![], + installed_profiles: vec![], + }, + Device { + dev_type: "PCI".to_string(), + class_name: "Host bridge".to_string(), + device_name: "Renoir PCIe Dummy Host Bridge".to_string(), + vendor_name: "Advanced Micro Devices, Inc. [AMD]".to_string(), + class_id: "0600".to_string(), + device_id: "1632".to_string(), + vendor_id: "1022".to_string(), + sysfs_busid: "0000:00:08.0".to_string(), + sysfs_id: "".to_string(), + available_profiles: vec![], + installed_profiles: vec![], + }, + Device { + dev_type: "PCI".to_string(), + class_name: "USB controller".to_string(), + device_name: "Renoir/Cezanne USB 3.1".to_string(), + vendor_name: "Advanced Micro Devices, Inc. [AMD]".to_string(), + class_id: "0c03".to_string(), + device_id: "1639".to_string(), + vendor_id: "1022".to_string(), + sysfs_busid: "0000:08:00.4".to_string(), + sysfs_id: "".to_string(), + available_profiles: vec![], + installed_profiles: vec![], + }, + Device { + dev_type: "PCI".to_string(), + class_name: "Display controller".to_string(), + device_name: "Navi 14 [Radeon RX 5500/5500M / Pro 5500M]".to_string(), + vendor_name: "Advanced Micro Devices, Inc. [AMD/ATI]".to_string(), + class_id: "0380".to_string(), + device_id: "7340".to_string(), + vendor_id: "1002".to_string(), + sysfs_busid: "0000:03:00.0".to_string(), + sysfs_id: "".to_string(), + available_profiles: vec![], + installed_profiles: vec![], + }, + ] + } + + #[test] + fn get_devices_from_gc_versions() { + let devices = test_data(); + let hwd_gc_versions = vec![ + ("0000:03:00.0".to_owned(), "10.1.1".to_owned()), + ("0000:08:00.0".to_owned(), "9.3.0".to_owned()), + ]; + let profile_gc_versions = + vec!["10.1.1".to_owned(), "9.3.0".to_owned(), "10.3.1".to_owned(), "11.0.0".to_owned()]; + + assert_eq!( + data::get_all_devices_from_gc_versions( + &devices, + &hwd_gc_versions, + &profile_gc_versions + ), + vec![35, 26] + ); + } +} diff --git a/src/misc.rs b/src/misc.rs index 35eff45..ef3f227 100644 --- a/src/misc.rs +++ b/src/misc.rs @@ -91,6 +91,45 @@ pub fn check_environment() -> Vec { missing_dirs } +pub fn get_sysfs_busid_from_amdgpu_path(amdgpu_path: &str) -> &str { + amdgpu_path.split('/') + // Extract the 7th element (amdgpu id) + .nth(6) + .unwrap_or_default() +} + +// returns Vec of ( sysfs busid, formatted GC version ) +pub fn get_gc_versions() -> Option> { + use std::fs; + + let ip_match_paths = glob::glob("/sys/bus/pci/drivers/amdgpu/*/ip_discovery/die/*/GC/*/") + .expect("Failed to read glob pattern"); + + let gc_versions = ip_match_paths + .filter_map(Result::ok) + .filter_map(|path| path.to_str().map(|s| s.to_owned())) + .filter_map(|ip_match_path| { + let sysfs_busid = get_sysfs_busid_from_amdgpu_path(&ip_match_path).to_owned(); + + let major = + fs::read_to_string(format!("{ip_match_path}/major")).ok()?.trim().to_owned(); + let minor = + fs::read_to_string(format!("{ip_match_path}/minor")).ok()?.trim().to_owned(); + let revision = + fs::read_to_string(format!("{ip_match_path}/revision")).ok()?.trim().to_owned(); + + Some((sysfs_busid, format!("{major}.{minor}.{revision}"))) + }) + .collect::>(); + + // Correctly check for empty Vec: + if gc_versions.is_empty() { + None + } else { + Some(gc_versions) + } +} + #[cfg(test)] mod tests { use crate::{misc, profile}; @@ -111,4 +150,58 @@ mod tests { assert!(misc::find_profile("nvidia-dkm", &profiles).is_none()); assert!(misc::find_profile("nvidia-dkms.40xxcards", &profiles).is_some()); } + + #[test] + fn gpu_from_amdgpu_path() { + assert_eq!( + misc::get_sysfs_busid_from_amdgpu_path( + "/sys/bus/pci/drivers/amdgpu/0000:c2:00.0/ip_discovery/die/0/GC/0/" + ), + "0000:c2:00.0" + ); + assert_eq!( + misc::get_sysfs_busid_from_amdgpu_path( + "/sys/bus/pci/drivers/amdgpu/0000:c2:00.0/ip_discovery/die//" + ), + "0000:c2:00.0" + ); + assert_eq!( + misc::get_sysfs_busid_from_amdgpu_path("/sys/bus/pci/drivers/amdgpu/0000:c2:00.0/"), + "0000:c2:00.0" + ); + assert_eq!( + misc::get_sysfs_busid_from_amdgpu_path( + "/sys/bus/pci/drivers/amdgpu/0000:30:00.0/ip_discovery/die/0/GC/0" + ), + "0000:30:00.0" + ); + assert_eq!( + misc::get_sysfs_busid_from_amdgpu_path( + "/sys/bus/pci/drivers/amdgpu/0000:30:00.0/ip_discovery/die//" + ), + "0000:30:00.0" + ); + assert_eq!( + misc::get_sysfs_busid_from_amdgpu_path("/sys/bus/pci/drivers/amdgpu/0000:30:00.0/"), + "0000:30:00.0" + ); + assert_eq!( + misc::get_sysfs_busid_from_amdgpu_path( + "/sys/bus/pci/drivers/amdgpu/0000:04:00.0/ip_discovery/die/0/GC/0" + ), + "0000:04:00.0" + ); + assert_eq!( + misc::get_sysfs_busid_from_amdgpu_path( + "/sys/bus/pci/drivers/amdgpu/0000:04:00.0/ip_discovery/die//" + ), + "0000:04:00.0" + ); + assert_eq!( + misc::get_sysfs_busid_from_amdgpu_path("/sys/bus/pci/drivers/amdgpu/0000:04:00.0/"), + "0000:04:00.0" + ); + + assert_eq!(misc::get_sysfs_busid_from_amdgpu_path("/sys/bus/pci/drivers/amdgpu/"), ""); + } } diff --git a/src/profile.rs b/src/profile.rs index 3f9557b..bddac62 100644 --- a/src/profile.rs +++ b/src/profile.rs @@ -46,6 +46,7 @@ pub struct Profile { pub post_remove: String, pub device_name_pattern: Option, pub hwd_product_name_pattern: Option, + pub gc_versions: Option>, pub hwd_ids: Vec, } @@ -154,6 +155,11 @@ fn parse_profile(node: &toml::Table, profile_name: &str) -> Result { hwd_product_name_pattern: node .get("hwd_product_name_pattern") .and_then(|x| x.as_str().map(str::to_string)), + gc_versions: node.get("gc_versions").and_then(|x| { + x.as_str() + .map(str::split_ascii_whitespace) + .map(|x| x.map(str::to_string).collect::>()) + }), }; let conf_devids = node.get("device_ids").and_then(|x| x.as_str()).unwrap_or(""); @@ -253,6 +259,9 @@ pub fn write_profile_to_file(file_path: &str, profile: &Profile) -> bool { if let Some(product_name_pattern) = &profile.hwd_product_name_pattern { table.insert("hwd_product_name_pattern".to_owned(), product_name_pattern.clone().into()); } + if let Some(gc_versions) = &profile.gc_versions { + table.insert("gc_versions".to_owned(), gc_versions.clone().into()); + } let last_hwd_id = profile.hwd_ids.last().unwrap(); @@ -349,6 +358,7 @@ mod tests { assert_eq!(parsed_profiles[1].device_name_pattern, None); assert_eq!(parsed_profiles[1].hwd_product_name_pattern, Some("(Ally)\\w+".to_owned())); assert_eq!(parsed_profiles[1].hwd_ids, hwd_ids); + assert_eq!(parsed_profiles[1].gc_versions, None); assert!(!parsed_profiles[1].post_install.is_empty()); assert!(!parsed_profiles[1].post_remove.is_empty()); }