13da5c369Sopenharmony_ci/// The datatype used for the ioctl number
23da5c369Sopenharmony_ci#[cfg(any(target_os = "android", target_env = "musl", target_env = "ohos"))]
33da5c369Sopenharmony_ci#[doc(hidden)]
43da5c369Sopenharmony_cipub type ioctl_num_type = ::libc::c_int;
53da5c369Sopenharmony_ci#[cfg(not(any(target_os = "android", target_env = "musl", target_env = "ohos")))]
63da5c369Sopenharmony_ci#[doc(hidden)]
73da5c369Sopenharmony_cipub type ioctl_num_type = ::libc::c_ulong;
83da5c369Sopenharmony_ci/// The datatype used for the 3rd argument
93da5c369Sopenharmony_ci#[doc(hidden)]
103da5c369Sopenharmony_cipub type ioctl_param_type = ::libc::c_ulong;
113da5c369Sopenharmony_ci
123da5c369Sopenharmony_ci#[doc(hidden)]
133da5c369Sopenharmony_cipub const NRBITS: ioctl_num_type = 8;
143da5c369Sopenharmony_ci#[doc(hidden)]
153da5c369Sopenharmony_cipub const TYPEBITS: ioctl_num_type = 8;
163da5c369Sopenharmony_ci
173da5c369Sopenharmony_ci#[cfg(any(
183da5c369Sopenharmony_ci    target_arch = "mips",
193da5c369Sopenharmony_ci    target_arch = "mips64",
203da5c369Sopenharmony_ci    target_arch = "powerpc",
213da5c369Sopenharmony_ci    target_arch = "powerpc64",
223da5c369Sopenharmony_ci    target_arch = "sparc64"
233da5c369Sopenharmony_ci))]
243da5c369Sopenharmony_cimod consts {
253da5c369Sopenharmony_ci    #[doc(hidden)]
263da5c369Sopenharmony_ci    pub const NONE: u8 = 1;
273da5c369Sopenharmony_ci    #[doc(hidden)]
283da5c369Sopenharmony_ci    pub const READ: u8 = 2;
293da5c369Sopenharmony_ci    #[doc(hidden)]
303da5c369Sopenharmony_ci    pub const WRITE: u8 = 4;
313da5c369Sopenharmony_ci    #[doc(hidden)]
323da5c369Sopenharmony_ci    pub const SIZEBITS: u8 = 13;
333da5c369Sopenharmony_ci    #[doc(hidden)]
343da5c369Sopenharmony_ci    pub const DIRBITS: u8 = 3;
353da5c369Sopenharmony_ci}
363da5c369Sopenharmony_ci
373da5c369Sopenharmony_ci// "Generic" ioctl protocol
383da5c369Sopenharmony_ci#[cfg(any(
393da5c369Sopenharmony_ci    target_arch = "x86",
403da5c369Sopenharmony_ci    target_arch = "arm",
413da5c369Sopenharmony_ci    target_arch = "s390x",
423da5c369Sopenharmony_ci    target_arch = "x86_64",
433da5c369Sopenharmony_ci    target_arch = "aarch64",
443da5c369Sopenharmony_ci    target_arch = "riscv32",
453da5c369Sopenharmony_ci    target_arch = "riscv64",
463da5c369Sopenharmony_ci    target_arch = "loongarch64"
473da5c369Sopenharmony_ci))]
483da5c369Sopenharmony_cimod consts {
493da5c369Sopenharmony_ci    #[doc(hidden)]
503da5c369Sopenharmony_ci    pub const NONE: u8 = 0;
513da5c369Sopenharmony_ci    #[doc(hidden)]
523da5c369Sopenharmony_ci    pub const READ: u8 = 2;
533da5c369Sopenharmony_ci    #[doc(hidden)]
543da5c369Sopenharmony_ci    pub const WRITE: u8 = 1;
553da5c369Sopenharmony_ci    #[doc(hidden)]
563da5c369Sopenharmony_ci    pub const SIZEBITS: u8 = 14;
573da5c369Sopenharmony_ci    #[doc(hidden)]
583da5c369Sopenharmony_ci    pub const DIRBITS: u8 = 2;
593da5c369Sopenharmony_ci}
603da5c369Sopenharmony_ci
613da5c369Sopenharmony_cipub use self::consts::*;
623da5c369Sopenharmony_ci
633da5c369Sopenharmony_ci#[doc(hidden)]
643da5c369Sopenharmony_cipub const NRSHIFT: ioctl_num_type = 0;
653da5c369Sopenharmony_ci#[doc(hidden)]
663da5c369Sopenharmony_cipub const TYPESHIFT: ioctl_num_type = NRSHIFT + NRBITS as ioctl_num_type;
673da5c369Sopenharmony_ci#[doc(hidden)]
683da5c369Sopenharmony_cipub const SIZESHIFT: ioctl_num_type = TYPESHIFT + TYPEBITS as ioctl_num_type;
693da5c369Sopenharmony_ci#[doc(hidden)]
703da5c369Sopenharmony_cipub const DIRSHIFT: ioctl_num_type = SIZESHIFT + SIZEBITS as ioctl_num_type;
713da5c369Sopenharmony_ci
723da5c369Sopenharmony_ci#[doc(hidden)]
733da5c369Sopenharmony_cipub const NRMASK: ioctl_num_type = (1 << NRBITS) - 1;
743da5c369Sopenharmony_ci#[doc(hidden)]
753da5c369Sopenharmony_cipub const TYPEMASK: ioctl_num_type = (1 << TYPEBITS) - 1;
763da5c369Sopenharmony_ci#[doc(hidden)]
773da5c369Sopenharmony_cipub const SIZEMASK: ioctl_num_type = (1 << SIZEBITS) - 1;
783da5c369Sopenharmony_ci#[doc(hidden)]
793da5c369Sopenharmony_cipub const DIRMASK: ioctl_num_type = (1 << DIRBITS) - 1;
803da5c369Sopenharmony_ci
813da5c369Sopenharmony_ci/// Encode an ioctl command.
823da5c369Sopenharmony_ci#[macro_export]
833da5c369Sopenharmony_ci#[doc(hidden)]
843da5c369Sopenharmony_cimacro_rules! ioc {
853da5c369Sopenharmony_ci    ($dir:expr, $ty:expr, $nr:expr, $sz:expr) => {
863da5c369Sopenharmony_ci        (($dir as $crate::sys::ioctl::ioctl_num_type
873da5c369Sopenharmony_ci            & $crate::sys::ioctl::DIRMASK)
883da5c369Sopenharmony_ci            << $crate::sys::ioctl::DIRSHIFT)
893da5c369Sopenharmony_ci            | (($ty as $crate::sys::ioctl::ioctl_num_type
903da5c369Sopenharmony_ci                & $crate::sys::ioctl::TYPEMASK)
913da5c369Sopenharmony_ci                << $crate::sys::ioctl::TYPESHIFT)
923da5c369Sopenharmony_ci            | (($nr as $crate::sys::ioctl::ioctl_num_type
933da5c369Sopenharmony_ci                & $crate::sys::ioctl::NRMASK)
943da5c369Sopenharmony_ci                << $crate::sys::ioctl::NRSHIFT)
953da5c369Sopenharmony_ci            | (($sz as $crate::sys::ioctl::ioctl_num_type
963da5c369Sopenharmony_ci                & $crate::sys::ioctl::SIZEMASK)
973da5c369Sopenharmony_ci                << $crate::sys::ioctl::SIZESHIFT)
983da5c369Sopenharmony_ci    };
993da5c369Sopenharmony_ci}
1003da5c369Sopenharmony_ci
1013da5c369Sopenharmony_ci/// Generate an ioctl request code for a command that passes no data.
1023da5c369Sopenharmony_ci///
1033da5c369Sopenharmony_ci/// This is equivalent to the `_IO()` macro exposed by the C ioctl API.
1043da5c369Sopenharmony_ci///
1053da5c369Sopenharmony_ci/// You should only use this macro directly if the `ioctl` you're working
1063da5c369Sopenharmony_ci/// with is "bad" and you cannot use `ioctl_none!()` directly.
1073da5c369Sopenharmony_ci///
1083da5c369Sopenharmony_ci/// # Example
1093da5c369Sopenharmony_ci///
1103da5c369Sopenharmony_ci/// ```
1113da5c369Sopenharmony_ci/// # #[macro_use] extern crate nix;
1123da5c369Sopenharmony_ci/// const KVMIO: u8 = 0xAE;
1133da5c369Sopenharmony_ci/// ioctl_write_int_bad!(kvm_create_vm, request_code_none!(KVMIO, 0x03));
1143da5c369Sopenharmony_ci/// # fn main() {}
1153da5c369Sopenharmony_ci/// ```
1163da5c369Sopenharmony_ci#[macro_export(local_inner_macros)]
1173da5c369Sopenharmony_cimacro_rules! request_code_none {
1183da5c369Sopenharmony_ci    ($ty:expr, $nr:expr) => {
1193da5c369Sopenharmony_ci        ioc!($crate::sys::ioctl::NONE, $ty, $nr, 0)
1203da5c369Sopenharmony_ci    };
1213da5c369Sopenharmony_ci}
1223da5c369Sopenharmony_ci
1233da5c369Sopenharmony_ci/// Generate an ioctl request code for a command that reads.
1243da5c369Sopenharmony_ci///
1253da5c369Sopenharmony_ci/// This is equivalent to the `_IOR()` macro exposed by the C ioctl API.
1263da5c369Sopenharmony_ci///
1273da5c369Sopenharmony_ci/// You should only use this macro directly if the `ioctl` you're working
1283da5c369Sopenharmony_ci/// with is "bad" and you cannot use `ioctl_read!()` directly.
1293da5c369Sopenharmony_ci///
1303da5c369Sopenharmony_ci/// The read/write direction is relative to userland, so this
1313da5c369Sopenharmony_ci/// command would be userland is reading and the kernel is
1323da5c369Sopenharmony_ci/// writing.
1333da5c369Sopenharmony_ci#[macro_export(local_inner_macros)]
1343da5c369Sopenharmony_cimacro_rules! request_code_read {
1353da5c369Sopenharmony_ci    ($ty:expr, $nr:expr, $sz:expr) => {
1363da5c369Sopenharmony_ci        ioc!($crate::sys::ioctl::READ, $ty, $nr, $sz)
1373da5c369Sopenharmony_ci    };
1383da5c369Sopenharmony_ci}
1393da5c369Sopenharmony_ci
1403da5c369Sopenharmony_ci/// Generate an ioctl request code for a command that writes.
1413da5c369Sopenharmony_ci///
1423da5c369Sopenharmony_ci/// This is equivalent to the `_IOW()` macro exposed by the C ioctl API.
1433da5c369Sopenharmony_ci///
1443da5c369Sopenharmony_ci/// You should only use this macro directly if the `ioctl` you're working
1453da5c369Sopenharmony_ci/// with is "bad" and you cannot use `ioctl_write!()` directly.
1463da5c369Sopenharmony_ci///
1473da5c369Sopenharmony_ci/// The read/write direction is relative to userland, so this
1483da5c369Sopenharmony_ci/// command would be userland is writing and the kernel is
1493da5c369Sopenharmony_ci/// reading.
1503da5c369Sopenharmony_ci#[macro_export(local_inner_macros)]
1513da5c369Sopenharmony_cimacro_rules! request_code_write {
1523da5c369Sopenharmony_ci    ($ty:expr, $nr:expr, $sz:expr) => {
1533da5c369Sopenharmony_ci        ioc!($crate::sys::ioctl::WRITE, $ty, $nr, $sz)
1543da5c369Sopenharmony_ci    };
1553da5c369Sopenharmony_ci}
1563da5c369Sopenharmony_ci
1573da5c369Sopenharmony_ci/// Generate an ioctl request code for a command that reads and writes.
1583da5c369Sopenharmony_ci///
1593da5c369Sopenharmony_ci/// This is equivalent to the `_IOWR()` macro exposed by the C ioctl API.
1603da5c369Sopenharmony_ci///
1613da5c369Sopenharmony_ci/// You should only use this macro directly if the `ioctl` you're working
1623da5c369Sopenharmony_ci/// with is "bad" and you cannot use `ioctl_readwrite!()` directly.
1633da5c369Sopenharmony_ci#[macro_export(local_inner_macros)]
1643da5c369Sopenharmony_cimacro_rules! request_code_readwrite {
1653da5c369Sopenharmony_ci    ($ty:expr, $nr:expr, $sz:expr) => {
1663da5c369Sopenharmony_ci        ioc!(
1673da5c369Sopenharmony_ci            $crate::sys::ioctl::READ | $crate::sys::ioctl::WRITE,
1683da5c369Sopenharmony_ci            $ty,
1693da5c369Sopenharmony_ci            $nr,
1703da5c369Sopenharmony_ci            $sz
1713da5c369Sopenharmony_ci        )
1723da5c369Sopenharmony_ci    };
1733da5c369Sopenharmony_ci}
174