Linux USB
 help / color / mirror / Atom feed
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

  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