Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/1.1/patches/2229215/?format=api
{ "id": 2229215, "url": "http://patchwork.ozlabs.org/api/1.1/patches/2229215/?format=api", "web_url": "http://patchwork.ozlabs.org/project/linux-pwm/patch/20260427221155.2144848-5-dakr@kernel.org/", "project": { "id": 38, "url": "http://patchwork.ozlabs.org/api/1.1/projects/38/?format=api", "name": "Linux PWM development", "link_name": "linux-pwm", "list_id": "linux-pwm.vger.kernel.org", "list_email": "linux-pwm@vger.kernel.org", "web_url": "", "scm_url": "", "webscm_url": "" }, "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": "handled-elsewhere", "archived": false, "hash": "20263ea1c61b650e5d2b87291e079cb0f961b230", "submitter": { "id": 89037, "url": "http://patchwork.ozlabs.org/api/1.1/people/89037/?format=api", "name": "Danilo Krummrich", "email": "dakr@kernel.org" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/linux-pwm/patch/20260427221155.2144848-5-dakr@kernel.org/mbox/", "series": [ { "id": 501734, "url": "http://patchwork.ozlabs.org/api/1.1/series/501734/?format=api", "web_url": "http://patchwork.ozlabs.org/project/linux-pwm/list/?series=501734", "date": "2026-04-27T22:10:58", "name": "rust: device: Higher-Ranked Lifetime Types for device drivers", "version": 1, "mbox": "http://patchwork.ozlabs.org/series/501734/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2229215/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2229215/checks/", "tags": {}, "headers": { "Return-Path": "\n <linux-pwm+bounces-8707-incoming=patchwork.ozlabs.org@vger.kernel.org>", "X-Original-To": [ "incoming@patchwork.ozlabs.org", "linux-pwm@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=172.234.253.10; helo=sea.lore.kernel.org;\n envelope-from=linux-pwm+bounces-8707-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 [172.234.253.10])\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 4g4HtL5pB0z1xrS\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 28 Apr 2026 08:14:50 +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 30C73303FDE9\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 C7BC93A7F4B;\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-pwm@vger.kernel.org", "List-Id": "<linux-pwm.vger.kernel.org>", "List-Subscribe": "<mailto:linux-pwm+subscribe@vger.kernel.org>", "List-Unsubscribe": "<mailto:linux-pwm+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" ] }