@@ -8,7 +8,10 @@ use crate::{
88 bindings,
99 types:: { ARef , Opaque } ,
1010} ;
11- use core:: ptr;
11+ use core:: { fmt, ptr} ;
12+
13+ #[ cfg( CONFIG_PRINTK ) ]
14+ use crate :: c_str;
1215
1316/// A reference-counted device.
1417///
@@ -82,6 +85,110 @@ impl Device {
8285 // SAFETY: Guaranteed by the safety requirements of the function.
8386 unsafe { & * ptr. cast ( ) }
8487 }
88+
89+ /// Prints an emergency-level message (level 0) prefixed with device information.
90+ ///
91+ /// More details are available from [`dev_emerg`].
92+ ///
93+ /// [`dev_emerg`]: crate::dev_emerg
94+ pub fn pr_emerg ( & self , args : fmt:: Arguments < ' _ > ) {
95+ // SAFETY: `klevel` is null-terminated, uses one of the kernel constants.
96+ unsafe { self . printk ( bindings:: KERN_EMERG , args) } ;
97+ }
98+
99+ /// Prints an alert-level message (level 1) prefixed with device information.
100+ ///
101+ /// More details are available from [`dev_alert`].
102+ ///
103+ /// [`dev_alert`]: crate::dev_alert
104+ pub fn pr_alert ( & self , args : fmt:: Arguments < ' _ > ) {
105+ // SAFETY: `klevel` is null-terminated, uses one of the kernel constants.
106+ unsafe { self . printk ( bindings:: KERN_ALERT , args) } ;
107+ }
108+
109+ /// Prints a critical-level message (level 2) prefixed with device information.
110+ ///
111+ /// More details are available from [`dev_crit`].
112+ ///
113+ /// [`dev_crit`]: crate::dev_crit
114+ pub fn pr_crit ( & self , args : fmt:: Arguments < ' _ > ) {
115+ // SAFETY: `klevel` is null-terminated, uses one of the kernel constants.
116+ unsafe { self . printk ( bindings:: KERN_CRIT , args) } ;
117+ }
118+
119+ /// Prints an error-level message (level 3) prefixed with device information.
120+ ///
121+ /// More details are available from [`dev_err`].
122+ ///
123+ /// [`dev_err`]: crate::dev_err
124+ pub fn pr_err ( & self , args : fmt:: Arguments < ' _ > ) {
125+ // SAFETY: `klevel` is null-terminated, uses one of the kernel constants.
126+ unsafe { self . printk ( bindings:: KERN_ERR , args) } ;
127+ }
128+
129+ /// Prints a warning-level message (level 4) prefixed with device information.
130+ ///
131+ /// More details are available from [`dev_warn`].
132+ ///
133+ /// [`dev_warn`]: crate::dev_warn
134+ pub fn pr_warn ( & self , args : fmt:: Arguments < ' _ > ) {
135+ // SAFETY: `klevel` is null-terminated, uses one of the kernel constants.
136+ unsafe { self . printk ( bindings:: KERN_WARNING , args) } ;
137+ }
138+
139+ /// Prints a notice-level message (level 5) prefixed with device information.
140+ ///
141+ /// More details are available from [`dev_notice`].
142+ ///
143+ /// [`dev_notice`]: crate::dev_notice
144+ pub fn pr_notice ( & self , args : fmt:: Arguments < ' _ > ) {
145+ // SAFETY: `klevel` is null-terminated, uses one of the kernel constants.
146+ unsafe { self . printk ( bindings:: KERN_NOTICE , args) } ;
147+ }
148+
149+ /// Prints an info-level message (level 6) prefixed with device information.
150+ ///
151+ /// More details are available from [`dev_info`].
152+ ///
153+ /// [`dev_info`]: crate::dev_info
154+ pub fn pr_info ( & self , args : fmt:: Arguments < ' _ > ) {
155+ // SAFETY: `klevel` is null-terminated, uses one of the kernel constants.
156+ unsafe { self . printk ( bindings:: KERN_INFO , args) } ;
157+ }
158+
159+ /// Prints a debug-level message (level 7) prefixed with device information.
160+ ///
161+ /// More details are available from [`dev_dbg`].
162+ ///
163+ /// [`dev_dbg`]: crate::dev_dbg
164+ pub fn pr_dbg ( & self , args : fmt:: Arguments < ' _ > ) {
165+ if cfg ! ( debug_assertions) {
166+ // SAFETY: `klevel` is null-terminated, uses one of the kernel constants.
167+ unsafe { self . printk ( bindings:: KERN_DEBUG , args) } ;
168+ }
169+ }
170+
171+ /// Prints the provided message to the console.
172+ ///
173+ /// # Safety
174+ ///
175+ /// Callers must ensure that `klevel` is null-terminated; in particular, one of the
176+ /// `KERN_*`constants, for example, `KERN_CRIT`, `KERN_ALERT`, etc.
177+ #[ cfg_attr( not( CONFIG_PRINTK ) , allow( unused_variables) ) ]
178+ unsafe fn printk ( & self , klevel : & [ u8 ] , msg : fmt:: Arguments < ' _ > ) {
179+ // SAFETY: `klevel` is null-terminated and one of the kernel constants. `self.as_raw`
180+ // is valid because `self` is valid. The "%pA" format string expects a pointer to
181+ // `fmt::Arguments`, which is what we're passing as the last argument.
182+ #[ cfg( CONFIG_PRINTK ) ]
183+ unsafe {
184+ bindings:: _dev_printk (
185+ klevel as * const _ as * const core:: ffi:: c_char ,
186+ self . as_raw ( ) ,
187+ c_str ! ( "%pA" ) . as_char_ptr ( ) ,
188+ & msg as * const _ as * const core:: ffi:: c_void ,
189+ )
190+ } ;
191+ }
85192}
86193
87194// SAFETY: Instances of `Device` are always reference-counted.
@@ -103,3 +210,213 @@ unsafe impl Send for Device {}
103210// SAFETY: `Device` can be shared among threads because all immutable methods are protected by the
104211// synchronization in `struct device`.
105212unsafe impl Sync for Device { }
213+
214+ #[ doc( hidden) ]
215+ #[ macro_export]
216+ macro_rules! dev_printk {
217+ ( $method: ident, $dev: expr, $( $f: tt) * ) => {
218+ {
219+ ( $dev) . $method( core:: format_args!( $( $f) * ) ) ;
220+ }
221+ }
222+ }
223+
224+ /// Prints an emergency-level message (level 0) prefixed with device information.
225+ ///
226+ /// This level should be used if the system is unusable.
227+ ///
228+ /// Equivalent to the kernel's `dev_emerg` macro.
229+ ///
230+ /// Mimics the interface of [`std::print!`]. More information about the syntax is available from
231+ /// [`core::fmt`] and [`alloc::format!`].
232+ ///
233+ /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html
234+ ///
235+ /// # Examples
236+ ///
237+ /// ```
238+ /// # use kernel::device::Device;
239+ ///
240+ /// fn example(dev: &Device) {
241+ /// dev_emerg!(dev, "hello {}\n", "there");
242+ /// }
243+ /// ```
244+ #[ macro_export]
245+ macro_rules! dev_emerg {
246+ ( $( $f: tt) * ) => { $crate:: dev_printk!( pr_emerg, $( $f) * ) ; }
247+ }
248+
249+ /// Prints an alert-level message (level 1) prefixed with device information.
250+ ///
251+ /// This level should be used if action must be taken immediately.
252+ ///
253+ /// Equivalent to the kernel's `dev_alert` macro.
254+ ///
255+ /// Mimics the interface of [`std::print!`]. More information about the syntax is available from
256+ /// [`core::fmt`] and [`alloc::format!`].
257+ ///
258+ /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html
259+ ///
260+ /// # Examples
261+ ///
262+ /// ```
263+ /// # use kernel::device::Device;
264+ ///
265+ /// fn example(dev: &Device) {
266+ /// dev_alert!(dev, "hello {}\n", "there");
267+ /// }
268+ /// ```
269+ #[ macro_export]
270+ macro_rules! dev_alert {
271+ ( $( $f: tt) * ) => { $crate:: dev_printk!( pr_alert, $( $f) * ) ; }
272+ }
273+
274+ /// Prints a critical-level message (level 2) prefixed with device information.
275+ ///
276+ /// This level should be used in critical conditions.
277+ ///
278+ /// Equivalent to the kernel's `dev_crit` macro.
279+ ///
280+ /// Mimics the interface of [`std::print!`]. More information about the syntax is available from
281+ /// [`core::fmt`] and [`alloc::format!`].
282+ ///
283+ /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html
284+ ///
285+ /// # Examples
286+ ///
287+ /// ```
288+ /// # use kernel::device::Device;
289+ ///
290+ /// fn example(dev: &Device) {
291+ /// dev_crit!(dev, "hello {}\n", "there");
292+ /// }
293+ /// ```
294+ #[ macro_export]
295+ macro_rules! dev_crit {
296+ ( $( $f: tt) * ) => { $crate:: dev_printk!( pr_crit, $( $f) * ) ; }
297+ }
298+
299+ /// Prints an error-level message (level 3) prefixed with device information.
300+ ///
301+ /// This level should be used in error conditions.
302+ ///
303+ /// Equivalent to the kernel's `dev_err` macro.
304+ ///
305+ /// Mimics the interface of [`std::print!`]. More information about the syntax is available from
306+ /// [`core::fmt`] and [`alloc::format!`].
307+ ///
308+ /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html
309+ ///
310+ /// # Examples
311+ ///
312+ /// ```
313+ /// # use kernel::device::Device;
314+ ///
315+ /// fn example(dev: &Device) {
316+ /// dev_err!(dev, "hello {}\n", "there");
317+ /// }
318+ /// ```
319+ #[ macro_export]
320+ macro_rules! dev_err {
321+ ( $( $f: tt) * ) => { $crate:: dev_printk!( pr_err, $( $f) * ) ; }
322+ }
323+
324+ /// Prints a warning-level message (level 4) prefixed with device information.
325+ ///
326+ /// This level should be used in warning conditions.
327+ ///
328+ /// Equivalent to the kernel's `dev_warn` macro.
329+ ///
330+ /// Mimics the interface of [`std::print!`]. More information about the syntax is available from
331+ /// [`core::fmt`] and [`alloc::format!`].
332+ ///
333+ /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html
334+ ///
335+ /// # Examples
336+ ///
337+ /// ```
338+ /// # use kernel::device::Device;
339+ ///
340+ /// fn example(dev: &Device) {
341+ /// dev_warn!(dev, "hello {}\n", "there");
342+ /// }
343+ /// ```
344+ #[ macro_export]
345+ macro_rules! dev_warn {
346+ ( $( $f: tt) * ) => { $crate:: dev_printk!( pr_warn, $( $f) * ) ; }
347+ }
348+
349+ /// Prints a notice-level message (level 5) prefixed with device information.
350+ ///
351+ /// This level should be used in normal but significant conditions.
352+ ///
353+ /// Equivalent to the kernel's `dev_notice` macro.
354+ ///
355+ /// Mimics the interface of [`std::print!`]. More information about the syntax is available from
356+ /// [`core::fmt`] and [`alloc::format!`].
357+ ///
358+ /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html
359+ ///
360+ /// # Examples
361+ ///
362+ /// ```
363+ /// # use kernel::device::Device;
364+ ///
365+ /// fn example(dev: &Device) {
366+ /// dev_notice!(dev, "hello {}\n", "there");
367+ /// }
368+ /// ```
369+ #[ macro_export]
370+ macro_rules! dev_notice {
371+ ( $( $f: tt) * ) => { $crate:: dev_printk!( pr_notice, $( $f) * ) ; }
372+ }
373+
374+ /// Prints an info-level message (level 6) prefixed with device information.
375+ ///
376+ /// This level should be used for informational messages.
377+ ///
378+ /// Equivalent to the kernel's `dev_info` macro.
379+ ///
380+ /// Mimics the interface of [`std::print!`]. More information about the syntax is available from
381+ /// [`core::fmt`] and [`alloc::format!`].
382+ ///
383+ /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html
384+ ///
385+ /// # Examples
386+ ///
387+ /// ```
388+ /// # use kernel::device::Device;
389+ ///
390+ /// fn example(dev: &Device) {
391+ /// dev_info!(dev, "hello {}\n", "there");
392+ /// }
393+ /// ```
394+ #[ macro_export]
395+ macro_rules! dev_info {
396+ ( $( $f: tt) * ) => { $crate:: dev_printk!( pr_info, $( $f) * ) ; }
397+ }
398+
399+ /// Prints a debug-level message (level 7) prefixed with device information.
400+ ///
401+ /// This level should be used for debug messages.
402+ ///
403+ /// Equivalent to the kernel's `dev_dbg` macro, except that it doesn't support dynamic debug yet.
404+ ///
405+ /// Mimics the interface of [`std::print!`]. More information about the syntax is available from
406+ /// [`core::fmt`] and [`alloc::format!`].
407+ ///
408+ /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html
409+ ///
410+ /// # Examples
411+ ///
412+ /// ```
413+ /// # use kernel::device::Device;
414+ ///
415+ /// fn example(dev: &Device) {
416+ /// dev_dbg!(dev, "hello {}\n", "there");
417+ /// }
418+ /// ```
419+ #[ macro_export]
420+ macro_rules! dev_dbg {
421+ ( $( $f: tt) * ) => { $crate:: dev_printk!( pr_dbg, $( $f) * ) ; }
422+ }
0 commit comments