gpio: Migrate to the upstream version of libgpiod

The upstream version doesn't compile the .c files locally and depends on
the package to be locally compiled and installed in advance.

It also doesn't provide pre-generated bindings, and requires bindgen
support.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
This commit is contained in:
Viresh Kumar 2023-01-23 15:27:14 +05:30 committed by Mathieu Poirier
parent 6b14c0b179
commit 799073f17c
5 changed files with 159 additions and 16 deletions

124
Cargo.lock generated
View File

@ -23,6 +23,28 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "bindgen"
version = "0.63.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "36d860121800b2a9a94f9b5604b332d5cffb234ce17609ea479d723dbc9d3885"
dependencies = [
"bitflags",
"cexpr",
"clang-sys",
"lazy_static",
"lazycell",
"log",
"peeking_take_while",
"proc-macro2",
"quote",
"regex",
"rustc-hash",
"shlex",
"syn",
"which",
]
[[package]]
name = "bitflags"
version = "1.3.2"
@ -41,12 +63,32 @@ version = "1.0.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
[[package]]
name = "cexpr"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766"
dependencies = [
"nom",
]
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "clang-sys"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa2e27ae6ab525c3d369ded447057bca5438d86dc3a68f6faafb8269ba82ebf3"
dependencies = [
"glob",
"libc",
"libloading",
]
[[package]]
name = "clap"
version = "4.1.4"
@ -97,6 +139,12 @@ dependencies = [
"parking_lot_core",
]
[[package]]
name = "either"
version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91"
[[package]]
name = "env_logger"
version = "0.10.0"
@ -143,9 +191,9 @@ dependencies = [
[[package]]
name = "fastrand"
version = "1.8.0"
version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499"
checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be"
dependencies = [
"instant",
]
@ -251,6 +299,12 @@ dependencies = [
"wasi",
]
[[package]]
name = "glob"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
[[package]]
name = "hashbrown"
version = "0.12.3"
@ -327,6 +381,12 @@ version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "lazycell"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
[[package]]
name = "libc"
version = "0.2.139"
@ -336,7 +396,7 @@ checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"
[[package]]
name = "libgpiod"
version = "0.1.0"
source = "git+https://github.com/vireshk/libgpiod?branch=vhost-gpio#b412261453c3bcde60ac7597f19a042899acb68a"
source = "git+https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git/?rev=d8d3a84b2ddf#d8d3a84b2ddfc29670430fc73ff8483a44b8f61e"
dependencies = [
"errno",
"intmap",
@ -348,11 +408,22 @@ dependencies = [
[[package]]
name = "libgpiod-sys"
version = "0.1.0"
source = "git+https://github.com/vireshk/libgpiod?branch=vhost-gpio#b412261453c3bcde60ac7597f19a042899acb68a"
source = "git+https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git/?rev=d8d3a84b2ddf#d8d3a84b2ddfc29670430fc73ff8483a44b8f61e"
dependencies = [
"bindgen",
"cc",
]
[[package]]
name = "libloading"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f"
dependencies = [
"cfg-if",
"winapi",
]
[[package]]
name = "linux-raw-sys"
version = "0.1.4"
@ -384,6 +455,22 @@ version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
[[package]]
name = "minimal-lexical"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
[[package]]
name = "nom"
version = "7.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
dependencies = [
"memchr",
"minimal-lexical",
]
[[package]]
name = "num_cpus"
version = "1.15.0"
@ -429,6 +516,12 @@ dependencies = [
"windows-sys",
]
[[package]]
name = "peeking_take_while"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
[[package]]
name = "pin-project-lite"
version = "0.2.9"
@ -554,6 +647,12 @@ dependencies = [
"winapi",
]
[[package]]
name = "rustc-hash"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
[[package]]
name = "rustix"
version = "0.36.8"
@ -599,6 +698,12 @@ dependencies = [
"syn",
]
[[package]]
name = "shlex"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3"
[[package]]
name = "slab"
version = "0.4.7"
@ -845,6 +950,17 @@ version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "which"
version = "4.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2441c784c52b289a054b7201fc93253e288f094e2f4be9058343127c4226a269"
dependencies = [
"either",
"libc",
"once_cell",
]
[[package]]
name = "winapi"
version = "0.3.9"

View File

@ -43,3 +43,16 @@ devices](https://github.com/rust-vmm/vm-virtio/tree/main/crates/devices).
This way a monolithic rust-vmm VMM implementation can reuse the core
logic to service the virtio requests directly in the application.
## Build dependency
The GPIO crate needs a local installation of libgpiod library to be available,
which can be done like:
$ git clone --depth 1 --branch v2.0-rc1 https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git/
$ cd libgpiod
$ ./autogen.sh && make
Either you can do a 'make install' now on your system, or provide path to the
locally build library like this while building vhost-device crates:
$ RUSTFLAGS='-L /home/<username>/libgpiod/lib/.libs/' cargo build --release

View File

@ -1,5 +1,5 @@
{
"coverage_score": 68.9,
"coverage_score": 67.6,
"exclude_path": "",
"crate_features": ""
}

View File

@ -25,7 +25,7 @@ vm-memory = "0.10"
vmm-sys-util = "0.11"
[target.'cfg(target_env = "gnu")'.dependencies]
libgpiod = { git = "https://github.com/vireshk/libgpiod", branch = "vhost-gpio" }
libgpiod = { git = "https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git/", rev = "d8d3a84b2ddf" }
[dev-dependencies]
virtio-queue = { version = "0.7", features = ["test-utils"] }

View File

@ -6,7 +6,7 @@
// SPDX-License-Identifier: Apache-2.0 or BSD-3-Clause
use log::error;
use std::sync::{Arc, RwLock};
use std::sync::{Arc, Mutex, RwLock};
use std::time::Duration;
use libgpiod::{chip, line, request, Error as LibGpiodError};
@ -110,7 +110,7 @@ pub(crate) trait GpioDevice: Send + Sync + 'static {
pub(crate) struct PhysLineState {
// See wait_for_interrupt() for explanation of Arc.
request: Option<Arc<request::Request>>,
request: Option<Arc<Mutex<request::Request>>>,
buffer: Option<request::Buffer>,
}
@ -201,27 +201,29 @@ impl GpioDevice for PhysDevice {
_ => return Err(Error::GpioDirectionInvalid(value)),
};
let lconfig = line::Config::new().map_err(Error::GpiodFailed)?;
let mut lconfig = line::Config::new().map_err(Error::GpiodFailed)?;
lconfig
.add_line_settings(&[gpio as u32], lsettings)
.map_err(Error::GpiodFailed)?;
if let Some(request) = &state.request {
if let Some(request) = &mut state.request {
request
.lock()
.unwrap()
.reconfigure_lines(&lconfig)
.map_err(Error::GpiodFailed)?;
} else {
let rconfig = request::Config::new().map_err(Error::GpiodFailed)?;
let mut rconfig = request::Config::new().map_err(Error::GpiodFailed)?;
rconfig
.set_consumer("vhu-gpio")
.map_err(Error::GpiodFailed)?;
state.request = Some(Arc::new(
state.request = Some(Arc::new(Mutex::new(
self.chip
.request_lines(Some(&rconfig), &lconfig)
.map_err(Error::GpiodFailed)?,
));
)));
}
Ok(())
@ -231,7 +233,11 @@ impl GpioDevice for PhysDevice {
let state = &self.state[gpio as usize].read().unwrap();
if let Some(request) = &state.request {
Ok(request.value(gpio as u32).map_err(Error::GpiodFailed)? as u8)
Ok(request
.lock()
.unwrap()
.value(gpio as u32)
.map_err(Error::GpiodFailed)? as u8)
} else {
Err(Error::GpioDirectionInvalid(
VIRTIO_GPIO_DIRECTION_NONE as u32,
@ -247,6 +253,8 @@ impl GpioDevice for PhysDevice {
if let Some(request) = &state.request {
let value = line::Value::new(value as i32).map_err(Error::GpiodFailed)?;
request
.lock()
.unwrap()
.set_value(gpio as u32, value)
.map_err(Error::GpiodFailed)?;
}
@ -281,7 +289,7 @@ impl GpioDevice for PhysDevice {
.set_edge_detection(Some(edge))
.map_err(Error::GpiodFailed)?;
let lconfig = line::Config::new().map_err(Error::GpiodFailed)?;
let mut lconfig = line::Config::new().map_err(Error::GpiodFailed)?;
lconfig
.add_line_settings(&[gpio as u32], lsettings)
.map_err(Error::GpiodFailed)?;
@ -296,8 +304,12 @@ impl GpioDevice for PhysDevice {
.request
.as_ref()
.unwrap()
.lock()
.unwrap()
.reconfigure_lines(&lconfig)
.map_err(Error::GpiodFailed)
.map_err(Error::GpiodFailed)?;
Ok(())
}
fn wait_for_interrupt(&self, gpio: u16) -> Result<bool> {
@ -336,6 +348,8 @@ impl GpioDevice for PhysDevice {
}
};
let request = request.lock().unwrap();
// Wait for the interrupt for a second.
if !request
.wait_edge_events(Some(Duration::new(1, 0)))