1#![doc = "DRM RAS (Reliability, Availability, Serviceability) over Generic\nNetlink. Provides a standardized mechanism for DRM drivers to register\n\\\"nodes\\\" representing hardware/software components capable of reporting\nerror counters. Userspace tools can query the list of nodes or\nindividual error counters via the Generic Netlink interface.\n"]
2#![allow(clippy::all)]
3#![allow(unused_imports)]
4#![allow(unused_assignments)]
5#![allow(non_snake_case)]
6#![allow(unused_variables)]
7#![allow(irrefutable_let_patterns)]
8#![allow(unreachable_code)]
9#![allow(unreachable_patterns)]
10use crate::builtin::{BuiltinBitfield32, BuiltinNfgenmsg, Nlmsghdr, PushDummy};
11use crate::{
12 consts,
13 traits::{NetlinkRequest, Protocol},
14 utils::*,
15};
16pub const PROTONAME: &str = "drm-ras";
17pub const PROTONAME_CSTR: &CStr = c"drm-ras";
18#[doc = "Type of the node. Currently, only error-counter nodes are supported,\nwhich expose reliability counters for a hardware/software component.\n"]
19#[doc = "Enum - defines an integer enumeration, with values for each entry incrementing by 1, (e.g. 0, 1, 2, 3)"]
20#[derive(Debug, Clone, Copy)]
21pub enum NodeType {
22 ErrorCounter = 1,
23}
24impl NodeType {
25 pub fn from_value(value: u64) -> Option<Self> {
26 Some(match value {
27 1 => Self::ErrorCounter,
28 _ => return None,
29 })
30 }
31}
32#[derive(Clone)]
33pub enum NodeAttrs<'a> {
34 #[doc = "Unique identifier for the node. Assigned dynamically by the DRM RAS core\nupon registration.\n"]
35 NodeId(u32),
36 #[doc = "Device name chosen by the driver at registration. Can be a PCI BDF,\nUUID, or module name if unique.\n"]
37 DeviceName(&'a CStr),
38 #[doc = "Node name chosen by the driver at registration. Can be an IP block name,\nor any name that identifies the RAS node inside the device.\n"]
39 NodeName(&'a CStr),
40 #[doc = "Type of this node, identifying its function.\n\nAssociated type: [`NodeType`] (enum)"]
41 NodeType(u32),
42}
43impl<'a> IterableNodeAttrs<'a> {
44 #[doc = "Unique identifier for the node. Assigned dynamically by the DRM RAS core\nupon registration.\n"]
45 pub fn get_node_id(&self) -> Result<u32, ErrorContext> {
46 let mut iter = self.clone();
47 iter.pos = 0;
48 for attr in iter {
49 if let Ok(NodeAttrs::NodeId(val)) = attr {
50 return Ok(val);
51 }
52 }
53 Err(ErrorContext::new_missing(
54 "NodeAttrs",
55 "NodeId",
56 self.orig_loc,
57 self.buf.as_ptr() as usize,
58 ))
59 }
60 #[doc = "Device name chosen by the driver at registration. Can be a PCI BDF,\nUUID, or module name if unique.\n"]
61 pub fn get_device_name(&self) -> Result<&'a CStr, ErrorContext> {
62 let mut iter = self.clone();
63 iter.pos = 0;
64 for attr in iter {
65 if let Ok(NodeAttrs::DeviceName(val)) = attr {
66 return Ok(val);
67 }
68 }
69 Err(ErrorContext::new_missing(
70 "NodeAttrs",
71 "DeviceName",
72 self.orig_loc,
73 self.buf.as_ptr() as usize,
74 ))
75 }
76 #[doc = "Node name chosen by the driver at registration. Can be an IP block name,\nor any name that identifies the RAS node inside the device.\n"]
77 pub fn get_node_name(&self) -> Result<&'a CStr, ErrorContext> {
78 let mut iter = self.clone();
79 iter.pos = 0;
80 for attr in iter {
81 if let Ok(NodeAttrs::NodeName(val)) = attr {
82 return Ok(val);
83 }
84 }
85 Err(ErrorContext::new_missing(
86 "NodeAttrs",
87 "NodeName",
88 self.orig_loc,
89 self.buf.as_ptr() as usize,
90 ))
91 }
92 #[doc = "Type of this node, identifying its function.\n\nAssociated type: [`NodeType`] (enum)"]
93 pub fn get_node_type(&self) -> Result<u32, ErrorContext> {
94 let mut iter = self.clone();
95 iter.pos = 0;
96 for attr in iter {
97 if let Ok(NodeAttrs::NodeType(val)) = attr {
98 return Ok(val);
99 }
100 }
101 Err(ErrorContext::new_missing(
102 "NodeAttrs",
103 "NodeType",
104 self.orig_loc,
105 self.buf.as_ptr() as usize,
106 ))
107 }
108}
109impl NodeAttrs<'_> {
110 pub fn new<'a>(buf: &'a [u8]) -> IterableNodeAttrs<'a> {
111 IterableNodeAttrs::with_loc(buf, buf.as_ptr() as usize)
112 }
113 fn attr_from_type(r#type: u16) -> Option<&'static str> {
114 let res = match r#type {
115 1u16 => "NodeId",
116 2u16 => "DeviceName",
117 3u16 => "NodeName",
118 4u16 => "NodeType",
119 _ => return None,
120 };
121 Some(res)
122 }
123}
124#[derive(Clone, Copy, Default)]
125pub struct IterableNodeAttrs<'a> {
126 buf: &'a [u8],
127 pos: usize,
128 orig_loc: usize,
129}
130impl<'a> IterableNodeAttrs<'a> {
131 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
132 Self {
133 buf,
134 pos: 0,
135 orig_loc,
136 }
137 }
138 pub fn get_buf(&self) -> &'a [u8] {
139 self.buf
140 }
141}
142impl<'a> Iterator for IterableNodeAttrs<'a> {
143 type Item = Result<NodeAttrs<'a>, ErrorContext>;
144 fn next(&mut self) -> Option<Self::Item> {
145 let mut pos;
146 let mut r#type;
147 loop {
148 pos = self.pos;
149 r#type = None;
150 if self.buf.len() == self.pos {
151 return None;
152 }
153 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
154 self.pos = self.buf.len();
155 break;
156 };
157 r#type = Some(header.r#type);
158 let res = match header.r#type {
159 1u16 => NodeAttrs::NodeId({
160 let res = parse_u32(next);
161 let Some(val) = res else { break };
162 val
163 }),
164 2u16 => NodeAttrs::DeviceName({
165 let res = CStr::from_bytes_with_nul(next).ok();
166 let Some(val) = res else { break };
167 val
168 }),
169 3u16 => NodeAttrs::NodeName({
170 let res = CStr::from_bytes_with_nul(next).ok();
171 let Some(val) = res else { break };
172 val
173 }),
174 4u16 => NodeAttrs::NodeType({
175 let res = parse_u32(next);
176 let Some(val) = res else { break };
177 val
178 }),
179 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
180 n => continue,
181 };
182 return Some(Ok(res));
183 }
184 Some(Err(ErrorContext::new(
185 "NodeAttrs",
186 r#type.and_then(|t| NodeAttrs::attr_from_type(t)),
187 self.orig_loc,
188 self.buf.as_ptr().wrapping_add(pos) as usize,
189 )))
190 }
191}
192impl<'a> std::fmt::Debug for IterableNodeAttrs<'_> {
193 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
194 let mut fmt = f.debug_struct("NodeAttrs");
195 for attr in self.clone() {
196 let attr = match attr {
197 Ok(a) => a,
198 Err(err) => {
199 fmt.finish()?;
200 f.write_str("Err(")?;
201 err.fmt(f)?;
202 return f.write_str(")");
203 }
204 };
205 match attr {
206 NodeAttrs::NodeId(val) => fmt.field("NodeId", &val),
207 NodeAttrs::DeviceName(val) => fmt.field("DeviceName", &val),
208 NodeAttrs::NodeName(val) => fmt.field("NodeName", &val),
209 NodeAttrs::NodeType(val) => {
210 fmt.field("NodeType", &FormatEnum(val.into(), NodeType::from_value))
211 }
212 };
213 }
214 fmt.finish()
215 }
216}
217impl IterableNodeAttrs<'_> {
218 pub fn lookup_attr(
219 &self,
220 offset: usize,
221 missing_type: Option<u16>,
222 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
223 let mut stack = Vec::new();
224 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
225 if missing_type.is_some() && cur == offset {
226 stack.push(("NodeAttrs", offset));
227 return (
228 stack,
229 missing_type.and_then(|t| NodeAttrs::attr_from_type(t)),
230 );
231 }
232 if cur > offset || cur + self.buf.len() < offset {
233 return (stack, None);
234 }
235 let mut attrs = self.clone();
236 let mut last_off = cur + attrs.pos;
237 while let Some(attr) = attrs.next() {
238 let Ok(attr) = attr else { break };
239 match attr {
240 NodeAttrs::NodeId(val) => {
241 if last_off == offset {
242 stack.push(("NodeId", last_off));
243 break;
244 }
245 }
246 NodeAttrs::DeviceName(val) => {
247 if last_off == offset {
248 stack.push(("DeviceName", last_off));
249 break;
250 }
251 }
252 NodeAttrs::NodeName(val) => {
253 if last_off == offset {
254 stack.push(("NodeName", last_off));
255 break;
256 }
257 }
258 NodeAttrs::NodeType(val) => {
259 if last_off == offset {
260 stack.push(("NodeType", last_off));
261 break;
262 }
263 }
264 _ => {}
265 };
266 last_off = cur + attrs.pos;
267 }
268 if !stack.is_empty() {
269 stack.push(("NodeAttrs", cur));
270 }
271 (stack, None)
272 }
273}
274#[derive(Clone)]
275pub enum ErrorCounterAttrs<'a> {
276 #[doc = "Node ID targeted by this error counter operation.\n"]
277 NodeId(u32),
278 #[doc = "Unique identifier for a specific error counter within an node.\n"]
279 ErrorId(u32),
280 #[doc = "Name of the error.\n"]
281 ErrorName(&'a CStr),
282 #[doc = "Current value of the requested error counter.\n"]
283 ErrorValue(u32),
284}
285impl<'a> IterableErrorCounterAttrs<'a> {
286 #[doc = "Node ID targeted by this error counter operation.\n"]
287 pub fn get_node_id(&self) -> Result<u32, ErrorContext> {
288 let mut iter = self.clone();
289 iter.pos = 0;
290 for attr in iter {
291 if let Ok(ErrorCounterAttrs::NodeId(val)) = attr {
292 return Ok(val);
293 }
294 }
295 Err(ErrorContext::new_missing(
296 "ErrorCounterAttrs",
297 "NodeId",
298 self.orig_loc,
299 self.buf.as_ptr() as usize,
300 ))
301 }
302 #[doc = "Unique identifier for a specific error counter within an node.\n"]
303 pub fn get_error_id(&self) -> Result<u32, ErrorContext> {
304 let mut iter = self.clone();
305 iter.pos = 0;
306 for attr in iter {
307 if let Ok(ErrorCounterAttrs::ErrorId(val)) = attr {
308 return Ok(val);
309 }
310 }
311 Err(ErrorContext::new_missing(
312 "ErrorCounterAttrs",
313 "ErrorId",
314 self.orig_loc,
315 self.buf.as_ptr() as usize,
316 ))
317 }
318 #[doc = "Name of the error.\n"]
319 pub fn get_error_name(&self) -> Result<&'a CStr, ErrorContext> {
320 let mut iter = self.clone();
321 iter.pos = 0;
322 for attr in iter {
323 if let Ok(ErrorCounterAttrs::ErrorName(val)) = attr {
324 return Ok(val);
325 }
326 }
327 Err(ErrorContext::new_missing(
328 "ErrorCounterAttrs",
329 "ErrorName",
330 self.orig_loc,
331 self.buf.as_ptr() as usize,
332 ))
333 }
334 #[doc = "Current value of the requested error counter.\n"]
335 pub fn get_error_value(&self) -> Result<u32, ErrorContext> {
336 let mut iter = self.clone();
337 iter.pos = 0;
338 for attr in iter {
339 if let Ok(ErrorCounterAttrs::ErrorValue(val)) = attr {
340 return Ok(val);
341 }
342 }
343 Err(ErrorContext::new_missing(
344 "ErrorCounterAttrs",
345 "ErrorValue",
346 self.orig_loc,
347 self.buf.as_ptr() as usize,
348 ))
349 }
350}
351impl ErrorCounterAttrs<'_> {
352 pub fn new<'a>(buf: &'a [u8]) -> IterableErrorCounterAttrs<'a> {
353 IterableErrorCounterAttrs::with_loc(buf, buf.as_ptr() as usize)
354 }
355 fn attr_from_type(r#type: u16) -> Option<&'static str> {
356 let res = match r#type {
357 1u16 => "NodeId",
358 2u16 => "ErrorId",
359 3u16 => "ErrorName",
360 4u16 => "ErrorValue",
361 _ => return None,
362 };
363 Some(res)
364 }
365}
366#[derive(Clone, Copy, Default)]
367pub struct IterableErrorCounterAttrs<'a> {
368 buf: &'a [u8],
369 pos: usize,
370 orig_loc: usize,
371}
372impl<'a> IterableErrorCounterAttrs<'a> {
373 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
374 Self {
375 buf,
376 pos: 0,
377 orig_loc,
378 }
379 }
380 pub fn get_buf(&self) -> &'a [u8] {
381 self.buf
382 }
383}
384impl<'a> Iterator for IterableErrorCounterAttrs<'a> {
385 type Item = Result<ErrorCounterAttrs<'a>, ErrorContext>;
386 fn next(&mut self) -> Option<Self::Item> {
387 let mut pos;
388 let mut r#type;
389 loop {
390 pos = self.pos;
391 r#type = None;
392 if self.buf.len() == self.pos {
393 return None;
394 }
395 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
396 self.pos = self.buf.len();
397 break;
398 };
399 r#type = Some(header.r#type);
400 let res = match header.r#type {
401 1u16 => ErrorCounterAttrs::NodeId({
402 let res = parse_u32(next);
403 let Some(val) = res else { break };
404 val
405 }),
406 2u16 => ErrorCounterAttrs::ErrorId({
407 let res = parse_u32(next);
408 let Some(val) = res else { break };
409 val
410 }),
411 3u16 => ErrorCounterAttrs::ErrorName({
412 let res = CStr::from_bytes_with_nul(next).ok();
413 let Some(val) = res else { break };
414 val
415 }),
416 4u16 => ErrorCounterAttrs::ErrorValue({
417 let res = parse_u32(next);
418 let Some(val) = res else { break };
419 val
420 }),
421 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
422 n => continue,
423 };
424 return Some(Ok(res));
425 }
426 Some(Err(ErrorContext::new(
427 "ErrorCounterAttrs",
428 r#type.and_then(|t| ErrorCounterAttrs::attr_from_type(t)),
429 self.orig_loc,
430 self.buf.as_ptr().wrapping_add(pos) as usize,
431 )))
432 }
433}
434impl<'a> std::fmt::Debug for IterableErrorCounterAttrs<'_> {
435 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
436 let mut fmt = f.debug_struct("ErrorCounterAttrs");
437 for attr in self.clone() {
438 let attr = match attr {
439 Ok(a) => a,
440 Err(err) => {
441 fmt.finish()?;
442 f.write_str("Err(")?;
443 err.fmt(f)?;
444 return f.write_str(")");
445 }
446 };
447 match attr {
448 ErrorCounterAttrs::NodeId(val) => fmt.field("NodeId", &val),
449 ErrorCounterAttrs::ErrorId(val) => fmt.field("ErrorId", &val),
450 ErrorCounterAttrs::ErrorName(val) => fmt.field("ErrorName", &val),
451 ErrorCounterAttrs::ErrorValue(val) => fmt.field("ErrorValue", &val),
452 };
453 }
454 fmt.finish()
455 }
456}
457impl IterableErrorCounterAttrs<'_> {
458 pub fn lookup_attr(
459 &self,
460 offset: usize,
461 missing_type: Option<u16>,
462 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
463 let mut stack = Vec::new();
464 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
465 if missing_type.is_some() && cur == offset {
466 stack.push(("ErrorCounterAttrs", offset));
467 return (
468 stack,
469 missing_type.and_then(|t| ErrorCounterAttrs::attr_from_type(t)),
470 );
471 }
472 if cur > offset || cur + self.buf.len() < offset {
473 return (stack, None);
474 }
475 let mut attrs = self.clone();
476 let mut last_off = cur + attrs.pos;
477 while let Some(attr) = attrs.next() {
478 let Ok(attr) = attr else { break };
479 match attr {
480 ErrorCounterAttrs::NodeId(val) => {
481 if last_off == offset {
482 stack.push(("NodeId", last_off));
483 break;
484 }
485 }
486 ErrorCounterAttrs::ErrorId(val) => {
487 if last_off == offset {
488 stack.push(("ErrorId", last_off));
489 break;
490 }
491 }
492 ErrorCounterAttrs::ErrorName(val) => {
493 if last_off == offset {
494 stack.push(("ErrorName", last_off));
495 break;
496 }
497 }
498 ErrorCounterAttrs::ErrorValue(val) => {
499 if last_off == offset {
500 stack.push(("ErrorValue", last_off));
501 break;
502 }
503 }
504 _ => {}
505 };
506 last_off = cur + attrs.pos;
507 }
508 if !stack.is_empty() {
509 stack.push(("ErrorCounterAttrs", cur));
510 }
511 (stack, None)
512 }
513}
514pub struct PushNodeAttrs<Prev: Pusher> {
515 pub(crate) prev: Option<Prev>,
516 pub(crate) header_offset: Option<usize>,
517}
518impl<Prev: Pusher> Pusher for PushNodeAttrs<Prev> {
519 fn as_vec_mut(&mut self) -> &mut Vec<u8> {
520 self.prev.as_mut().unwrap().as_vec_mut()
521 }
522 fn as_vec(&self) -> &Vec<u8> {
523 self.prev.as_ref().unwrap().as_vec()
524 }
525}
526impl<Prev: Pusher> PushNodeAttrs<Prev> {
527 pub fn new(prev: Prev) -> Self {
528 Self {
529 prev: Some(prev),
530 header_offset: None,
531 }
532 }
533 pub fn end_nested(mut self) -> Prev {
534 let mut prev = self.prev.take().unwrap();
535 if let Some(header_offset) = &self.header_offset {
536 finalize_nested_header(prev.as_vec_mut(), *header_offset);
537 }
538 prev
539 }
540 #[doc = "Unique identifier for the node. Assigned dynamically by the DRM RAS core\nupon registration.\n"]
541 pub fn push_node_id(mut self, value: u32) -> Self {
542 push_header(self.as_vec_mut(), 1u16, 4 as u16);
543 self.as_vec_mut().extend(value.to_ne_bytes());
544 self
545 }
546 #[doc = "Device name chosen by the driver at registration. Can be a PCI BDF,\nUUID, or module name if unique.\n"]
547 pub fn push_device_name(mut self, value: &CStr) -> Self {
548 push_header(
549 self.as_vec_mut(),
550 2u16,
551 value.to_bytes_with_nul().len() as u16,
552 );
553 self.as_vec_mut().extend(value.to_bytes_with_nul());
554 self
555 }
556 #[doc = "Device name chosen by the driver at registration. Can be a PCI BDF,\nUUID, or module name if unique.\n"]
557 pub fn push_device_name_bytes(mut self, value: &[u8]) -> Self {
558 push_header(self.as_vec_mut(), 2u16, (value.len() + 1) as u16);
559 self.as_vec_mut().extend(value);
560 self.as_vec_mut().push(0);
561 self
562 }
563 #[doc = "Node name chosen by the driver at registration. Can be an IP block name,\nor any name that identifies the RAS node inside the device.\n"]
564 pub fn push_node_name(mut self, value: &CStr) -> Self {
565 push_header(
566 self.as_vec_mut(),
567 3u16,
568 value.to_bytes_with_nul().len() as u16,
569 );
570 self.as_vec_mut().extend(value.to_bytes_with_nul());
571 self
572 }
573 #[doc = "Node name chosen by the driver at registration. Can be an IP block name,\nor any name that identifies the RAS node inside the device.\n"]
574 pub fn push_node_name_bytes(mut self, value: &[u8]) -> Self {
575 push_header(self.as_vec_mut(), 3u16, (value.len() + 1) as u16);
576 self.as_vec_mut().extend(value);
577 self.as_vec_mut().push(0);
578 self
579 }
580 #[doc = "Type of this node, identifying its function.\n\nAssociated type: [`NodeType`] (enum)"]
581 pub fn push_node_type(mut self, value: u32) -> Self {
582 push_header(self.as_vec_mut(), 4u16, 4 as u16);
583 self.as_vec_mut().extend(value.to_ne_bytes());
584 self
585 }
586}
587impl<Prev: Pusher> Drop for PushNodeAttrs<Prev> {
588 fn drop(&mut self) {
589 if let Some(prev) = &mut self.prev {
590 if let Some(header_offset) = &self.header_offset {
591 finalize_nested_header(prev.as_vec_mut(), *header_offset);
592 }
593 }
594 }
595}
596pub struct PushErrorCounterAttrs<Prev: Pusher> {
597 pub(crate) prev: Option<Prev>,
598 pub(crate) header_offset: Option<usize>,
599}
600impl<Prev: Pusher> Pusher for PushErrorCounterAttrs<Prev> {
601 fn as_vec_mut(&mut self) -> &mut Vec<u8> {
602 self.prev.as_mut().unwrap().as_vec_mut()
603 }
604 fn as_vec(&self) -> &Vec<u8> {
605 self.prev.as_ref().unwrap().as_vec()
606 }
607}
608impl<Prev: Pusher> PushErrorCounterAttrs<Prev> {
609 pub fn new(prev: Prev) -> Self {
610 Self {
611 prev: Some(prev),
612 header_offset: None,
613 }
614 }
615 pub fn end_nested(mut self) -> Prev {
616 let mut prev = self.prev.take().unwrap();
617 if let Some(header_offset) = &self.header_offset {
618 finalize_nested_header(prev.as_vec_mut(), *header_offset);
619 }
620 prev
621 }
622 #[doc = "Node ID targeted by this error counter operation.\n"]
623 pub fn push_node_id(mut self, value: u32) -> Self {
624 push_header(self.as_vec_mut(), 1u16, 4 as u16);
625 self.as_vec_mut().extend(value.to_ne_bytes());
626 self
627 }
628 #[doc = "Unique identifier for a specific error counter within an node.\n"]
629 pub fn push_error_id(mut self, value: u32) -> Self {
630 push_header(self.as_vec_mut(), 2u16, 4 as u16);
631 self.as_vec_mut().extend(value.to_ne_bytes());
632 self
633 }
634 #[doc = "Name of the error.\n"]
635 pub fn push_error_name(mut self, value: &CStr) -> Self {
636 push_header(
637 self.as_vec_mut(),
638 3u16,
639 value.to_bytes_with_nul().len() as u16,
640 );
641 self.as_vec_mut().extend(value.to_bytes_with_nul());
642 self
643 }
644 #[doc = "Name of the error.\n"]
645 pub fn push_error_name_bytes(mut self, value: &[u8]) -> Self {
646 push_header(self.as_vec_mut(), 3u16, (value.len() + 1) as u16);
647 self.as_vec_mut().extend(value);
648 self.as_vec_mut().push(0);
649 self
650 }
651 #[doc = "Current value of the requested error counter.\n"]
652 pub fn push_error_value(mut self, value: u32) -> Self {
653 push_header(self.as_vec_mut(), 4u16, 4 as u16);
654 self.as_vec_mut().extend(value.to_ne_bytes());
655 self
656 }
657}
658impl<Prev: Pusher> Drop for PushErrorCounterAttrs<Prev> {
659 fn drop(&mut self) {
660 if let Some(prev) = &mut self.prev {
661 if let Some(header_offset) = &self.header_offset {
662 finalize_nested_header(prev.as_vec_mut(), *header_offset);
663 }
664 }
665 }
666}
667#[doc = "Retrieve the full list of currently registered DRM RAS nodes. Each node\nincludes its dynamically assigned ID, name, and type. **Important:**\nUser space must call this operation first to obtain the node IDs. These\nIDs are required for all subsequent operations on nodes, such as\nquerying error counters.\n\nFlags: admin-perm\n\nReply attributes:\n- [.get_node_id()](IterableNodeAttrs::get_node_id)\n- [.get_device_name()](IterableNodeAttrs::get_device_name)\n- [.get_node_name()](IterableNodeAttrs::get_node_name)\n- [.get_node_type()](IterableNodeAttrs::get_node_type)\n\n"]
668#[derive(Debug)]
669pub struct OpListNodesDump<'r> {
670 request: Request<'r>,
671}
672impl<'r> OpListNodesDump<'r> {
673 pub fn new(mut request: Request<'r>) -> Self {
674 Self::write_header(request.buf_mut());
675 Self {
676 request: request.set_dump(),
677 }
678 }
679 pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushNodeAttrs<&'buf mut Vec<u8>> {
680 Self::write_header(buf);
681 PushNodeAttrs::new(buf)
682 }
683 pub fn encode(&mut self) -> PushNodeAttrs<&mut Vec<u8>> {
684 PushNodeAttrs::new(self.request.buf_mut())
685 }
686 pub fn into_encoder(self) -> PushNodeAttrs<RequestBuf<'r>> {
687 PushNodeAttrs::new(self.request.buf)
688 }
689 pub fn decode_request<'a>(buf: &'a [u8]) -> IterableNodeAttrs<'a> {
690 let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
691 IterableNodeAttrs::with_loc(attrs, buf.as_ptr() as usize)
692 }
693 fn write_header<Prev: Pusher>(prev: &mut Prev) {
694 let mut header = BuiltinNfgenmsg::new();
695 header.cmd = 1u8;
696 header.version = 1u8;
697 prev.as_vec_mut().extend(header.as_slice());
698 }
699}
700impl NetlinkRequest for OpListNodesDump<'_> {
701 fn protocol(&self) -> Protocol {
702 Protocol::Generic("drm-ras".as_bytes())
703 }
704 fn flags(&self) -> u16 {
705 self.request.flags
706 }
707 fn payload(&self) -> &[u8] {
708 self.request.buf()
709 }
710 type ReplyType<'buf> = IterableNodeAttrs<'buf>;
711 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
712 Self::decode_request(buf)
713 }
714 fn lookup(
715 buf: &[u8],
716 offset: usize,
717 missing_type: Option<u16>,
718 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
719 Self::decode_request(buf).lookup_attr(offset, missing_type)
720 }
721}
722#[doc = "Retrieve error counter for a given node. The response includes the id,\nthe name, and even the current value of each counter.\n\nFlags: admin-perm\n\nRequest attributes:\n- [.push_node_id()](PushErrorCounterAttrs::push_node_id)\n\nReply attributes:\n- [.get_error_id()](IterableErrorCounterAttrs::get_error_id)\n- [.get_error_name()](IterableErrorCounterAttrs::get_error_name)\n- [.get_error_value()](IterableErrorCounterAttrs::get_error_value)\n\n"]
723#[derive(Debug)]
724pub struct OpGetErrorCounterDump<'r> {
725 request: Request<'r>,
726}
727impl<'r> OpGetErrorCounterDump<'r> {
728 pub fn new(mut request: Request<'r>) -> Self {
729 Self::write_header(request.buf_mut());
730 Self {
731 request: request.set_dump(),
732 }
733 }
734 pub fn encode_request<'buf>(
735 buf: &'buf mut Vec<u8>,
736 ) -> PushErrorCounterAttrs<&'buf mut Vec<u8>> {
737 Self::write_header(buf);
738 PushErrorCounterAttrs::new(buf)
739 }
740 pub fn encode(&mut self) -> PushErrorCounterAttrs<&mut Vec<u8>> {
741 PushErrorCounterAttrs::new(self.request.buf_mut())
742 }
743 pub fn into_encoder(self) -> PushErrorCounterAttrs<RequestBuf<'r>> {
744 PushErrorCounterAttrs::new(self.request.buf)
745 }
746 pub fn decode_request<'a>(buf: &'a [u8]) -> IterableErrorCounterAttrs<'a> {
747 let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
748 IterableErrorCounterAttrs::with_loc(attrs, buf.as_ptr() as usize)
749 }
750 fn write_header<Prev: Pusher>(prev: &mut Prev) {
751 let mut header = BuiltinNfgenmsg::new();
752 header.cmd = 2u8;
753 header.version = 1u8;
754 prev.as_vec_mut().extend(header.as_slice());
755 }
756}
757impl NetlinkRequest for OpGetErrorCounterDump<'_> {
758 fn protocol(&self) -> Protocol {
759 Protocol::Generic("drm-ras".as_bytes())
760 }
761 fn flags(&self) -> u16 {
762 self.request.flags
763 }
764 fn payload(&self) -> &[u8] {
765 self.request.buf()
766 }
767 type ReplyType<'buf> = IterableErrorCounterAttrs<'buf>;
768 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
769 Self::decode_request(buf)
770 }
771 fn lookup(
772 buf: &[u8],
773 offset: usize,
774 missing_type: Option<u16>,
775 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
776 Self::decode_request(buf).lookup_attr(offset, missing_type)
777 }
778}
779#[doc = "Retrieve error counter for a given node. The response includes the id,\nthe name, and even the current value of each counter.\n\nFlags: admin-perm\n\nRequest attributes:\n- [.push_node_id()](PushErrorCounterAttrs::push_node_id)\n- [.push_error_id()](PushErrorCounterAttrs::push_error_id)\n\nReply attributes:\n- [.get_error_id()](IterableErrorCounterAttrs::get_error_id)\n- [.get_error_name()](IterableErrorCounterAttrs::get_error_name)\n- [.get_error_value()](IterableErrorCounterAttrs::get_error_value)\n\n"]
780#[derive(Debug)]
781pub struct OpGetErrorCounterDo<'r> {
782 request: Request<'r>,
783}
784impl<'r> OpGetErrorCounterDo<'r> {
785 pub fn new(mut request: Request<'r>) -> Self {
786 Self::write_header(request.buf_mut());
787 Self { request: request }
788 }
789 pub fn encode_request<'buf>(
790 buf: &'buf mut Vec<u8>,
791 ) -> PushErrorCounterAttrs<&'buf mut Vec<u8>> {
792 Self::write_header(buf);
793 PushErrorCounterAttrs::new(buf)
794 }
795 pub fn encode(&mut self) -> PushErrorCounterAttrs<&mut Vec<u8>> {
796 PushErrorCounterAttrs::new(self.request.buf_mut())
797 }
798 pub fn into_encoder(self) -> PushErrorCounterAttrs<RequestBuf<'r>> {
799 PushErrorCounterAttrs::new(self.request.buf)
800 }
801 pub fn decode_request<'a>(buf: &'a [u8]) -> IterableErrorCounterAttrs<'a> {
802 let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
803 IterableErrorCounterAttrs::with_loc(attrs, buf.as_ptr() as usize)
804 }
805 fn write_header<Prev: Pusher>(prev: &mut Prev) {
806 let mut header = BuiltinNfgenmsg::new();
807 header.cmd = 2u8;
808 header.version = 1u8;
809 prev.as_vec_mut().extend(header.as_slice());
810 }
811}
812impl NetlinkRequest for OpGetErrorCounterDo<'_> {
813 fn protocol(&self) -> Protocol {
814 Protocol::Generic("drm-ras".as_bytes())
815 }
816 fn flags(&self) -> u16 {
817 self.request.flags
818 }
819 fn payload(&self) -> &[u8] {
820 self.request.buf()
821 }
822 type ReplyType<'buf> = IterableErrorCounterAttrs<'buf>;
823 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
824 Self::decode_request(buf)
825 }
826 fn lookup(
827 buf: &[u8],
828 offset: usize,
829 missing_type: Option<u16>,
830 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
831 Self::decode_request(buf).lookup_attr(offset, missing_type)
832 }
833}
834#[doc = "Clear error counter for a given node. The request includes the error-id\nand node-id of the counter to be cleared.\n\nFlags: admin-perm\n\nRequest attributes:\n- [.push_node_id()](PushErrorCounterAttrs::push_node_id)\n- [.push_error_id()](PushErrorCounterAttrs::push_error_id)\n\n"]
835#[derive(Debug)]
836pub struct OpClearErrorCounterDo<'r> {
837 request: Request<'r>,
838}
839impl<'r> OpClearErrorCounterDo<'r> {
840 pub fn new(mut request: Request<'r>) -> Self {
841 Self::write_header(request.buf_mut());
842 Self { request: request }
843 }
844 pub fn encode_request<'buf>(
845 buf: &'buf mut Vec<u8>,
846 ) -> PushErrorCounterAttrs<&'buf mut Vec<u8>> {
847 Self::write_header(buf);
848 PushErrorCounterAttrs::new(buf)
849 }
850 pub fn encode(&mut self) -> PushErrorCounterAttrs<&mut Vec<u8>> {
851 PushErrorCounterAttrs::new(self.request.buf_mut())
852 }
853 pub fn into_encoder(self) -> PushErrorCounterAttrs<RequestBuf<'r>> {
854 PushErrorCounterAttrs::new(self.request.buf)
855 }
856 pub fn decode_request<'a>(buf: &'a [u8]) -> IterableErrorCounterAttrs<'a> {
857 let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
858 IterableErrorCounterAttrs::with_loc(attrs, buf.as_ptr() as usize)
859 }
860 fn write_header<Prev: Pusher>(prev: &mut Prev) {
861 let mut header = BuiltinNfgenmsg::new();
862 header.cmd = 3u8;
863 header.version = 1u8;
864 prev.as_vec_mut().extend(header.as_slice());
865 }
866}
867impl NetlinkRequest for OpClearErrorCounterDo<'_> {
868 fn protocol(&self) -> Protocol {
869 Protocol::Generic("drm-ras".as_bytes())
870 }
871 fn flags(&self) -> u16 {
872 self.request.flags
873 }
874 fn payload(&self) -> &[u8] {
875 self.request.buf()
876 }
877 type ReplyType<'buf> = IterableErrorCounterAttrs<'buf>;
878 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
879 Self::decode_request(buf)
880 }
881 fn lookup(
882 buf: &[u8],
883 offset: usize,
884 missing_type: Option<u16>,
885 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
886 Self::decode_request(buf).lookup_attr(offset, missing_type)
887 }
888}
889use crate::traits::LookupFn;
890use crate::utils::RequestBuf;
891#[derive(Debug)]
892pub struct Request<'buf> {
893 buf: RequestBuf<'buf>,
894 flags: u16,
895 writeback: Option<&'buf mut Option<RequestInfo>>,
896}
897#[allow(unused)]
898#[derive(Debug, Clone)]
899pub struct RequestInfo {
900 protocol: Protocol,
901 flags: u16,
902 name: &'static str,
903 lookup: LookupFn,
904}
905impl Request<'static> {
906 pub fn new() -> Self {
907 Self::new_from_buf(Vec::new())
908 }
909 pub fn new_from_buf(buf: Vec<u8>) -> Self {
910 Self {
911 flags: 0,
912 buf: RequestBuf::Own(buf),
913 writeback: None,
914 }
915 }
916 pub fn into_buf(self) -> Vec<u8> {
917 match self.buf {
918 RequestBuf::Own(buf) => buf,
919 _ => unreachable!(),
920 }
921 }
922}
923impl<'buf> Request<'buf> {
924 pub fn new_with_buf(buf: &'buf mut Vec<u8>) -> Self {
925 buf.clear();
926 Self::new_extend(buf)
927 }
928 pub fn new_extend(buf: &'buf mut Vec<u8>) -> Self {
929 Self {
930 flags: 0,
931 buf: RequestBuf::Ref(buf),
932 writeback: None,
933 }
934 }
935 fn do_writeback(&mut self, protocol: Protocol, name: &'static str, lookup: LookupFn) {
936 let Some(writeback) = &mut self.writeback else {
937 return;
938 };
939 **writeback = Some(RequestInfo {
940 protocol,
941 flags: self.flags,
942 name,
943 lookup,
944 })
945 }
946 pub fn buf(&self) -> &Vec<u8> {
947 self.buf.buf()
948 }
949 pub fn buf_mut(&mut self) -> &mut Vec<u8> {
950 self.buf.buf_mut()
951 }
952 #[doc = "Set `NLM_F_CREATE` flag"]
953 pub fn set_create(mut self) -> Self {
954 self.flags |= consts::NLM_F_CREATE as u16;
955 self
956 }
957 #[doc = "Set `NLM_F_EXCL` flag"]
958 pub fn set_excl(mut self) -> Self {
959 self.flags |= consts::NLM_F_EXCL as u16;
960 self
961 }
962 #[doc = "Set `NLM_F_REPLACE` flag"]
963 pub fn set_replace(mut self) -> Self {
964 self.flags |= consts::NLM_F_REPLACE as u16;
965 self
966 }
967 #[doc = "Set `NLM_F_CREATE` and `NLM_F_REPLACE` flag"]
968 pub fn set_change(self) -> Self {
969 self.set_create().set_replace()
970 }
971 #[doc = "Set `NLM_F_APPEND` flag"]
972 pub fn set_append(mut self) -> Self {
973 self.flags |= consts::NLM_F_APPEND as u16;
974 self
975 }
976 #[doc = "Set `self.flags |= flags`"]
977 pub fn set_flags(mut self, flags: u16) -> Self {
978 self.flags |= flags;
979 self
980 }
981 #[doc = "Set `self.flags ^= self.flags & flags`"]
982 pub fn unset_flags(mut self, flags: u16) -> Self {
983 self.flags ^= self.flags & flags;
984 self
985 }
986 #[doc = "Set `NLM_F_DUMP` flag"]
987 fn set_dump(mut self) -> Self {
988 self.flags |= consts::NLM_F_DUMP as u16;
989 self
990 }
991 #[doc = "Retrieve the full list of currently registered DRM RAS nodes. Each node\nincludes its dynamically assigned ID, name, and type. **Important:**\nUser space must call this operation first to obtain the node IDs. These\nIDs are required for all subsequent operations on nodes, such as\nquerying error counters.\n\nFlags: admin-perm\n\nReply attributes:\n- [.get_node_id()](IterableNodeAttrs::get_node_id)\n- [.get_device_name()](IterableNodeAttrs::get_device_name)\n- [.get_node_name()](IterableNodeAttrs::get_node_name)\n- [.get_node_type()](IterableNodeAttrs::get_node_type)\n\n"]
992 pub fn op_list_nodes_dump(self) -> OpListNodesDump<'buf> {
993 let mut res = OpListNodesDump::new(self);
994 res.request.do_writeback(
995 res.protocol(),
996 "op-list-nodes-dump",
997 OpListNodesDump::lookup,
998 );
999 res
1000 }
1001 #[doc = "Retrieve error counter for a given node. The response includes the id,\nthe name, and even the current value of each counter.\n\nFlags: admin-perm\n\nRequest attributes:\n- [.push_node_id()](PushErrorCounterAttrs::push_node_id)\n\nReply attributes:\n- [.get_error_id()](IterableErrorCounterAttrs::get_error_id)\n- [.get_error_name()](IterableErrorCounterAttrs::get_error_name)\n- [.get_error_value()](IterableErrorCounterAttrs::get_error_value)\n\n"]
1002 pub fn op_get_error_counter_dump(self) -> OpGetErrorCounterDump<'buf> {
1003 let mut res = OpGetErrorCounterDump::new(self);
1004 res.request.do_writeback(
1005 res.protocol(),
1006 "op-get-error-counter-dump",
1007 OpGetErrorCounterDump::lookup,
1008 );
1009 res
1010 }
1011 #[doc = "Retrieve error counter for a given node. The response includes the id,\nthe name, and even the current value of each counter.\n\nFlags: admin-perm\n\nRequest attributes:\n- [.push_node_id()](PushErrorCounterAttrs::push_node_id)\n- [.push_error_id()](PushErrorCounterAttrs::push_error_id)\n\nReply attributes:\n- [.get_error_id()](IterableErrorCounterAttrs::get_error_id)\n- [.get_error_name()](IterableErrorCounterAttrs::get_error_name)\n- [.get_error_value()](IterableErrorCounterAttrs::get_error_value)\n\n"]
1012 pub fn op_get_error_counter_do(self) -> OpGetErrorCounterDo<'buf> {
1013 let mut res = OpGetErrorCounterDo::new(self);
1014 res.request.do_writeback(
1015 res.protocol(),
1016 "op-get-error-counter-do",
1017 OpGetErrorCounterDo::lookup,
1018 );
1019 res
1020 }
1021 #[doc = "Clear error counter for a given node. The request includes the error-id\nand node-id of the counter to be cleared.\n\nFlags: admin-perm\n\nRequest attributes:\n- [.push_node_id()](PushErrorCounterAttrs::push_node_id)\n- [.push_error_id()](PushErrorCounterAttrs::push_error_id)\n\n"]
1022 pub fn op_clear_error_counter_do(self) -> OpClearErrorCounterDo<'buf> {
1023 let mut res = OpClearErrorCounterDo::new(self);
1024 res.request.do_writeback(
1025 res.protocol(),
1026 "op-clear-error-counter-do",
1027 OpClearErrorCounterDo::lookup,
1028 );
1029 res
1030 }
1031}
1032#[cfg(test)]
1033mod generated_tests {
1034 use super::*;
1035 #[test]
1036 fn tests() {
1037 let _ = IterableErrorCounterAttrs::get_error_id;
1038 let _ = IterableErrorCounterAttrs::get_error_name;
1039 let _ = IterableErrorCounterAttrs::get_error_value;
1040 let _ = IterableNodeAttrs::get_device_name;
1041 let _ = IterableNodeAttrs::get_node_id;
1042 let _ = IterableNodeAttrs::get_node_name;
1043 let _ = IterableNodeAttrs::get_node_type;
1044 let _ = PushErrorCounterAttrs::<&mut Vec<u8>>::push_error_id;
1045 let _ = PushErrorCounterAttrs::<&mut Vec<u8>>::push_node_id;
1046 }
1047}