xref: /linux/rust/kernel/auxiliary.rs (revision 24799831d631239ff21ea1bf7feee832df48b81f)
1 // SPDX-License-Identifier: GPL-2.0
2 
3 //! Abstractions for the auxiliary bus.
4 //!
5 //! C header: [`include/linux/auxiliary_bus.h`](srctree/include/linux/auxiliary_bus.h)
6 
7 use crate::{
8     bindings,
9     container_of,
10     device,
11     device_id::{
12         RawDeviceId,
13         RawDeviceIdIndex, //
14     },
15     devres::Devres,
16     driver,
17     error::{
18         from_result,
19         to_result, //
20     },
21     prelude::*,
22     types::{
23         ForeignOwnable,
24         Opaque, //
25     },
26     ThisModule, //
27 };
28 use core::{
29     any::TypeId,
30     marker::PhantomData,
31     mem::offset_of,
32     pin::Pin,
33     ptr::{
34         addr_of_mut,
35         NonNull, //
36     },
37 };
38 
39 /// An adapter for the registration of auxiliary drivers.
40 pub struct Adapter<T: Driver>(T);
41 
42 // SAFETY:
43 // - `bindings::auxiliary_driver` is a C type declared as `repr(C)`.
44 // - `T::Data` is the type of the driver's device private data.
45 // - `struct auxiliary_driver` embeds a `struct device_driver`.
46 // - `DEVICE_DRIVER_OFFSET` is the correct byte offset to the embedded `struct device_driver`.
47 unsafe impl<T: Driver> driver::DriverLayout for Adapter<T> {
48     type DriverType = bindings::auxiliary_driver;
49     type DriverData<'bound> = T::Data;
50     const DEVICE_DRIVER_OFFSET: usize = core::mem::offset_of!(Self::DriverType, driver);
51 }
52 
53 // SAFETY: A call to `unregister` for a given instance of `DriverType` is guaranteed to be valid if
54 // a preceding call to `register` has been successful.
55 unsafe impl<T: Driver> driver::RegistrationOps for Adapter<T> {
56     unsafe fn register(
57         adrv: &Opaque<Self::DriverType>,
58         name: &'static CStr,
59         module: &'static ThisModule,
60     ) -> Result {
61         // SAFETY: It's safe to set the fields of `struct auxiliary_driver` on initialization.
62         unsafe {
63             (*adrv.get()).name = name.as_char_ptr();
64             (*adrv.get()).probe = Some(Self::probe_callback);
65             (*adrv.get()).remove = Some(Self::remove_callback);
66             (*adrv.get()).id_table = T::ID_TABLE.as_ptr();
67         }
68 
69         // SAFETY: `adrv` is guaranteed to be a valid `DriverType`.
70         to_result(unsafe {
71             bindings::__auxiliary_driver_register(adrv.get(), module.0, name.as_char_ptr())
72         })
73     }
74 
75     unsafe fn unregister(adrv: &Opaque<Self::DriverType>) {
76         // SAFETY: `adrv` is guaranteed to be a valid `DriverType`.
77         unsafe { bindings::auxiliary_driver_unregister(adrv.get()) }
78     }
79 }
80 
81 impl<T: Driver> Adapter<T> {
82     extern "C" fn probe_callback(
83         adev: *mut bindings::auxiliary_device,
84         id: *const bindings::auxiliary_device_id,
85     ) -> c_int {
86         // SAFETY: The auxiliary bus only ever calls the probe callback with a valid pointer to a
87         // `struct auxiliary_device`.
88         //
89         // INVARIANT: `adev` is valid for the duration of `probe_callback()`.
90         let adev = unsafe { &*adev.cast::<Device<device::CoreInternal<'_>>>() };
91 
92         // SAFETY: `DeviceId` is a `#[repr(transparent)`] wrapper of `struct auxiliary_device_id`
93         // and does not add additional invariants, so it's safe to transmute.
94         let id = unsafe { &*id.cast::<DeviceId>() };
95         let info = T::ID_TABLE.info(id.index());
96 
97         from_result(|| {
98             let data = T::probe(adev, info);
99 
100             adev.as_ref().set_drvdata(data)?;
101             Ok(0)
102         })
103     }
104 
105     extern "C" fn remove_callback(adev: *mut bindings::auxiliary_device) {
106         // SAFETY: The auxiliary bus only ever calls the probe callback with a valid pointer to a
107         // `struct auxiliary_device`.
108         //
109         // INVARIANT: `adev` is valid for the duration of `remove_callback()`.
110         let adev = unsafe { &*adev.cast::<Device<device::CoreInternal<'_>>>() };
111 
112         // SAFETY: `remove_callback` is only ever called after a successful call to
113         // `probe_callback`, hence it's guaranteed that `Device::set_drvdata()` has been called
114         // and stored a `Pin<KBox<T::Data>>`.
115         let data = unsafe { adev.as_ref().drvdata_borrow::<T::Data>() };
116 
117         T::unbind(adev, data);
118     }
119 }
120 
121 /// Declares a kernel module that exposes a single auxiliary driver.
122 #[macro_export]
123 macro_rules! module_auxiliary_driver {
124     ($($f:tt)*) => {
125         $crate::module_driver!(<T>, $crate::auxiliary::Adapter<T>, { $($f)* });
126     };
127 }
128 
129 /// Abstraction for `bindings::auxiliary_device_id`.
130 #[repr(transparent)]
131 #[derive(Clone, Copy)]
132 pub struct DeviceId(bindings::auxiliary_device_id);
133 
134 impl DeviceId {
135     /// Create a new [`DeviceId`] from name.
136     pub const fn new(modname: &'static CStr, name: &'static CStr) -> Self {
137         let name = name.to_bytes_with_nul();
138         let modname = modname.to_bytes_with_nul();
139 
140         let mut id: bindings::auxiliary_device_id = pin_init::zeroed();
141         let mut i = 0;
142         while i < modname.len() {
143             id.name[i] = modname[i];
144             i += 1;
145         }
146 
147         // Reuse the space of the NULL terminator.
148         id.name[i - 1] = b'.';
149 
150         let mut j = 0;
151         while j < name.len() {
152             id.name[i] = name[j];
153             i += 1;
154             j += 1;
155         }
156 
157         Self(id)
158     }
159 }
160 
161 // SAFETY: `DeviceId` is a `#[repr(transparent)]` wrapper of `auxiliary_device_id` and does not add
162 // additional invariants, so it's safe to transmute to `RawType`.
163 unsafe impl RawDeviceId for DeviceId {
164     type RawType = bindings::auxiliary_device_id;
165 }
166 
167 // SAFETY: `DRIVER_DATA_OFFSET` is the offset to the `driver_data` field.
168 unsafe impl RawDeviceIdIndex for DeviceId {
169     const DRIVER_DATA_OFFSET: usize =
170         core::mem::offset_of!(bindings::auxiliary_device_id, driver_data);
171 
172     fn index(&self) -> usize {
173         self.0.driver_data
174     }
175 }
176 
177 /// IdTable type for auxiliary drivers.
178 pub type IdTable<T> = &'static dyn kernel::device_id::IdTable<DeviceId, T>;
179 
180 /// Create a auxiliary `IdTable` with its alias for modpost.
181 #[macro_export]
182 macro_rules! auxiliary_device_table {
183     ($table_name:ident, $module_table_name:ident, $id_info_type: ty, $table_data: expr) => {
184         const $table_name: $crate::device_id::IdArray<
185             $crate::auxiliary::DeviceId,
186             $id_info_type,
187             { $table_data.len() },
188         > = $crate::device_id::IdArray::new($table_data);
189 
190         $crate::module_device_table!("auxiliary", $module_table_name, $table_name);
191     };
192 }
193 
194 /// The auxiliary driver trait.
195 ///
196 /// Drivers must implement this trait in order to get an auxiliary driver registered.
197 pub trait Driver {
198     /// The type holding information about each device id supported by the driver.
199     ///
200     /// TODO: Use associated_type_defaults once stabilized:
201     ///
202     /// type IdInfo: 'static = ();
203     type IdInfo: 'static;
204 
205     /// The type of the driver's bus device private data.
206     type Data: Send;
207 
208     /// The table of device ids supported by the driver.
209     const ID_TABLE: IdTable<Self::IdInfo>;
210 
211     /// Auxiliary driver probe.
212     ///
213     /// Called when an auxiliary device is matches a corresponding driver.
214     fn probe(
215         dev: &Device<device::Core<'_>>,
216         id_info: &Self::IdInfo,
217     ) -> impl PinInit<Self::Data, Error>;
218 
219     /// Auxiliary driver unbind.
220     ///
221     /// Called when a [`Device`] is unbound from its bound [`Driver`]. Implementing this callback
222     /// is optional.
223     ///
224     /// This callback serves as a place for drivers to perform teardown operations that require a
225     /// `&Device<Core>` or `&Device<Bound>` reference. For instance, drivers may try to perform I/O
226     /// operations to gracefully tear down the device.
227     ///
228     /// Otherwise, release operations for driver resources should be performed in `Drop`.
229     fn unbind(dev: &Device<device::Core<'_>>, this: Pin<&Self::Data>) {
230         let _ = (dev, this);
231     }
232 }
233 
234 /// The auxiliary device representation.
235 ///
236 /// This structure represents the Rust abstraction for a C `struct auxiliary_device`. The
237 /// implementation abstracts the usage of an already existing C `struct auxiliary_device` within
238 /// Rust code that we get passed from the C side.
239 ///
240 /// # Invariants
241 ///
242 /// A [`Device`] instance represents a valid `struct auxiliary_device` created by the C portion of
243 /// the kernel.
244 #[repr(transparent)]
245 pub struct Device<Ctx: device::DeviceContext = device::Normal>(
246     Opaque<bindings::auxiliary_device>,
247     PhantomData<Ctx>,
248 );
249 
250 impl<Ctx: device::DeviceContext> Device<Ctx> {
251     fn as_raw(&self) -> *mut bindings::auxiliary_device {
252         self.0.get()
253     }
254 
255     /// Returns the auxiliary device' id.
256     pub fn id(&self) -> u32 {
257         // SAFETY: By the type invariant `self.as_raw()` is a valid pointer to a
258         // `struct auxiliary_device`.
259         unsafe { (*self.as_raw()).id }
260     }
261 }
262 
263 impl Device<device::Bound> {
264     /// Returns a bound reference to the parent [`device::Device`].
265     pub fn parent(&self) -> &device::Device<device::Bound> {
266         let parent = (**self).parent();
267 
268         // SAFETY: A bound auxiliary device always has a bound parent device.
269         unsafe { parent.as_bound() }
270     }
271 
272     /// Returns a pinned reference to the registration data set by the registering (parent) driver.
273     ///
274     /// Returns [`EINVAL`] if `T` does not match the type used by the parent driver when calling
275     /// [`Registration::new()`].
276     ///
277     /// Returns [`ENOENT`] if no registration data has been set, e.g. when the device was
278     /// registered by a C driver.
279     pub fn registration_data<T: 'static>(&self) -> Result<Pin<&T>> {
280         // SAFETY: By the type invariant, `self.as_raw()` is a valid `struct auxiliary_device`.
281         let ptr = unsafe { (*self.as_raw()).registration_data_rust };
282         if ptr.is_null() {
283             dev_warn!(
284                 self.as_ref(),
285                 "No registration data set; parent is not a Rust driver.\n"
286             );
287             return Err(ENOENT);
288         }
289 
290         // SAFETY: `ptr` is non-null and was set via `into_foreign()` in `Registration::new()`;
291         // `RegistrationData` is `#[repr(C)]` with `type_id` at offset 0, so reading a `TypeId`
292         // at the start of the allocation is valid regardless of `T`.
293         let type_id = unsafe { ptr.cast::<TypeId>().read() };
294         if type_id != TypeId::of::<T>() {
295             return Err(EINVAL);
296         }
297 
298         // SAFETY: The `TypeId` check above confirms that the stored type is `T`; `ptr` remains
299         // valid until `Registration::drop()` calls `from_foreign()`.
300         let wrapper = unsafe { Pin::<KBox<RegistrationData<T>>>::borrow(ptr) };
301 
302         // SAFETY: `data` is a structurally pinned field of `RegistrationData`.
303         Ok(unsafe { wrapper.map_unchecked(|w| &w.data) })
304     }
305 }
306 
307 impl Device {
308     /// Returns a reference to the parent [`device::Device`].
309     pub fn parent(&self) -> &device::Device {
310         // SAFETY: A `struct auxiliary_device` always has a parent.
311         unsafe { self.as_ref().parent().unwrap_unchecked() }
312     }
313 
314     extern "C" fn release(dev: *mut bindings::device) {
315         // SAFETY: By the type invariant `self.0.as_raw` is a pointer to the `struct device`
316         // embedded in `struct auxiliary_device`.
317         let adev = unsafe { container_of!(dev, bindings::auxiliary_device, dev) };
318 
319         // SAFETY: `adev` points to the memory that has been allocated in `Registration::new`, via
320         // `KBox::new(Opaque::<bindings::auxiliary_device>::zeroed(), GFP_KERNEL)`.
321         let _ = unsafe { KBox::<Opaque<bindings::auxiliary_device>>::from_raw(adev.cast()) };
322     }
323 }
324 
325 // SAFETY: `auxiliary::Device` is a transparent wrapper of `struct auxiliary_device`.
326 // The offset is guaranteed to point to a valid device field inside `auxiliary::Device`.
327 unsafe impl<Ctx: device::DeviceContext> device::AsBusDevice<Ctx> for Device<Ctx> {
328     const OFFSET: usize = offset_of!(bindings::auxiliary_device, dev);
329 }
330 
331 // SAFETY: `Device` is a transparent wrapper of a type that doesn't depend on `Device`'s generic
332 // argument.
333 kernel::impl_device_context_deref!(unsafe { Device });
334 kernel::impl_device_context_into_aref!(Device);
335 
336 // SAFETY: Instances of `Device` are always reference-counted.
337 unsafe impl crate::sync::aref::AlwaysRefCounted for Device {
338     fn inc_ref(&self) {
339         // SAFETY: The existence of a shared reference guarantees that the refcount is non-zero.
340         unsafe { bindings::get_device(self.as_ref().as_raw()) };
341     }
342 
343     unsafe fn dec_ref(obj: NonNull<Self>) {
344         // CAST: `Self` a transparent wrapper of `bindings::auxiliary_device`.
345         let adev: *mut bindings::auxiliary_device = obj.cast().as_ptr();
346 
347         // SAFETY: By the type invariant of `Self`, `adev` is a pointer to a valid
348         // `struct auxiliary_device`.
349         let dev = unsafe { addr_of_mut!((*adev).dev) };
350 
351         // SAFETY: The safety requirements guarantee that the refcount is non-zero.
352         unsafe { bindings::put_device(dev) }
353     }
354 }
355 
356 impl<Ctx: device::DeviceContext> AsRef<device::Device<Ctx>> for Device<Ctx> {
357     fn as_ref(&self) -> &device::Device<Ctx> {
358         // SAFETY: By the type invariant of `Self`, `self.as_raw()` is a pointer to a valid
359         // `struct auxiliary_device`.
360         let dev = unsafe { addr_of_mut!((*self.as_raw()).dev) };
361 
362         // SAFETY: `dev` points to a valid `struct device`.
363         unsafe { device::Device::from_raw(dev) }
364     }
365 }
366 
367 // SAFETY: A `Device` is always reference-counted and can be released from any thread.
368 unsafe impl Send for Device {}
369 
370 // SAFETY: `Device` can be shared among threads because all methods of `Device`
371 // (i.e. `Device<Normal>) are thread safe.
372 unsafe impl Sync for Device {}
373 
374 // SAFETY: Same as `Device<Normal>` -- the underlying `struct auxiliary_device` is the same;
375 // `Bound` is a zero-sized type-state marker that does not affect thread safety.
376 unsafe impl Sync for Device<device::Bound> {}
377 
378 /// Wrapper that stores a [`TypeId`] alongside the registration data for runtime type checking.
379 #[repr(C)]
380 #[pin_data]
381 struct RegistrationData<T> {
382     type_id: TypeId,
383     #[pin]
384     data: T,
385 }
386 
387 /// The registration of an auxiliary device.
388 ///
389 /// This type represents the registration of a [`struct auxiliary_device`]. When its parent device
390 /// is unbound, the corresponding auxiliary device will be unregistered from the system.
391 ///
392 /// The type parameter `T` is the type of the registration data owned by the registering (parent)
393 /// driver. It can be accessed by the auxiliary driver through
394 /// [`Device::registration_data()`].
395 ///
396 /// # Invariants
397 ///
398 /// `self.adev` always holds a valid pointer to an initialized and registered
399 /// [`struct auxiliary_device`] whose `registration_data_rust` field points to a
400 /// valid `Pin<KBox<RegistrationData<T>>>`.
401 pub struct Registration<T: 'static> {
402     adev: NonNull<bindings::auxiliary_device>,
403     _data: PhantomData<T>,
404 }
405 
406 impl<T: Send + Sync + 'static> Registration<T> {
407     /// Create and register a new auxiliary device with the given registration data.
408     ///
409     /// The `data` is owned by the registration and can be accessed through the auxiliary device
410     /// via [`Device::registration_data()`].
411     pub fn new<E>(
412         parent: &device::Device<device::Bound>,
413         name: &CStr,
414         id: u32,
415         modname: &CStr,
416         data: impl PinInit<T, E>,
417     ) -> Result<Devres<Self>>
418     where
419         Error: From<E>,
420     {
421         let data = KBox::pin_init::<Error>(
422             try_pin_init!(RegistrationData {
423                 type_id: TypeId::of::<T>(),
424                 data <- data,
425             }),
426             GFP_KERNEL,
427         )?;
428 
429         let boxed: KBox<Opaque<bindings::auxiliary_device>> = KBox::zeroed(GFP_KERNEL)?;
430         let adev = boxed.get();
431 
432         // SAFETY: It's safe to set the fields of `struct auxiliary_device` on initialization.
433         unsafe {
434             (*adev).dev.parent = parent.as_raw();
435             (*adev).dev.release = Some(Device::release);
436             (*adev).name = name.as_char_ptr();
437             (*adev).id = id;
438             (*adev).registration_data_rust = data.into_foreign();
439         }
440 
441         // SAFETY: `adev` is guaranteed to be a valid pointer to a `struct auxiliary_device`,
442         // which has not been initialized yet.
443         unsafe { bindings::auxiliary_device_init(adev) };
444 
445         // Now that `adev` is initialized, leak the `Box`; the corresponding memory will be
446         // freed by `Device::release` when the last reference to the `struct auxiliary_device`
447         // is dropped.
448         let _ = KBox::into_raw(boxed);
449 
450         // SAFETY:
451         // - `adev` is guaranteed to be a valid pointer to a `struct auxiliary_device`, which
452         //   has been initialized,
453         // - `modname.as_char_ptr()` is a NULL terminated string.
454         let ret = unsafe { bindings::__auxiliary_device_add(adev, modname.as_char_ptr()) };
455         if ret != 0 {
456             // SAFETY: `registration_data` was set above via `into_foreign()`.
457             drop(unsafe {
458                 Pin::<KBox<RegistrationData<T>>>::from_foreign((*adev).registration_data_rust)
459             });
460 
461             // SAFETY: `adev` is guaranteed to be a valid pointer to a
462             // `struct auxiliary_device`, which has been initialized.
463             unsafe { bindings::auxiliary_device_uninit(adev) };
464 
465             return Err(Error::from_errno(ret));
466         }
467 
468         // INVARIANT: The device will remain registered until `auxiliary_device_delete()` is
469         // called, which happens in `Self::drop()`.
470         let reg = Self {
471             // SAFETY: `adev` is guaranteed to be non-null, since the `KBox` was allocated
472             // successfully.
473             adev: unsafe { NonNull::new_unchecked(adev) },
474             _data: PhantomData,
475         };
476 
477         Devres::new::<core::convert::Infallible>(parent, reg)
478     }
479 }
480 
481 impl<T: 'static> Drop for Registration<T> {
482     fn drop(&mut self) {
483         // SAFETY: By the type invariant of `Self`, `self.adev.as_ptr()` is a valid registered
484         // `struct auxiliary_device`.
485         unsafe { bindings::auxiliary_device_delete(self.adev.as_ptr()) };
486 
487         // SAFETY: `registration_data` was set in `new()` via `into_foreign()`.
488         drop(unsafe {
489             Pin::<KBox<RegistrationData<T>>>::from_foreign(
490                 (*self.adev.as_ptr()).registration_data_rust,
491             )
492         });
493 
494         // This drops the reference we acquired through `auxiliary_device_init()`.
495         //
496         // SAFETY: By the type invariant of `Self`, `self.adev.as_ptr()` is a valid registered
497         // `struct auxiliary_device`.
498         unsafe { bindings::auxiliary_device_uninit(self.adev.as_ptr()) };
499     }
500 }
501 
502 // SAFETY: A `Registration` of a `struct auxiliary_device` can be released from any thread.
503 unsafe impl<T: Send + Sync> Send for Registration<T> {}
504 
505 // SAFETY: `Registration` does not expose any methods or fields that need synchronization.
506 unsafe impl<T: Send + Sync> Sync for Registration<T> {}
507