From f0a2e8c5a71ff701e7b980b361ab9396886ee351 Mon Sep 17 00:00:00 2001 From: Kevin Mehall Date: Fri, 7 Mar 2025 22:43:22 -0700 Subject: [PATCH] linux: use ioctl numbers from linux_raw_sys --- Cargo.toml | 1 + src/platform/linux_usbfs/usbfs.rs | 83 ++++++++++--------------------- 2 files changed, 28 insertions(+), 56 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index b0afabd..67a0576 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,6 +23,7 @@ futures-lite = "1.13.0" [target.'cfg(any(target_os="linux", target_os="android"))'.dependencies] rustix = { version = "1.0.1", features = ["fs", "event", "net"] } +linux-raw-sys = { version = "0.9.2", features = ["ioctl"] } [target.'cfg(target_os="windows")'.dependencies] windows-sys = { version = "0.59.0", features = ["Win32_Devices_Usb", "Win32_Devices_DeviceAndDriverInstallation", "Win32_Foundation", "Win32_Devices_Properties", "Win32_Storage_FileSystem", "Win32_Security", "Win32_System_IO", "Win32_System_Registry", "Win32_System_Com"] } diff --git a/src/platform/linux_usbfs/usbfs.rs b/src/platform/linux_usbfs/usbfs.rs index 19a693c..e0e6ea1 100644 --- a/src/platform/linux_usbfs/usbfs.rs +++ b/src/platform/linux_usbfs/usbfs.rs @@ -6,6 +6,12 @@ #![allow(dead_code)] use std::ffi::{c_int, c_uchar, c_uint, c_void}; +use linux_raw_sys::ioctl::{ + USBDEVFS_CLAIMINTERFACE, USBDEVFS_CLEAR_HALT, USBDEVFS_CONNECT, USBDEVFS_CONTROL, + USBDEVFS_DISCARDURB, USBDEVFS_DISCONNECT, USBDEVFS_DISCONNECT_CLAIM, USBDEVFS_GET_SPEED, + USBDEVFS_IOCTL, USBDEVFS_REAPURBNDELAY, USBDEVFS_RELEASEINTERFACE, USBDEVFS_RESET, + USBDEVFS_SETCONFIGURATION, USBDEVFS_SETINTERFACE, USBDEVFS_SUBMITURB, +}; use rustix::{ fd::AsFd, io, @@ -14,27 +20,23 @@ use rustix::{ pub fn set_configuration(fd: Fd, configuration: u8) -> io::Result<()> { unsafe { - let ctl = ioctl::Setter::<{ ioctl::opcode::read::(b'U', 5) }, c_uint>::new( - configuration.into(), - ); + let ctl = + ioctl::Setter::<{ USBDEVFS_SETCONFIGURATION as _ }, c_uint>::new(configuration.into()); ioctl::ioctl(fd, ctl) } } pub fn claim_interface(fd: Fd, interface: u8) -> io::Result<()> { unsafe { - let ctl = ioctl::Setter::<{ ioctl::opcode::read::(b'U', 15) }, c_uint>::new( - interface.into(), - ); + let ctl = ioctl::Setter::<{ USBDEVFS_CLAIMINTERFACE as _ }, c_uint>::new(interface.into()); ioctl::ioctl(fd, ctl) } } pub fn release_interface(fd: Fd, interface: u8) -> io::Result<()> { unsafe { - let ctl = ioctl::Setter::<{ ioctl::opcode::read::(b'U', 16) }, c_uint>::new( - interface.into(), - ); + let ctl = + ioctl::Setter::<{ USBDEVFS_RELEASEINTERFACE as _ }, c_uint>::new(interface.into()); ioctl::ioctl(fd, ctl) } } @@ -57,7 +59,7 @@ pub fn detach_and_claim_interface(fd: Fd, interface: u8) -> io::Result dc.driver[0..6].copy_from_slice(b"usbfs\0"); - let ctl = ioctl::Setter::<{ opcodes::USBDEVFS_DISCONNECT_CLAIM }, DetachAndClaim>::new(dc); + let ctl = ioctl::Setter::<{ USBDEVFS_DISCONNECT_CLAIM as _ }, DetachAndClaim>::new(dc); ioctl::ioctl(&fd, ctl) } @@ -70,39 +72,15 @@ struct UsbFsIoctl { data: *mut c_void, } -/// Opcodes used in ioctl with the usb device fs. -/// -/// Taken from https://github.com/torvalds/linux/blob/e9680017b2dc8686a908ea1b51941a91b6da9f1d/include/uapi/linux/usbdevice_fs.h#L187 -// We repeat the USBDEVFS_ prefix to help keep the same names as what linux uses. -// This makes the code more searchable. -// TODO: Move the rest of the opcodes into here. -#[allow(non_camel_case_types)] -mod opcodes { - use rustix::ioctl::Opcode; - - use super::*; - - pub const USBDEVFS_IOCTL: Opcode = ioctl::opcode::read_write::(b'U', 18); - pub const USBDEVFS_DISCONNECT_CLAIM: Opcode = ioctl::opcode::read::(b'U', 27); - - /// These opcodes are nested inside a [`USBDEVFS_IOCTL`] operation. - pub mod nested { - use super::*; - - pub const USBDEVFS_DISCONNECT: Opcode = ioctl::opcode::none(b'U', 22); - pub const USBDEVFS_CONNECT: Opcode = ioctl::opcode::none(b'U', 23); - } -} - pub fn detach_kernel_driver(fd: Fd, interface: u8) -> io::Result<()> { let command = UsbFsIoctl { interface: interface.into(), // NOTE: Cast needed since on android this type is i32 vs u32 on linux - ioctl_code: opcodes::nested::USBDEVFS_DISCONNECT as _, + ioctl_code: USBDEVFS_DISCONNECT as _, data: std::ptr::null_mut(), }; unsafe { - let ctl = ioctl::Setter::<{ opcodes::USBDEVFS_IOCTL }, UsbFsIoctl>::new(command); + let ctl = ioctl::Setter::<{ USBDEVFS_IOCTL as _ }, UsbFsIoctl>::new(command); ioctl::ioctl(fd, ctl) } } @@ -110,11 +88,11 @@ pub fn detach_kernel_driver(fd: Fd, interface: u8) -> io::Result<()> { pub fn attach_kernel_driver(fd: Fd, interface: u8) -> io::Result<()> { let command = UsbFsIoctl { interface: interface.into(), - ioctl_code: opcodes::nested::USBDEVFS_CONNECT as _, + ioctl_code: USBDEVFS_CONNECT as _, data: std::ptr::null_mut(), }; unsafe { - let ctl = ioctl::Setter::<{ opcodes::USBDEVFS_IOCTL }, UsbFsIoctl>::new(command); + let ctl = ioctl::Setter::<{ USBDEVFS_IOCTL as _ }, UsbFsIoctl>::new(command); ioctl::ioctl(fd, ctl) } } @@ -128,12 +106,10 @@ struct SetAltSetting { pub fn set_interface(fd: Fd, interface: u8, alt_setting: u8) -> io::Result<()> { unsafe { let ctl = - ioctl::Setter::<{ ioctl::opcode::read::(b'U', 4) }, SetAltSetting>::new( - SetAltSetting { - interface: interface.into(), - alt_setting: alt_setting.into(), - }, - ); + ioctl::Setter::<{ USBDEVFS_SETINTERFACE as _ }, SetAltSetting>::new(SetAltSetting { + interface: interface.into(), + alt_setting: alt_setting.into(), + }); ioctl::ioctl(fd, ctl) } } @@ -176,28 +152,28 @@ unsafe impl Ioctl for PassPtr { pub unsafe fn submit_urb(fd: Fd, urb: *mut Urb) -> io::Result<()> { unsafe { - let ctl = PassPtr::<{ ioctl::opcode::read::(b'U', 10) }, Urb>::new(urb); + let ctl = PassPtr::<{ USBDEVFS_SUBMITURB as _ }, Urb>::new(urb); ioctl::ioctl(fd, ctl) } } pub fn reap_urb_ndelay(fd: Fd) -> io::Result<*mut Urb> { unsafe { - let ctl = ioctl::Getter::<{ ioctl::opcode::write::<*mut Urb>(b'U', 13) }, *mut Urb>::new(); + let ctl = ioctl::Getter::<{ USBDEVFS_REAPURBNDELAY as _ }, *mut Urb>::new(); ioctl::ioctl(fd, ctl) } } pub unsafe fn discard_urb(fd: Fd, urb: *mut Urb) -> io::Result<()> { unsafe { - let ctl = PassPtr::<{ ioctl::opcode::none(b'U', 11) }, Urb>::new(urb); + let ctl = PassPtr::<{ USBDEVFS_DISCARDURB as _ }, Urb>::new(urb); ioctl::ioctl(fd, ctl) } } pub fn reset(fd: Fd) -> io::Result<()> { unsafe { - let ctl = ioctl::NoArg::<{ ioctl::opcode::none(b'U', 20) }>::new(); + let ctl = ioctl::NoArg::<{ USBDEVFS_RESET as _ }>::new(); ioctl::ioctl(fd, ctl) } } @@ -274,26 +250,21 @@ pub struct CtrlTransfer { pub fn control(fd: Fd, transfer: CtrlTransfer) -> io::Result { unsafe { - let ctl = - Transfer::<{ ioctl::opcode::read_write::(b'U', 0) }, CtrlTransfer>::new( - transfer, - ); + let ctl = Transfer::<{ USBDEVFS_CONTROL as _ }, CtrlTransfer>::new(transfer); ioctl::ioctl(fd, ctl) } } pub fn clear_halt(fd: Fd, endpoint: u8) -> io::Result<()> { unsafe { - let ctl = ioctl::Setter::<{ ioctl::opcode::read::(b'U', 21) }, c_uint>::new( - endpoint.into(), - ); + let ctl = ioctl::Setter::<{ USBDEVFS_CLEAR_HALT as _ }, c_uint>::new(endpoint.into()); ioctl::ioctl(fd, ctl) } } pub fn get_speed(fd: Fd) -> io::Result { unsafe { - let ctl = Transfer::<{ ioctl::opcode::none(b'U', 31) }, ()>::new(()); + let ctl = Transfer::<{ USBDEVFS_GET_SPEED as _ }, ()>::new(()); ioctl::ioctl(fd, ctl) } }