|
| 1 | +// SPDX-License-Identifier: MIT OR Apache-2.0 |
| 2 | + |
| 3 | +use core::time::Duration; |
| 4 | +use uefi::boot; |
| 5 | +use uefi::proto::device_path::text::{AllowShortcuts, DisplayOnly}; |
| 6 | +use uefi::proto::device_path::DevicePath; |
| 7 | +use uefi::proto::media::block::BlockIO; |
| 8 | +use uefi::proto::nvme::pass_thru::NvmePassThru; |
| 9 | +use uefi::proto::nvme::{NvmeQueueType, NvmeRequestBuilder}; |
| 10 | + |
| 11 | +pub fn test() { |
| 12 | + info!("Running NVMe PassThru tests"); |
| 13 | + |
| 14 | + assert!(try_find_drive()); |
| 15 | +} |
| 16 | + |
| 17 | +fn try_find_drive() -> bool { |
| 18 | + let block_io_handles = boot::find_handles::<BlockIO>().unwrap(); |
| 19 | + for handle in block_io_handles { |
| 20 | + let Ok(device_path) = boot::open_protocol_exclusive::<DevicePath>(handle) else { |
| 21 | + continue; |
| 22 | + }; |
| 23 | + let mut device_path = &*device_path; |
| 24 | + |
| 25 | + let Ok(nvme_pt_handle) = boot::locate_device_path::<NvmePassThru>(&mut device_path) else { |
| 26 | + continue; |
| 27 | + }; |
| 28 | + let nvme_pt = boot::open_protocol_exclusive::<NvmePassThru>(nvme_pt_handle).unwrap(); |
| 29 | + let device_path_str = device_path |
| 30 | + .to_string(DisplayOnly(true), AllowShortcuts(false)) |
| 31 | + .unwrap(); |
| 32 | + info!("- Successfully opened NVMe: {}", device_path_str); |
| 33 | + let mut nvme_ctrl = nvme_pt.controller(); |
| 34 | + |
| 35 | + let request = NvmeRequestBuilder::new(nvme_pt.io_align(), 0x06, NvmeQueueType::ADMIN) |
| 36 | + .with_timeout(Duration::from_millis(500)) |
| 37 | + .with_cdw10(1) // we want info about controller |
| 38 | + .with_transfer_buffer(4096) |
| 39 | + .unwrap() |
| 40 | + .build(); |
| 41 | + let result = nvme_ctrl.execute_command(request); |
| 42 | + if let Ok(result) = result { |
| 43 | + let bfr = result.transfer_buffer().unwrap(); |
| 44 | + let serial = core::str::from_utf8(&bfr[4..24]).unwrap().trim(); |
| 45 | + info!("Found NVMe with serial: '{}'", serial); |
| 46 | + if serial == "uefi-rsNvmePassThru" { |
| 47 | + return true; |
| 48 | + } |
| 49 | + } |
| 50 | + } |
| 51 | + |
| 52 | + false |
| 53 | +} |
0 commit comments