Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ jobs:
path: target/debug/framework_tool

- name: Build Linux tool (Release)
run: cargo build -p framework_tool --release --features nvidia
run: cargo build -p framework_tool --release --features nvidia,smartmontools

- name: Upload Linux App
uses: actions/upload-artifact@v6
Expand Down Expand Up @@ -143,10 +143,10 @@ jobs:
- name: Build Windows tool
run: |
cargo build -p framework_tool
cargo build -p framework_tool --release --features nvidia
cargo build -p framework_tool --release --features nvidia,smartmontools

- name: Check if Windows tool can start
run: cargo run -- --help --release
run: target/release/framework_tool.exe --help

# Upload release build so that vcruntime is statically linked
- name: Upload Windows App
Expand Down
10 changes: 10 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 22 additions & 0 deletions EXAMPLES.md
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,28 @@ Touchpad
Firmware Version: v0E07
```

### Disks (needs `smartmontools` feature)

Shows model, serial and firmware version of all ATA, NVMe and SCSI disks,
including NVMe drives behind USB bridges, like the Storage Expansion Card.

```
> framework_tool --versions
[...]
NVMe Device: /dev/sda (sntasmedia)
Model Number: 250GB Expansion Card
Serial Number: 071C4BE9098A2D57
Firmware Version: UHFM00.7
NVMe Device: /dev/sdb (sntasmedia)
Model Number: USB DISK 3.2
Serial Number: 07001A60B3A20F79
Firmware Version: UHFM10.0
NVMe Device: /dev/nvme0 (nvme)
Model Number: WD PC SN8000S SDEPNRG-2T00
Serial Number: 24434D800023
Firmware Version: 63100000
```

### Input modules (Laptop 16)

Shows firmware version and location of the modules.
Expand Down
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,8 @@ On UEFI and FreeBSD raw port I/O is used - on Linux this can also be used as a f
- [x] Retimer
- [x] Touchpad (Linux, Windows, FreeBSD, not UEFI)
- [x] Touchscreen (Linux, Windows, FreeBSD, not UEFI)
- [x] NVMe SSD (Linux only)
- [x] Storage Expansion Card, NVMe/SATA/SCSI disks (Needs `smartmontools` feature)
- [x] Get Expansion Card Firmware (Not on UEFI so far)
- [x] HDMI Expansion Card (`--dp-hdmi-info`)
- [x] DisplayPort Expansion Card (`--dp-hdmi-info`)
Expand Down Expand Up @@ -293,6 +295,23 @@ make -C framework_uefi
ls -l framework_uefi/build/x86_64-unknown-uefi/boot.efi
```

#### Optional: smartmontools

With the `smartmontools` feature, `--versions` uses libsmartmon to show model,
serial and firmware version of all disks, including the Storage Expansion Card
and other NVMe drives behind USB bridges.

The library is built from source by the
[`smartmon`](https://crates.io/crates/smartmon) crate, only a C++ compiler is
needed.

Note: smartmontools is licensed GPL-2.0-or-later, so a binary built with this
feature must be distributed under the GPL.

```
cargo build --features smartmontools
```

## Install local package

```
Expand Down
3 changes: 3 additions & 0 deletions framework_lib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ rusb = ["dep:rusb"]
hidapi = ["dep:hidapi"]
uefi = [ "lazy_static/spin_no_std" ]
nvidia = ["dep:nvml-wrapper"]
# Needs libsmartmon (GPL-2.0-or-later), see README
smartmontools = ["dep:smartmon"]

[build-dependencies]
built = { version = "0.8", features = ["chrono", "git2"] }
Expand All @@ -39,6 +41,7 @@ hidapi = { version = "2.6.3", features = [ "windows-native" ], optional = true }
rusb = { version = "0.9.4", optional = true }
guid-create = { version = "0.5.0", default-features = false }
zerocopy = { version = "0.8", default-features = false, features = ["derive"] }
smartmon = { version = "0.1", optional = true }

[target.'cfg(target_os = "uefi")'.dependencies]
uefi = { version = "0.36.1", features = ["alloc", "global_allocator", "panic_handler", "logger"] }
Expand Down
27 changes: 25 additions & 2 deletions framework_lib/src/commandline/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ use crate::esrt::{self, ResourceType};
use crate::fw_uefi::enable_page_break;
#[cfg(feature = "rusb")]
use crate::inputmodule::check_inputmodule_version;
#[cfg(target_os = "linux")]
#[cfg(all(target_os = "linux", not(feature = "smartmontools")))]
use crate::nvme;
use crate::os_specific;
use crate::parade_retimer;
Expand Down Expand Up @@ -843,7 +843,10 @@ fn print_versions(ec: &CrosEc) {
#[cfg(feature = "hidapi")]
print_dp_hdmi_details(false);

#[cfg(target_os = "linux")]
#[cfg(feature = "smartmontools")]
print_disk_versions();

#[cfg(all(target_os = "linux", not(feature = "smartmontools")))]
for i in 0..4 {
let device = format!("/dev/nvme{i}");
match nvme::get_nvme_firmware_version(&device) {
Expand All @@ -863,6 +866,26 @@ fn print_versions(ec: &CrosEc) {
print_nvidia_details();
}

#[cfg(feature = "smartmontools")]
fn print_disk_versions() {
match smartmon::scan_disks() {
Ok(disks) => {
for disk in disks {
println!(
"{} Device: {} ({})",
disk.protocol, disk.name, disk.dev_type
);
println!(" Model Number: {}", disk.model);
if !disk.serial.is_empty() {
println!(" Serial Number: {}", disk.serial);
}
println!(" Firmware Version: {}", disk.firmware);
}
}
Err(err) => error!("{}", err),
}
}

#[cfg(feature = "nvidia")]
fn probably_has_nvidia() -> bool {
match smbios::get_platform().and_then(Platform::which_family) {
Expand Down
1 change: 1 addition & 0 deletions framework_tool/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ path = "src/main.rs"
default = [ ]
readonly = [ "framework_lib/readonly" ]
nvidia = [ "framework_lib/nvidia" ]
smartmontools = [ "framework_lib/smartmontools" ]

[dependencies.framework_lib]
path = "../framework_lib"
Expand Down
Loading