Skip to main content

kernel/
serdev.rs

1// SPDX-License-Identifier: GPL-2.0
2
3//! Abstractions for the serial device bus.
4//!
5//! C header: [`include/linux/serdev.h`](srctree/include/linux/serdev.h)
6
7use crate::{
8    acpi,
9    device,
10    driver,
11    error::{
12        from_result,
13        to_result,
14        VTABLE_DEFAULT_ERROR, //
15    },
16    new_mutex,
17    of,
18    prelude::*,
19    sync::{
20        aref::AlwaysRefCounted,
21        Mutex, //
22    },
23    time::Jiffies,
24    types::{
25        Opaque,
26        ScopeGuard, //
27    }, //
28};
29
30use core::{
31    cell::UnsafeCell,
32    marker::PhantomData,
33    mem::{offset_of, MaybeUninit},
34    ptr::NonNull, //
35};
36
37/// Parity bit to use with a serial device.
38#[repr(u32)]
39pub enum Parity {
40    /// No parity bit.
41    None = bindings::serdev_parity_SERDEV_PARITY_NONE,
42    /// Even partiy.
43    Even = bindings::serdev_parity_SERDEV_PARITY_EVEN,
44    /// Odd parity.
45    Odd = bindings::serdev_parity_SERDEV_PARITY_ODD,
46}
47
48/// An adapter for the registration of serial device bus device drivers.
49pub struct Adapter<T: Driver>(T);
50
51// SAFETY:
52// - `bindings::serdev_device_driver` is a C type declared as `repr(C)`.
53// - `PrivateData<'bound, T>` is the type of the driver's device private data.
54// - `struct serdev_device_driver` embeds a `struct device_driver`.
55// - `DEVICE_DRIVER_OFFSET` is the correct byte offset to the embedded `struct device_driver`.
56unsafe impl<T: Driver> driver::DriverLayout for Adapter<T> {
57    type DriverType = bindings::serdev_device_driver;
58    type DriverData<'bound> = PrivateData<'bound, T>;
59    const DEVICE_DRIVER_OFFSET: usize = core::mem::offset_of!(Self::DriverType, driver);
60}
61
62// SAFETY: A call to `unregister` for a given instance of `DriverType` is guaranteed to be valid if
63// a preceding call to `register` has been successful.
64unsafe impl<T: Driver> driver::RegistrationOps for Adapter<T> {
65    unsafe fn register(
66        sdrv: &Opaque<Self::DriverType>,
67        name: &'static CStr,
68        module: &'static ThisModule,
69    ) -> Result {
70        let of_table = match T::OF_ID_TABLE {
71            Some(table) => table.as_ptr(),
72            None => core::ptr::null(),
73        };
74
75        let acpi_table = match T::ACPI_ID_TABLE {
76            Some(table) => table.as_ptr(),
77            None => core::ptr::null(),
78        };
79
80        // SAFETY: It's safe to set the fields of `struct serdev_device_driver` on initialization.
81        unsafe {
82            (*sdrv.get()).driver.name = name.as_char_ptr();
83            (*sdrv.get()).probe = Some(Self::probe_callback);
84            (*sdrv.get()).remove = Some(Self::remove_callback);
85            (*sdrv.get()).driver.of_match_table = of_table;
86            (*sdrv.get()).driver.acpi_match_table = acpi_table;
87        }
88
89        // SAFETY: `sdrv` is guaranteed to be a valid `DriverType`.
90        to_result(unsafe { bindings::__serdev_device_driver_register(sdrv.get(), module.0) })
91    }
92
93    unsafe fn unregister(sdrv: &Opaque<Self::DriverType>) {
94        // SAFETY: `sdrv` is guaranteed to be a valid `DriverType`.
95        unsafe { bindings::serdev_device_driver_unregister(sdrv.get()) };
96    }
97}
98
99#[doc(hidden)]
100#[pin_data(PinnedDrop)]
101pub struct PrivateData<'bound, T: Driver> {
102    sdev: &'bound Device<device::Bound>,
103    #[pin]
104    driver: UnsafeCell<MaybeUninit<T::Data<'bound>>>,
105    open: UnsafeCell<bool>,
106    /// Whether `receive_buf_callback` is allowed to call `Driver::receive`.
107    ///
108    /// If locked, the receive_buf_callback will be blocked on data reception.
109    /// This is the case while the driver is being probed or while [`PrivateData`] is being dropped.
110    /// This is necessary, because we need to open the serdev device before the driver has been
111    /// probed in order to allow it to be configured, which allows `receive_buf_callback` to be
112    /// called. Thus we need to block data until probe completes and the driver data becomes
113    /// initialized.
114    ///
115    /// If unlocked and true, the receive_buf_callback will forward the data to
116    /// `Driver::receive`. This is the normal state of operation.
117    ///
118    /// If unlocked and false, the receive_buf_callback will throw away the data.
119    /// This is only the case, if the serdev device is open and
120    /// - the driver returned an error in probe
121    /// or
122    /// - the driver data already has been dropped, because it was unbound.
123    #[pin]
124    active: Mutex<bool>,
125}
126
127#[pinned_drop]
128impl<T: Driver> PinnedDrop for PrivateData<'_, T> {
129    fn drop(self: Pin<&mut Self>) {
130        let mut active = self.active.lock();
131        if *active {
132            // SAFETY:
133            // - We have exclusive access to `self.driver`.
134            // - `self.driver` is guaranteed to be initialized.
135            unsafe { (*self.driver.get()).assume_init_drop() };
136            *active = false;
137        }
138        drop(active);
139
140        // SAFETY: We have exclusive access to `self.open`.
141        if unsafe { *self.open.get() } {
142            // SAFETY: `self.sdev.as_raw()` is guaranteed to be a pointer to a valid
143            // `struct serdev_device`.
144            unsafe { bindings::serdev_device_close(self.sdev.as_raw()) };
145        }
146    }
147}
148
149impl<T: Driver> Adapter<T> {
150    const OPS: &'static bindings::serdev_device_ops = &bindings::serdev_device_ops {
151        receive_buf: if T::HAS_RECEIVE {
152            Some(Self::receive_buf_callback)
153        } else {
154            None
155        },
156        write_wakeup: Some(bindings::serdev_device_write_wakeup),
157    };
158
159    extern "C" fn probe_callback(sdev: *mut bindings::serdev_device) -> kernel::ffi::c_int {
160        // SAFETY: The serial device bus only ever calls the probe callback with a valid pointer to
161        // a `struct serdev_device`.
162        //
163        // INVARIANT: `sdev` is valid for the duration of `probe_callback()`.
164        let sdev = unsafe { &*sdev.cast::<Device<device::CoreInternal<'_>>>() };
165        // SAFETY: `sdev` matched data is of type `Self::IdInfo`.
166        let info = unsafe { <Self as driver::Adapter>::id_info(sdev.as_ref()) };
167
168        from_result(|| {
169            sdev.as_ref().set_drvdata(try_pin_init!(PrivateData::<T> {
170                sdev: &**sdev,
171                driver: MaybeUninit::<T::Data<'_>>::zeroed().into(),
172                open: false.into(),
173                active <- new_mutex!(false),
174            }))?;
175            // SAFETY: We just set drvdata to `PrivateData<'_, T>`.
176            let private_data = unsafe { sdev.as_ref().drvdata_borrow::<PrivateData<'_, T>>() };
177            let private_data = ScopeGuard::new_with_data(private_data, |_| {
178                // SAFETY: We just set drvdata to `PrivateData<'_, T>`.
179                drop(unsafe { sdev.as_ref().drvdata_obtain::<PrivateData<'_, T>>() });
180            });
181            let mut active = private_data.active.lock();
182
183            // SAFETY: `sdev.as_raw()` is guaranteed to be a valid pointer to `serdev_device`.
184            unsafe { bindings::serdev_device_set_client_ops(sdev.as_raw(), Self::OPS) };
185
186            // SAFETY: The serial device bus only ever calls the probe callback with a valid pointer
187            // to a `serdev_device`.
188            to_result(unsafe { bindings::serdev_device_open(sdev.as_raw()) })?;
189
190            // SAFETY: We have exclusive access to `private_data.open`.
191            unsafe { *private_data.open.get() = true };
192
193            let data = T::probe(sdev, info);
194
195            // SAFETY: We have exclusive access to `private_data.driver`.
196            let driver = unsafe { &mut *private_data.driver.get() };
197            // SAFETY:
198            // - `driver.as_mut_ptr()` is a valid pointer to uninitialized data.
199            // - `private_data.driver` is pinned.
200            let result = unsafe { pin_init::raw_try_init(driver.as_mut_ptr(), data) };
201
202            *active = result.is_ok();
203
204            drop(active);
205
206            result.map(|()| {
207                private_data.dismiss();
208                0
209            })
210        })
211    }
212
213    extern "C" fn remove_callback(sdev: *mut bindings::serdev_device) {
214        // SAFETY: The serial device bus only ever calls the remove callback with a valid pointer
215        // to a `struct serdev_device`.
216        //
217        // INVARIANT: `sdev` is valid for the duration of `remove_callback()`.
218        let sdev = unsafe { &*sdev.cast::<Device<device::CoreInternal<'_>>>() };
219
220        // SAFETY: `remove_callback` is only ever called after a successful call to
221        // `probe_callback`, hence it's guaranteed that `Device::set_drvdata()` has been called
222        // and stored a `Pin<KBox<PrivateData<'_, T>>>`.
223        let private_data = unsafe { sdev.as_ref().drvdata_borrow::<PrivateData<'_, T>>() };
224
225        // SAFETY: No one has exclusive access to `private_data.driver`.
226        let data = unsafe { &*private_data.driver.get() };
227        // SAFETY:
228        // - `private_data.driver` is pinned.
229        // - `remove_callback` is only ever called after a successful call to `probe_callback`,
230        //   hence it's guaranteed that `private_data.driver` was initialized.
231        let data_pinned = unsafe { Pin::new_unchecked(data.assume_init_ref()) };
232
233        T::unbind(sdev, data_pinned);
234    }
235
236    extern "C" fn receive_buf_callback(
237        sdev: *mut bindings::serdev_device,
238        buf: *const u8,
239        length: usize,
240    ) -> usize {
241        // SAFETY: The serial device bus only ever calls the receive buf callback with a valid
242        // pointer to a `struct serdev_device`.
243        //
244        // INVARIANT: `sdev` is valid for the duration of `receive_buf_callback()`.
245        let sdev = unsafe { &*sdev.cast::<Device<device::BoundInternal>>() };
246
247        // SAFETY: `receive_buf_callback` is only ever called after a successful call to
248        // `probe_callback`, hence it's guaranteed that `Device::set_drvdata()` has been called
249        // and stored a `Pin<KBox<PrivateData<'_, T>>>`.
250        let private_data = unsafe { sdev.as_ref().drvdata_borrow::<PrivateData<'_, T>>() };
251        let active = private_data.active.lock();
252
253        if !*active {
254            return length;
255        }
256
257        // SAFETY: No one has exclusive access to `private_data.driver`.
258        let data = unsafe { &*private_data.driver.get() };
259        // SAFETY:
260        // - `private_data.driver` is pinned.
261        // - `receive_buf_callback` is only ever called after a successful call to `probe_callback`,
262        //   hence it's guaranteed that `private_data.driver` was initialized.
263        let data_pinned = unsafe { Pin::new_unchecked(data.assume_init_ref()) };
264
265        // SAFETY: `buf` is guaranteed to be non-null and has the size of `length`.
266        let buf = unsafe { core::slice::from_raw_parts(buf, length) };
267
268        T::receive(sdev, data_pinned, buf)
269    }
270}
271
272impl<T: Driver> driver::Adapter for Adapter<T> {
273    type IdInfo = T::IdInfo;
274
275    fn of_id_table() -> Option<of::IdTable<Self::IdInfo>> {
276        T::OF_ID_TABLE
277    }
278
279    fn acpi_id_table() -> Option<acpi::IdTable<Self::IdInfo>> {
280        T::ACPI_ID_TABLE
281    }
282}
283
284/// Declares a kernel module that exposes a single serial device bus device driver.
285///
286/// # Examples
287///
288/// ```ignore
289/// kernel::module_serdev_device_driver! {
290///     type: MyDriver,
291///     name: "Module name",
292///     authors: ["Author name"],
293///     description: "Description",
294///     license: "GPL v2",
295/// }
296/// ```
297#[macro_export]
298macro_rules! module_serdev_device_driver {
299    ($($f:tt)*) => {
300        $crate::module_driver!(<T>, $crate::serdev::Adapter<T>, { $($f)* });
301    };
302}
303
304/// The serial device bus device driver trait.
305///
306/// Drivers must implement this trait in order to get a serial device bus device driver registered.
307///
308/// # Examples
309///
310///```
311/// # use kernel::{
312///     acpi,
313///     bindings,
314///     device::{
315///         Bound,
316///         Core, //
317///     },
318///     of,
319///     serdev, //
320/// };
321///
322/// struct MyDriver;
323///
324/// kernel::of_device_table!(
325///     OF_TABLE,
326///     <MyDriver as serdev::Driver>::IdInfo,
327///     [
328///         (of::DeviceId::new(c"test,device"), ())
329///     ]
330/// );
331///
332/// kernel::acpi_device_table!(
333///     ACPI_TABLE,
334///     <MyDriver as serdev::Driver>::IdInfo,
335///     [
336///         (acpi::DeviceId::new(c"LNUXBEEF"), ())
337///     ]
338/// );
339///
340/// #[vtable]
341/// impl serdev::Driver for MyDriver {
342///     type IdInfo = ();
343///     type Data<'bound> = Self;
344///     const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = Some(&OF_TABLE);
345///     const ACPI_ID_TABLE: Option<acpi::IdTable<Self::IdInfo>> = Some(&ACPI_TABLE);
346///
347///     fn probe<'bound>(
348///         sdev: &'bound serdev::Device<Core<'_>>,
349///         _id_info: Option<&'bound Self::IdInfo>,
350///     ) -> impl PinInit<Self::Data<'bound>, Error> + 'bound {
351///         sdev.set_baudrate(115200);
352///         sdev.write_all(b"Hello\n", 0)?;
353///         Ok(MyDriver)
354///     }
355/// }
356///```
357#[vtable]
358pub trait Driver {
359    /// The type holding driver private data about each device id supported by the driver.
360    // TODO: Use associated_type_defaults once stabilized:
361    //
362    // ```
363    // type IdInfo: 'static = ();
364    // ```
365    type IdInfo: 'static;
366
367    /// The type of the driver's bus device private data.
368    type Data<'bound>: Send + Sync + 'bound;
369
370    /// The table of OF device ids supported by the driver.
371    const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = None;
372
373    /// The table of ACPI device ids supported by the driver.
374    const ACPI_ID_TABLE: Option<acpi::IdTable<Self::IdInfo>> = None;
375
376    /// Serial device bus device driver probe.
377    ///
378    /// Called when a new serial device bus device is added or discovered.
379    /// Implementers should attempt to initialize the device here.
380    fn probe<'bound>(
381        sdev: &'bound Device<device::Core<'_>>,
382        id_info: Option<&'bound Self::IdInfo>,
383    ) -> impl PinInit<Self::Data<'bound>, Error> + 'bound;
384
385    /// Serial device bus device driver unbind.
386    ///
387    /// Called when a [`Device`] is unbound from its bound [`Driver`]. Implementing this callback
388    /// is optional.
389    ///
390    /// This callback serves as a place for drivers to perform teardown operations that require a
391    /// `&Device<Core>` or `&Device<Bound>` reference. For instance.
392    ///
393    /// Otherwise, release operations for driver resources should be performed in `Drop`.
394    fn unbind<'bound>(sdev: &'bound Device<device::Core<'_>>, this: Pin<&Self::Data<'bound>>) {
395        let _ = (sdev, this);
396    }
397
398    /// Serial device bus device data receive callback.
399    ///
400    /// Called when data got received from device.
401    ///
402    /// Returns the number of bytes accepted.
403    fn receive<'bound>(
404        sdev: &'bound Device<device::Bound>,
405        this: Pin<&Self::Data<'bound>>,
406        data: &[u8],
407    ) -> usize {
408        let _ = (sdev, this, data);
409        build_error!(VTABLE_DEFAULT_ERROR)
410    }
411}
412
413/// The serial device bus device representation.
414///
415/// This structure represents the Rust abstraction for a C `struct serdev_device`. The
416/// implementation abstracts the usage of an already existing C `struct serdev_device` within Rust
417/// code that we get passed from the C side.
418///
419/// # Invariants
420///
421/// A [`Device`] instance represents a valid `struct serdev_device` created by the C portion of
422/// the kernel.
423#[repr(transparent)]
424pub struct Device<Ctx: device::DeviceContext = device::Normal>(
425    Opaque<bindings::serdev_device>,
426    PhantomData<Ctx>,
427);
428
429impl<Ctx: device::DeviceContext> Device<Ctx> {
430    #[inline]
431    fn as_raw(&self) -> *mut bindings::serdev_device {
432        self.0.get()
433    }
434}
435
436impl Device<device::Bound> {
437    /// Set the baudrate in bits per second.
438    ///
439    /// Common baudrates are 115200, 9600, 19200, 57600, 4800.
440    ///
441    /// Use [`Device::write_flush`] before calling this if you have written data prior to this call.
442    #[inline]
443    pub fn set_baudrate(&self, speed: u32) -> Result<(), u32> {
444        // SAFETY: `self.as_raw()` is guaranteed to be a pointer to a valid `serdev_device`.
445        let ret = unsafe { bindings::serdev_device_set_baudrate(self.as_raw(), speed) };
446        if ret == speed {
447            Ok(())
448        } else {
449            Err(ret)
450        }
451    }
452
453    /// Set if flow control should be enabled.
454    ///
455    /// Use [`Device::write_flush`] before calling this if you have written data prior to this call.
456    #[inline]
457    pub fn set_flow_control(&self, enable: bool) {
458        // SAFETY: `self.as_raw()` is guaranteed to be a pointer to a valid `serdev_device`.
459        unsafe { bindings::serdev_device_set_flow_control(self.as_raw(), enable) };
460    }
461
462    /// Set parity to use.
463    ///
464    /// Use [`Device::write_flush`] before calling this if you have written data prior to this call.
465    #[inline]
466    pub fn set_parity(&self, parity: Parity) -> Result {
467        // SAFETY: `self.as_raw()` is guaranteed to be a pointer to a valid `serdev_device`.
468        to_result(unsafe { bindings::serdev_device_set_parity(self.as_raw(), parity as u32) })
469    }
470
471    /// Write data to the serial device until the controller has accepted all the data or has
472    /// been interrupted by a timeout or signal.
473    ///
474    /// Note that any accepted data has only been buffered by the controller. Use
475    /// [`Device::wait_until_sent`] to make sure the controller write buffer has actually been
476    /// emptied.
477    ///
478    /// Use a timeout of 0 to wait indefinitely.
479    ///
480    /// Returns the number of bytes written (less than `data.len()` if interrupted).
481    /// [`kernel::error::code::ETIMEDOUT`] or [`kernel::error::code::ERESTARTSYS`] if interrupted
482    /// before any bytes were written. [`kernel::error::code::EINVAL`] if `data.len() > i32::MAX`.
483    #[inline]
484    pub fn write_all(&self, data: &[u8], timeout: Jiffies) -> Result<usize> {
485        if data.len() > i32::MAX as usize {
486            return Err(EINVAL);
487        }
488
489        // SAFETY:
490        // - `self.as_raw()` is guaranteed to be a pointer to a valid `serdev_device`.
491        // - `data.as_ptr()` is guaranteed to be a valid array pointer with the size of
492        //   `data.len()`.
493        let ret = unsafe {
494            bindings::serdev_device_write(
495                self.as_raw(),
496                data.as_ptr(),
497                data.len(),
498                isize::try_from(timeout).unwrap_or_default(),
499            )
500        };
501        // CAST: negative return values are guaranteed to be between `-MAX_ERRNO` and `-1`,
502        // which always fit into a `i32`.
503        to_result(ret as i32).map(|()| ret.unsigned_abs())
504    }
505
506    /// Write data to the serial device.
507    ///
508    /// If you want to write until the controller has accepted all the data, use
509    /// [`Device::write_all`].
510    ///
511    /// Note that any accepted data has only been buffered by the controller. Use
512    /// [`Device::wait_until_sent`] to make sure the controller write buffer has actually been
513    /// emptied.
514    ///
515    /// Returns the number of bytes written (less than `data.len()` if not enough room in the
516    /// write buffer).
517    #[inline]
518    pub fn write(&self, data: &[u8]) -> Result<u32> {
519        if data.len() > i32::MAX as usize {
520            return Err(EINVAL);
521        }
522
523        // SAFETY:
524        // - `self.as_raw()` is guaranteed to be a pointer to a valid `serdev_device`.
525        // - `data.as_ptr()` is guaranteed to be a valid array pointer with the size of
526        //   `data.len()`.
527        let ret =
528            unsafe { bindings::serdev_device_write_buf(self.as_raw(), data.as_ptr(), data.len()) };
529
530        to_result(ret as i32).map(|()| ret.unsigned_abs())
531    }
532
533    /// Send data to the serial device immediately.
534    ///
535    /// Note that this doesn't guarantee that the data has been transmitted.
536    /// Use [`Device::wait_until_sent`] for this purpose.
537    #[inline]
538    pub fn write_flush(&self) {
539        // SAFETY: `self.as_raw()` is guaranteed to be a pointer to a valid `serdev_device`.
540        unsafe { bindings::serdev_device_write_flush(self.as_raw()) };
541    }
542
543    /// Wait for the data to be sent.
544    ///
545    /// After this function, the write buffer of the controller should be empty or the timeout
546    /// elapsed.
547    ///
548    /// Use a timeout of 0 to wait indefinitely.
549    #[inline]
550    pub fn wait_until_sent(&self, timeout: Jiffies) {
551        // SAFETY: `self.as_raw()` is guaranteed to be a pointer to a valid `serdev_device`.
552        unsafe {
553            bindings::serdev_device_wait_until_sent(
554                self.as_raw(),
555                isize::try_from(timeout).unwrap_or_default(),
556            )
557        };
558    }
559}
560
561// SAFETY: `serdev::Device` is a transparent wrapper of `struct serdev_device`.
562// The offset is guaranteed to point to a valid device field inside `serdev::Device`.
563unsafe impl<Ctx: device::DeviceContext> device::AsBusDevice<Ctx> for Device<Ctx> {
564    const OFFSET: usize = offset_of!(bindings::serdev_device, dev);
565}
566
567// SAFETY: `Device` is a transparent wrapper of a type that doesn't depend on `Device`'s generic
568// argument.
569kernel::impl_device_context_deref!(unsafe { Device });
570kernel::impl_device_context_into_aref!(Device);
571
572// SAFETY: Instances of `Device` are always reference-counted.
573unsafe impl AlwaysRefCounted for Device {
574    fn inc_ref(&self) {
575        self.as_ref().inc_ref();
576    }
577
578    unsafe fn dec_ref(obj: NonNull<Self>) {
579        // SAFETY: The safety requirements guarantee that the refcount is non-zero.
580        unsafe { bindings::serdev_device_put(obj.cast().as_ptr()) }
581    }
582}
583
584impl<Ctx: device::DeviceContext> AsRef<device::Device<Ctx>> for Device<Ctx> {
585    fn as_ref(&self) -> &device::Device<Ctx> {
586        // SAFETY: By the type invariant of `Self`, `self.as_raw()` is a pointer to a valid
587        // `struct serdev_device`.
588        let dev = unsafe { &raw mut (*self.as_raw()).dev };
589
590        // SAFETY: `dev` points to a valid `struct device`.
591        unsafe { device::Device::from_raw(dev) }
592    }
593}
594
595// SAFETY: A `Device` is always reference-counted and can be released from any thread.
596unsafe impl Send for Device {}
597
598// SAFETY: `Device` can be shared among threads because all methods of `Device`
599// (i.e. `Device<Normal>) are thread safe.
600unsafe impl Sync for Device {}
601
602// SAFETY: Same as `Device<Normal>` -- the underlying `struct serdev_device` is the same;
603// `Bound` is a zero-sized type-state marker that does not affect thread safety.
604unsafe impl Sync for Device<device::Bound> {}