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> {}