windows: fix submit-time error
This commit is contained in:
parent
5ac12ef088
commit
00667caa01
2 changed files with 29 additions and 13 deletions
|
|
@ -21,7 +21,10 @@ use windows_sys::Win32::{
|
||||||
WinUsb_SetPipePolicy, WinUsb_WritePipe, USB_DEVICE_DESCRIPTOR, WINUSB_INTERFACE_HANDLE,
|
WinUsb_SetPipePolicy, WinUsb_WritePipe, USB_DEVICE_DESCRIPTOR, WINUSB_INTERFACE_HANDLE,
|
||||||
WINUSB_SETUP_PACKET,
|
WINUSB_SETUP_PACKET,
|
||||||
},
|
},
|
||||||
Foundation::{GetLastError, ERROR_IO_PENDING, ERROR_NOT_FOUND, FALSE, HANDLE, TRUE},
|
Foundation::{
|
||||||
|
GetLastError, ERROR_BAD_COMMAND, ERROR_DEVICE_NOT_CONNECTED, ERROR_FILE_NOT_FOUND,
|
||||||
|
ERROR_IO_PENDING, ERROR_NOT_FOUND, ERROR_NO_SUCH_DEVICE, FALSE, HANDLE, TRUE,
|
||||||
|
},
|
||||||
System::IO::{CancelIoEx, OVERLAPPED},
|
System::IO::{CancelIoEx, OVERLAPPED},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -540,6 +543,7 @@ impl WindowsInterface {
|
||||||
let len = t.request_len;
|
let len = t.request_len;
|
||||||
let buf = t.buf;
|
let buf = t.buf;
|
||||||
t.overlapped.InternalHigh = 0;
|
t.overlapped.InternalHigh = 0;
|
||||||
|
t.error_from_submit = Ok(());
|
||||||
|
|
||||||
let t = t.pre_submit();
|
let t = t.pre_submit();
|
||||||
let ptr = t.as_ptr();
|
let ptr = t.as_ptr();
|
||||||
|
|
@ -580,6 +584,7 @@ impl WindowsInterface {
|
||||||
let len = t.request_len;
|
let len = t.request_len;
|
||||||
let buf = t.buf;
|
let buf = t.buf;
|
||||||
t.overlapped.InternalHigh = 0;
|
t.overlapped.InternalHigh = 0;
|
||||||
|
t.error_from_submit = Ok(());
|
||||||
|
|
||||||
let t = t.pre_submit();
|
let t = t.pre_submit();
|
||||||
let ptr = t.as_ptr();
|
let ptr = t.as_ptr();
|
||||||
|
|
@ -613,7 +618,13 @@ impl WindowsInterface {
|
||||||
// Safety: Transfer was not submitted, so we still own it
|
// Safety: Transfer was not submitted, so we still own it
|
||||||
// and must complete it in place of the event thread.
|
// and must complete it in place of the event thread.
|
||||||
unsafe {
|
unsafe {
|
||||||
(*t.as_ptr()).overlapped.Internal = err as _;
|
(*t.as_ptr()).error_from_submit = match err {
|
||||||
|
ERROR_BAD_COMMAND
|
||||||
|
| ERROR_FILE_NOT_FOUND
|
||||||
|
| ERROR_DEVICE_NOT_CONNECTED
|
||||||
|
| ERROR_NO_SUCH_DEVICE => Err(TransferError::Disconnected),
|
||||||
|
other => Err(TransferError::Unknown(other)),
|
||||||
|
};
|
||||||
notify_completion::<TransferData>(t.as_ptr());
|
notify_completion::<TransferData>(t.as_ptr());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ pub struct TransferData {
|
||||||
pub(crate) capacity: u32,
|
pub(crate) capacity: u32,
|
||||||
pub(crate) request_len: u32,
|
pub(crate) request_len: u32,
|
||||||
pub(crate) endpoint: u8,
|
pub(crate) endpoint: u8,
|
||||||
|
pub(crate) error_from_submit: Result<(), TransferError>,
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl Send for TransferData {}
|
unsafe impl Send for TransferData {}
|
||||||
|
|
@ -39,6 +40,7 @@ impl TransferData {
|
||||||
capacity: 0,
|
capacity: 0,
|
||||||
request_len: 0,
|
request_len: 0,
|
||||||
endpoint,
|
endpoint,
|
||||||
|
error_from_submit: Ok(()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -62,19 +64,22 @@ impl TransferData {
|
||||||
pub fn take_completion(&mut self, intf: &Interface) -> Completion {
|
pub fn take_completion(&mut self, intf: &Interface) -> Completion {
|
||||||
let mut actual_len: u32 = 0;
|
let mut actual_len: u32 = 0;
|
||||||
|
|
||||||
unsafe { GetOverlappedResult(intf.handle, &self.overlapped, &mut actual_len, 0) };
|
let status = self.error_from_submit.and_then(|()| {
|
||||||
|
unsafe { GetOverlappedResult(intf.handle, &self.overlapped, &mut actual_len, 0) };
|
||||||
|
|
||||||
let status = match unsafe { GetLastError() } {
|
match unsafe { GetLastError() } {
|
||||||
ERROR_SUCCESS => Ok(()),
|
ERROR_SUCCESS => Ok(()),
|
||||||
ERROR_GEN_FAILURE => Err(TransferError::Stall),
|
ERROR_GEN_FAILURE => Err(TransferError::Stall),
|
||||||
ERROR_REQUEST_ABORTED | ERROR_TIMEOUT | ERROR_SEM_TIMEOUT | ERROR_OPERATION_ABORTED => {
|
ERROR_REQUEST_ABORTED
|
||||||
Err(TransferError::Cancelled)
|
| ERROR_TIMEOUT
|
||||||
|
| ERROR_SEM_TIMEOUT
|
||||||
|
| ERROR_OPERATION_ABORTED => Err(TransferError::Cancelled),
|
||||||
|
ERROR_FILE_NOT_FOUND | ERROR_DEVICE_NOT_CONNECTED | ERROR_NO_SUCH_DEVICE => {
|
||||||
|
Err(TransferError::Disconnected)
|
||||||
|
}
|
||||||
|
e => Err(TransferError::Unknown(e)),
|
||||||
}
|
}
|
||||||
ERROR_FILE_NOT_FOUND | ERROR_DEVICE_NOT_CONNECTED | ERROR_NO_SUCH_DEVICE => {
|
});
|
||||||
Err(TransferError::Disconnected)
|
|
||||||
}
|
|
||||||
e => Err(TransferError::Unknown(e)),
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut empty = ManuallyDrop::new(Vec::new());
|
let mut empty = ManuallyDrop::new(Vec::new());
|
||||||
let ptr = mem::replace(&mut self.buf, empty.as_mut_ptr());
|
let ptr = mem::replace(&mut self.buf, empty.as_mut_ptr());
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue