Rebase against d744f367d263a131feee96e103fb8220e8400b53

This commit is contained in:
Alistair Leslie-Hughes
2018-08-16 09:16:32 +10:00
parent e7bff1bb4f
commit ec47c04ab3
9 changed files with 59 additions and 438 deletions

View File

@@ -1,155 +0,0 @@
From c6c0b64be4f8505a769aa08dca8fa3078831aed5 Mon Sep 17 00:00:00 2001
From: Aric Stewart <aric@codeweavers.com>
Date: Tue, 24 Jul 2018 08:16:45 -0500
Subject: [PATCH 06/24] hidclass.sys: Unload all devices before unloading a
minidriver
Signed-off-by: Aric Stewart <aric@codeweavers.com>
---
dlls/hidclass.sys/hid.h | 8 ++++++++
dlls/hidclass.sys/main.c | 8 ++++++++
dlls/hidclass.sys/pnp.c | 35 +++++++++++++++++++++++++++++++----
3 files changed, 47 insertions(+), 4 deletions(-)
diff --git a/dlls/hidclass.sys/hid.h b/dlls/hidclass.sys/hid.h
index 1829319..4e8ba3c 100644
--- a/dlls/hidclass.sys/hid.h
+++ b/dlls/hidclass.sys/hid.h
@@ -70,6 +70,12 @@ void RingBuffer_Destroy(struct ReportRingBuffer *buffer) DECLSPEC_HIDDEN;
struct ReportRingBuffer* RingBuffer_Create(UINT buffer_size) DECLSPEC_HIDDEN;
NTSTATUS RingBuffer_SetSize(struct ReportRingBuffer *buffer, UINT size) DECLSPEC_HIDDEN;
+typedef struct _hiddevice
+{
+ struct list entry;
+ DEVICE_OBJECT *device;
+} hid_device;
+
typedef struct _minidriver
{
struct list entry;
@@ -80,6 +86,7 @@ typedef struct _minidriver
pAddDevice AddDevice;
PDRIVER_DISPATCH PNPDispatch;
+ struct list device_list;
} minidriver;
NTSTATUS call_minidriver(ULONG code, DEVICE_OBJECT *device, void *in_buff, ULONG in_size, void *out_buff, ULONG out_size) DECLSPEC_HIDDEN;
@@ -100,6 +107,7 @@ NTSTATUS WINAPI HID_PNP_Dispatch(DEVICE_OBJECT *device, IRP *irp) DECLSPEC_HIDDE
/* Pseudo-Plug and Play support*/
NTSTATUS WINAPI PNP_AddDevice(DRIVER_OBJECT *driver, DEVICE_OBJECT* PDO) DECLSPEC_HIDDEN;
+NTSTATUS PNP_RemoveDevice(minidriver *minidriver, DEVICE_OBJECT* device, IRP* irp) DECLSPEC_HIDDEN;
/* Parsing HID Report Descriptors into preparsed data */
WINE_HIDP_PREPARSED_DATA* ParseDescriptor(BYTE *descriptor, unsigned int length) DECLSPEC_HIDDEN;
diff --git a/dlls/hidclass.sys/main.c b/dlls/hidclass.sys/main.c
index 1742cfe..8bb423b 100644
--- a/dlls/hidclass.sys/main.c
+++ b/dlls/hidclass.sys/main.c
@@ -49,6 +49,12 @@ static VOID WINAPI UnloadDriver(DRIVER_OBJECT *driver)
md = find_minidriver(driver);
if (md)
{
+ hid_device *device, *next;
+ TRACE("%i devices to unload\n", list_count(&md->device_list));
+ LIST_FOR_EACH_ENTRY_SAFE(device, next, &md->device_list, hid_device, entry)
+ {
+ PNP_RemoveDevice(md, device->device, NULL);
+ }
if (md->DriverUnload)
md->DriverUnload(md->minidriver.DriverObject);
list_remove(&md->entry);
@@ -82,6 +88,8 @@ NTSTATUS WINAPI HidRegisterMinidriver(HID_MINIDRIVER_REGISTRATION *registration)
driver->minidriver = *registration;
list_add_tail(&minidriver_list, &driver->entry);
+ list_init(&driver->device_list);
+
return STATUS_SUCCESS;
}
diff --git a/dlls/hidclass.sys/pnp.c b/dlls/hidclass.sys/pnp.c
index 30d1045..c501a74 100644
--- a/dlls/hidclass.sys/pnp.c
+++ b/dlls/hidclass.sys/pnp.c
@@ -75,6 +75,7 @@ static NTSTATUS get_device_id(DEVICE_OBJECT *device, BUS_QUERY_ID_TYPE type, WCH
NTSTATUS WINAPI PNP_AddDevice(DRIVER_OBJECT *driver, DEVICE_OBJECT *PDO)
{
+ hid_device *hiddev;
DEVICE_OBJECT *device = NULL;
NTSTATUS status;
minidriver *minidriver;
@@ -96,13 +97,19 @@ NTSTATUS WINAPI PNP_AddDevice(DRIVER_OBJECT *driver, DEVICE_OBJECT *PDO)
TRACE("PDO add device(%p:%s)\n", PDO, debugstr_w(PDO_id));
minidriver = find_minidriver(driver);
- status = HID_CreateDevice(PDO, &minidriver->minidriver, &device);
+ hiddev = HeapAlloc(GetProcessHeap(), 0, sizeof(*hiddev));
+ if (!hiddev)
+ return STATUS_NO_MEMORY;
+
+ status = HID_CreateDevice(PDO, &minidriver->minidriver, &hiddev->device);
if (status != STATUS_SUCCESS)
{
ERR("Failed to create HID object (%x)\n",status);
HeapFree(GetProcessHeap(), 0, PDO_id);
+ HeapFree(GetProcessHeap(), 0, hiddev);
return status;
}
+ device = hiddev->device;
ext = device->DeviceExtension;
InitializeListHead(&ext->irp_queue);
@@ -177,6 +184,8 @@ NTSTATUS WINAPI PNP_AddDevice(DRIVER_OBJECT *driver, DEVICE_OBJECT *PDO)
return STATUS_NOT_SUPPORTED;
}
+ list_add_tail(&(minidriver->device_list), &hiddev->entry);
+
ext->information.DescriptorSize = ext->preparseData->dwSize;
lstrcpyW(ext->instance_id, device_enumeratorW);
@@ -200,6 +209,26 @@ NTSTATUS WINAPI PNP_AddDevice(DRIVER_OBJECT *driver, DEVICE_OBJECT *PDO)
return STATUS_SUCCESS;
}
+NTSTATUS PNP_RemoveDevice(minidriver *minidriver, DEVICE_OBJECT *device, IRP* irp)
+{
+ hid_device *hiddev;
+ NTSTATUS rc = STATUS_NOT_SUPPORTED;
+
+ if (irp)
+ rc = minidriver->PNPDispatch(device, irp);
+ HID_DeleteDevice(&minidriver->minidriver, device);
+ LIST_FOR_EACH_ENTRY(hiddev, &minidriver->device_list, hid_device, entry)
+ {
+ if (hiddev->device == device)
+ {
+ list_remove(&hiddev->entry);
+ HeapFree(GetProcessHeap(), 0, hiddev);
+ break;
+ }
+ }
+ return rc;
+}
+
NTSTATUS WINAPI HID_PNP_Dispatch(DEVICE_OBJECT *device, IRP *irp)
{
NTSTATUS rc = STATUS_NOT_SUPPORTED;
@@ -255,9 +284,7 @@ NTSTATUS WINAPI HID_PNP_Dispatch(DEVICE_OBJECT *device, IRP *irp)
}
case IRP_MN_REMOVE_DEVICE:
{
- rc = minidriver->PNPDispatch(device, irp);
- HID_DeleteDevice(&minidriver->minidriver, device);
- return rc;
+ return PNP_RemoveDevice(minidriver, device, irp);
}
default:
{
--
1.9.1

View File

@@ -1,198 +0,0 @@
From 6b416c0b1c963ced6ec11ccf46b9e99650267297 Mon Sep 17 00:00:00 2001
From: Kai Krakow <kai@kaishome.de>
Date: Sat, 28 Jul 2018 10:24:04 +0200
Subject: [PATCH 13/24] winebus.sys: Do not report HID report read errors
unconditionally
Device reports may come in faster than our consumers could possibly read
them, this is especially true for multi-axis events: When you move a
stick across its range, it will always generate at least two events, one
for the x axis, and one for the y axis. This is not really an error
situation, so let's report this situation only once at most. If we
already know the multi-event situation, let's skip logging this
completely: We won't loose any information anyway because the report
contains a complete device state and only axis positions were updated.
Thus, this commit adds a parameter to process_hid_report() to let it
know if we are currently processing reports that are known to be sent
multiple times in sequence (with updated reports).
Also, if our consumers are slow to respond, then report the issue only
once and not per each occurrence during the duration of one consumer
read cycle.
Finally, this is not really an error, it's a warning at most, thus
degrade the error message to a warning to not pollute peoples consoles
and logs with unimportant stuff.
Especially during gaming I was seeing screens over screens full of only
this single log message. This commit fixes it.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=43125
CC: Aric Stewart <aric@codeweavers.com>
Signed-off-by: Aric Stewart <aric@codeweavers.com>
Signed-off-by: Kai Krakow <kai@kaishome.de>
---
dlls/winebus.sys/bus.h | 2 +-
dlls/winebus.sys/bus_iohid.c | 2 +-
dlls/winebus.sys/bus_sdl.c | 12 ++++++------
dlls/winebus.sys/bus_udev.c | 4 ++--
dlls/winebus.sys/main.c | 18 +++++++++++++++---
5 files changed, 25 insertions(+), 13 deletions(-)
diff --git a/dlls/winebus.sys/bus.h b/dlls/winebus.sys/bus.h
index bf93c04..1e2989e 100644
--- a/dlls/winebus.sys/bus.h
+++ b/dlls/winebus.sys/bus.h
@@ -45,7 +45,7 @@ DEVICE_OBJECT *bus_create_hid_device(DRIVER_OBJECT *driver, const WCHAR *busidW,
DEVICE_OBJECT *bus_find_hid_device(const platform_vtbl *vtbl, void *platform_dev) DECLSPEC_HIDDEN;
void bus_remove_hid_device(DEVICE_OBJECT *device) DECLSPEC_HIDDEN;
NTSTATUS WINAPI hid_internal_dispatch(DEVICE_OBJECT *device, IRP *irp) DECLSPEC_HIDDEN;
-void process_hid_report(DEVICE_OBJECT *device, BYTE *report, DWORD length) DECLSPEC_HIDDEN;
+void process_hid_report(DEVICE_OBJECT *device, BYTE *report, DWORD length, BOOL warn_multi_events) DECLSPEC_HIDDEN;
DEVICE_OBJECT* bus_enumerate_hid_devices(const platform_vtbl *vtbl, enum_func function, void* context) DECLSPEC_HIDDEN;
/* General Bus Functions */
diff --git a/dlls/winebus.sys/bus_iohid.c b/dlls/winebus.sys/bus_iohid.c
index 501a40d..74e5d82 100644
--- a/dlls/winebus.sys/bus_iohid.c
+++ b/dlls/winebus.sys/bus_iohid.c
@@ -135,7 +135,7 @@ static void handle_IOHIDDeviceIOHIDReportCallback(void *context,
uint32_t reportID, uint8_t *report, CFIndex report_length)
{
DEVICE_OBJECT *device = (DEVICE_OBJECT*)context;
- process_hid_report(device, report, report_length);
+ process_hid_report(device, report, report_length, TRUE);
}
static int compare_platform_device(DEVICE_OBJECT *device, void *platform_dev)
diff --git a/dlls/winebus.sys/bus_sdl.c b/dlls/winebus.sys/bus_sdl.c
index 159727f..99a206c 100644
--- a/dlls/winebus.sys/bus_sdl.c
+++ b/dlls/winebus.sys/bus_sdl.c
@@ -683,7 +683,7 @@ static BOOL set_report_from_event(SDL_Event *event)
set_button_value(ie->button, ie->state, private->report_buffer);
- process_hid_report(device, private->report_buffer, private->buffer_length);
+ process_hid_report(device, private->report_buffer, private->buffer_length, TRUE);
break;
}
case SDL_JOYAXISMOTION:
@@ -693,7 +693,7 @@ static BOOL set_report_from_event(SDL_Event *event)
if (ie->axis < 6)
{
set_axis_value(private, ie->axis, ie->value);
- process_hid_report(device, private->report_buffer, private->buffer_length);
+ process_hid_report(device, private->report_buffer, private->buffer_length, FALSE);
}
break;
}
@@ -702,7 +702,7 @@ static BOOL set_report_from_event(SDL_Event *event)
SDL_JoyBallEvent *ie = &event->jball;
set_ball_value(private, ie->ball, ie->xrel, ie->yrel);
- process_hid_report(device, private->report_buffer, private->buffer_length);
+ process_hid_report(device, private->report_buffer, private->buffer_length, FALSE);
break;
}
case SDL_JOYHATMOTION:
@@ -710,7 +710,7 @@ static BOOL set_report_from_event(SDL_Event *event)
SDL_JoyHatEvent *ie = &event->jhat;
set_hat_value(private, ie->hat, ie->value);
- process_hid_report(device, private->report_buffer, private->buffer_length);
+ process_hid_report(device, private->report_buffer, private->buffer_length, TRUE);
break;
}
default:
@@ -765,7 +765,7 @@ static BOOL set_mapped_report_from_event(SDL_Event *event)
if (usage >= 0)
{
set_button_value(usage, ie->state, private->report_buffer);
- process_hid_report(device, private->report_buffer, private->buffer_length);
+ process_hid_report(device, private->report_buffer, private->buffer_length, TRUE);
}
break;
}
@@ -774,7 +774,7 @@ static BOOL set_mapped_report_from_event(SDL_Event *event)
SDL_ControllerAxisEvent *ie = &event->caxis;
set_axis_value(private, ie->axis, ie->value);
- process_hid_report(device, private->report_buffer, private->buffer_length);
+ process_hid_report(device, private->report_buffer, private->buffer_length, FALSE);
break;
}
default:
diff --git a/dlls/winebus.sys/bus_udev.c b/dlls/winebus.sys/bus_udev.c
index d34e18c..47b9758 100644
--- a/dlls/winebus.sys/bus_udev.c
+++ b/dlls/winebus.sys/bus_udev.c
@@ -768,7 +768,7 @@ static DWORD CALLBACK device_report_thread(void *args)
else if (size == 0)
TRACE_(hid_report)("Failed to read report\n");
else
- process_hid_report(device, report_buffer, size);
+ process_hid_report(device, report_buffer, size, TRUE);
}
return 0;
}
@@ -979,7 +979,7 @@ static DWORD CALLBACK lnxev_device_report_thread(void *args)
else if (size == 0)
TRACE_(hid_report)("Failed to read report\n");
else if (set_report_from_event(private, &ie))
- process_hid_report(device, private->current_report_buffer, private->buffer_length);
+ process_hid_report(device, private->current_report_buffer, private->buffer_length, TRUE);
}
return 0;
}
diff --git a/dlls/winebus.sys/main.c b/dlls/winebus.sys/main.c
index 2f3c05a..624ddd5 100644
--- a/dlls/winebus.sys/main.c
+++ b/dlls/winebus.sys/main.c
@@ -614,11 +614,12 @@ NTSTATUS WINAPI hid_internal_dispatch(DEVICE_OBJECT *device, IRP *irp)
return status;
}
-void process_hid_report(DEVICE_OBJECT *device, BYTE *report, DWORD length)
+void process_hid_report(DEVICE_OBJECT *device, BYTE *report, DWORD length, BOOL warn_multi_events)
{
struct device_extension *ext = (struct device_extension*)device->DeviceExtension;
IRP *irp;
LIST_ENTRY *entry;
+ static int overwrite_reported;
if (!length || !report)
return;
@@ -641,8 +642,18 @@ void process_hid_report(DEVICE_OBJECT *device, BYTE *report, DWORD length)
ext->buffer_size = length;
}
- if (!ext->last_report_read)
- ERR_(hid_report)("Device reports coming in too fast, last report not read yet!\n");
+ /*
+ * Device reports may come in faster than our consumers could possibly
+ * read them, this is especially true for multi-axis events: When you move
+ * a stick across its range, it will always generate at least two events,
+ * one for the x axis, and one for the y axis. This is not really an error
+ * situation, so let's report this situation only once at most. If we
+ * already know the multi-event situation, let's skip logging this
+ * completely: We won't loose any information anyway because the report
+ * contains a complete device state and only axis positions were updated.
+ */
+ if (warn_multi_events && !ext->last_report_read && !overwrite_reported++)
+ WARN_(hid_report)("Device reports coming in too fast, last report not read yet!\n");
memcpy(ext->last_report, report, length);
ext->last_report_size = length;
@@ -659,6 +670,7 @@ void process_hid_report(DEVICE_OBJECT *device, BYTE *report, DWORD length)
irp->UserBuffer, &irp->IoStatus.Information);
ext->last_report_read = TRUE;
IoCompleteRequest(irp, IO_NO_INCREMENT);
+ overwrite_reported = 0;
}
LeaveCriticalSection(&ext->report_cs);
}
--
1.9.1