USB: graceful disconnect handling in usbhidd — survive transfer errors
Replaced .context("failed to get report")? crash-on-disconnect
with explicit match/continue loop that logs the error and retries.
On device disconnect: transfer_read/get_report fails → warn log →
continue loop (transient). Driver survives USB unplug/replug
without process exit. On permanent failure: loop exits normally.
Pattern to replicate across all class drivers.
This commit is contained in:
@@ -338,21 +338,27 @@ fn main() -> Result<()> {
|
||||
}
|
||||
|
||||
if let Some(endpoint) = &mut endpoint_opt {
|
||||
// interrupt transfer
|
||||
endpoint
|
||||
.transfer_read(&mut report_buffer)
|
||||
.context("failed to get report")?;
|
||||
match endpoint.transfer_read(&mut report_buffer) {
|
||||
Ok(_) => {}
|
||||
Err(e) => {
|
||||
log::warn!("usbhidd: interrupt transfer failed: {} — retrying", e);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// control transfer
|
||||
reqs::get_report(
|
||||
match reqs::get_report(
|
||||
&handle,
|
||||
report_ty,
|
||||
report_id,
|
||||
//TODO: should this be an index into interface_descs?
|
||||
interface_num as u16,
|
||||
&mut report_buffer,
|
||||
)
|
||||
.context("failed to get report")?;
|
||||
) {
|
||||
Ok(()) => {}
|
||||
Err(e) => {
|
||||
log::warn!("usbhidd: control transfer failed: {} — retrying", e);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut mouse_pos = last_mouse_pos;
|
||||
|
||||
Reference in New Issue
Block a user