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