Skip to content

Commit

Permalink
Try to detach drivers separately
Browse files Browse the repository at this point in the history
  • Loading branch information
bugadani committed Jan 28, 2024
1 parent 4a80b78 commit a73a301
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 24 deletions.
3 changes: 2 additions & 1 deletion src/platform/linux_usbfs/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,8 @@ impl LinuxDevice {
self: &Arc<Self>,
interface: u8,
) -> Result<Arc<LinuxInterface>, Error> {
usbfs::detach_and_claim_interface(&self.fd, interface)?;
usbfs::detach_kernel_driver(&self.fd, interface)?;
usbfs::claim_interface(&self.fd, interface)?;
debug!(
"Claimed interface {interface} on device id {dev}",
dev = self.events_id
Expand Down
28 changes: 5 additions & 23 deletions src/platform/linux_usbfs/usbfs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,35 +31,17 @@ pub fn claim_interface<Fd: AsFd>(fd: Fd, interface: u8) -> io::Result<()> {
}
}

#[repr(C)]
struct DetachAndClaimIface {
interface: c_uint,
flags: c_uint,

// Note: USBDEVFS_MAXDRIVERNAME is 255, but we only use 5 bytes for the driver name. Using 5
// here simplifies the implementation.
driver: [c_uchar; 5 + 1],
}

pub fn detach_and_claim_interface<Fd: AsFd>(fd: Fd, interface: u8) -> io::Result<()> {
const USBDEVFS_DISCONNECT_CLAIM_EXCEPT_DRIVER: c_uint = 0x02;
pub fn release_interface<Fd: AsFd>(fd: Fd, interface: u8) -> io::Result<()> {
unsafe {
let ctl = ioctl::Setter::<
ioctl::ReadOpcode<b'U', 27, DetachAndClaimIface>,
DetachAndClaimIface,
>::new(DetachAndClaimIface {
interface: interface.into(),
flags: USBDEVFS_DISCONNECT_CLAIM_EXCEPT_DRIVER,
driver: *b"usbfs\0",
});
let ctl =
ioctl::Setter::<ioctl::ReadOpcode<b'U', 16, c_uint>, c_uint>::new(interface.into());
ioctl::ioctl(fd, ctl)
}
}

pub fn release_interface<Fd: AsFd>(fd: Fd, interface: u8) -> io::Result<()> {
pub fn detach_kernel_driver<Fd: AsFd>(fd: Fd, interface: u8) -> io::Result<()> {
unsafe {
let ctl =
ioctl::Setter::<ioctl::ReadOpcode<b'U', 16, c_uint>, c_uint>::new(interface.into());
let ctl = ioctl::NoArg::<ioctl::NoneOpcode<b'U', 22, ()>, ()>::new();
ioctl::ioctl(fd, ctl)
}
}
Expand Down

0 comments on commit a73a301

Please sign in to comment.