From: Mike Lothian <mike@fireburn.co.uk>
To: rust-for-linux@vger.kernel.org
Cc: linux-usb@vger.kernel.org,
"Greg Kroah-Hartman" <gregkh@linuxfoundation.org>,
"Daniel Almeida" <daniel.almeida@collabora.com>,
"Miguel Ojeda" <ojeda@kernel.org>,
"Boqun Feng" <boqun@kernel.org>, "Gary Guo" <gary@garyguo.net>,
"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
"Benno Lossin" <lossin@kernel.org>,
"Andreas Hindborg" <a.hindborg@kernel.org>,
"Alice Ryhl" <aliceryhl@google.com>,
"Trevor Gross" <tmgross@umich.edu>,
"Danilo Krummrich" <dakr@kernel.org>,
"Alexandre Courbot" <acourbot@nvidia.com>,
linux-kernel@vger.kernel.org,
"Mike Lothian" <mike@fireburn.co.uk>
Subject: [RFC PATCH v2 00/11] rust: usb: synchronous + asynchronous bulk/control transfers + helpers
Date: Fri, 3 Jul 2026 04:00:04 +0100 [thread overview]
Message-ID: <20260703030020.2694-1-mike@fireburn.co.uk> (raw)
In-Reply-To: <20260617145946.1894-1-mike@fireburn.co.uk>
This is v2 of the USB transfer bindings, rebased onto current drm-next
(no functional change from the version prepared but never sent after
v1's review -- see "Changes since v1" below for what that review fixed).
It adds the synchronous transfer primitives a driver needs at bring-up
to the Rust USB abstraction (rust/kernel/usb.rs), which currently lets
a driver bind a device (probe/disconnect) but provides no way to move
data, so any real driver still has to drop to C:
1/11 bulk_send() / bulk_recv() over usb_bulk_msg()
2/11 control_send() / control_recv() over usb_control_msg_send()/_recv()
3/11 set_interface() over usb_set_interface()
4/11 Interface::number() bInterfaceNumber accessor
5/11 clear_halt() over usb_clear_halt()
6/11 interrupt_recv() over usb_interrupt_msg()
7/11 reset_configuration() over usb_reset_configuration()
8/11 bulk_in_queue() / BulkInQueue persistently-queued async bulk IN
9/11 bulk_out_queue() / BulkOutQueue pipelined async bulk OUT
10/11 Device private + transfers gated on Interface<Bound>
11/11 let drivers choose the transfer allocation flags
usb::Device is kept private; the transfer methods are exposed on
usb::Interface<Bound> so a transfer cannot be issued before the
interface's device is bound to the driver. Each method documents its
blocking/sleeping context, timeouts are taken as a Delta, transfer
lengths are range-checked into the C int types, and every FFI call
carries a SAFETY comment. All the transfer methods take the endpoint's
bEndpointAddress as it appears in the descriptor (e.g. 0x84) and use
its low four bits as the endpoint number, so the convention is uniform
across bulk_send/bulk_recv, interrupt_recv and clear_halt.
DMA-buffer handling: bulk_send/bulk_recv/interrupt_recv copy through an
internally-allocated bounce buffer, so any &[u8]/&mut [u8] is accepted
rather than pushing an unenforced DMA-capable-memory precondition onto
callers. Patch 11 lets the caller choose the allocation flags for that
bounce (GFP_KERNEL normally, GFP_NOIO/GFP_NOFS from a reset/resume or
error-handling path) instead of hardcoding GFP_KERNEL, per Oliver
Neukum's v1 review.
Patches 8 and 9 add the asynchronous URB path (usb_submit_urb) for
endpoints where the per-transfer device-ACK round-trip of the
synchronous calls is too costly. bulk_in_queue() keeps depth IN URBs
perpetually posted and hands each completion to BulkInQueue::recv();
bulk_out_queue() pipelines OUT URBs submit-and-reap so a back-to-back
burst is not serialised.
The additions were developed for an out-of-tree in-kernel Rust
DisplayLink DL3 dock driver, but are generic and not driver-specific.
Each patch builds on its own, so the tree stays bisectable; the full
series builds in-tree on drm-next (LLVM/Rust) with no new warnings.
The consumer is the in-kernel Rust DisplayLink DL3 dock driver, posted
alongside as drm/vino ("[RFC PATCH v2 00/6] drm/vino: DisplayLink DL3
dock driver"). Source:
https://github.com/FireBurn/vino-scripts
https://github.com/FireBurn/linux/tree/vino
https://gitlab.freedesktop.org/FireBurn/linux/-/tree/vino
Changes since v1:
- Keep usb::Device private (it was made public in v1); expose the
transfer methods on usb::Interface<Bound> instead, so they cannot be
called before the device is bound. New patch 10. (Danilo Krummrich)
- Interface::as_bound() lets a driver that defers transfers to a work
item reach the bound transfer surface, with a flush-before-unbind
contract.
- Drivers now choose the transfer allocation flags instead of a
hardcoded GFP_KERNEL. New patch 11. (Oliver Neukum)
- Rebased onto current drm-next; no other functional change.
Mike Lothian (11):
rust: usb: add synchronous bulk transfer support
rust: usb: add synchronous control transfer support
rust: usb: add usb::Device::set_interface()
rust: usb: add usb::Interface::number()
rust: usb: add usb::Device::clear_halt()
rust: usb: add usb::Device::interrupt_recv()
rust: usb: add usb::Device::reset_configuration()
rust: usb: add an asynchronous persistently-queued bulk IN reader
rust: usb: add an asynchronous pipelined bulk OUT queue
rust: usb: keep usb::Device private and gate transfers on
Interface<Bound>
rust: usb: let drivers choose the transfer allocation flags
rust/helpers/usb.c | 35 ++
rust/kernel/usb.rs | 845 ++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 869 insertions(+), 11 deletions(-)
--
2.55.0
next prev parent reply other threads:[~2026-07-03 3:00 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-17 14:59 [RFC PATCH 0/9] rust: usb: synchronous bulk/control transfers + helpers Mike Lothian
2026-06-17 14:59 ` [RFC PATCH 1/9] rust: usb: add synchronous bulk transfer support Mike Lothian
2026-06-17 16:07 ` Danilo Krummrich
2026-06-17 14:59 ` [RFC PATCH 2/9] rust: usb: add synchronous control " Mike Lothian
2026-06-22 9:54 ` Oliver Neukum
2026-06-17 14:59 ` [RFC PATCH 3/9] rust: usb: add usb::Device::set_interface() Mike Lothian
2026-06-17 14:59 ` [RFC PATCH 4/9] rust: usb: add usb::Interface::number() Mike Lothian
2026-06-17 14:59 ` [RFC PATCH 5/9] rust: usb: add usb::Device::clear_halt() Mike Lothian
2026-06-17 14:59 ` [RFC PATCH 6/9] rust: usb: add usb::Device::interrupt_recv() Mike Lothian
2026-06-17 14:59 ` [RFC PATCH 7/9] rust: usb: add usb::Device::reset_configuration() Mike Lothian
2026-06-17 14:59 ` [RFC PATCH 8/9] rust: usb: add an asynchronous persistently-queued bulk IN reader Mike Lothian
2026-06-17 14:59 ` [RFC PATCH 9/9] rust: usb: add an asynchronous pipelined bulk OUT queue Mike Lothian
2026-07-03 3:00 ` Mike Lothian [this message]
2026-07-03 3:00 ` [RFC PATCH v2 01/11] rust: usb: add synchronous bulk transfer support Mike Lothian
2026-07-06 9:17 ` Oliver Neukum
2026-07-03 3:00 ` [RFC PATCH v2 02/11] rust: usb: add synchronous control " Mike Lothian
2026-07-03 3:00 ` [RFC PATCH v2 03/11] rust: usb: add usb::Device::set_interface() Mike Lothian
2026-07-03 3:00 ` [RFC PATCH v2 04/11] rust: usb: add usb::Interface::number() Mike Lothian
2026-07-03 3:00 ` [RFC PATCH v2 05/11] rust: usb: add usb::Device::clear_halt() Mike Lothian
2026-07-03 3:00 ` [RFC PATCH v2 06/11] rust: usb: add usb::Device::interrupt_recv() Mike Lothian
2026-07-03 3:00 ` [RFC PATCH v2 07/11] rust: usb: add usb::Device::reset_configuration() Mike Lothian
2026-07-03 3:00 ` [RFC PATCH v2 08/11] rust: usb: add an asynchronous persistently-queued bulk IN reader Mike Lothian
2026-07-03 3:00 ` [RFC PATCH v2 09/11] rust: usb: add an asynchronous pipelined bulk OUT queue Mike Lothian
2026-07-03 3:00 ` [RFC PATCH v2 10/11] rust: usb: keep usb::Device private and gate transfers on Interface<Bound> Mike Lothian
2026-07-06 9:45 ` Oliver Neukum
2026-07-06 10:38 ` Danilo Krummrich
2026-07-06 13:46 ` Alan Stern
2026-07-06 10:40 ` Danilo Krummrich
2026-07-03 3:00 ` [RFC PATCH v2 11/11] rust: usb: let drivers choose the transfer allocation flags Mike Lothian
2026-07-06 9:47 ` Oliver Neukum
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260703030020.2694-1-mike@fireburn.co.uk \
--to=mike@fireburn.co.uk \
--cc=a.hindborg@kernel.org \
--cc=acourbot@nvidia.com \
--cc=aliceryhl@google.com \
--cc=bjorn3_gh@protonmail.com \
--cc=boqun@kernel.org \
--cc=dakr@kernel.org \
--cc=daniel.almeida@collabora.com \
--cc=gary@garyguo.net \
--cc=gregkh@linuxfoundation.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-usb@vger.kernel.org \
--cc=lossin@kernel.org \
--cc=ojeda@kernel.org \
--cc=rust-for-linux@vger.kernel.org \
--cc=tmgross@umich.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox