@@ -8,7 +8,10 @@ use crate::{
8
8
bindings,
9
9
types:: { ARef , Opaque } ,
10
10
} ;
11
- use core:: ptr;
11
+ use core:: { fmt, ptr} ;
12
+
13
+ #[ cfg( CONFIG_PRINTK ) ]
14
+ use crate :: c_str;
12
15
13
16
/// A reference-counted device.
14
17
///
@@ -82,6 +85,110 @@ impl Device {
82
85
// SAFETY: Guaranteed by the safety requirements of the function.
83
86
unsafe { & * ptr. cast ( ) }
84
87
}
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
+ }
85
192
}
86
193
87
194
// SAFETY: Instances of `Device` are always reference-counted.
@@ -103,3 +210,213 @@ unsafe impl Send for Device {}
103
210
// SAFETY: `Device` can be shared among threads because all immutable methods are protected by the
104
211
// synchronization in `struct device`.
105
212
unsafe 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