Docs edits

This commit is contained in:
Kevin Mehall 2025-05-03 12:01:09 -06:00
parent 4a3b5ddf9f
commit b976e91ce8
4 changed files with 49 additions and 24 deletions

View file

@ -154,7 +154,7 @@ impl Device {
/// Set the device configuration.
///
/// The argument is the desired configuration's `bConfigurationValue`
/// descriptor field from [`Configuration::configuration_value`] or `0` to
/// descriptor field from [`ConfigurationDescriptor::configuration_value`] or `0` to
/// unconfigure the device.
///
/// ### Platform-specific notes
@ -270,7 +270,7 @@ impl Device {
/// Reset the device, forcing it to re-enumerate.
///
/// This `Device` will no longer be usable, and you should drop it and call
/// [`super::list_devices`] to find and re-open it again.
/// [`list_devices`][`super::list_devices`] to find and re-open it again.
///
/// ### Platform-specific notes
/// * Not supported on Windows
@ -278,7 +278,7 @@ impl Device {
self.backend.clone().reset()
}
/// Asynchronously submit a single **IN (device-to-host)** transfer on the default **control** endpoint.
/// Submit a single **IN (device-to-host)** transfer on the default **control** endpoint.
///
/// ### Example
///
@ -359,7 +359,7 @@ impl Device {
///
/// This type is reference-counted with an [`Arc`] internally, and can be cloned cheaply for
/// use in multiple places in your program. The interface is released when all clones, and all
/// associated [`TransferFuture`]s and [`Queue`]s are dropped.
/// associated [`Endpoint`]s are dropped.
#[derive(Clone)]
pub struct Interface {
backend: Arc<platform::Interface>,
@ -415,6 +415,8 @@ impl Interface {
/// overriding any value passed. A warning is logged if the passed `index`
/// least significant byte differs from the interface number, and this may
/// become an error in the future.
/// * On Windows, the timeout is currently fixed to 5 seconds and the timeout
/// argument is ignored.
pub fn control_in(
&self,
data: ControlIn,
@ -423,7 +425,8 @@ impl Interface {
self.backend.clone().control_in(data, timeout)
}
/// Submit a single **OUT (host-to-device)** transfer on the default **control** endpoint.
/// Submit a single **OUT (host-to-device)** transfer on the default
/// **control** endpoint.
///
/// ### Example
///
@ -454,6 +457,8 @@ impl Interface {
/// overriding any value passed. A warning is logged if the passed `index`
/// least significant byte differs from the interface number, and this may
/// become an error in the future.
/// * On Windows, the timeout is currently fixed to 5 seconds and the timeout
/// argument is ignored.
pub fn control_out(
&self,
data: ControlOut,
@ -545,6 +550,22 @@ impl std::error::Error for ClaimEndpointError {}
/// Exclusive access to an endpoint of a USB device.
///
/// Obtain an `Endpoint` with the [`Interface::endpoint`] method.
///
/// An `Endpoint` manages a queue of pending transfers. Submitting a transfer is
/// a non-blocking operation that adds the operation to the queue. Completed
/// transfers can be popped from the queue synchronously or asynchronously.
///
/// This separation of submission and completion makes the API cancel-safe,
/// and makes it easy to submit multiple transfers at once, regardless of
/// whether you are using asynchronous or blocking waits.
///
/// To maximize throughput and minimize latency when streaming data, the host
/// controller needs to attempt a transfer in every possible frame. That
/// requires always having a transfer request pending with the kernel by
/// submitting multiple transfer requests and re-submitting them as they
/// complete.
///
/// When the `Endpoint` is dropped, any pending transfers are cancelled.
pub struct Endpoint<EpType, Dir> {
backend: platform::Endpoint,
ep_type: PhantomData<EpType>,
@ -588,7 +609,7 @@ impl<EpType: BulkOrInterrupt, Dir: EndpointDirection> Endpoint<EpType, Dir> {
///
/// A zero-copy buffer allows the kernel to DMA directly to/from this
/// buffer for improved performance. However, because it is not allocated
/// with the system allocator, it cannot be converted to a `Vec` without
/// with the system allocator, it cannot be converted to a [`Vec`] without
/// copying.
///
/// This is currently only supported on Linux, falling back to [`Buffer::new`]
@ -607,14 +628,14 @@ impl<EpType: BulkOrInterrupt, Dir: EndpointDirection> Endpoint<EpType, Dir> {
/// Begin a transfer on the endpoint.
///
/// Submitted transfers are queued and completed in order. Once the transfer
/// completes, it will be returned from [`Self::next_complete`]. Any error
/// in submitting or performing the transfer is deferred until
/// [`next_complete`][`Self::next_complete`].
/// completes, it will be returned from
/// [`next_complete()`][`Self::next_complete`]. Any error in submitting or
/// performing the transfer is deferred until `next_complete`.
///
/// For an OUT transfer, the buffer's `len` field is the number of bytes
/// For an OUT transfer, the buffer's `len` is the number of bytes
/// initialized, which will be sent to the device.
///
/// For an IN transfer, the buffer's `transfer_len` field is the number of
/// For an IN transfer, the buffer's `requested_len` is the number of
/// bytes requested. It must be a multiple of the endpoint's [maximum packet
/// size][`Self::max_packet_size`].
pub fn submit(&mut self, buf: Buffer) {
@ -650,6 +671,9 @@ impl<EpType: BulkOrInterrupt, Dir: EndpointDirection> Endpoint<EpType, Dir> {
/// Blocks for up to `timeout` waiting for a transfer to complete, or
/// returns `None` if the timeout is reached.
///
/// Note that the transfer is not cancelled after the timeout, and can still
/// be returned from a subsequent call.
///
/// ## Panics
/// * if there are no transfers pending (that is, if [`Self::pending()`]
/// would return 0).

View file

@ -34,10 +34,11 @@
//! device. To open an interface, call [`Device::claim_interface`]. Only one
//! program (or kernel driver) may claim an interface at a time.
//!
//! Use the resulting [`Interface`] to transfer data on the device's control,
//! bulk or interrupt endpoints. Transfers are async by default, and can be
//! awaited as individual [`Future`][`transfer::TransferFuture`]s, or use a
//! [`Queue`][`transfer::Queue`] to manage streams of data.
//! Use the resulting [`Interface`] to perform control transfers or open
//! an [`Endpoint`] to perform bulk or interrupt transfers. Submitting a
//! transfer is a non-blocking operation that adds the transfer to an
//! internal queue for the endpoint. Completed transfers can be popped
//! from the queue synchronously or asynchronously.
//!
//! *For more details on how USB works, [USB in a
//! Nutshell](https://beyondlogic.org/usbnutshell/usb1.shtml) is a good
@ -119,9 +120,9 @@
//! This allows for async usage in an async context, or blocking usage in a
//! non-async context.
//!
//! Operations such as [`Device::open`], [`Device::set_configuration`],
//! Operations such as [`DeviceInfo::open`], [`Device::set_configuration`],
//! [`Device::reset`], [`Device::claim_interface`],
//! [`Interface::set_alt_setting`], and [`Interface::clear_halt`] require
//! [`Interface::set_alt_setting`], and [`Endpoint::clear_halt`] require
//! blocking system calls. To use these in an asynchronous context, `nusb`
//! relies on an async runtime to run these operations on an IO thread to avoid
//! blocking in async code. Enable the cargo feature `tokio` or `smol` to use

View file

@ -181,7 +181,7 @@ impl Buffer {
/// Convert the buffer into a `Vec<u8>`.
///
/// This is zero-cost if the buffer was allocated with the default allocator
/// (if [`is_zero_copy()`] returns false), otherwise it will copy the data
/// (if [`is_zero_copy()`][Self::is_zero_copy] returns false), otherwise it will copy the data
/// into a new `Vec<u8>`.
pub fn into_vec(self) -> Vec<u8> {
match self.allocator {

View file

@ -1,7 +1,7 @@
//! Transfer-related types.
//!
//! Use the methods on an [`Interface`][`super::Interface`] to make individual
//! transfers or obtain a [`Queue`] to manage multiple transfers.
//! Use the methods on an [`Interface`][`super::Interface`] and
//! [`Endpoint`][`super::Endpoint`] to perform transfers.
use std::{fmt::Display, io};
@ -21,14 +21,14 @@ use crate::descriptors::TransferType;
/// Transfer error.
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum TransferError {
/// Transfer was cancelled.
/// Transfer was cancelled or timed out.
Cancelled,
/// Endpoint in a STALL condition.
///
/// This is used by the device to signal that an error occurred. For bulk
/// and interrupt endpoints, the stall condition can be cleared with
/// [`Interface::clear_halt`][crate::Interface::clear_halt]. For control
/// [`Interface::clear_halt`][crate::Endpoint::clear_halt]. For control
/// requests, the stall is automatically cleared when another request is
/// submitted.
Stall,
@ -52,7 +52,7 @@ impl Display for TransferError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
TransferError::Cancelled => write!(f, "transfer was cancelled"),
TransferError::Stall => write!(f, "endpoint STALL condition"),
TransferError::Stall => write!(f, "endpoint stalled"),
TransferError::Disconnected => write!(f, "device disconnected"),
TransferError::Fault => write!(f, "hardware fault or protocol violation"),
TransferError::Unknown(e) => {
@ -125,7 +125,7 @@ impl EndpointType for Interrupt {
}
impl BulkOrInterrupt for Interrupt {}
/// A completed transfer returned from [`Endpoint::next_complete`].
/// A completed transfer returned from [`Endpoint::next_complete`][`crate::Endpoint::next_complete`].
///
/// A transfer can partially complete even in the case of failure or
/// cancellation, thus the [`actual_len`][`Self::actual_len`] may be nonzero