feat: add Interface::clear_halt(endpoint: u8) for direct endpoint halt clearing
Some checks failed
Rust / format (push) Has been cancelled
Rust / build (macos-latest, 1.79) (push) Has been cancelled
Rust / build (macos-latest, stable) (push) Has been cancelled
Rust / build (ubuntu-latest, 1.79) (push) Has been cancelled
Rust / build (ubuntu-latest, stable) (push) Has been cancelled
Rust / build (windows-latest, 1.79) (push) Has been cancelled
Rust / build (windows-latest, stable) (push) Has been cancelled
Rust / build_android (push) Has been cancelled
Some checks failed
Rust / format (push) Has been cancelled
Rust / build (macos-latest, 1.79) (push) Has been cancelled
Rust / build (macos-latest, stable) (push) Has been cancelled
Rust / build (ubuntu-latest, 1.79) (push) Has been cancelled
Rust / build (ubuntu-latest, stable) (push) Has been cancelled
Rust / build (windows-latest, 1.79) (push) Has been cancelled
Rust / build (windows-latest, stable) (push) Has been cancelled
Rust / build_android (push) Has been cancelled
Allows clearing a halt/stall condition by raw endpoint address without needing to construct a typed Endpoint object. Implemented on all three platform backends (Linux usbfs, macOS IOKit, Windows WinUSB). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
1239c6765a
commit
a45a3e08be
4 changed files with 55 additions and 0 deletions
|
|
@ -391,6 +391,19 @@ impl Interface {
|
|||
self.backend.clone().set_alt_setting(alt_setting)
|
||||
}
|
||||
|
||||
/// Clear a halt / stall condition on the given endpoint and reset the
|
||||
/// host-side data toggle.
|
||||
///
|
||||
/// Use this after receiving
|
||||
/// [`TransferError::Stall`][crate::transfer::TransferError::Stall] to clear
|
||||
/// the error and resume use of the endpoint.
|
||||
///
|
||||
/// Unlike [`Endpoint::clear_halt`], this operates directly by endpoint
|
||||
/// address without requiring an open [`Endpoint`].
|
||||
pub fn clear_halt(&self, endpoint: u8) -> impl MaybeFuture<Output = Result<(), Error>> {
|
||||
self.backend.clone().clear_halt(endpoint)
|
||||
}
|
||||
|
||||
/// Get the current alternate setting of this interface.
|
||||
pub fn get_alt_setting(&self) -> u8 {
|
||||
self.backend.get_alt_setting()
|
||||
|
|
|
|||
|
|
@ -757,6 +757,16 @@ impl LinuxInterface {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn clear_halt(self: Arc<Self>, endpoint: u8) -> impl MaybeFuture<Output = Result<(), Error>> {
|
||||
Blocking::new(move || {
|
||||
debug!("Clear halt, endpoint {endpoint:02x}");
|
||||
usbfs::clear_halt(&self.device.fd, endpoint).map_err(|e| match e {
|
||||
Errno::NODEV => Error::new_os(ErrorKind::Disconnected, "device disconnected", e),
|
||||
_ => Error::new_os(ErrorKind::Other, "failed to clear halt", e),
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
pub fn endpoint(
|
||||
self: &Arc<Self>,
|
||||
descriptor: EndpointDescriptor,
|
||||
|
|
|
|||
|
|
@ -422,6 +422,23 @@ impl MacInterface {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn clear_halt(self: Arc<Self>, endpoint: u8) -> impl MaybeFuture<Output = Result<(), Error>> {
|
||||
Blocking::new(move || {
|
||||
debug!("Clear halt, endpoint {endpoint:02x}");
|
||||
let pipe_ref = self.interface.find_pipe_ref(endpoint).ok_or_else(|| {
|
||||
Error::new(ErrorKind::NotFound, "endpoint not found on interface")
|
||||
})?;
|
||||
self.interface
|
||||
.clear_pipe_stall_both_ends(pipe_ref)
|
||||
.map_err(|e| match e {
|
||||
io_kit_sys::ret::kIOReturnNoDevice => {
|
||||
Error::new_os(ErrorKind::Disconnected, "device disconnected", e)
|
||||
}
|
||||
_ => Error::new_os(ErrorKind::Other, "failed to clear halt on endpoint", e),
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_alt_setting(&self) -> u8 {
|
||||
self.state.lock().unwrap().alt_setting
|
||||
}
|
||||
|
|
|
|||
|
|
@ -508,6 +508,21 @@ impl WindowsInterface {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn clear_halt(self: Arc<Self>, endpoint: u8) -> impl MaybeFuture<Output = Result<(), Error>> {
|
||||
Blocking::new(move || {
|
||||
debug!("Clear halt, endpoint {endpoint:02x}");
|
||||
unsafe {
|
||||
if WinUsb_ResetPipe(self.winusb_handle, endpoint) == TRUE {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(match GetLastError() {
|
||||
e => Error::new_os(ErrorKind::Other, "failed to clear halt", e),
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_alt_setting(&self) -> u8 {
|
||||
self.state.lock().unwrap().alt_setting
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue