[i2c] Shuffle code around

This moves the code around to keep structures together with their
implementations, and also keep all configuration stuff to main.c itself.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
This commit is contained in:
Viresh Kumar 2021-10-06 12:13:46 +05:30
parent c9e88b69ab
commit 88d62dd2ab
3 changed files with 93 additions and 89 deletions

View File

@ -11,6 +11,8 @@ use std::os::unix::io::AsRawFd;
use libc::{c_ulong, ioctl, EINVAL};
use vmm_sys_util::errno::{errno_result, Error, Result};
use super::AdapterConfig;
// The type of the `req` parameter is different for the `musl` library. This will enable
// successful build for other non-musl libraries.
#[cfg(target_env = "musl")]
@ -231,12 +233,6 @@ pub struct I2cReq {
pub buf: Vec<u8>,
}
pub struct I2cAdapter<D: I2cDevice> {
device: D,
adapter_no: u32,
smbus: bool,
}
/// Trait that represents an I2C Device.
///
/// This trait is introduced for development purposes only, and should not
@ -295,6 +291,12 @@ impl I2cDevice for PhysDevice {
}
}
pub struct I2cAdapter<D: I2cDevice> {
device: D,
adapter_no: u32,
smbus: bool,
}
impl<D: I2cDevice> I2cAdapter<D> {
// Creates a new adapter corresponding to the specified number.
fn new(adapter_no: u32) -> Result<I2cAdapter<D>> {
@ -425,68 +427,6 @@ pub struct I2cMap<D: I2cDevice> {
device_map: [u32; MAX_I2C_VDEV],
}
#[derive(Debug, PartialEq)]
pub(crate) struct DeviceConfig {
adapter_no: u32,
addr: Vec<u16>,
}
impl DeviceConfig {
pub fn new(adapter_no: u32) -> Self {
DeviceConfig {
adapter_no,
addr: Vec::new(),
}
}
pub fn push(&mut self, addr: u16) -> std::result::Result<(), String> {
if addr as usize > MAX_I2C_VDEV {
return Err(format!("Invalid address: {} (> maximum allowed)", addr));
}
if self.addr.contains(&addr) {
return Err(format!("Address already in use: {}", addr));
}
self.addr.push(addr);
Ok(())
}
}
#[derive(Debug, PartialEq)]
pub(crate) struct AdapterConfig {
inner: Vec<DeviceConfig>,
}
impl AdapterConfig {
pub fn new() -> Self {
Self { inner: Vec::new() }
}
fn contains_adapter_no(&self, adapter_no: u32) -> bool {
self.inner.iter().any(|elem| elem.adapter_no == adapter_no)
}
fn contains_addr(&self, addr: u16) -> bool {
self.inner.iter().any(|elem| elem.addr.contains(&addr))
}
pub fn push(&mut self, device: DeviceConfig) -> std::result::Result<(), String> {
if self.contains_adapter_no(device.adapter_no) {
return Err("Duplicated adapter number".to_string());
}
for addr in device.addr.iter() {
if self.contains_addr(*addr) {
return Err(format!("Address already in use: {}", addr));
}
}
self.inner.push(device);
Ok(())
}
}
impl<D: I2cDevice> I2cMap<D> {
pub(crate) fn new(device_config: &AdapterConfig) -> Result<Self>
where
@ -529,7 +469,7 @@ impl<D: I2cDevice> I2cMap<D> {
return Err(Error::new(EINVAL));
}
// get the corresponding adapter based on teh device config.
// get the corresponding adapter based on the device config.
let adapter = &self.adapters[index as usize];
// Set device's address
@ -543,18 +483,6 @@ pub mod tests {
use super::*;
use std::convert::TryFrom;
impl DeviceConfig {
pub fn new_with(adapter_no: u32, addr: Vec<u16>) -> Self {
DeviceConfig { adapter_no, addr }
}
}
impl AdapterConfig {
pub fn new_with(devices: Vec<DeviceConfig>) -> Self {
AdapterConfig { inner: devices }
}
}
#[derive(Debug, Default)]
pub struct DummyDevice {
funcs_result: i32,

View File

@ -17,15 +17,69 @@ use vhost::{vhost_user, vhost_user::Listener};
use vhost_user_backend::VhostUserDaemon;
use vm_memory::{GuestMemoryAtomic, GuestMemoryMmap};
use crate::i2c::DeviceConfig;
use i2c::{AdapterConfig, I2cDevice, I2cMap, PhysDevice};
use i2c::{I2cDevice, I2cMap, PhysDevice, MAX_I2C_VDEV};
use vhu_i2c::VhostUserI2cBackend;
#[derive(PartialEq, Debug)]
struct I2cConfiguration {
socket_path: String,
socket_count: usize,
devices: AdapterConfig,
#[derive(Debug, PartialEq)]
struct DeviceConfig {
adapter_no: u32,
addr: Vec<u16>,
}
impl DeviceConfig {
fn new(adapter_no: u32) -> Self {
DeviceConfig {
adapter_no,
addr: Vec::new(),
}
}
fn push(&mut self, addr: u16) -> std::result::Result<(), String> {
if addr as usize > MAX_I2C_VDEV {
return Err(format!("Invalid address: {} (> maximum allowed)", addr));
}
if self.addr.contains(&addr) {
return Err(format!("Address already in use: {}", addr));
}
self.addr.push(addr);
Ok(())
}
}
#[derive(Debug, PartialEq)]
pub(crate) struct AdapterConfig {
inner: Vec<DeviceConfig>,
}
impl AdapterConfig {
fn new() -> Self {
Self { inner: Vec::new() }
}
fn contains_adapter_no(&self, adapter_no: u32) -> bool {
self.inner.iter().any(|elem| elem.adapter_no == adapter_no)
}
fn contains_addr(&self, addr: u16) -> bool {
self.inner.iter().any(|elem| elem.addr.contains(&addr))
}
fn push(&mut self, device: DeviceConfig) -> std::result::Result<(), String> {
if self.contains_adapter_no(device.adapter_no) {
return Err("Duplicated adapter number".to_string());
}
for addr in device.addr.iter() {
if self.contains_addr(*addr) {
return Err(format!("Address already in use: {}", addr));
}
}
self.inner.push(device);
Ok(())
}
}
impl TryFrom<&str> for AdapterConfig {
@ -53,6 +107,13 @@ impl TryFrom<&str> for AdapterConfig {
}
}
#[derive(PartialEq, Debug)]
struct I2cConfiguration {
socket_path: String,
socket_count: usize,
devices: AdapterConfig,
}
impl TryFrom<ArgMatches> for I2cConfiguration {
type Error = String;
@ -153,6 +214,18 @@ fn main() -> Result<(), String> {
mod tests {
use super::*;
impl DeviceConfig {
pub fn new_with(adapter_no: u32, addr: Vec<u16>) -> Self {
DeviceConfig { adapter_no, addr }
}
}
impl AdapterConfig {
pub fn new_with(devices: Vec<DeviceConfig>) -> Self {
AdapterConfig { inner: devices }
}
}
fn get_cmd_args(name: &str, devices: &str, count: u32) -> ArgMatches {
let yaml = load_yaml!("cli.yaml");
let app = App::from(yaml);

View File

@ -5,10 +5,10 @@
//
// SPDX-License-Identifier: Apache-2.0
use crate::i2c::*;
use std::mem::size_of;
use std::sync::Arc;
use std::{convert, error, fmt, io};
use vhost::vhost_user::message::{VhostUserProtocolFeatures, VhostUserVirtioFeatures};
use vhost_user_backend::{VhostUserBackendMut, VringRwLock, VringT};
use virtio_bindings::bindings::virtio_net::{VIRTIO_F_NOTIFY_ON_EMPTY, VIRTIO_F_VERSION_1};
@ -18,6 +18,8 @@ use virtio_bindings::bindings::virtio_ring::{
use vm_memory::{ByteValued, Bytes, GuestMemoryAtomic, GuestMemoryMmap, Le16, Le32};
use vmm_sys_util::eventfd::{EventFd, EFD_NONBLOCK};
use crate::i2c::*;
const QUEUE_SIZE: usize = 1024;
const NUM_QUEUES: usize = 1;
@ -306,6 +308,7 @@ impl<D: 'static + I2cDevice + Sync + Send> VhostUserBackendMut<VringRwLock, ()>
mod tests {
use super::*;
use crate::i2c::tests::DummyDevice;
use crate::AdapterConfig;
use std::convert::TryFrom;
#[test]