mirror of
https://github.com/Wack0/entii-for-workcubes.git
synced 2025-12-20 10:25:03 -05:00
arcfw(usb): when shutting down usb, ensure the device change callback is unlocked on the IOS side
this prevents deadlocks when loading iosusb.sys in NT
This commit is contained in:
@@ -749,8 +749,59 @@ LONG UlInit(void) {
|
|||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void UlpDeviceChangeCallback(LONG Status, ULONG Result, USB_INTERNAL_ASYNC_VARIANT Variant);
|
||||||
|
|
||||||
void UlShutdown(void) {
|
void UlShutdown(void) {
|
||||||
if (s_hUsbVen != IOS_HANDLE_INVALID) {
|
if (s_hUsbVen != IOS_HANDLE_INVALID) {
|
||||||
|
// Ensure async operations are done with.
|
||||||
|
// Might be stuck inside devicechange for both, this is allowed;
|
||||||
|
// allow one second for an async operation to complete, reset it if something completed.
|
||||||
|
UCHAR done = 0;
|
||||||
|
ULONG EndTime = currmsecs() + 1001;
|
||||||
|
while (done != (ARC_BIT(0) | ARC_BIT(1))) {
|
||||||
|
LONG Result;
|
||||||
|
PVOID Context;
|
||||||
|
USB_INTERNAL_ASYNC_STATE State;
|
||||||
|
bool doneOne = false;
|
||||||
|
if ((done & ARC_BIT(0)) == 0 && PxiIopIoctlAsyncPoll(s_AsyncIndexVen, &Result, &Context)) {
|
||||||
|
State = (USB_INTERNAL_ASYNC_STATE)Context;
|
||||||
|
|
||||||
|
if (State == STATE_DEVICE_CHANGE) UlpDeviceChangeCallback(Result, Result, VARIANT_VEN);
|
||||||
|
else if (State == STATE_ATTACH_FINISH) {
|
||||||
|
if (Result < 0) {
|
||||||
|
Result = PxiIopIoctlAsync(s_hUsbVen, USB_IOCTL_ATTACH_FINISH, NULL, 0, NULL, 0, IOCTL_SWAP_NONE, IOCTL_SWAP_NONE, (PVOID)STATE_ATTACH_FINISH);
|
||||||
|
if (Result < 0) done |= ARC_BIT(0);
|
||||||
|
else s_AsyncIndexVen = Result;
|
||||||
|
}
|
||||||
|
else done |= ARC_BIT(0);
|
||||||
|
}
|
||||||
|
doneOne = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((done & ARC_BIT(1)) == 0 && PxiIopIoctlAsyncPoll(s_AsyncIndexHid, &Result, &Context)) {
|
||||||
|
State = (USB_INTERNAL_ASYNC_STATE)Context;
|
||||||
|
|
||||||
|
if (State == STATE_DEVICE_CHANGE) UlpDeviceChangeCallback(Result, Result, VARIANT_HID);
|
||||||
|
else if (State == STATE_ATTACH_FINISH) {
|
||||||
|
if (Result < 0) {
|
||||||
|
Result = PxiIopIoctlAsync(s_hUsbHid, USB_IOCTL_ATTACH_FINISH, NULL, 0, NULL, 0, IOCTL_SWAP_NONE, IOCTL_SWAP_NONE, (PVOID)STATE_ATTACH_FINISH);
|
||||||
|
if (Result < 0) done |= ARC_BIT(1);
|
||||||
|
else s_AsyncIndexHid = Result;
|
||||||
|
}
|
||||||
|
else done |= ARC_BIT(1);
|
||||||
|
}
|
||||||
|
doneOne = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!doneOne) {
|
||||||
|
if (currmsecs() >= EndTime) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else EndTime = currmsecs() + 1001;
|
||||||
|
|
||||||
|
udelay(100);
|
||||||
|
}
|
||||||
PxiIopIoctl(s_hUsbHid, USB_IOCTL_SHUTDOWN, NULL, 0, NULL, 0, IOCTL_SWAP_NONE, IOCTL_SWAP_NONE);
|
PxiIopIoctl(s_hUsbHid, USB_IOCTL_SHUTDOWN, NULL, 0, NULL, 0, IOCTL_SWAP_NONE, IOCTL_SWAP_NONE);
|
||||||
PxiIopClose(s_hUsbHid);
|
PxiIopClose(s_hUsbHid);
|
||||||
PxiIopIoctl(s_hUsbVen, USB_IOCTL_SHUTDOWN, NULL, 0, NULL, 0, IOCTL_SWAP_NONE, IOCTL_SWAP_NONE);
|
PxiIopIoctl(s_hUsbVen, USB_IOCTL_SHUTDOWN, NULL, 0, NULL, 0, IOCTL_SWAP_NONE, IOCTL_SWAP_NONE);
|
||||||
|
|||||||
Reference in New Issue
Block a user