88use crate :: { clk:: Clk , error:: from_kernel_err_ptr} ;
99
1010use crate :: {
11- bindings,
11+ bindings, c_str , c_types ,
1212 revocable:: { Revocable , RevocableGuard } ,
1313 str:: CStr ,
1414 sync:: { NeedsLockClass , RevocableMutex , RevocableMutexGuard , UniqueRef } ,
1515 Result ,
1616} ;
1717use core:: {
18+ fmt,
1819 ops:: { Deref , DerefMut } ,
1920 pin:: Pin ,
2021} ;
@@ -64,6 +65,92 @@ pub unsafe trait RawDevice {
6465 // SAFETY: clock is initialized with valid pointer returned from `bindings::clk_get` call.
6566 unsafe { Ok ( Clk :: new ( clk_ptr) ) }
6667 }
68+
69+ /// Prints an emergency-level message (level 0) prefixed with device information.
70+ ///
71+ /// More details are available from [`dev_emerg`].
72+ fn pr_emerg ( & self , args : fmt:: Arguments < ' _ > ) {
73+ // SAFETY: `klevel` is null-terminated, uses one of the kernel constants.
74+ unsafe { self . printk ( bindings:: KERN_EMERG , args) } ;
75+ }
76+
77+ /// Prints an alert-level message (level 1) prefixed with device information.
78+ ///
79+ /// More details are available from [`dev_alert`].
80+ fn pr_alert ( & self , args : fmt:: Arguments < ' _ > ) {
81+ // SAFETY: `klevel` is null-terminated, uses one of the kernel constants.
82+ unsafe { self . printk ( bindings:: KERN_ALERT , args) } ;
83+ }
84+
85+ /// Prints a critical-level message (level 2) prefixed with device information.
86+ ///
87+ /// More details are available from [`dev_crit`].
88+ fn pr_crit ( & self , args : fmt:: Arguments < ' _ > ) {
89+ // SAFETY: `klevel` is null-terminated, uses one of the kernel constants.
90+ unsafe { self . printk ( bindings:: KERN_CRIT , args) } ;
91+ }
92+
93+ /// Prints an error-level message (level 3) prefixed with device information.
94+ ///
95+ /// More details are available from [`dev_err`].
96+ fn pr_err ( & self , args : fmt:: Arguments < ' _ > ) {
97+ // SAFETY: `klevel` is null-terminated, uses one of the kernel constants.
98+ unsafe { self . printk ( bindings:: KERN_ERR , args) } ;
99+ }
100+
101+ /// Prints a warning-level message (level 4) prefixed with device information.
102+ ///
103+ /// More details are available from [`dev_warn`].
104+ fn pr_warn ( & self , args : fmt:: Arguments < ' _ > ) {
105+ // SAFETY: `klevel` is null-terminated, uses one of the kernel constants.
106+ unsafe { self . printk ( bindings:: KERN_WARNING , args) } ;
107+ }
108+
109+ /// Prints a notice-level message (level 5) prefixed with device information.
110+ ///
111+ /// More details are available from [`dev_notice`].
112+ fn pr_notice ( & self , args : fmt:: Arguments < ' _ > ) {
113+ // SAFETY: `klevel` is null-terminated, uses one of the kernel constants.
114+ unsafe { self . printk ( bindings:: KERN_NOTICE , args) } ;
115+ }
116+
117+ /// Prints an info-level message (level 6) prefixed with device information.
118+ ///
119+ /// More details are available from [`dev_info`].
120+ fn pr_info ( & self , args : fmt:: Arguments < ' _ > ) {
121+ // SAFETY: `klevel` is null-terminated, uses one of the kernel constants.
122+ unsafe { self . printk ( bindings:: KERN_INFO , args) } ;
123+ }
124+
125+ /// Prints a debug-level message (level 7) prefixed with device information.
126+ ///
127+ /// More details are available from [`dev_dbg`].
128+ fn pr_dbg ( & self , args : fmt:: Arguments < ' _ > ) {
129+ if cfg ! ( debug_assertions) {
130+ // SAFETY: `klevel` is null-terminated, uses one of the kernel constants.
131+ unsafe { self . printk ( bindings:: KERN_DEBUG , args) } ;
132+ }
133+ }
134+
135+ /// Prints the provided message to the console.
136+ ///
137+ /// # Safety
138+ ///
139+ /// Callers must ensure that `klevel` is null-terminated; in particular, one of the
140+ /// `KERN_*`constants, for example, `KERN_CRIT`, `KERN_ALERT`, etc.
141+ unsafe fn printk ( & self , klevel : & [ u8 ] , msg : fmt:: Arguments < ' _ > ) {
142+ // SAFETY: `klevel` is null-terminated and one of the kernel constants. `self.raw_device`
143+ // is valid because `self` is valid. The "%pA" format string expects a pointer to
144+ // `fmt::Arguments`, which is what we're passing as the last argument.
145+ unsafe {
146+ bindings:: _dev_printk (
147+ klevel as * const _ as * const c_types:: c_char ,
148+ self . raw_device ( ) ,
149+ c_str ! ( "%pA" ) . as_char_ptr ( ) ,
150+ & msg as * const _ as * const c_types:: c_void ,
151+ )
152+ } ;
153+ }
67154}
68155
69156/// A ref-counted device.
@@ -76,6 +163,13 @@ pub struct Device {
76163 pub ( crate ) ptr : * mut bindings:: device ,
77164}
78165
166+ // SAFETY: `Device` only holds a pointer to a C device, which is safe to be used from any thread.
167+ unsafe impl Send for Device { }
168+
169+ // SAFETY: `Device` only holds a pointer to a C device, references to which are safe to be used
170+ // from any thread.
171+ unsafe impl Sync for Device { }
172+
79173impl Device {
80174 /// Creates a new device instance.
81175 ///
@@ -98,6 +192,13 @@ impl Device {
98192 }
99193}
100194
195+ // SAFETY: The device returned by `raw_device` is the one for which we hold a reference.
196+ unsafe impl RawDevice for Device {
197+ fn raw_device ( & self ) -> * mut bindings:: device {
198+ self . ptr
199+ }
200+ }
201+
101202impl Drop for Device {
102203 fn drop ( & mut self ) {
103204 // SAFETY: By the type invariants, we know that `self` owns a reference, so it is safe to
@@ -225,3 +326,224 @@ impl<T, U, V> DerefMut for Data<T, U, V> {
225326 & mut self . general
226327 }
227328}
329+
330+ #[ doc( hidden) ]
331+ #[ macro_export]
332+ macro_rules! dev_printk {
333+ ( $method: ident, $dev: expr, $( $f: tt) * ) => {
334+ {
335+ // We have an explicity `use` statement here so that callers of this macro are not
336+ // required to explicitly use the `RawDevice` trait to use its functions.
337+ use $crate:: device:: RawDevice ;
338+ ( $dev) . $method( core:: format_args!( $( $f) * ) ) ;
339+ }
340+ }
341+ }
342+
343+ /// Prints an emergency-level message (level 0) prefixed with device information.
344+ ///
345+ /// This level should be used if the system is unusable.
346+ ///
347+ /// Equivalent to the kernel's `dev_emerg` macro.
348+ ///
349+ /// Mimics the interface of [`std::print!`]. More information about the syntax is available from
350+ /// [`core::fmt`] and [`alloc::format!`].
351+ ///
352+ /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html
353+ ///
354+ /// # Examples
355+ ///
356+ /// ```
357+ /// # use kernel::prelude::*;
358+ /// # use kernel::device::Device;
359+ ///
360+ /// fn example(dev: &Device) {
361+ /// dev_emerg!(dev, "hello {}\n", "there");
362+ /// }
363+ /// ```
364+ #[ macro_export]
365+ macro_rules! dev_emerg {
366+ ( $( $f: tt) * ) => { $crate:: dev_printk!( pr_emerg, $( $f) * ) ; }
367+ }
368+
369+ /// Prints an alert-level message (level 1) prefixed with device information.
370+ ///
371+ /// This level should be used if action must be taken immediately.
372+ ///
373+ /// Equivalent to the kernel's `dev_alert` macro.
374+ ///
375+ /// Mimics the interface of [`std::print!`]. More information about the syntax is available from
376+ /// [`core::fmt`] and [`alloc::format!`].
377+ ///
378+ /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html
379+ ///
380+ /// # Examples
381+ ///
382+ /// ```
383+ /// # use kernel::prelude::*;
384+ /// # use kernel::device::Device;
385+ ///
386+ /// fn example(dev: &Device) {
387+ /// dev_alert!(dev, "hello {}\n", "there");
388+ /// }
389+ /// ```
390+ #[ macro_export]
391+ macro_rules! dev_alert {
392+ ( $( $f: tt) * ) => { $crate:: dev_printk!( pr_alert, $( $f) * ) ; }
393+ }
394+
395+ /// Prints a critical-level message (level 2) prefixed with device information.
396+ ///
397+ /// This level should be used in critical conditions.
398+ ///
399+ /// Equivalent to the kernel's `dev_crit` macro.
400+ ///
401+ /// Mimics the interface of [`std::print!`]. More information about the syntax is available from
402+ /// [`core::fmt`] and [`alloc::format!`].
403+ ///
404+ /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html
405+ ///
406+ /// # Examples
407+ ///
408+ /// ```
409+ /// # use kernel::prelude::*;
410+ /// # use kernel::device::Device;
411+ ///
412+ /// fn example(dev: &Device) {
413+ /// dev_crit!(dev, "hello {}\n", "there");
414+ /// }
415+ /// ```
416+ #[ macro_export]
417+ macro_rules! dev_crit {
418+ ( $( $f: tt) * ) => { $crate:: dev_printk!( pr_crit, $( $f) * ) ; }
419+ }
420+
421+ /// Prints an error-level message (level 3) prefixed with device information.
422+ ///
423+ /// This level should be used in error conditions.
424+ ///
425+ /// Equivalent to the kernel's `dev_err` macro.
426+ ///
427+ /// Mimics the interface of [`std::print!`]. More information about the syntax is available from
428+ /// [`core::fmt`] and [`alloc::format!`].
429+ ///
430+ /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html
431+ ///
432+ /// # Examples
433+ ///
434+ /// ```
435+ /// # use kernel::prelude::*;
436+ /// # use kernel::device::Device;
437+ ///
438+ /// fn example(dev: &Device) {
439+ /// dev_err!(dev, "hello {}\n", "there");
440+ /// }
441+ /// ```
442+ #[ macro_export]
443+ macro_rules! dev_err {
444+ ( $( $f: tt) * ) => { $crate:: dev_printk!( pr_err, $( $f) * ) ; }
445+ }
446+
447+ /// Prints a warning-level message (level 4) prefixed with device information.
448+ ///
449+ /// This level should be used in warning conditions.
450+ ///
451+ /// Equivalent to the kernel's `dev_warn` macro.
452+ ///
453+ /// Mimics the interface of [`std::print!`]. More information about the syntax is available from
454+ /// [`core::fmt`] and [`alloc::format!`].
455+ ///
456+ /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html
457+ ///
458+ /// # Examples
459+ ///
460+ /// ```
461+ /// # use kernel::prelude::*;
462+ /// # use kernel::device::Device;
463+ ///
464+ /// fn example(dev: &Device) {
465+ /// dev_warn!(dev, "hello {}\n", "there");
466+ /// }
467+ /// ```
468+ #[ macro_export]
469+ macro_rules! dev_warn {
470+ ( $( $f: tt) * ) => { $crate:: dev_printk!( pr_warn, $( $f) * ) ; }
471+ }
472+
473+ /// Prints a notice-level message (level 5) prefixed with device information.
474+ ///
475+ /// This level should be used in normal but significant conditions.
476+ ///
477+ /// Equivalent to the kernel's `dev_notice` macro.
478+ ///
479+ /// Mimics the interface of [`std::print!`]. More information about the syntax is available from
480+ /// [`core::fmt`] and [`alloc::format!`].
481+ ///
482+ /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html
483+ ///
484+ /// # Examples
485+ ///
486+ /// ```
487+ /// # use kernel::prelude::*;
488+ /// # use kernel::device::Device;
489+ ///
490+ /// fn example(dev: &Device) {
491+ /// dev_notice!(dev, "hello {}\n", "there");
492+ /// }
493+ /// ```
494+ #[ macro_export]
495+ macro_rules! dev_notice {
496+ ( $( $f: tt) * ) => { $crate:: dev_printk!( pr_notice, $( $f) * ) ; }
497+ }
498+
499+ /// Prints an info-level message (level 6) prefixed with device information.
500+ ///
501+ /// This level should be used for informational messages.
502+ ///
503+ /// Equivalent to the kernel's `dev_info` macro.
504+ ///
505+ /// Mimics the interface of [`std::print!`]. More information about the syntax is available from
506+ /// [`core::fmt`] and [`alloc::format!`].
507+ ///
508+ /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html
509+ ///
510+ /// # Examples
511+ ///
512+ /// ```
513+ /// # use kernel::prelude::*;
514+ /// # use kernel::device::Device;
515+ ///
516+ /// fn example(dev: &Device) {
517+ /// dev_info!(dev, "hello {}\n", "there");
518+ /// }
519+ /// ```
520+ #[ macro_export]
521+ macro_rules! dev_info {
522+ ( $( $f: tt) * ) => { $crate:: dev_printk!( pr_info, $( $f) * ) ; }
523+ }
524+
525+ /// Prints a debug-level message (level 7) prefixed with device information.
526+ ///
527+ /// This level should be used for debug messages.
528+ ///
529+ /// Equivalent to the kernel's `dev_dbg` macro, except that it doesn't support dynamic debug yet.
530+ ///
531+ /// Mimics the interface of [`std::print!`]. More information about the syntax is available from
532+ /// [`core::fmt`] and [`alloc::format!`].
533+ ///
534+ /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html
535+ ///
536+ /// # Examples
537+ ///
538+ /// ```
539+ /// # use kernel::prelude::*;
540+ /// # use kernel::device::Device;
541+ ///
542+ /// fn example(dev: &Device) {
543+ /// dev_dbg!(dev, "hello {}\n", "there");
544+ /// }
545+ /// ```
546+ #[ macro_export]
547+ macro_rules! dev_dbg {
548+ ( $( $f: tt) * ) => { $crate:: dev_printk!( pr_dbg, $( $f) * ) ; }
549+ }
0 commit comments