From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A9C9D2571DC; Tue, 23 Sep 2025 13:21:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758633674; cv=none; b=o02hV13f+V/7zExpJ9yURNQefNNIqrRcC9VAOnDzpq2TEX+xDlyNKsJe451wRPe7ViCltD4YaM5RTDp27AZrV8q/W7DzsxxzraI10ZWlggLn1+GgKUS5m274JsoYMZmbfnBWsdpukirUsQ41OPN7AuQYlVtvLuQ7Tvi3np5ozQE= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758633674; c=relaxed/simple; bh=5pH7JaFaGSuIhtRdAkXOOjQ94n93vl2U/NiatkBb4Ts=; h=Mime-Version:Content-Type:Date:Message-Id:Subject:Cc:To:From: References:In-Reply-To; b=Oq69LFaUQHvwVOVwKlpmDgwSFfAjjpeZvKahVLDnX91ec7KnHKmucEvCm6ozxB+Szn3HsGtTipHhDRotJYT8E8iT1SmCN0v3N2vERXooW6vxR6aAcPKH1eK+kM/CFm0HEUDZcowM9qQQ1l2sBziezYBzQjHs8euVv3a7l5gb59U= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Pwu9f8j8; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Pwu9f8j8" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7E561C4CEF5; Tue, 23 Sep 2025 13:21:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1758633674; bh=5pH7JaFaGSuIhtRdAkXOOjQ94n93vl2U/NiatkBb4Ts=; h=Date:Subject:Cc:To:From:References:In-Reply-To:From; b=Pwu9f8j8b7iq5zqBUdCmMmZcwyk1Fw5LasCRRYbv2Q6mAb5PZvq8JJ5+7JX0pPfky Sim2oWVlgFETmAg88/dq9UI070Scu6gMZqbPFfYJ6bS8kCOmopfacoM4LqiKuVHADe 4QZwEaP0woutQYrSaGjO2y+O5KC0KUvrbZ/I0sNYQfzk5n40PH4Z+socBalPTXq+ZJ WttD+4Hyno0KaxRm6Aw9nNkyxHAzK2hVjeMpXq6Er4JaATuqx/vm7qIYiKpuhpWjNj R8nGAi/NRogfJMDOOG2EPFQGgBZaYreVcoIoy6vDH+U30Ai2PO99bvaqc9oely/Mnu A0bqoD8kO1Iwg== Precedence: bulk X-Mailing-List: rust-for-linux@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=UTF-8 Date: Tue, 23 Sep 2025 15:21:09 +0200 Message-Id: Subject: Re: [PATCH 1/2] rust: usb: add basic USB abstractions Cc: "Miguel Ojeda" , "Alex Gaynor" , "Boqun Feng" , "Gary Guo" , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , "Benno Lossin" , "Andreas Hindborg" , "Alice Ryhl" , "Trevor Gross" , "Greg Kroah-Hartman" , , , To: "Daniel Almeida" From: "Danilo Krummrich" References: <20250825-b4-usb-v1-0-7aa024de7ae8@collabora.com> <20250825-b4-usb-v1-1-7aa024de7ae8@collabora.com> In-Reply-To: <20250825-b4-usb-v1-1-7aa024de7ae8@collabora.com> On Mon Aug 25, 2025 at 8:18 PM CEST, Daniel Almeida wrote: > +/// The USB driver trait. > +/// > +/// # Examples > +/// > +///``` > +/// # use kernel::{bindings, device::Core, usb}; > +/// use kernel::prelude::*; > +/// > +/// struct MyDriver; > +/// > +/// kernel::usb_device_table!( > +/// USB_TABLE, > +/// MODULE_USB_TABLE, > +/// ::IdInfo, > +/// [ > +/// (usb::DeviceId::from_id(0x1234, 0x5678), ()), > +/// (usb::DeviceId::from_id(0xabcd, 0xef01), ()), > +/// ] > +/// ); > +/// > +/// impl usb::Driver for MyDriver { > +/// type IdInfo =3D (); > +/// const ID_TABLE: usb::IdTable =3D &USB_TABLE; > +/// > +/// fn probe( > +/// _interface: &usb::Interface, > +/// _id: &usb::DeviceId, > +/// _info: &Self::IdInfo, > +/// ) -> Result>> { > +/// Err(ENODEV) > +/// } > +/// > +/// fn disconnect(_interface: &usb::Interface, _data: Pin<&Sel= f>) {} > +/// } > +///``` > +pub trait Driver { > + /// The type holding information about each one of the device ids su= pported by the driver. > + type IdInfo: 'static; > + > + /// The table of device ids supported by the driver. > + const ID_TABLE: IdTable; > + > + /// USB driver probe. > + /// > + /// Called when a new USB interface is bound to this driver. > + /// Implementers should attempt to initialize the interface here. > + fn probe( > + interface: &Interface, > + id: &DeviceId, > + id_info: &Self::IdInfo, > + ) -> Result>>; > + > + /// USB driver disconnect. > + /// > + /// Called when the USB interface is about to be unbound from this d= river. > + fn disconnect(interface: &Interface, data: Pin<&Self>)= ; I think this callback should be optional, like all the other unbind() we ha= ve in other busses. @Greg: Why is this called disconnect() in the C code instead of remove()? For Rust, I feel like we should align to the unbind() terminology we use everywhere else (for the same reasons we chose unbind() over remove() for o= ther busses as well). We went with unbind(), since the "raw" remove() (or disconnect()) callback = does more, i.e. it first calls into unbind() and then drops the driver's private= data for this specific device. So, the unbind() callback that goes to the driver is only meant as a place = for drivers to perform operations to tear down the device. Resources are freed subsequently when the driver's private data is dropped. > +/// A USB device. > +/// > +/// This structure represents the Rust abstraction for a C [`struct usb_= device`]. > +/// The implementation abstracts the usage of a C [`struct usb_device`] = passed in > +/// from the C side. > +/// > +/// # Invariants > +/// > +/// A [`Device`] instance represents a valid [`struct usb_device`] creat= ed by the C portion of the > +/// kernel. > +/// > +/// [`struct usb_device`]: https://www.kernel.org/doc/html/latest/driver= -api/usb/usb.html#c.usb_device > +#[repr(transparent)] > +pub struct Device( > + Opaque, > + PhantomData, > +); What do you use the struct usb_device abstraction for? I only see the sampl= e driver probing a USB interface instead.