virtio_device/
lib.rs

1// Copyright 2021 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5//! Write virtio devices in Rust.
6//!
7//! This crate provides utilities for virtio devices to manipulate descriptor rings. Only the device
8//! side is targeted, and this crate is completely unsuitable, and not intended, for writing
9//! drivers.
10//!
11//! The provided wrappers are built up in a series of layers, each providing a higher level and more
12//! convenient interface, at the cost of injecting some policy opinions for managing the rings. The
13//! layers/modules are:
14//! - [`chain`] High level iteration and walking of descriptor chains as series of byte ranges
15//!   including manipulation through [`std::io::read`] and [`std::io::write`] interfaces.
16//! - [`queue`] Provides functional virt queue management allowing for descriptor chains to be
17//!   retrieved, iterated and returned.
18//! - [`ring`] Provides the barest minimum Rust type safety over accessing the rings.
19//!   This is not expected to generally be needed, with [`queue`] completely hiding all [`ring`]
20//!   details.
21//! There are some additional modules providing:
22//! - [`mem`] Definitions for memory translation between drivers and devices.
23//! - [`util`] Small wrappers and trait implementations that are commonly useful, but very
24//!   opinionated.
25//! - [`fake_queue`] Helpers for writing unittests against virtio devices.
26//!
27//! What this crate does not provide is any transport or device type specific management. The user
28//! then is responsible for performing all setup and feature negotiation prior to using this crate
29//! to manage the negotiated queues. The user therefore needs to provide:
30//! - Location of negotiated desc, used and avail rings as [`mem::DeviceRange`] definitions.
31//! - Implementation of [`mem::DriverMem`] for driver to device memory address translation.
32//! - Implementation of [`queue::DriverNotify`] for signaling the driver.
33//! - A way to receive signals from the driver to know when to check for descriptors.
34//!
35//! With these pieces existing a typical usage of this crate is expected to be:
36//! - Construct a [`queue::Queue`] by passing the ring definitions to [`queue::Queue::new`]
37//! - Build a [`util::DescChainStream`] from the [`queue::Queue`] and connect the
38//!   [`util::DescChainStream::waker`]
39//! - Construct  [`chain::ReadableChain`] or [`chain::WritableChain`] from the [`queue::DescChain`]
40//!   items generated by the [`util::DescChainStream`]
41//! - Process the [`chain::ReadableChain`] or [`chain::WritableChain`] using their provided methods
42//!   or the [`std::io::read`] and [`std::io::write`] trait implementations.
43//! - Explicitly [return](chain::ReadableChain::return_complete) the chain or let it `drop` to have
44//!   the [`queue::Queue`] return it to the driver.
45//!
46//! Commonly if expecting to process descriptors chains in batches you will also want to wrap your
47//! [`queue::DriverNotify`] in a [`util::BufferedNotify`], but you must ensure to call
48//! [`util::BufferedNotify::flush`].
49
50pub mod chain;
51pub mod fake_queue;
52pub mod mem;
53pub mod queue;
54pub mod ring;
55pub mod util;