libdevinfo_sys/
lib.rs

1/*
2 * Copyright 2024 Oxide Computer Company
3 */
4
5#![allow(non_camel_case_types)]
6
7use std::{
8    marker::{PhantomData, PhantomPinned},
9    os::raw::{c_char, c_int, c_uchar, c_uint, c_void},
10};
11
12macro_rules! opaque_handle {
13    ($type_name:ident) => {
14        #[repr(C)]
15        pub struct $type_name {
16            _data: [u8; 0],
17            /*
18             * See https://doc.rust-lang.org/nomicon/ffi.html; this marker
19             * guarantees our type does not implement `Send`, `Sync`, or
20             * `Unpin`.
21             */
22            _marker: PhantomData<(*mut u8, PhantomPinned)>,
23        }
24        impl Copy for $type_name {}
25        impl Clone for $type_name {
26            fn clone(&self) -> $type_name {
27                *self
28            }
29        }
30    };
31}
32
33opaque_handle!(di_node_t);
34opaque_handle!(di_prop_t);
35opaque_handle!(di_minor_t);
36opaque_handle!(di_devlink_handle_t);
37opaque_handle!(di_devlink_t);
38#[cfg(feature = "private")]
39opaque_handle!(di_dim_t);
40
41pub const DI_NODE_NIL: *mut di_node_t = std::ptr::null_mut();
42pub const DI_PROP_NIL: *mut di_prop_t = std::ptr::null_mut();
43pub const DI_MINOR_NIL: *mut di_minor_t = std::ptr::null_mut();
44pub const DI_LINK_NIL: *mut di_devlink_handle_t = std::ptr::null_mut();
45
46pub const DIIOC: c_uint = 0xDF << 8;
47pub const DINFOSUBTREE: c_uint = DIIOC | 0x01; /* include subtree */
48pub const DINFOMINOR: c_uint = DIIOC | 0x02; /* include minor data */
49pub const DINFOPROP: c_uint = DIIOC | 0x04; /* include properties */
50pub const DINFOPATH: c_uint = DIIOC | 0x08; /* include multipath node data */
51pub const DINFOLYR: c_uint = DIIOC | 0x40; /* include device layering data */
52pub const DINFOHP: c_uint = DIIOC | 0x400000; /* include hotplug info (?) */
53
54pub const DINFOCPYONE: c_uint = DIIOC; /* just a single node */
55pub const DINFOCPYALL: c_uint = DINFOSUBTREE | DINFOPROP | DINFOMINOR;
56
57/*
58 * These flags are Private:
59 */
60#[cfg(feature = "private")]
61pub const DINFOPRIVDATA: c_uint = DIIOC | 0x10; /* include private data */
62#[cfg(feature = "private")]
63pub const DINFOFORCE: c_uint = DIIOC | 0x20; /* force load all drivers */
64#[cfg(feature = "private")]
65pub const DINFOCACHE: c_uint = DIIOC | 0x100000; /* use cached data  */
66#[cfg(feature = "private")]
67pub const DINFOCLEANUP: c_uint = DIIOC | 0x200000; /* cleanup /etc files */
68
69pub const DI_MAKE_LINK: c_uint = 0x01;
70
71pub const DI_PRIMARY_LINK: c_uint = 0x01;
72pub const DI_SECONDARY_LINK: c_uint = 0x02;
73pub const DI_LINK_TYPES: c_uint = 0x03;
74
75pub const DI_WALK_CONTINUE: c_int = 0;
76pub const DI_WALK_PRUNESIB: c_int = -1;
77pub const DI_WALK_PRUNECHILD: c_int = -2;
78pub const DI_WALK_TERMINATE: c_int = -3;
79
80pub const DI_PROP_TYPE_BOOLEAN: c_int = 0;
81pub const DI_PROP_TYPE_INT: c_int = 1;
82pub const DI_PROP_TYPE_STRING: c_int = 2;
83pub const DI_PROP_TYPE_BYTE: c_int = 3;
84pub const DI_PROP_TYPE_UNKNOWN: c_int = 4;
85pub const DI_PROP_TYPE_UNDEF_IT: c_int = 5;
86pub const DI_PROP_TYPE_INT64: c_int = 6;
87
88#[link(name = "devinfo")]
89extern "C" {
90    pub fn di_init(phys_path: *const c_char, flag: c_uint) -> *mut di_node_t;
91    pub fn di_fini(root: *mut di_node_t);
92
93    pub fn di_drv_first_node(
94        drv_name: *const c_char,
95        root: *mut di_node_t,
96    ) -> *mut di_node_t;
97    pub fn di_drv_next_node(node: *mut di_node_t) -> *mut di_node_t;
98
99    pub fn di_parent_node(node: *mut di_node_t) -> *mut di_node_t;
100    pub fn di_sibling_node(node: *mut di_node_t) -> *mut di_node_t;
101    pub fn di_child_node(node: *mut di_node_t) -> *mut di_node_t;
102
103    pub fn di_node_name(node: *mut di_node_t) -> *const c_char;
104    pub fn di_driver_name(node: *mut di_node_t) -> *const c_char;
105    pub fn di_instance(node: *mut di_node_t) -> c_int;
106
107    pub fn di_prop_next(
108        node: *mut di_node_t,
109        prop: *mut di_prop_t,
110    ) -> *mut di_prop_t;
111
112    pub fn di_prop_name(prop: *mut di_prop_t) -> *const c_char;
113    pub fn di_prop_type(prop: *mut di_prop_t) -> c_int;
114
115    pub fn di_prop_strings(
116        prop: *mut di_prop_t,
117        data: *mut *mut c_char,
118    ) -> c_int;
119    pub fn di_prop_bytes(
120        prop: *mut di_prop_t,
121        data: *mut *mut c_uchar,
122    ) -> c_int;
123    pub fn di_prop_ints(prop: *mut di_prop_t, data: *mut *mut c_int) -> c_int;
124    pub fn di_prop_int64(prop: *mut di_prop_t, data: *mut *mut i64) -> c_int;
125
126    pub fn di_devfs_path(node: *mut di_node_t) -> *mut c_char;
127    pub fn di_devfs_minor_path(minor: *mut di_minor_t) -> *mut c_char;
128    pub fn di_devfs_path_free(path_buf: *mut c_char);
129
130    pub fn di_minor_next(
131        node: *mut di_node_t,
132        minor: *mut di_minor_t,
133    ) -> *mut di_minor_t;
134    pub fn di_minor_name(minor: *mut di_minor_t) -> *const c_char;
135    pub fn di_minor_nodetype(minor: *mut di_minor_t) -> *const c_char;
136    pub fn di_minor_spectype(minor: *mut di_minor_t) -> c_int;
137
138    pub fn di_devlink_init(
139        name: *const c_char,
140        flags: c_uint,
141    ) -> *mut di_devlink_handle_t;
142    pub fn di_devlink_fini(hdlp: *mut *mut di_devlink_handle_t) -> c_int;
143
144    pub fn di_devlink_walk(
145        hdl: *mut di_devlink_handle_t,
146        re: *const c_char,
147        mpath: *const c_char,
148        flags: c_uint,
149        arg: *mut c_void,
150        devlink_callback: unsafe extern "C" fn(
151            *const di_devlink_t,
152            *mut c_void,
153        ) -> c_int,
154    ) -> c_int;
155
156    pub fn di_devlink_path(devlink: *const di_devlink_t) -> *const c_char;
157    pub fn di_devlink_content(devlink: *const di_devlink_t) -> *const c_char;
158    pub fn di_devlink_type(devlink: *const di_devlink_t) -> c_int;
159}
160
161/*
162 * These routines are currently Private:
163 */
164#[cfg(feature = "private")]
165#[link(name = "devinfo")]
166extern "C" {
167    pub fn di_dim_init() -> *mut di_dim_t;
168    pub fn di_dim_fini(dim: *mut di_dim_t);
169
170    /**
171     * Returns a string that the caller is responsible for freeing with
172     * free(3C).
173     */
174    pub fn di_dim_path_dev(
175        dim: *mut di_dim_t,
176        drv_name: *const c_char,
177        instance: c_int,
178        minor_name: *const c_char,
179    ) -> *mut c_char;
180}