{"id":2229216,"url":"http://patchwork.ozlabs.org/api/1.1/patches/2229216/?format=json","web_url":"http://patchwork.ozlabs.org/project/linux-pci/patch/20260427221155.2144848-5-dakr@kernel.org/","project":{"id":28,"url":"http://patchwork.ozlabs.org/api/1.1/projects/28/?format=json","name":"Linux PCI development","link_name":"linux-pci","list_id":"linux-pci.vger.kernel.org","list_email":"linux-pci@vger.kernel.org","web_url":null,"scm_url":null,"webscm_url":null},"msgid":"<20260427221155.2144848-5-dakr@kernel.org>","date":"2026-04-27T22:11:02","name":"[04/24] rust: device: generalize drvdata methods over ForLt","commit_ref":null,"pull_url":null,"state":"new","archived":false,"hash":"20263ea1c61b650e5d2b87291e079cb0f961b230","submitter":{"id":89037,"url":"http://patchwork.ozlabs.org/api/1.1/people/89037/?format=json","name":"Danilo Krummrich","email":"dakr@kernel.org"},"delegate":null,"mbox":"http://patchwork.ozlabs.org/project/linux-pci/patch/20260427221155.2144848-5-dakr@kernel.org/mbox/","series":[{"id":501733,"url":"http://patchwork.ozlabs.org/api/1.1/series/501733/?format=json","web_url":"http://patchwork.ozlabs.org/project/linux-pci/list/?series=501733","date":"2026-04-27T22:10:58","name":"rust: device: Higher-Ranked Lifetime Types for device drivers","version":1,"mbox":"http://patchwork.ozlabs.org/series/501733/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/2229216/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/2229216/checks/","tags":{},"headers":{"Return-Path":"\n <linux-pci+bounces-53272-incoming=patchwork.ozlabs.org@vger.kernel.org>","X-Original-To":["incoming@patchwork.ozlabs.org","linux-pci@vger.kernel.org"],"Delivered-To":"patchwork-incoming@legolas.ozlabs.org","Authentication-Results":["legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256\n header.s=k20201202 header.b=Z0SXXuMi;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org\n (client-ip=2600:3c0a:e001:db::12fc:5321; helo=sea.lore.kernel.org;\n envelope-from=linux-pci+bounces-53272-incoming=patchwork.ozlabs.org@vger.kernel.org;\n receiver=patchwork.ozlabs.org)","smtp.subspace.kernel.org;\n\tdkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org\n header.b=\"Z0SXXuMi\"","smtp.subspace.kernel.org;\n arc=none smtp.client-ip=10.30.226.201"],"Received":["from sea.lore.kernel.org (sea.lore.kernel.org\n [IPv6:2600:3c0a:e001:db::12fc:5321])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4g4HtN1vWJz1xrS\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 28 Apr 2026 08:14:52 +1000 (AEST)","from smtp.subspace.kernel.org (conduit.subspace.kernel.org\n [100.90.174.1])\n\tby sea.lore.kernel.org (Postfix) with ESMTP id 5700430C2101\n\tfor <incoming@patchwork.ozlabs.org>; Mon, 27 Apr 2026 22:12:34 +0000 (UTC)","from localhost.localdomain (localhost.localdomain [127.0.0.1])\n\tby smtp.subspace.kernel.org (Postfix) with ESMTP id C7CDA3A9625;\n\tMon, 27 Apr 2026 22:12:33 +0000 (UTC)","from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org\n [10.30.226.201])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby smtp.subspace.kernel.org (Postfix) with ESMTPS id A280526F2BE;\n\tMon, 27 Apr 2026 22:12:33 +0000 (UTC)","by smtp.kernel.org (Postfix) with ESMTPSA id 646BCC2BCB5;\n\tMon, 27 Apr 2026 22:12:27 +0000 (UTC)"],"ARC-Seal":"i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;\n\tt=1777327953; cv=none;\n b=b3vDcDHfpNKg6TllAOYjfiScgeO5bhflkEHJfmTbBlACpZ6QJD73biPTERQUD+8KhAs/WY9K8E1C9iBTn4tbFSNIQtx/51eG2wdbPRa1uc/Sp+sNqJovzLm1erc4qkqTMcmkbUewsQBubkqEZ++HTjaWVMCUpT8bPbT/6gBe8yQ=","ARC-Message-Signature":"i=1; a=rsa-sha256; d=subspace.kernel.org;\n\ts=arc-20240116; t=1777327953; c=relaxed/simple;\n\tbh=Ati2vPAhnUy/yRihj18ZVX8vWDPBaY6FgcnT2mNf5VQ=;\n\th=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References:\n\t MIME-Version;\n b=lnWtejeJ+js8lRbDx2YBObtBMhhjxnJ8+Z2c+K+DZ1q97DrOgQrEylWr6sKwPyGIrUt88+1MyXz9DlfwMaenGc7B0yfWjf3gZra2PcFOXgsmh6rU+Gzr51ySeHEEcIFO1fCT0PNejE6rXgx/xr2Anv+6831JR6t/vvGkLFT9fVY=","ARC-Authentication-Results":"i=1; smtp.subspace.kernel.org;\n dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org\n header.b=Z0SXXuMi; arc=none smtp.client-ip=10.30.226.201","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org;\n\ts=k20201202; t=1777327953;\n\tbh=Ati2vPAhnUy/yRihj18ZVX8vWDPBaY6FgcnT2mNf5VQ=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=Z0SXXuMi6XVskH6BEWb1d0OgooVVS++6oDw5xpPSYFQG8y73wco9uA3rAsWS5CsYl\n\t LzKdIyioztkN3kpNbtfhXZiPbBhlcBc7/AZ7DMY7Gc6EJm2QfzWmuP27e2gg9+AiAE\n\t /zBJyNAQyLypvUxBwP5GtJaF3FZPAkFhwbyb8McmCb/3ETP+tcOrGouNmYpYRSaOKb\n\t TkdyWExk8Ud8ZlvEK1abmxsnLavKhekYgzkdvlscm7CFcxIMVlhZp3cXZUuiZzuMOn\n\t I3bCxXGQfCzfQtenEp05tARDsj/Kj3VF+Z1FBb3gqFrj9ismWV3t+wcGJbkdoXLY5T\n\t Pyy/Q8u44I2Kw==","From":"Danilo Krummrich <dakr@kernel.org>","To":"gregkh@linuxfoundation.org,\n\trafael@kernel.org,\n\tacourbot@nvidia.com,\n\taliceryhl@google.com,\n\tdavid.m.ertman@intel.com,\n\tira.weiny@intel.com,\n\tleon@kernel.org,\n\tviresh.kumar@linaro.org,\n\tm.wilczynski@samsung.com,\n\tukleinek@kernel.org,\n\tbhelgaas@google.com,\n\tkwilczynski@kernel.org,\n\tabdiel.janulgue@gmail.com,\n\trobin.murphy@arm.com,\n\tmarkus.probst@posteo.de,\n\tojeda@kernel.org,\n\tboqun@kernel.org,\n\tgary@garyguo.net,\n\tbjorn3_gh@protonmail.com,\n\tlossin@kernel.org,\n\ta.hindborg@kernel.org,\n\ttmgross@umich.edu","Cc":"driver-core@lists.linux.dev,\n\tlinux-kernel@vger.kernel.org,\n\tnova-gpu@lists.linux.dev,\n\tdri-devel@lists.freedesktop.org,\n\tlinux-pm@vger.kernel.org,\n\tlinux-pwm@vger.kernel.org,\n\tlinux-pci@vger.kernel.org,\n\trust-for-linux@vger.kernel.org,\n\tDanilo Krummrich <dakr@kernel.org>","Subject":"[PATCH 04/24] rust: device: generalize drvdata methods over ForLt","Date":"Tue, 28 Apr 2026 00:11:02 +0200","Message-ID":"<20260427221155.2144848-5-dakr@kernel.org>","X-Mailer":"git-send-email 2.54.0","In-Reply-To":"<20260427221155.2144848-1-dakr@kernel.org>","References":"<20260427221155.2144848-1-dakr@kernel.org>","Precedence":"bulk","X-Mailing-List":"linux-pci@vger.kernel.org","List-Id":"<linux-pci.vger.kernel.org>","List-Subscribe":"<mailto:linux-pci+subscribe@vger.kernel.org>","List-Unsubscribe":"<mailto:linux-pci+unsubscribe@vger.kernel.org>","MIME-Version":"1.0","Content-Transfer-Encoding":"8bit"},"content":"Generalize set_drvdata(), drvdata_obtain() and drvdata_borrow() to take\nF: ForLt, enabling Higher-Ranked Lifetime Types (HRT) for device private\ndata.\n\nThe data is initialized as F::Of<'a> and stored as F::Of<'static>; ForLt\nguarantees covariance, making it sound to shorten the stored 'static\nlifetime to the borrow lifetime of &self.\n\nSigned-off-by: Danilo Krummrich <dakr@kernel.org>\n---\n rust/kernel/auxiliary.rs |  7 ++--\n rust/kernel/device.rs    | 80 +++++++++++++++++++++++++++++-----------\n rust/kernel/driver.rs    | 15 +++++---\n rust/kernel/i2c.rs       | 13 ++++---\n rust/kernel/pci.rs       | 11 ++++--\n rust/kernel/platform.rs  | 11 ++++--\n rust/kernel/usb.rs       | 11 ++++--\n 7 files changed, 101 insertions(+), 47 deletions(-)","diff":"diff --git a/rust/kernel/auxiliary.rs b/rust/kernel/auxiliary.rs\nindex 467befea8e44..5cd10b254baf 100644\n--- a/rust/kernel/auxiliary.rs\n+++ b/rust/kernel/auxiliary.rs\n@@ -20,6 +20,7 @@\n     },\n     prelude::*,\n     types::{\n+        ForLt,\n         ForeignOwnable,\n         Opaque, //\n     },\n@@ -46,7 +47,7 @@\n // - `DEVICE_DRIVER_OFFSET` is the correct byte offset to the embedded `struct device_driver`.\n unsafe impl<T: Driver + 'static> driver::DriverLayout for Adapter<T> {\n     type DriverType = bindings::auxiliary_driver;\n-    type DriverData = T;\n+    type DriverData = ForLt!(T);\n     const DEVICE_DRIVER_OFFSET: usize = core::mem::offset_of!(Self::DriverType, driver);\n }\n \n@@ -97,7 +98,7 @@ extern \"C\" fn probe_callback(\n         from_result(|| {\n             let data = T::probe(adev, info);\n \n-            adev.as_ref().set_drvdata(data)?;\n+            adev.as_ref().set_drvdata::<ForLt!(T)>(data)?;\n             Ok(0)\n         })\n     }\n@@ -112,7 +113,7 @@ extern \"C\" fn remove_callback(adev: *mut bindings::auxiliary_device) {\n         // SAFETY: `remove_callback` is only ever called after a successful call to\n         // `probe_callback`, hence it's guaranteed that `Device::set_drvdata()` has been called\n         // and stored a `Pin<KBox<T>>`.\n-        let data = unsafe { adev.as_ref().drvdata_borrow::<T>() };\n+        let data = unsafe { adev.as_ref().drvdata_borrow::<ForLt!(T)>() };\n \n         T::unbind(adev, data);\n     }\ndiff --git a/rust/kernel/device.rs b/rust/kernel/device.rs\nindex fd50399aadea..09cbe8a438a9 100644\n--- a/rust/kernel/device.rs\n+++ b/rust/kernel/device.rs\n@@ -10,6 +10,7 @@\n     prelude::*,\n     sync::aref::ARef,\n     types::{\n+        ForLt,\n         ForeignOwnable,\n         Opaque, //\n     }, //\n@@ -202,23 +203,41 @@ pub unsafe fn as_bound(&self) -> &Device<Bound> {\n }\n \n impl Device<CoreInternal> {\n-    /// Store a pointer to the bound driver's private data.\n-    pub fn set_drvdata<T: 'static>(&self, data: impl PinInit<T, Error>) -> Result {\n+    /// Store the bound driver's private data.\n+    ///\n+    /// `F` is the [`ForLt`] encoding of the data type. For types without a lifetime parameter,\n+    /// use [`ForLt!(T)`](macro@ForLt). For lifetime-parameterized types, the data is\n+    /// initialized as `F::Of<'a>` and stored as `F::Of<'static>`; lifetimes are erased and do not\n+    /// affect layout, while [`ForLt`] guarantees covariance for safe lifetime shortening.\n+    ///\n+    /// [`ForLt`]: trait@ForLt\n+    pub fn set_drvdata<'a, F: ForLt>(&self, data: impl PinInit<F::Of<'a>, Error>) -> Result\n+    where\n+        F::Of<'static>: 'static,\n+    {\n         let data = KBox::pin_init(data, GFP_KERNEL)?;\n \n+        // SAFETY: Lifetimes are erased and do not affect layout, so Of<'a> and Of<'static> have\n+        // identical representation. The raw pointer is type-erased through c_void anyway.\n+        let ptr = KBox::into_raw(unsafe { Pin::into_inner_unchecked(data) });\n+\n         // SAFETY: By the type invariants, `self.as_raw()` is a valid pointer to a `struct device`.\n-        unsafe { bindings::dev_set_drvdata(self.as_raw(), data.into_foreign().cast()) };\n+        unsafe { bindings::dev_set_drvdata(self.as_raw(), ptr.cast()) };\n \n         Ok(())\n     }\n \n     /// Take ownership of the private data stored in this [`Device`].\n     ///\n+    /// `F` is the [`ForLt`] encoding of the data type. The returned [`KBox`] has its lifetime\n+    /// tied to `&self`, ensuring it is dropped before the device goes away.\n+    ///\n     /// # Safety\n     ///\n-    /// - The type `T` must match the type of the `ForeignOwnable` previously stored by\n-    ///   [`Device::set_drvdata`].\n-    pub(crate) unsafe fn drvdata_obtain<T: 'static>(&self) -> Option<Pin<KBox<T>>> {\n+    /// - `F` must match the [`ForLt`] type previously stored by [`Device::set_drvdata`].\n+    ///\n+    /// [`ForLt`]: trait@ForLt\n+    pub(crate) unsafe fn drvdata_obtain<F: ForLt>(&self) -> Option<Pin<KBox<F::Of<'_>>>> {\n         // SAFETY: By the type invariants, `self.as_raw()` is a valid pointer to a `struct device`.\n         let ptr = unsafe { bindings::dev_get_drvdata(self.as_raw()) };\n \n@@ -230,24 +249,34 @@ pub(crate) unsafe fn drvdata_obtain<T: 'static>(&self) -> Option<Pin<KBox<T>>> {\n         }\n \n         // SAFETY:\n-        // - If `ptr` is not NULL, it comes from a previous call to `into_foreign()`.\n-        // - `dev_get_drvdata()` guarantees to return the same pointer given to `dev_set_drvdata()`\n-        //   in `into_foreign()`.\n-        Some(unsafe { Pin::<KBox<T>>::from_foreign(ptr.cast()) })\n+        // - If `ptr` is not NULL, it was stored by a previous call to `set_drvdata()`, which\n+        //   stores a pointer via `KBox::into_raw()`.\n+        // - Lifetimes are erased and do not affect layout, so reconstructing as `F::Of<'_>`\n+        //   (tied to `&self`) is sound.\n+        // - `dev_get_drvdata()` guarantees to return the same pointer given to\n+        //   `dev_set_drvdata()`.\n+        Some(unsafe { Pin::new_unchecked(KBox::from_raw(ptr.cast())) })\n     }\n \n     /// Borrow the driver's private data bound to this [`Device`].\n     ///\n+    /// `F` is the [`ForLt`] encoding of the data type. The returned reference has its lifetime\n+    /// shortened from `'static` to `&self`'s borrow lifetime via [`ForLt::cast_ref`].\n+    ///\n     /// # Safety\n     ///\n     /// - Must only be called after a preceding call to [`Device::set_drvdata`] and before the\n     ///   device is fully unbound.\n-    /// - The type `T` must match the type of the `ForeignOwnable` previously stored by\n-    ///   [`Device::set_drvdata`].\n-    pub unsafe fn drvdata_borrow<T: 'static>(&self) -> Pin<&T> {\n+    /// - `F` must match the [`ForLt`] type previously stored by [`Device::set_drvdata`].\n+    ///\n+    /// [`ForLt`]: trait@ForLt\n+    pub unsafe fn drvdata_borrow<F: ForLt>(&self) -> Pin<&F::Of<'_>>\n+    where\n+        F::Of<'static>: 'static,\n+    {\n         // SAFETY: `drvdata_unchecked()` has the exact same safety requirements as the ones\n         // required by this method.\n-        unsafe { self.drvdata_unchecked() }\n+        unsafe { self.drvdata_unchecked::<F>() }\n     }\n }\n \n@@ -258,18 +287,25 @@ impl Device<Bound> {\n     ///\n     /// - Must only be called after a preceding call to [`Device::set_drvdata`] and before\n     ///   the device is fully unbound.\n-    /// - The type `T` must match the type of the `ForeignOwnable` previously stored by\n-    ///   [`Device::set_drvdata`].\n-    unsafe fn drvdata_unchecked<T: 'static>(&self) -> Pin<&T> {\n+    /// - `F` must match the [`ForLt`] type previously stored by [`Device::set_drvdata`].\n+    unsafe fn drvdata_unchecked<F: ForLt>(&self) -> Pin<&F::Of<'_>>\n+    where\n+        F::Of<'static>: 'static,\n+    {\n         // SAFETY: By the type invariants, `self.as_raw()` is a valid pointer to a `struct device`.\n         let ptr = unsafe { bindings::dev_get_drvdata(self.as_raw()) };\n \n         // SAFETY:\n-        // - By the safety requirements of this function, `ptr` comes from a previous call to\n-        //   `into_foreign()`.\n-        // - `dev_get_drvdata()` guarantees to return the same pointer given to `dev_set_drvdata()`\n-        //   in `into_foreign()`.\n-        unsafe { Pin::<KBox<T>>::borrow(ptr.cast()) }\n+        // - By the safety requirements of this function, `ptr` was stored by a previous call to\n+        //   `set_drvdata()` via `KBox::into_raw()`.\n+        // - `dev_get_drvdata()` guarantees to return the same pointer given to\n+        //   `dev_set_drvdata()`.\n+        let pinned: Pin<&F::Of<'static>> =\n+            unsafe { Pin::<KBox<F::Of<'static>>>::borrow(ptr.cast()) };\n+\n+        // SAFETY: `ForLt` guarantees covariance, making it sound to shorten 'static to &self's\n+        // lifetime via cast_ref().\n+        unsafe { Pin::new_unchecked(F::cast_ref(pinned.get_ref())) }\n     }\n }\n \ndiff --git a/rust/kernel/driver.rs b/rust/kernel/driver.rs\nindex 8f0e50729215..29a67b12c872 100644\n--- a/rust/kernel/driver.rs\n+++ b/rust/kernel/driver.rs\n@@ -99,7 +99,10 @@\n     device,\n     of,\n     prelude::*,\n-    types::Opaque,\n+    types::{\n+        ForLt,\n+        Opaque, //\n+    },\n     ThisModule, //\n };\n \n@@ -112,14 +115,16 @@\n ///\n /// Implementors must guarantee that:\n /// - `DriverType` is `repr(C)`,\n-/// - `DriverData` is the type of the driver's device private data.\n+/// - `DriverData` is the [`ForLt`] encoding of the driver's device private data type.\n /// - `DriverType` embeds a valid `struct device_driver` at byte offset `DEVICE_DRIVER_OFFSET`.\n+///\n+/// [`ForLt`]: trait@ForLt\n pub unsafe trait DriverLayout {\n     /// The specific driver type embedding a `struct device_driver`.\n     type DriverType: Default;\n \n-    /// The type of the driver's device private data.\n-    type DriverData;\n+    /// The [`ForLt`](trait@ForLt) encoding of the driver's device private data type.\n+    type DriverData: ForLt;\n \n     /// Byte offset of the embedded `struct device_driver` within `DriverType`.\n     ///\n@@ -193,7 +198,7 @@ extern \"C\" fn post_unbind_callback(dev: *mut bindings::device) {\n         // be released after the driver's bus device private data is dropped.\n         //\n         // SAFETY: By the safety requirements of the `Driver` trait, `T::DriverData` is the\n-        // driver's device private data type.\n+        // ForLt encoding of the driver's device private data type.\n         drop(unsafe { dev.drvdata_obtain::<T::DriverData>() });\n     }\n \ndiff --git a/rust/kernel/i2c.rs b/rust/kernel/i2c.rs\nindex 7b908f0c5a58..cde3dd7a6cc7 100644\n--- a/rust/kernel/i2c.rs\n+++ b/rust/kernel/i2c.rs\n@@ -20,7 +20,10 @@\n         ARef,\n         AlwaysRefCounted, //\n     },\n-    types::Opaque, //\n+    types::{\n+        ForLt,\n+        Opaque, //\n+    }, //\n };\n \n use core::{\n@@ -98,7 +101,7 @@ macro_rules! i2c_device_table {\n // - `DEVICE_DRIVER_OFFSET` is the correct byte offset to the embedded `struct device_driver`.\n unsafe impl<T: Driver + 'static> driver::DriverLayout for Adapter<T> {\n     type DriverType = bindings::i2c_driver;\n-    type DriverData = T;\n+    type DriverData = ForLt!(T);\n     const DEVICE_DRIVER_OFFSET: usize = core::mem::offset_of!(Self::DriverType, driver);\n }\n \n@@ -165,7 +168,7 @@ extern \"C\" fn probe_callback(idev: *mut bindings::i2c_client) -> kernel::ffi::c_\n         from_result(|| {\n             let data = T::probe(idev, info);\n \n-            idev.as_ref().set_drvdata(data)?;\n+            idev.as_ref().set_drvdata::<ForLt!(T)>(data)?;\n             Ok(0)\n         })\n     }\n@@ -177,7 +180,7 @@ extern \"C\" fn remove_callback(idev: *mut bindings::i2c_client) {\n         // SAFETY: `remove_callback` is only ever called after a successful call to\n         // `probe_callback`, hence it's guaranteed that `I2cClient::set_drvdata()` has been called\n         // and stored a `Pin<KBox<T>>`.\n-        let data = unsafe { idev.as_ref().drvdata_borrow::<T>() };\n+        let data = unsafe { idev.as_ref().drvdata_borrow::<ForLt!(T)>() };\n \n         T::unbind(idev, data);\n     }\n@@ -189,7 +192,7 @@ extern \"C\" fn shutdown_callback(idev: *mut bindings::i2c_client) {\n         // SAFETY: `shutdown_callback` is only ever called after a successful call to\n         // `probe_callback`, hence it's guaranteed that `Device::set_drvdata()` has been called\n         // and stored a `Pin<KBox<T>>`.\n-        let data = unsafe { idev.as_ref().drvdata_borrow::<T>() };\n+        let data = unsafe { idev.as_ref().drvdata_borrow::<ForLt!(T)>() };\n \n         T::shutdown(idev, data);\n     }\ndiff --git a/rust/kernel/pci.rs b/rust/kernel/pci.rs\nindex af74ddff6114..fe5148f41d8b 100644\n--- a/rust/kernel/pci.rs\n+++ b/rust/kernel/pci.rs\n@@ -19,7 +19,10 @@\n     },\n     prelude::*,\n     str::CStr,\n-    types::Opaque,\n+    types::{\n+        ForLt,\n+        Opaque, //\n+    },\n     ThisModule, //\n };\n use core::{\n@@ -64,7 +67,7 @@\n // - `DEVICE_DRIVER_OFFSET` is the correct byte offset to the embedded `struct device_driver`.\n unsafe impl<T: Driver + 'static> driver::DriverLayout for Adapter<T> {\n     type DriverType = bindings::pci_driver;\n-    type DriverData = T;\n+    type DriverData = ForLt!(T);\n     const DEVICE_DRIVER_OFFSET: usize = core::mem::offset_of!(Self::DriverType, driver);\n }\n \n@@ -115,7 +118,7 @@ extern \"C\" fn probe_callback(\n         from_result(|| {\n             let data = T::probe(pdev, info);\n \n-            pdev.as_ref().set_drvdata(data)?;\n+            pdev.as_ref().set_drvdata::<ForLt!(T)>(data)?;\n             Ok(0)\n         })\n     }\n@@ -130,7 +133,7 @@ extern \"C\" fn remove_callback(pdev: *mut bindings::pci_dev) {\n         // SAFETY: `remove_callback` is only ever called after a successful call to\n         // `probe_callback`, hence it's guaranteed that `Device::set_drvdata()` has been called\n         // and stored a `Pin<KBox<T>>`.\n-        let data = unsafe { pdev.as_ref().drvdata_borrow::<T>() };\n+        let data = unsafe { pdev.as_ref().drvdata_borrow::<ForLt!(T)>() };\n \n         T::unbind(pdev, data);\n     }\ndiff --git a/rust/kernel/platform.rs b/rust/kernel/platform.rs\nindex 8917d4ee499f..7ff69e3eea90 100644\n--- a/rust/kernel/platform.rs\n+++ b/rust/kernel/platform.rs\n@@ -27,7 +27,10 @@\n     },\n     of,\n     prelude::*,\n-    types::Opaque,\n+    types::{\n+        ForLt,\n+        Opaque, //\n+    },\n     ThisModule, //\n };\n \n@@ -50,7 +53,7 @@\n // - `DEVICE_DRIVER_OFFSET` is the correct byte offset to the embedded `struct device_driver`.\n unsafe impl<T: Driver + 'static> driver::DriverLayout for Adapter<T> {\n     type DriverType = bindings::platform_driver;\n-    type DriverData = T;\n+    type DriverData = ForLt!(T);\n     const DEVICE_DRIVER_OFFSET: usize = core::mem::offset_of!(Self::DriverType, driver);\n }\n \n@@ -103,7 +106,7 @@ extern \"C\" fn probe_callback(pdev: *mut bindings::platform_device) -> kernel::ff\n         from_result(|| {\n             let data = T::probe(pdev, info);\n \n-            pdev.as_ref().set_drvdata(data)?;\n+            pdev.as_ref().set_drvdata::<ForLt!(T)>(data)?;\n             Ok(0)\n         })\n     }\n@@ -118,7 +121,7 @@ extern \"C\" fn remove_callback(pdev: *mut bindings::platform_device) {\n         // SAFETY: `remove_callback` is only ever called after a successful call to\n         // `probe_callback`, hence it's guaranteed that `Device::set_drvdata()` has been called\n         // and stored a `Pin<KBox<T>>`.\n-        let data = unsafe { pdev.as_ref().drvdata_borrow::<T>() };\n+        let data = unsafe { pdev.as_ref().drvdata_borrow::<ForLt!(T)>() };\n \n         T::unbind(pdev, data);\n     }\ndiff --git a/rust/kernel/usb.rs b/rust/kernel/usb.rs\nindex 9c17a672cd27..9b9d3ae41087 100644\n--- a/rust/kernel/usb.rs\n+++ b/rust/kernel/usb.rs\n@@ -19,7 +19,10 @@\n     },\n     prelude::*,\n     sync::aref::AlwaysRefCounted,\n-    types::Opaque,\n+    types::{\n+        ForLt,\n+        Opaque, //\n+    },\n     ThisModule, //\n };\n use core::{\n@@ -41,7 +44,7 @@\n // - `DEVICE_DRIVER_OFFSET` is the correct byte offset to the embedded `struct device_driver`.\n unsafe impl<T: Driver + 'static> driver::DriverLayout for Adapter<T> {\n     type DriverType = bindings::usb_driver;\n-    type DriverData = T;\n+    type DriverData = ForLt!(T);\n     const DEVICE_DRIVER_OFFSET: usize = core::mem::offset_of!(Self::DriverType, driver);\n }\n \n@@ -93,7 +96,7 @@ extern \"C\" fn probe_callback(\n             let data = T::probe(intf, id, info);\n \n             let dev: &device::Device<device::CoreInternal> = intf.as_ref();\n-            dev.set_drvdata(data)?;\n+            dev.set_drvdata::<ForLt!(T)>(data)?;\n             Ok(0)\n         })\n     }\n@@ -110,7 +113,7 @@ extern \"C\" fn disconnect_callback(intf: *mut bindings::usb_interface) {\n         // SAFETY: `disconnect_callback` is only ever called after a successful call to\n         // `probe_callback`, hence it's guaranteed that `Device::set_drvdata()` has been called\n         // and stored a `Pin<KBox<T>>`.\n-        let data = unsafe { dev.drvdata_borrow::<T>() };\n+        let data = unsafe { dev.drvdata_borrow::<ForLt!(T)>() };\n \n         T::disconnect(intf, data);\n     }\n","prefixes":["04/24"]}