Skip to main content

netlink_bindings/drm-ras/
mod.rs

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: Rec> {
515    pub(crate) prev: Option<Prev>,
516    pub(crate) header_offset: Option<usize>,
517}
518impl<Prev: Rec> Rec for PushNodeAttrs<Prev> {
519    fn as_rec_mut(&mut self) -> &mut Vec<u8> {
520        self.prev.as_mut().unwrap().as_rec_mut()
521    }
522    fn as_rec(&self) -> &Vec<u8> {
523        self.prev.as_ref().unwrap().as_rec()
524    }
525}
526impl<Prev: Rec> 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_rec_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_rec_mut(), 1u16, 4 as u16);
543        self.as_rec_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_rec_mut(),
550            2u16,
551            value.to_bytes_with_nul().len() as u16,
552        );
553        self.as_rec_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_rec_mut(), 2u16, (value.len() + 1) as u16);
559        self.as_rec_mut().extend(value);
560        self.as_rec_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_rec_mut(),
567            3u16,
568            value.to_bytes_with_nul().len() as u16,
569        );
570        self.as_rec_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_rec_mut(), 3u16, (value.len() + 1) as u16);
576        self.as_rec_mut().extend(value);
577        self.as_rec_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_rec_mut(), 4u16, 4 as u16);
583        self.as_rec_mut().extend(value.to_ne_bytes());
584        self
585    }
586}
587impl<Prev: Rec> 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_rec_mut(), *header_offset);
592            }
593        }
594    }
595}
596pub struct PushErrorCounterAttrs<Prev: Rec> {
597    pub(crate) prev: Option<Prev>,
598    pub(crate) header_offset: Option<usize>,
599}
600impl<Prev: Rec> Rec for PushErrorCounterAttrs<Prev> {
601    fn as_rec_mut(&mut self) -> &mut Vec<u8> {
602        self.prev.as_mut().unwrap().as_rec_mut()
603    }
604    fn as_rec(&self) -> &Vec<u8> {
605        self.prev.as_ref().unwrap().as_rec()
606    }
607}
608impl<Prev: Rec> 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_rec_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_rec_mut(), 1u16, 4 as u16);
625        self.as_rec_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_rec_mut(), 2u16, 4 as u16);
631        self.as_rec_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_rec_mut(),
638            3u16,
639            value.to_bytes_with_nul().len() as u16,
640        );
641        self.as_rec_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_rec_mut(), 3u16, (value.len() + 1) as u16);
647        self.as_rec_mut().extend(value);
648        self.as_rec_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_rec_mut(), 4u16, 4 as u16);
654        self.as_rec_mut().extend(value.to_ne_bytes());
655        self
656    }
657}
658impl<Prev: Rec> 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_rec_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: Rec>(prev: &mut Prev) {
694        let mut header = BuiltinNfgenmsg::new();
695        header.cmd = 1u8;
696        header.version = 1u8;
697        prev.as_rec_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: Rec>(prev: &mut Prev) {
751        let mut header = BuiltinNfgenmsg::new();
752        header.cmd = 2u8;
753        header.version = 1u8;
754        prev.as_rec_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: Rec>(prev: &mut Prev) {
806        let mut header = BuiltinNfgenmsg::new();
807        header.cmd = 2u8;
808        header.version = 1u8;
809        prev.as_rec_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}
834use crate::traits::LookupFn;
835use crate::utils::RequestBuf;
836#[derive(Debug)]
837pub struct Request<'buf> {
838    buf: RequestBuf<'buf>,
839    flags: u16,
840    writeback: Option<&'buf mut Option<RequestInfo>>,
841}
842#[allow(unused)]
843#[derive(Debug, Clone)]
844pub struct RequestInfo {
845    protocol: Protocol,
846    flags: u16,
847    name: &'static str,
848    lookup: LookupFn,
849}
850impl Request<'static> {
851    pub fn new() -> Self {
852        Self::new_from_buf(Vec::new())
853    }
854    pub fn new_from_buf(buf: Vec<u8>) -> Self {
855        Self {
856            flags: 0,
857            buf: RequestBuf::Own(buf),
858            writeback: None,
859        }
860    }
861    pub fn into_buf(self) -> Vec<u8> {
862        match self.buf {
863            RequestBuf::Own(buf) => buf,
864            _ => unreachable!(),
865        }
866    }
867}
868impl<'buf> Request<'buf> {
869    pub fn new_with_buf(buf: &'buf mut Vec<u8>) -> Self {
870        buf.clear();
871        Self::new_extend(buf)
872    }
873    pub fn new_extend(buf: &'buf mut Vec<u8>) -> Self {
874        Self {
875            flags: 0,
876            buf: RequestBuf::Ref(buf),
877            writeback: None,
878        }
879    }
880    fn do_writeback(&mut self, protocol: Protocol, name: &'static str, lookup: LookupFn) {
881        let Some(writeback) = &mut self.writeback else {
882            return;
883        };
884        **writeback = Some(RequestInfo {
885            protocol,
886            flags: self.flags,
887            name,
888            lookup,
889        })
890    }
891    pub fn buf(&self) -> &Vec<u8> {
892        self.buf.buf()
893    }
894    pub fn buf_mut(&mut self) -> &mut Vec<u8> {
895        self.buf.buf_mut()
896    }
897    #[doc = "Set `NLM_F_CREATE` flag"]
898    pub fn set_create(mut self) -> Self {
899        self.flags |= consts::NLM_F_CREATE as u16;
900        self
901    }
902    #[doc = "Set `NLM_F_EXCL` flag"]
903    pub fn set_excl(mut self) -> Self {
904        self.flags |= consts::NLM_F_EXCL as u16;
905        self
906    }
907    #[doc = "Set `NLM_F_REPLACE` flag"]
908    pub fn set_replace(mut self) -> Self {
909        self.flags |= consts::NLM_F_REPLACE as u16;
910        self
911    }
912    #[doc = "Set `NLM_F_CREATE` and `NLM_F_REPLACE` flag"]
913    pub fn set_change(self) -> Self {
914        self.set_create().set_replace()
915    }
916    #[doc = "Set `NLM_F_APPEND` flag"]
917    pub fn set_append(mut self) -> Self {
918        self.flags |= consts::NLM_F_APPEND as u16;
919        self
920    }
921    #[doc = "Set `self.flags |= flags`"]
922    pub fn set_flags(mut self, flags: u16) -> Self {
923        self.flags |= flags;
924        self
925    }
926    #[doc = "Set `self.flags ^= self.flags & flags`"]
927    pub fn unset_flags(mut self, flags: u16) -> Self {
928        self.flags ^= self.flags & flags;
929        self
930    }
931    #[doc = "Set `NLM_F_DUMP` flag"]
932    fn set_dump(mut self) -> Self {
933        self.flags |= consts::NLM_F_DUMP as u16;
934        self
935    }
936    #[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"]
937    pub fn op_list_nodes_dump(self) -> OpListNodesDump<'buf> {
938        let mut res = OpListNodesDump::new(self);
939        res.request.do_writeback(
940            res.protocol(),
941            "op-list-nodes-dump",
942            OpListNodesDump::lookup,
943        );
944        res
945    }
946    #[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"]
947    pub fn op_get_error_counter_dump(self) -> OpGetErrorCounterDump<'buf> {
948        let mut res = OpGetErrorCounterDump::new(self);
949        res.request.do_writeback(
950            res.protocol(),
951            "op-get-error-counter-dump",
952            OpGetErrorCounterDump::lookup,
953        );
954        res
955    }
956    #[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"]
957    pub fn op_get_error_counter_do(self) -> OpGetErrorCounterDo<'buf> {
958        let mut res = OpGetErrorCounterDo::new(self);
959        res.request.do_writeback(
960            res.protocol(),
961            "op-get-error-counter-do",
962            OpGetErrorCounterDo::lookup,
963        );
964        res
965    }
966}
967#[cfg(test)]
968mod generated_tests {
969    use super::*;
970    #[test]
971    fn tests() {
972        let _ = IterableErrorCounterAttrs::get_error_id;
973        let _ = IterableErrorCounterAttrs::get_error_name;
974        let _ = IterableErrorCounterAttrs::get_error_value;
975        let _ = IterableNodeAttrs::get_device_name;
976        let _ = IterableNodeAttrs::get_node_id;
977        let _ = IterableNodeAttrs::get_node_name;
978        let _ = IterableNodeAttrs::get_node_type;
979        let _ = PushErrorCounterAttrs::<&mut Vec<u8>>::push_error_id;
980        let _ = PushErrorCounterAttrs::<&mut Vec<u8>>::push_node_id;
981    }
982}