1a674fefdSDanilo Krummrich // SPDX-License-Identifier: GPL-2.0 2a674fefdSDanilo Krummrich 3a674fefdSDanilo Krummrich //! Generic devices that are part of the kernel's driver model. 4a674fefdSDanilo Krummrich //! 5a674fefdSDanilo Krummrich //! C header: [`include/linux/device.h`](srctree/include/linux/device.h) 6a674fefdSDanilo Krummrich 7a674fefdSDanilo Krummrich use crate::{ 8a674fefdSDanilo Krummrich bindings, 9e1cd24afSViresh Kumar str::CStr, 10a674fefdSDanilo Krummrich types::{ARef, Opaque}, 11a674fefdSDanilo Krummrich }; 125c7ca6faSWedson Almeida Filho use core::{fmt, ptr}; 135c7ca6faSWedson Almeida Filho 145c7ca6faSWedson Almeida Filho #[cfg(CONFIG_PRINTK)] 155c7ca6faSWedson Almeida Filho use crate::c_str; 16a674fefdSDanilo Krummrich 17a674fefdSDanilo Krummrich /// A reference-counted device. 18a674fefdSDanilo Krummrich /// 19a674fefdSDanilo Krummrich /// This structure represents the Rust abstraction for a C `struct device`. This implementation 20a674fefdSDanilo Krummrich /// abstracts the usage of an already existing C `struct device` within Rust code that we get 21a674fefdSDanilo Krummrich /// passed from the C side. 22a674fefdSDanilo Krummrich /// 23a674fefdSDanilo Krummrich /// An instance of this abstraction can be obtained temporarily or permanent. 24a674fefdSDanilo Krummrich /// 25a674fefdSDanilo Krummrich /// A temporary one is bound to the lifetime of the C `struct device` pointer used for creation. 26a674fefdSDanilo Krummrich /// A permanent instance is always reference-counted and hence not restricted by any lifetime 27a674fefdSDanilo Krummrich /// boundaries. 28a674fefdSDanilo Krummrich /// 29a674fefdSDanilo Krummrich /// For subsystems it is recommended to create a permanent instance to wrap into a subsystem 30a674fefdSDanilo Krummrich /// specific device structure (e.g. `pci::Device`). This is useful for passing it to drivers in 31a674fefdSDanilo Krummrich /// `T::probe()`, such that a driver can store the `ARef<Device>` (equivalent to storing a 32a674fefdSDanilo Krummrich /// `struct device` pointer in a C driver) for arbitrary purposes, e.g. allocating DMA coherent 33a674fefdSDanilo Krummrich /// memory. 34a674fefdSDanilo Krummrich /// 35a674fefdSDanilo Krummrich /// # Invariants 36a674fefdSDanilo Krummrich /// 374ead6c37SDanilo Krummrich /// A `Device` instance represents a valid `struct device` created by the C portion of the kernel. 384ead6c37SDanilo Krummrich /// 394ead6c37SDanilo Krummrich /// Instances of this type are always reference-counted, that is, a call to `get_device` ensures 404ead6c37SDanilo Krummrich /// that the allocation remains valid at least until the matching call to `put_device`. 41a674fefdSDanilo Krummrich /// 42a674fefdSDanilo Krummrich /// `bindings::device::release` is valid to be called from any thread, hence `ARef<Device>` can be 43a674fefdSDanilo Krummrich /// dropped from any thread. 44a674fefdSDanilo Krummrich #[repr(transparent)] 45a674fefdSDanilo Krummrich pub struct Device(Opaque<bindings::device>); 46a674fefdSDanilo Krummrich 47a674fefdSDanilo Krummrich impl Device { 48a674fefdSDanilo Krummrich /// Creates a new reference-counted abstraction instance of an existing `struct device` pointer. 49a674fefdSDanilo Krummrich /// 50a674fefdSDanilo Krummrich /// # Safety 51a674fefdSDanilo Krummrich /// 52a674fefdSDanilo Krummrich /// Callers must ensure that `ptr` is valid, non-null, and has a non-zero reference count, 53a674fefdSDanilo Krummrich /// i.e. it must be ensured that the reference count of the C `struct device` `ptr` points to 54a674fefdSDanilo Krummrich /// can't drop to zero, for the duration of this function call. 55a674fefdSDanilo Krummrich /// 56a674fefdSDanilo Krummrich /// It must also be ensured that `bindings::device::release` can be called from any thread. 57a674fefdSDanilo Krummrich /// While not officially documented, this should be the case for any `struct device`. get_device(ptr: *mut bindings::device) -> ARef<Self>58cc4332afSGuilherme Giacomo Simoes pub unsafe fn get_device(ptr: *mut bindings::device) -> ARef<Self> { 59cc4332afSGuilherme Giacomo Simoes // SAFETY: By the safety requirements ptr is valid 60cc4332afSGuilherme Giacomo Simoes unsafe { Self::as_ref(ptr) }.into() 61a674fefdSDanilo Krummrich } 62a674fefdSDanilo Krummrich 63a674fefdSDanilo Krummrich /// Obtain the raw `struct device *`. as_raw(&self) -> *mut bindings::device64a674fefdSDanilo Krummrich pub(crate) fn as_raw(&self) -> *mut bindings::device { 65a674fefdSDanilo Krummrich self.0.get() 66a674fefdSDanilo Krummrich } 67a674fefdSDanilo Krummrich 68a674fefdSDanilo Krummrich /// Convert a raw C `struct device` pointer to a `&'a Device`. 69a674fefdSDanilo Krummrich /// 70a674fefdSDanilo Krummrich /// # Safety 71a674fefdSDanilo Krummrich /// 72a674fefdSDanilo Krummrich /// Callers must ensure that `ptr` is valid, non-null, and has a non-zero reference count, 73a674fefdSDanilo Krummrich /// i.e. it must be ensured that the reference count of the C `struct device` `ptr` points to 74a674fefdSDanilo Krummrich /// can't drop to zero, for the duration of this function call and the entire duration when the 75a674fefdSDanilo Krummrich /// returned reference exists. as_ref<'a>(ptr: *mut bindings::device) -> &'a Self76a674fefdSDanilo Krummrich pub unsafe fn as_ref<'a>(ptr: *mut bindings::device) -> &'a Self { 77a674fefdSDanilo Krummrich // SAFETY: Guaranteed by the safety requirements of the function. 78a674fefdSDanilo Krummrich unsafe { &*ptr.cast() } 79a674fefdSDanilo Krummrich } 805c7ca6faSWedson Almeida Filho 815c7ca6faSWedson Almeida Filho /// Prints an emergency-level message (level 0) prefixed with device information. 825c7ca6faSWedson Almeida Filho /// 835c7ca6faSWedson Almeida Filho /// More details are available from [`dev_emerg`]. 845c7ca6faSWedson Almeida Filho /// 855c7ca6faSWedson Almeida Filho /// [`dev_emerg`]: crate::dev_emerg pr_emerg(&self, args: fmt::Arguments<'_>)865c7ca6faSWedson Almeida Filho pub fn pr_emerg(&self, args: fmt::Arguments<'_>) { 875c7ca6faSWedson Almeida Filho // SAFETY: `klevel` is null-terminated, uses one of the kernel constants. 885c7ca6faSWedson Almeida Filho unsafe { self.printk(bindings::KERN_EMERG, args) }; 895c7ca6faSWedson Almeida Filho } 905c7ca6faSWedson Almeida Filho 915c7ca6faSWedson Almeida Filho /// Prints an alert-level message (level 1) prefixed with device information. 925c7ca6faSWedson Almeida Filho /// 935c7ca6faSWedson Almeida Filho /// More details are available from [`dev_alert`]. 945c7ca6faSWedson Almeida Filho /// 955c7ca6faSWedson Almeida Filho /// [`dev_alert`]: crate::dev_alert pr_alert(&self, args: fmt::Arguments<'_>)965c7ca6faSWedson Almeida Filho pub fn pr_alert(&self, args: fmt::Arguments<'_>) { 975c7ca6faSWedson Almeida Filho // SAFETY: `klevel` is null-terminated, uses one of the kernel constants. 985c7ca6faSWedson Almeida Filho unsafe { self.printk(bindings::KERN_ALERT, args) }; 995c7ca6faSWedson Almeida Filho } 1005c7ca6faSWedson Almeida Filho 1015c7ca6faSWedson Almeida Filho /// Prints a critical-level message (level 2) prefixed with device information. 1025c7ca6faSWedson Almeida Filho /// 1035c7ca6faSWedson Almeida Filho /// More details are available from [`dev_crit`]. 1045c7ca6faSWedson Almeida Filho /// 1055c7ca6faSWedson Almeida Filho /// [`dev_crit`]: crate::dev_crit pr_crit(&self, args: fmt::Arguments<'_>)1065c7ca6faSWedson Almeida Filho pub fn pr_crit(&self, args: fmt::Arguments<'_>) { 1075c7ca6faSWedson Almeida Filho // SAFETY: `klevel` is null-terminated, uses one of the kernel constants. 1085c7ca6faSWedson Almeida Filho unsafe { self.printk(bindings::KERN_CRIT, args) }; 1095c7ca6faSWedson Almeida Filho } 1105c7ca6faSWedson Almeida Filho 1115c7ca6faSWedson Almeida Filho /// Prints an error-level message (level 3) prefixed with device information. 1125c7ca6faSWedson Almeida Filho /// 1135c7ca6faSWedson Almeida Filho /// More details are available from [`dev_err`]. 1145c7ca6faSWedson Almeida Filho /// 1155c7ca6faSWedson Almeida Filho /// [`dev_err`]: crate::dev_err pr_err(&self, args: fmt::Arguments<'_>)1165c7ca6faSWedson Almeida Filho pub fn pr_err(&self, args: fmt::Arguments<'_>) { 1175c7ca6faSWedson Almeida Filho // SAFETY: `klevel` is null-terminated, uses one of the kernel constants. 1185c7ca6faSWedson Almeida Filho unsafe { self.printk(bindings::KERN_ERR, args) }; 1195c7ca6faSWedson Almeida Filho } 1205c7ca6faSWedson Almeida Filho 1215c7ca6faSWedson Almeida Filho /// Prints a warning-level message (level 4) prefixed with device information. 1225c7ca6faSWedson Almeida Filho /// 1235c7ca6faSWedson Almeida Filho /// More details are available from [`dev_warn`]. 1245c7ca6faSWedson Almeida Filho /// 1255c7ca6faSWedson Almeida Filho /// [`dev_warn`]: crate::dev_warn pr_warn(&self, args: fmt::Arguments<'_>)1265c7ca6faSWedson Almeida Filho pub fn pr_warn(&self, args: fmt::Arguments<'_>) { 1275c7ca6faSWedson Almeida Filho // SAFETY: `klevel` is null-terminated, uses one of the kernel constants. 1285c7ca6faSWedson Almeida Filho unsafe { self.printk(bindings::KERN_WARNING, args) }; 1295c7ca6faSWedson Almeida Filho } 1305c7ca6faSWedson Almeida Filho 1315c7ca6faSWedson Almeida Filho /// Prints a notice-level message (level 5) prefixed with device information. 1325c7ca6faSWedson Almeida Filho /// 1335c7ca6faSWedson Almeida Filho /// More details are available from [`dev_notice`]. 1345c7ca6faSWedson Almeida Filho /// 1355c7ca6faSWedson Almeida Filho /// [`dev_notice`]: crate::dev_notice pr_notice(&self, args: fmt::Arguments<'_>)1365c7ca6faSWedson Almeida Filho pub fn pr_notice(&self, args: fmt::Arguments<'_>) { 1375c7ca6faSWedson Almeida Filho // SAFETY: `klevel` is null-terminated, uses one of the kernel constants. 1385c7ca6faSWedson Almeida Filho unsafe { self.printk(bindings::KERN_NOTICE, args) }; 1395c7ca6faSWedson Almeida Filho } 1405c7ca6faSWedson Almeida Filho 1415c7ca6faSWedson Almeida Filho /// Prints an info-level message (level 6) prefixed with device information. 1425c7ca6faSWedson Almeida Filho /// 1435c7ca6faSWedson Almeida Filho /// More details are available from [`dev_info`]. 1445c7ca6faSWedson Almeida Filho /// 1455c7ca6faSWedson Almeida Filho /// [`dev_info`]: crate::dev_info pr_info(&self, args: fmt::Arguments<'_>)1465c7ca6faSWedson Almeida Filho pub fn pr_info(&self, args: fmt::Arguments<'_>) { 1475c7ca6faSWedson Almeida Filho // SAFETY: `klevel` is null-terminated, uses one of the kernel constants. 1485c7ca6faSWedson Almeida Filho unsafe { self.printk(bindings::KERN_INFO, args) }; 1495c7ca6faSWedson Almeida Filho } 1505c7ca6faSWedson Almeida Filho 1515c7ca6faSWedson Almeida Filho /// Prints a debug-level message (level 7) prefixed with device information. 1525c7ca6faSWedson Almeida Filho /// 1535c7ca6faSWedson Almeida Filho /// More details are available from [`dev_dbg`]. 1545c7ca6faSWedson Almeida Filho /// 1555c7ca6faSWedson Almeida Filho /// [`dev_dbg`]: crate::dev_dbg pr_dbg(&self, args: fmt::Arguments<'_>)1565c7ca6faSWedson Almeida Filho pub fn pr_dbg(&self, args: fmt::Arguments<'_>) { 1575c7ca6faSWedson Almeida Filho if cfg!(debug_assertions) { 1585c7ca6faSWedson Almeida Filho // SAFETY: `klevel` is null-terminated, uses one of the kernel constants. 1595c7ca6faSWedson Almeida Filho unsafe { self.printk(bindings::KERN_DEBUG, args) }; 1605c7ca6faSWedson Almeida Filho } 1615c7ca6faSWedson Almeida Filho } 1625c7ca6faSWedson Almeida Filho 1635c7ca6faSWedson Almeida Filho /// Prints the provided message to the console. 1645c7ca6faSWedson Almeida Filho /// 1655c7ca6faSWedson Almeida Filho /// # Safety 1665c7ca6faSWedson Almeida Filho /// 1675c7ca6faSWedson Almeida Filho /// Callers must ensure that `klevel` is null-terminated; in particular, one of the 1685c7ca6faSWedson Almeida Filho /// `KERN_*`constants, for example, `KERN_CRIT`, `KERN_ALERT`, etc. 1695c7ca6faSWedson Almeida Filho #[cfg_attr(not(CONFIG_PRINTK), allow(unused_variables))] printk(&self, klevel: &[u8], msg: fmt::Arguments<'_>)1705c7ca6faSWedson Almeida Filho unsafe fn printk(&self, klevel: &[u8], msg: fmt::Arguments<'_>) { 1715c7ca6faSWedson Almeida Filho // SAFETY: `klevel` is null-terminated and one of the kernel constants. `self.as_raw` 1725c7ca6faSWedson Almeida Filho // is valid because `self` is valid. The "%pA" format string expects a pointer to 1735c7ca6faSWedson Almeida Filho // `fmt::Arguments`, which is what we're passing as the last argument. 1745c7ca6faSWedson Almeida Filho #[cfg(CONFIG_PRINTK)] 1755c7ca6faSWedson Almeida Filho unsafe { 1765c7ca6faSWedson Almeida Filho bindings::_dev_printk( 17727c7518eSMiguel Ojeda klevel as *const _ as *const crate::ffi::c_char, 1785c7ca6faSWedson Almeida Filho self.as_raw(), 1795c7ca6faSWedson Almeida Filho c_str!("%pA").as_char_ptr(), 18027c7518eSMiguel Ojeda &msg as *const _ as *const crate::ffi::c_void, 1815c7ca6faSWedson Almeida Filho ) 1825c7ca6faSWedson Almeida Filho }; 1835c7ca6faSWedson Almeida Filho } 184e3a89cc2SViresh Kumar 185e3a89cc2SViresh Kumar /// Checks if property is present or not. property_present(&self, name: &CStr) -> bool186e1cd24afSViresh Kumar pub fn property_present(&self, name: &CStr) -> bool { 187e1cd24afSViresh Kumar // SAFETY: By the invariant of `CStr`, `name` is null-terminated. 18801b3cb62SViresh Kumar unsafe { bindings::device_property_present(self.as_raw().cast_const(), name.as_char_ptr()) } 189e3a89cc2SViresh Kumar } 190a674fefdSDanilo Krummrich } 191a674fefdSDanilo Krummrich 192a674fefdSDanilo Krummrich // SAFETY: Instances of `Device` are always reference-counted. 193a674fefdSDanilo Krummrich unsafe impl crate::types::AlwaysRefCounted for Device { inc_ref(&self)194a674fefdSDanilo Krummrich fn inc_ref(&self) { 195a674fefdSDanilo Krummrich // SAFETY: The existence of a shared reference guarantees that the refcount is non-zero. 196a674fefdSDanilo Krummrich unsafe { bindings::get_device(self.as_raw()) }; 197a674fefdSDanilo Krummrich } 198a674fefdSDanilo Krummrich dec_ref(obj: ptr::NonNull<Self>)199a674fefdSDanilo Krummrich unsafe fn dec_ref(obj: ptr::NonNull<Self>) { 200a674fefdSDanilo Krummrich // SAFETY: The safety requirements guarantee that the refcount is non-zero. 201a674fefdSDanilo Krummrich unsafe { bindings::put_device(obj.cast().as_ptr()) } 202a674fefdSDanilo Krummrich } 203a674fefdSDanilo Krummrich } 204a674fefdSDanilo Krummrich 205a674fefdSDanilo Krummrich // SAFETY: As by the type invariant `Device` can be sent to any thread. 206a674fefdSDanilo Krummrich unsafe impl Send for Device {} 207a674fefdSDanilo Krummrich 208a674fefdSDanilo Krummrich // SAFETY: `Device` can be shared among threads because all immutable methods are protected by the 209a674fefdSDanilo Krummrich // synchronization in `struct device`. 210a674fefdSDanilo Krummrich unsafe impl Sync for Device {} 2115c7ca6faSWedson Almeida Filho 212*4d032779SDanilo Krummrich /// Marker trait for the context of a bus specific device. 213*4d032779SDanilo Krummrich /// 214*4d032779SDanilo Krummrich /// Some functions of a bus specific device should only be called from a certain context, i.e. bus 215*4d032779SDanilo Krummrich /// callbacks, such as `probe()`. 216*4d032779SDanilo Krummrich /// 217*4d032779SDanilo Krummrich /// This is the marker trait for structures representing the context of a bus specific device. 218*4d032779SDanilo Krummrich pub trait DeviceContext: private::Sealed {} 219*4d032779SDanilo Krummrich 220*4d032779SDanilo Krummrich /// The [`Normal`] context is the context of a bus specific device when it is not an argument of 221*4d032779SDanilo Krummrich /// any bus callback. 222*4d032779SDanilo Krummrich pub struct Normal; 223*4d032779SDanilo Krummrich 224*4d032779SDanilo Krummrich /// The [`Core`] context is the context of a bus specific device when it is supplied as argument of 225*4d032779SDanilo Krummrich /// any of the bus callbacks, such as `probe()`. 226*4d032779SDanilo Krummrich pub struct Core; 227*4d032779SDanilo Krummrich 228*4d032779SDanilo Krummrich mod private { 229*4d032779SDanilo Krummrich pub trait Sealed {} 230*4d032779SDanilo Krummrich 231*4d032779SDanilo Krummrich impl Sealed for super::Core {} 232*4d032779SDanilo Krummrich impl Sealed for super::Normal {} 233*4d032779SDanilo Krummrich } 234*4d032779SDanilo Krummrich 235*4d032779SDanilo Krummrich impl DeviceContext for Core {} 236*4d032779SDanilo Krummrich impl DeviceContext for Normal {} 237*4d032779SDanilo Krummrich 2385c7ca6faSWedson Almeida Filho #[doc(hidden)] 2395c7ca6faSWedson Almeida Filho #[macro_export] 2405c7ca6faSWedson Almeida Filho macro_rules! dev_printk { 2415c7ca6faSWedson Almeida Filho ($method:ident, $dev:expr, $($f:tt)*) => { 2425c7ca6faSWedson Almeida Filho { 2435c7ca6faSWedson Almeida Filho ($dev).$method(core::format_args!($($f)*)); 2445c7ca6faSWedson Almeida Filho } 2455c7ca6faSWedson Almeida Filho } 2465c7ca6faSWedson Almeida Filho } 2475c7ca6faSWedson Almeida Filho 2485c7ca6faSWedson Almeida Filho /// Prints an emergency-level message (level 0) prefixed with device information. 2495c7ca6faSWedson Almeida Filho /// 2505c7ca6faSWedson Almeida Filho /// This level should be used if the system is unusable. 2515c7ca6faSWedson Almeida Filho /// 2525c7ca6faSWedson Almeida Filho /// Equivalent to the kernel's `dev_emerg` macro. 2535c7ca6faSWedson Almeida Filho /// 2545c7ca6faSWedson Almeida Filho /// Mimics the interface of [`std::print!`]. More information about the syntax is available from 2555c7ca6faSWedson Almeida Filho /// [`core::fmt`] and `alloc::format!`. 2565c7ca6faSWedson Almeida Filho /// 2575c7ca6faSWedson Almeida Filho /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html 2585c7ca6faSWedson Almeida Filho /// 2595c7ca6faSWedson Almeida Filho /// # Examples 2605c7ca6faSWedson Almeida Filho /// 2615c7ca6faSWedson Almeida Filho /// ``` 2625c7ca6faSWedson Almeida Filho /// # use kernel::device::Device; 2635c7ca6faSWedson Almeida Filho /// 2645c7ca6faSWedson Almeida Filho /// fn example(dev: &Device) { 2655c7ca6faSWedson Almeida Filho /// dev_emerg!(dev, "hello {}\n", "there"); 2665c7ca6faSWedson Almeida Filho /// } 2675c7ca6faSWedson Almeida Filho /// ``` 2685c7ca6faSWedson Almeida Filho #[macro_export] 2695c7ca6faSWedson Almeida Filho macro_rules! dev_emerg { 2705c7ca6faSWedson Almeida Filho ($($f:tt)*) => { $crate::dev_printk!(pr_emerg, $($f)*); } 2715c7ca6faSWedson Almeida Filho } 2725c7ca6faSWedson Almeida Filho 2735c7ca6faSWedson Almeida Filho /// Prints an alert-level message (level 1) prefixed with device information. 2745c7ca6faSWedson Almeida Filho /// 2755c7ca6faSWedson Almeida Filho /// This level should be used if action must be taken immediately. 2765c7ca6faSWedson Almeida Filho /// 2775c7ca6faSWedson Almeida Filho /// Equivalent to the kernel's `dev_alert` macro. 2785c7ca6faSWedson Almeida Filho /// 2795c7ca6faSWedson Almeida Filho /// Mimics the interface of [`std::print!`]. More information about the syntax is available from 2805c7ca6faSWedson Almeida Filho /// [`core::fmt`] and `alloc::format!`. 2815c7ca6faSWedson Almeida Filho /// 2825c7ca6faSWedson Almeida Filho /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html 2835c7ca6faSWedson Almeida Filho /// 2845c7ca6faSWedson Almeida Filho /// # Examples 2855c7ca6faSWedson Almeida Filho /// 2865c7ca6faSWedson Almeida Filho /// ``` 2875c7ca6faSWedson Almeida Filho /// # use kernel::device::Device; 2885c7ca6faSWedson Almeida Filho /// 2895c7ca6faSWedson Almeida Filho /// fn example(dev: &Device) { 2905c7ca6faSWedson Almeida Filho /// dev_alert!(dev, "hello {}\n", "there"); 2915c7ca6faSWedson Almeida Filho /// } 2925c7ca6faSWedson Almeida Filho /// ``` 2935c7ca6faSWedson Almeida Filho #[macro_export] 2945c7ca6faSWedson Almeida Filho macro_rules! dev_alert { 2955c7ca6faSWedson Almeida Filho ($($f:tt)*) => { $crate::dev_printk!(pr_alert, $($f)*); } 2965c7ca6faSWedson Almeida Filho } 2975c7ca6faSWedson Almeida Filho 2985c7ca6faSWedson Almeida Filho /// Prints a critical-level message (level 2) prefixed with device information. 2995c7ca6faSWedson Almeida Filho /// 3005c7ca6faSWedson Almeida Filho /// This level should be used in critical conditions. 3015c7ca6faSWedson Almeida Filho /// 3025c7ca6faSWedson Almeida Filho /// Equivalent to the kernel's `dev_crit` macro. 3035c7ca6faSWedson Almeida Filho /// 3045c7ca6faSWedson Almeida Filho /// Mimics the interface of [`std::print!`]. More information about the syntax is available from 3055c7ca6faSWedson Almeida Filho /// [`core::fmt`] and `alloc::format!`. 3065c7ca6faSWedson Almeida Filho /// 3075c7ca6faSWedson Almeida Filho /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html 3085c7ca6faSWedson Almeida Filho /// 3095c7ca6faSWedson Almeida Filho /// # Examples 3105c7ca6faSWedson Almeida Filho /// 3115c7ca6faSWedson Almeida Filho /// ``` 3125c7ca6faSWedson Almeida Filho /// # use kernel::device::Device; 3135c7ca6faSWedson Almeida Filho /// 3145c7ca6faSWedson Almeida Filho /// fn example(dev: &Device) { 3155c7ca6faSWedson Almeida Filho /// dev_crit!(dev, "hello {}\n", "there"); 3165c7ca6faSWedson Almeida Filho /// } 3175c7ca6faSWedson Almeida Filho /// ``` 3185c7ca6faSWedson Almeida Filho #[macro_export] 3195c7ca6faSWedson Almeida Filho macro_rules! dev_crit { 3205c7ca6faSWedson Almeida Filho ($($f:tt)*) => { $crate::dev_printk!(pr_crit, $($f)*); } 3215c7ca6faSWedson Almeida Filho } 3225c7ca6faSWedson Almeida Filho 3235c7ca6faSWedson Almeida Filho /// Prints an error-level message (level 3) prefixed with device information. 3245c7ca6faSWedson Almeida Filho /// 3255c7ca6faSWedson Almeida Filho /// This level should be used in error conditions. 3265c7ca6faSWedson Almeida Filho /// 3275c7ca6faSWedson Almeida Filho /// Equivalent to the kernel's `dev_err` macro. 3285c7ca6faSWedson Almeida Filho /// 3295c7ca6faSWedson Almeida Filho /// Mimics the interface of [`std::print!`]. More information about the syntax is available from 3305c7ca6faSWedson Almeida Filho /// [`core::fmt`] and `alloc::format!`. 3315c7ca6faSWedson Almeida Filho /// 3325c7ca6faSWedson Almeida Filho /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html 3335c7ca6faSWedson Almeida Filho /// 3345c7ca6faSWedson Almeida Filho /// # Examples 3355c7ca6faSWedson Almeida Filho /// 3365c7ca6faSWedson Almeida Filho /// ``` 3375c7ca6faSWedson Almeida Filho /// # use kernel::device::Device; 3385c7ca6faSWedson Almeida Filho /// 3395c7ca6faSWedson Almeida Filho /// fn example(dev: &Device) { 3405c7ca6faSWedson Almeida Filho /// dev_err!(dev, "hello {}\n", "there"); 3415c7ca6faSWedson Almeida Filho /// } 3425c7ca6faSWedson Almeida Filho /// ``` 3435c7ca6faSWedson Almeida Filho #[macro_export] 3445c7ca6faSWedson Almeida Filho macro_rules! dev_err { 3455c7ca6faSWedson Almeida Filho ($($f:tt)*) => { $crate::dev_printk!(pr_err, $($f)*); } 3465c7ca6faSWedson Almeida Filho } 3475c7ca6faSWedson Almeida Filho 3485c7ca6faSWedson Almeida Filho /// Prints a warning-level message (level 4) prefixed with device information. 3495c7ca6faSWedson Almeida Filho /// 3505c7ca6faSWedson Almeida Filho /// This level should be used in warning conditions. 3515c7ca6faSWedson Almeida Filho /// 3525c7ca6faSWedson Almeida Filho /// Equivalent to the kernel's `dev_warn` macro. 3535c7ca6faSWedson Almeida Filho /// 3545c7ca6faSWedson Almeida Filho /// Mimics the interface of [`std::print!`]. More information about the syntax is available from 3555c7ca6faSWedson Almeida Filho /// [`core::fmt`] and `alloc::format!`. 3565c7ca6faSWedson Almeida Filho /// 3575c7ca6faSWedson Almeida Filho /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html 3585c7ca6faSWedson Almeida Filho /// 3595c7ca6faSWedson Almeida Filho /// # Examples 3605c7ca6faSWedson Almeida Filho /// 3615c7ca6faSWedson Almeida Filho /// ``` 3625c7ca6faSWedson Almeida Filho /// # use kernel::device::Device; 3635c7ca6faSWedson Almeida Filho /// 3645c7ca6faSWedson Almeida Filho /// fn example(dev: &Device) { 3655c7ca6faSWedson Almeida Filho /// dev_warn!(dev, "hello {}\n", "there"); 3665c7ca6faSWedson Almeida Filho /// } 3675c7ca6faSWedson Almeida Filho /// ``` 3685c7ca6faSWedson Almeida Filho #[macro_export] 3695c7ca6faSWedson Almeida Filho macro_rules! dev_warn { 3705c7ca6faSWedson Almeida Filho ($($f:tt)*) => { $crate::dev_printk!(pr_warn, $($f)*); } 3715c7ca6faSWedson Almeida Filho } 3725c7ca6faSWedson Almeida Filho 3735c7ca6faSWedson Almeida Filho /// Prints a notice-level message (level 5) prefixed with device information. 3745c7ca6faSWedson Almeida Filho /// 3755c7ca6faSWedson Almeida Filho /// This level should be used in normal but significant conditions. 3765c7ca6faSWedson Almeida Filho /// 3775c7ca6faSWedson Almeida Filho /// Equivalent to the kernel's `dev_notice` macro. 3785c7ca6faSWedson Almeida Filho /// 3795c7ca6faSWedson Almeida Filho /// Mimics the interface of [`std::print!`]. More information about the syntax is available from 3805c7ca6faSWedson Almeida Filho /// [`core::fmt`] and `alloc::format!`. 3815c7ca6faSWedson Almeida Filho /// 3825c7ca6faSWedson Almeida Filho /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html 3835c7ca6faSWedson Almeida Filho /// 3845c7ca6faSWedson Almeida Filho /// # Examples 3855c7ca6faSWedson Almeida Filho /// 3865c7ca6faSWedson Almeida Filho /// ``` 3875c7ca6faSWedson Almeida Filho /// # use kernel::device::Device; 3885c7ca6faSWedson Almeida Filho /// 3895c7ca6faSWedson Almeida Filho /// fn example(dev: &Device) { 3905c7ca6faSWedson Almeida Filho /// dev_notice!(dev, "hello {}\n", "there"); 3915c7ca6faSWedson Almeida Filho /// } 3925c7ca6faSWedson Almeida Filho /// ``` 3935c7ca6faSWedson Almeida Filho #[macro_export] 3945c7ca6faSWedson Almeida Filho macro_rules! dev_notice { 3955c7ca6faSWedson Almeida Filho ($($f:tt)*) => { $crate::dev_printk!(pr_notice, $($f)*); } 3965c7ca6faSWedson Almeida Filho } 3975c7ca6faSWedson Almeida Filho 3985c7ca6faSWedson Almeida Filho /// Prints an info-level message (level 6) prefixed with device information. 3995c7ca6faSWedson Almeida Filho /// 4005c7ca6faSWedson Almeida Filho /// This level should be used for informational messages. 4015c7ca6faSWedson Almeida Filho /// 4025c7ca6faSWedson Almeida Filho /// Equivalent to the kernel's `dev_info` macro. 4035c7ca6faSWedson Almeida Filho /// 4045c7ca6faSWedson Almeida Filho /// Mimics the interface of [`std::print!`]. More information about the syntax is available from 4055c7ca6faSWedson Almeida Filho /// [`core::fmt`] and `alloc::format!`. 4065c7ca6faSWedson Almeida Filho /// 4075c7ca6faSWedson Almeida Filho /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html 4085c7ca6faSWedson Almeida Filho /// 4095c7ca6faSWedson Almeida Filho /// # Examples 4105c7ca6faSWedson Almeida Filho /// 4115c7ca6faSWedson Almeida Filho /// ``` 4125c7ca6faSWedson Almeida Filho /// # use kernel::device::Device; 4135c7ca6faSWedson Almeida Filho /// 4145c7ca6faSWedson Almeida Filho /// fn example(dev: &Device) { 4155c7ca6faSWedson Almeida Filho /// dev_info!(dev, "hello {}\n", "there"); 4165c7ca6faSWedson Almeida Filho /// } 4175c7ca6faSWedson Almeida Filho /// ``` 4185c7ca6faSWedson Almeida Filho #[macro_export] 4195c7ca6faSWedson Almeida Filho macro_rules! dev_info { 4205c7ca6faSWedson Almeida Filho ($($f:tt)*) => { $crate::dev_printk!(pr_info, $($f)*); } 4215c7ca6faSWedson Almeida Filho } 4225c7ca6faSWedson Almeida Filho 4235c7ca6faSWedson Almeida Filho /// Prints a debug-level message (level 7) prefixed with device information. 4245c7ca6faSWedson Almeida Filho /// 4255c7ca6faSWedson Almeida Filho /// This level should be used for debug messages. 4265c7ca6faSWedson Almeida Filho /// 4275c7ca6faSWedson Almeida Filho /// Equivalent to the kernel's `dev_dbg` macro, except that it doesn't support dynamic debug yet. 4285c7ca6faSWedson Almeida Filho /// 4295c7ca6faSWedson Almeida Filho /// Mimics the interface of [`std::print!`]. More information about the syntax is available from 4305c7ca6faSWedson Almeida Filho /// [`core::fmt`] and `alloc::format!`. 4315c7ca6faSWedson Almeida Filho /// 4325c7ca6faSWedson Almeida Filho /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html 4335c7ca6faSWedson Almeida Filho /// 4345c7ca6faSWedson Almeida Filho /// # Examples 4355c7ca6faSWedson Almeida Filho /// 4365c7ca6faSWedson Almeida Filho /// ``` 4375c7ca6faSWedson Almeida Filho /// # use kernel::device::Device; 4385c7ca6faSWedson Almeida Filho /// 4395c7ca6faSWedson Almeida Filho /// fn example(dev: &Device) { 4405c7ca6faSWedson Almeida Filho /// dev_dbg!(dev, "hello {}\n", "there"); 4415c7ca6faSWedson Almeida Filho /// } 4425c7ca6faSWedson Almeida Filho /// ``` 4435c7ca6faSWedson Almeida Filho #[macro_export] 4445c7ca6faSWedson Almeida Filho macro_rules! dev_dbg { 4455c7ca6faSWedson Almeida Filho ($($f:tt)*) => { $crate::dev_printk!(pr_dbg, $($f)*); } 4465c7ca6faSWedson Almeida Filho } 447