Crate switchtec_user_sys

Source
Expand description

§switchtec-user-sys Build Docs

A Rust wrapper for the switchtec-user library.

Details and usage instructions for the switchtec-user library can be found here.

§Example Usage

The examples below use the SwitchtecDevice and CStrExt types introduced by this library, including functions from the switchtec-user C library that this crate wraps.

§Get pciswitch device name and temperature

Example using the switchtec_name and switchtec_die_temp functions provided by the switchtec-user library

use std::env;

use switchtec_user_sys::{switchtec_die_temp, switchtec_name, SwitchtecDevice, CStrExt};

fn main() -> anyhow::Result<()> {
    let path = env::args()
        .skip(1)
        .next()
        .unwrap_or_else(|| "/dev/pciswitch0".to_owned());

    let device = SwitchtecDevice::open(path)?;

    // SAFETY: We know that device holds a valid/open switchtec device
    let (device_name, temperature) = unsafe {
        let temp = switchtec_die_temp(*device);
        // `CStrExt` is providing `as_string()` here for the returned C-style char* string
        let name = switchtec_name(*device).as_string()?;
        (name, temp)
    };
    println!("Temperature for {device_name}: {temperature}");

    Ok(())
}

§Get status for each port for a pciswitch device

A more complex example using an out-value struct with switchtec_status

use std::env;
use std::io;
use std::ptr;

use switchtec_user_sys::{switchtec_status, switchtec_status_free, SwitchtecDevice};

fn main() -> anyhow::Result<()> {
    let path: std::path::PathBuf = "/dev/pciswitch1".into();
    let device = SwitchtecDevice::open(&path)?;

    // Response struct out-value, to be populated by `switchtec_status`
    // The struct is the same name as the function, so we access this by its
    // full path in order to keep from having a name conflict
    let mut status: *mut switchtec_user_sys::switchtec_status = ptr::null_mut();

    // SAFETY: We're checking that the returned status is not null, and the `port_count`
    // resp provides how many `switchtec_status` structs are present in the data
    let per_port_status = unsafe {
        // We pass in a pointer (*mut) to the status pointer (*mut)
        let port_count = switchtec_status(*device, ptr::addr_of_mut!(status));
        let resp = if status.is_null() || port_count.is_negative() {
            // Negative value represents an error
            // https://microsemi.github.io/switchtec-user/group__Device.html#ga780a757b81a704c19217aca00f42b50e

            // Don't return this immediately so this function can call switchtec_status_free first
            // - For getting the actual error, consider using `switchtec_user_sys::switchtec_strerror`
            // https://microsemi.github.io/switchtec-user/group__Device.html#ga595e1d62336ba76c59344352c334fa18
            Err(io::Error::new(io::ErrorKind::Other, format!("Unknown error")))
        } else {
            // If the call was successful, create a slice from the populated status array
            // for only as many structs were returned: `port_count`
            let statuses: Vec<_> = std::slice::from_raw_parts(status, port_count as usize)
                .iter()
                .take(port_count as usize)
                .copied()
                .collect();
            Ok(statuses)
        };

        // Must be called after switchtec_status to free allocated status structs
        // https://microsemi.github.io/switchtec-user/group__Device.html#ga742519774cbc236ba2d80a08a7dc6b5f
        switchtec_status_free(status as *mut _, port_count);

        resp
    }?;

    println!("{per_port_status:#?}");
    Ok(())
}

§Dependencies

§Bindgen & Clang

This crate uses bindgen which requires Clang to build: bindgen requirements

§Switchtec submodule

In order to build the bindgen bindings and link the library to the switchtec-user C library, the switchtec-user submodule needs to be present. The build.rs script will automatically init the submodule, but you can also do this like:

git submodule update --init

§License

switchtec-user-sys is both MIT and Apache License, Version 2.0 licensed, as found in the LICENSE-MIT and LICENSE-APACHE files.

Re-exports§

