linux: use ioctl numbers from linux_raw_sys
This commit is contained in:
parent
0e145f89a6
commit
f0a2e8c5a7
2 changed files with 28 additions and 56 deletions
|
|
@ -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"] }
|
||||
|
|
|
|||
|
|
@ -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: AsFd>(fd: Fd, configuration: u8) -> io::Result<()> {
|
||||
unsafe {
|
||||
let ctl = ioctl::Setter::<{ ioctl::opcode::read::<c_uint>(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: AsFd>(fd: Fd, interface: u8) -> io::Result<()> {
|
||||
unsafe {
|
||||
let ctl = ioctl::Setter::<{ ioctl::opcode::read::<c_uint>(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: AsFd>(fd: Fd, interface: u8) -> io::Result<()> {
|
||||
unsafe {
|
||||
let ctl = ioctl::Setter::<{ ioctl::opcode::read::<c_uint>(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: AsFd>(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::<UsbFsIoctl>(b'U', 18);
|
||||
pub const USBDEVFS_DISCONNECT_CLAIM: Opcode = ioctl::opcode::read::<DetachAndClaim>(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: AsFd>(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: AsFd>(fd: Fd, interface: u8) -> io::Result<()> {
|
|||
pub fn attach_kernel_driver<Fd: AsFd>(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: AsFd>(fd: Fd, interface: u8, alt_setting: u8) -> io::Result<()> {
|
||||
unsafe {
|
||||
let ctl =
|
||||
ioctl::Setter::<{ ioctl::opcode::read::<SetAltSetting>(b'U', 4) }, SetAltSetting>::new(
|
||||
SetAltSetting {
|
||||
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<const OPCODE: Opcode, Input> Ioctl for PassPtr<OPCODE, Input> {
|
|||
|
||||
pub unsafe fn submit_urb<Fd: AsFd>(fd: Fd, urb: *mut Urb) -> io::Result<()> {
|
||||
unsafe {
|
||||
let ctl = PassPtr::<{ ioctl::opcode::read::<Urb>(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: AsFd>(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: AsFd>(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: AsFd>(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: AsFd>(fd: Fd, transfer: CtrlTransfer) -> io::Result<usize> {
|
||||
unsafe {
|
||||
let ctl =
|
||||
Transfer::<{ ioctl::opcode::read_write::<CtrlTransfer>(b'U', 0) }, CtrlTransfer>::new(
|
||||
transfer,
|
||||
);
|
||||
let ctl = Transfer::<{ USBDEVFS_CONTROL as _ }, CtrlTransfer>::new(transfer);
|
||||
ioctl::ioctl(fd, ctl)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn clear_halt<Fd: AsFd>(fd: Fd, endpoint: u8) -> io::Result<()> {
|
||||
unsafe {
|
||||
let ctl = ioctl::Setter::<{ ioctl::opcode::read::<c_uint>(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: AsFd>(fd: Fd) -> io::Result<usize> {
|
||||
unsafe {
|
||||
let ctl = Transfer::<{ ioctl::opcode::none(b'U', 31) }, ()>::new(());
|
||||
let ctl = Transfer::<{ USBDEVFS_GET_SPEED as _ }, ()>::new(());
|
||||
ioctl::ioctl(fd, ctl)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue