Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

rust: auxiliary: use generic device drvdata accessors

Take advantage of the generic drvdata accessors of the generic Device
type.

While at it, use from_result() instead of match.

Link: https://lore.kernel.org/r/20250621195118.124245-6-dakr@kernel.org
Signed-off-by: Danilo Krummrich <dakr@kernel.org>

+15 -30
-10
rust/helpers/auxiliary.c
··· 2 2 3 3 #include <linux/auxiliary_bus.h> 4 4 5 - void rust_helper_auxiliary_set_drvdata(struct auxiliary_device *adev, void *data) 6 - { 7 - auxiliary_set_drvdata(adev, data); 8 - } 9 - 10 - void *rust_helper_auxiliary_get_drvdata(struct auxiliary_device *adev) 11 - { 12 - return auxiliary_get_drvdata(adev); 13 - } 14 - 15 5 void rust_helper_auxiliary_device_uninit(struct auxiliary_device *adev) 16 6 { 17 7 return auxiliary_device_uninit(adev);
+15 -20
rust/kernel/auxiliary.rs
··· 8 8 bindings, container_of, device, 9 9 device_id::RawDeviceId, 10 10 driver, 11 - error::{to_result, Result}, 11 + error::{from_result, to_result, Result}, 12 12 prelude::*, 13 - types::{ForeignOwnable, Opaque}, 13 + types::Opaque, 14 14 ThisModule, 15 15 }; 16 16 use core::{ ··· 60 60 // `struct auxiliary_device`. 61 61 // 62 62 // INVARIANT: `adev` is valid for the duration of `probe_callback()`. 63 - let adev = unsafe { &*adev.cast::<Device<device::Core>>() }; 63 + let adev = unsafe { &*adev.cast::<Device<device::CoreInternal>>() }; 64 64 65 65 // SAFETY: `DeviceId` is a `#[repr(transparent)`] wrapper of `struct auxiliary_device_id` 66 66 // and does not add additional invariants, so it's safe to transmute. 67 67 let id = unsafe { &*id.cast::<DeviceId>() }; 68 68 let info = T::ID_TABLE.info(id.index()); 69 69 70 - match T::probe(adev, info) { 71 - Ok(data) => { 72 - // Let the `struct auxiliary_device` own a reference of the driver's private data. 73 - // SAFETY: By the type invariant `adev.as_raw` returns a valid pointer to a 74 - // `struct auxiliary_device`. 75 - unsafe { 76 - bindings::auxiliary_set_drvdata(adev.as_raw(), data.into_foreign().cast()) 77 - }; 78 - } 79 - Err(err) => return Error::to_errno(err), 80 - } 70 + from_result(|| { 71 + let data = T::probe(adev, info)?; 81 72 82 - 0 73 + adev.as_ref().set_drvdata(data); 74 + Ok(0) 75 + }) 83 76 } 84 77 85 78 extern "C" fn remove_callback(adev: *mut bindings::auxiliary_device) { 86 - // SAFETY: The auxiliary bus only ever calls the remove callback with a valid pointer to a 79 + // SAFETY: The auxiliary bus only ever calls the probe callback with a valid pointer to a 87 80 // `struct auxiliary_device`. 88 - let ptr = unsafe { bindings::auxiliary_get_drvdata(adev) }; 81 + // 82 + // INVARIANT: `adev` is valid for the duration of `probe_callback()`. 83 + let adev = unsafe { &*adev.cast::<Device<device::CoreInternal>>() }; 89 84 90 85 // SAFETY: `remove_callback` is only ever called after a successful call to 91 - // `probe_callback`, hence it's guaranteed that `ptr` points to a valid and initialized 92 - // `KBox<T>` pointer created through `KBox::into_foreign`. 93 - drop(unsafe { KBox::<T>::from_foreign(ptr.cast()) }); 86 + // `probe_callback`, hence it's guaranteed that `Device::set_drvdata()` has been called 87 + // and stored a `Pin<KBox<T>>`. 88 + drop(unsafe { adev.as_ref().drvdata_obtain::<Pin<KBox<T>>>() }); 94 89 } 95 90 } 96 91