pub use super::ffi::switchtec_boot_phase;
pub use super::ffi::switchtec_boot_phase;
pub use super::ffi::switchtec_boot_phase_SWITCHTEC_BOOT_PHASE_BL1;
pub use super::ffi::switchtec_boot_phase_SWITCHTEC_BOOT_PHASE_BL2;
pub use super::ffi::switchtec_boot_phase_SWITCHTEC_BOOT_PHASE_FW;
pub use super::ffi::switchtec_boot_phase_SWITCHTEC_BOOT_PHASE_UNKNOWN;
pub use super::ffi::switchtec_bwcntr_res;
pub use super::ffi::switchtec_bwcntr_res_switchtec_bwcntr_dir;
pub use super::ffi::switchtec_close;
pub use super::ffi::switchtec_cmd;
pub use super::ffi::switchtec_dev;
pub use super::ffi::switchtec_device_info;
pub use super::ffi::switchtec_die_temp;
pub use super::ffi::switchtec_evcntr_get_both;
pub use super::ffi::switchtec_evcntr_setup;
pub use super::ffi::switchtec_evcntr_setup;
pub use super::ffi::switchtec_evcntr_type_str;
pub use super::ffi::switchtec_event_summary;
pub use super::ffi::switchtec_event_summary;
pub use super::ffi::switchtec_fw_body_read_fd;
pub use super::ffi::switchtec_fw_file_info;
pub use super::ffi::switchtec_fw_file_secure_version_newer;
pub use super::ffi::switchtec_fw_image_info;
pub use super::ffi::switchtec_fw_image_type;
pub use super::ffi::switchtec_fw_img_write_hdr;
pub use super::ffi::switchtec_fw_is_boot_ro;
pub use super::ffi::switchtec_fw_part_summary;
pub use super::ffi::switchtec_fw_part_summary;
pub use super::ffi::switchtec_fw_part_summary_free;
pub use super::ffi::switchtec_fw_part_summary_switchtec_fw_part_type;
pub use super::ffi::switchtec_fw_ro_SWITCHTEC_FW_RO;
pub use super::ffi::switchtec_fw_ro_SWITCHTEC_FW_RW;
pub use super::ffi::switchtec_fw_set_boot_ro;
pub use super::ffi::switchtec_fw_toggle_active_partition;
pub use super::ffi::switchtec_fw_type_SWITCHTEC_FW_TYPE_BL2;
pub use super::ffi::switchtec_fw_type_SWITCHTEC_FW_TYPE_BOOT;
pub use super::ffi::switchtec_fw_type_SWITCHTEC_FW_TYPE_CFG;
pub use super::ffi::switchtec_fw_type_SWITCHTEC_FW_TYPE_IMG;
pub use super::ffi::switchtec_fw_type_SWITCHTEC_FW_TYPE_KEY;
pub use super::ffi::switchtec_fw_type_SWITCHTEC_FW_TYPE_MAP;
pub use super::ffi::switchtec_fw_type_SWITCHTEC_FW_TYPE_NVLOG;
pub use super::ffi::switchtec_fw_type_SWITCHTEC_FW_TYPE_SEEPROM;
pub use super::ffi::switchtec_fw_type_SWITCHTEC_FW_TYPE_UNKNOWN;
pub use super::ffi::switchtec_fw_write_fd;
pub use super::ffi::switchtec_fw_write_file;
pub use super::ffi::switchtec_gen;
pub use super::ffi::switchtec_gen;
pub use super::ffi::switchtec_gen_SWITCHTEC_GEN3;
pub use super::ffi::switchtec_gen_SWITCHTEC_GEN4;
pub use super::ffi::switchtec_gen_SWITCHTEC_GEN5;
pub use super::ffi::switchtec_gen_SWITCHTEC_GEN_UNKNOWN;
pub use super::ffi::switchtec_get_fw_version;
pub use super::ffi::switchtec_hard_reset;
pub use super::ffi::switchtec_name;
pub use super::ffi::switchtec_open;
pub use super::ffi::switchtec_partition;
pub use super::ffi::switchtec_port_id;
pub use super::ffi::switchtec_status;
pub use super::ffi::switchtec_status;
pub use super::ffi::switchtec_status_free;
pub use super::ffi::switchtec_strerror;
pub use super::ffi::SWITCHTEC_MAX_EVENT_COUNTERS;
pub use super::ffi::SWITCHTEC_MAX_LANES;
pub use super::ffi::SWITCHTEC_MAX_PARTITIONS;
pub use super::ffi::SWITCHTEC_MAX_PARTS;
pub use super::ffi::SWITCHTEC_MAX_PHY_PORTS;
pub use super::ffi::SWITCHTEC_MAX_PORTS;
pub use super::ffi::SWITCHTEC_MAX_STACKS;

Modules§

ffi
The raw FFI bindings to libswitchtec
mrpc
Re-exported items from libswitchtec that relate to MRPC

Structs§

SwitchtecDevice
SwitchtecDevice offers an safer way to work with the underlying switchtec_dev and represents an open Switchtec PCI Switch device that can be passed into switchtec-user C library functions

Traits§

CStrExt