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