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_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},
|
||||
};
|
||||
|
||||
|
|
@ -540,6 +543,7 @@ impl WindowsInterface {
|
|||
let len = t.request_len;
|
||||
let buf = t.buf;
|
||||
t.overlapped.InternalHigh = 0;
|
||||
t.error_from_submit = Ok(());
|
||||
|
||||
let t = t.pre_submit();
|
||||
let ptr = t.as_ptr();
|
||||
|
|
@ -580,6 +584,7 @@ impl WindowsInterface {
|
|||
let len = t.request_len;
|
||||
let buf = t.buf;
|
||||
t.overlapped.InternalHigh = 0;
|
||||
t.error_from_submit = Ok(());
|
||||
|
||||
let t = t.pre_submit();
|
||||
let ptr = t.as_ptr();
|
||||
|
|
@ -613,7 +618,13 @@ impl WindowsInterface {
|
|||
// Safety: Transfer was not submitted, so we still own it
|
||||
// and must complete it in place of the event thread.
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ pub struct TransferData {
|
|||
pub(crate) capacity: u32,
|
||||
pub(crate) request_len: u32,
|
||||
pub(crate) endpoint: u8,
|
||||
pub(crate) error_from_submit: Result<(), TransferError>,
|
||||
}
|
||||
|
||||
unsafe impl Send for TransferData {}
|
||||
|
|
@ -39,6 +40,7 @@ impl TransferData {
|
|||
capacity: 0,
|
||||
request_len: 0,
|
||||
endpoint,
|
||||
error_from_submit: Ok(()),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -62,19 +64,22 @@ impl TransferData {
|
|||
pub fn take_completion(&mut self, intf: &Interface) -> Completion {
|
||||
let mut actual_len: u32 = 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_GEN_FAILURE => Err(TransferError::Stall),
|
||||
ERROR_REQUEST_ABORTED | ERROR_TIMEOUT | ERROR_SEM_TIMEOUT | ERROR_OPERATION_ABORTED => {
|
||||
Err(TransferError::Cancelled)
|
||||
}
|
||||
ERROR_REQUEST_ABORTED
|
||||
| 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)),
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
let mut empty = ManuallyDrop::new(Vec::new());
|
||||
let ptr = mem::replace(&mut self.buf, empty.as_mut_ptr());
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue