Cars: Mater National Championship expects that when two identical controllers are connected and then the first controller is unplugged and plugged back in, it gets the same device index that it had before. If it gets a different index, the controller does not work until the game is restarted.
As it stands without this patch, when the last device in the list is unplugged, its index becomes available for reuse, but if the last device is never unplugged, none of the indexes of the other devices formerly in the list can be reused. It doesn't make sense to make all index reuse depend on the last device. Instead, let's keep the device list sorted by index and reuse any free index immediately.
From: Alex Henrie dhenrale@amazon.com
Cars: Mater National Championship expects that when two identical controllers are connected and then the first controller is unplugged and plugged back in, it gets the same device index that it had before. If it gets a different index, the controller does not work until the game is restarted.
As it stands without this patch, when the last device in the list is unplugged, its index becomes available for reuse, but if the last device is never unplugged, none of the indexes of the other devices formerly in the list can be reused. It doesn't make sense to make all index reuse depend on the last device. Instead, let's keep the device list sorted by index and reuse any free index immediately. --- dlls/winebus.sys/main.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-)
diff --git a/dlls/winebus.sys/main.c b/dlls/winebus.sys/main.c index f7a634dbfe2..5128f737af1 100644 --- a/dlls/winebus.sys/main.c +++ b/dlls/winebus.sys/main.c @@ -159,15 +159,25 @@ static void unix_device_set_feature_report(DEVICE_OBJECT *device, HID_XFER_PACKE winebus_call(device_set_feature_report, ¶ms); }
-static DWORD get_device_index(struct device_desc *desc) +static DWORD get_device_index(struct device_desc *desc, struct list **before) { struct device_extension *ext; DWORD index = 0;
+ *before = NULL; + + /* The device list is sorted, so just increment the index until it doesn't match an index already in the list */ LIST_FOR_EACH_ENTRY(ext, &device_list, struct device_extension, entry) { if (ext->desc.vid == desc->vid && ext->desc.pid == desc->pid && ext->desc.input == desc->input) - index = max(ext->index + 1, index); + { + if (ext->index != index) + { + *before = &ext->entry; + break; + } + index++; + } }
return index; @@ -283,6 +293,7 @@ static DEVICE_OBJECT *bus_create_hid_device(struct device_desc *desc, UINT64 uni DEVICE_OBJECT *device; UNICODE_STRING nameW; WCHAR dev_name[256]; + struct list *before; NTSTATUS status;
TRACE("desc %s, unix_device %#I64x\n", debugstr_device_desc(desc), unix_device); @@ -302,7 +313,7 @@ static DEVICE_OBJECT *bus_create_hid_device(struct device_desc *desc, UINT64 uni ext = (struct device_extension *)device->DeviceExtension; ext->device = device; ext->desc = *desc; - ext->index = get_device_index(desc); + ext->index = get_device_index(desc, &before); ext->unix_device = unix_device; list_init(&ext->reports);
@@ -321,7 +332,10 @@ static DEVICE_OBJECT *bus_create_hid_device(struct device_desc *desc, UINT64 uni ext->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": cs");
/* add to list of pnp devices */ - list_add_tail(&device_list, &ext->entry); + if (before) + list_add_before(before, &ext->entry); + else + list_add_tail(&device_list, &ext->entry);
RtlLeaveCriticalSection(&device_list_cs);
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=149003
Your paranoid android.
=== debian11b (64 bit WoW report) ===
kernel32: comm.c:1574: Test failed: AbortWaitCts hComPortEvent failed comm.c:1586: Test failed: Unexpected time 1002, expected around 500
This merge request was approved by Rémi Bernon.