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: 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}