starnix_uapi/
device_type.rs1use std::fmt;
6use std::ops::Range;
7
8pub const MEM_MAJOR: u32 = 1;
9pub const TTY_MAJOR: u32 = 4;
10pub const TTY_ALT_MAJOR: u32 = 5;
11pub const LOOP_MAJOR: u32 = 7;
12pub const MISC_MAJOR: u32 = 10;
13pub const INPUT_MAJOR: u32 = 13;
14pub const FB_MAJOR: u32 = 29;
15
16pub const MISC_DYNANIC_MINOR_RANGE: Range<u32> = 52..128;
20
21pub const DYN_MAJOR_RANGE: Range<u32> = 234..252;
25
26pub const MMC_BLOCK_DEVICE_MAJOR: u32 = 179;
27
28pub const ZRAM_MAJOR: u32 = 252;
31
32pub const DEVICE_MAPPER_MAJOR: u32 = 254;
34
35pub const BLOCK_EXTENDED_MAJOR: u32 = 259;
36
37#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
38pub struct DeviceType(u64);
39
40impl DeviceType {
41 pub const NONE: DeviceType = DeviceType(0);
42
43 pub const NULL: DeviceType = DeviceType::new(MEM_MAJOR, 3);
45 pub const ZERO: DeviceType = DeviceType::new(MEM_MAJOR, 5);
46 pub const FULL: DeviceType = DeviceType::new(MEM_MAJOR, 7);
47 pub const RANDOM: DeviceType = DeviceType::new(MEM_MAJOR, 8);
48 pub const URANDOM: DeviceType = DeviceType::new(MEM_MAJOR, 9);
49 pub const KMSG: DeviceType = DeviceType::new(MEM_MAJOR, 11);
50
51 pub const TTY: DeviceType = DeviceType::new(TTY_ALT_MAJOR, 0);
53 pub const PTMX: DeviceType = DeviceType::new(TTY_ALT_MAJOR, 2);
54
55 pub const HW_RANDOM: DeviceType = DeviceType::new(MISC_MAJOR, 183);
57 pub const UINPUT: DeviceType = DeviceType::new(MISC_MAJOR, 223);
58 pub const FUSE: DeviceType = DeviceType::new(MISC_MAJOR, 229);
59 pub const DEVICE_MAPPER: DeviceType = DeviceType::new(MISC_MAJOR, 236);
60 pub const LOOP_CONTROL: DeviceType = DeviceType::new(MISC_MAJOR, 237);
61
62 pub const FB0: DeviceType = DeviceType::new(FB_MAJOR, 0);
64
65 pub const TUN: DeviceType = DeviceType::new(MISC_MAJOR, 200);
67
68 pub const MMCBLK0: DeviceType = DeviceType::new(MMC_BLOCK_DEVICE_MAJOR, 0);
70
71 pub const fn new(major: u32, minor: u32) -> DeviceType {
72 DeviceType(
76 (((major & 0xfffff000) as u64) << 32)
77 | (((major & 0xfff) as u64) << 8)
78 | (((minor & 0xffffff00) as u64) << 12)
79 | ((minor & 0xff) as u64),
80 )
81 }
82
83 pub const fn new_range(major: u32, minor: Range<u32>) -> Range<DeviceType> {
84 Self::new(major, minor.start)..Self::new(major, minor.end)
85 }
86
87 pub const fn from_bits(dev: u64) -> DeviceType {
88 DeviceType(dev)
89 }
90
91 pub const fn bits(&self) -> u64 {
92 self.0
93 }
94
95 pub fn next_minor(&self) -> Option<DeviceType> {
96 self.minor().checked_add(1).map(|minor| DeviceType::new(self.major(), minor))
97 }
98
99 pub const fn major(&self) -> u32 {
100 ((self.0 >> 32 & 0xfffff000) | ((self.0 >> 8) & 0xfff)) as u32
101 }
102
103 pub const fn minor(&self) -> u32 {
104 ((self.0 >> 12 & 0xffffff00) | (self.0 & 0xff)) as u32
105 }
106}
107
108impl fmt::Display for DeviceType {
109 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
110 write!(f, "{}:{}", self.major(), self.minor())
111 }
112}
113
114impl std::cmp::PartialOrd for DeviceType {
115 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
116 Some(self.cmp(other))
117 }
118}
119
120impl std::cmp::Ord for DeviceType {
121 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
122 (self.major(), self.minor()).cmp(&(other.major(), other.minor()))
123 }
124}
125
126#[cfg(test)]
127mod tests {
128 use super::*;
129
130 #[::fuchsia::test]
131 fn test_device_type() {
132 let dev = DeviceType::new(21, 17);
133 assert_eq!(dev.major(), 21);
134 assert_eq!(dev.minor(), 17);
135
136 let dev = DeviceType::new(0x83af83fe, 0xf98ecba1);
137 assert_eq!(dev.major(), 0x83af83fe);
138 assert_eq!(dev.minor(), 0xf98ecba1);
139 }
140}