https://bugs.winehq.org/show_bug.cgi?id=43125
Bug ID: 43125 Summary: Device reports coming in too fast Product: Wine Version: 2.9 Hardware: x86-64 OS: Linux Status: UNCONFIRMED Severity: normal Priority: P2 Component: -unknown Assignee: wine-bugs@winehq.org Reporter: pershyn_nikolay@mail.ru Distribution: ---
Launching wine or winecfg in any prefix(including clean prefix) reports errors about device reports coming too fast.
$ WINEPREFIX=~/.local/share/wineprefixes/Temp32/ WINEARCH=win32 winecfg err:hid_report:process_hid_report Device reports coming in too fast, last report not read yet!
After it(any application or winecfg) is closed following line appears in console output:
wine: Unhandled page fault on read access to 0x7e479e70 at address 0x7ec9e1e1 (thread 0034)
I don't really know what information would be useful to provide here. Well, it says hid, which I assume means human interface device. My input devices are ROCCAT Tyon and Microsoft Natural Ergonomic Keyboard 4000.
# uname -a Linux subspace 4.9.16-gentoo #1 SMP Fri Apr 21 19:37:09 MDT 2017 x86_64 Intel(R) Xeon(R) CPU E5-2630 v3 @ 2.40GHz GenuineIntel GNU/Linux
# grep INPUT /etc/portage/make.conf INPUT_DEVICES="${INPUT_DEVICES} evdev roccat_tyon"
# ls -l /dev/input/by-id/ total 0 lrwxrwxrwx 1 root root 9 May 23 21:37 usb-Microsoft_Natural®_Ergonomic_Keyboard_4000-event-kbd -> ../event9 lrwxrwxrwx 1 root root 10 May 23 21:37 usb-Microsoft_Natural®_Ergonomic_Keyboard_4000-if01-event-kbd -> ../event10 lrwxrwxrwx 1 root root 10 May 23 21:37 usb-ROCCAT_ROCCAT_Tyon_White_ROC-11-851-event-mouse -> ../event11 lrwxrwxrwx 1 root root 10 May 23 21:37 usb-ROCCAT_ROCCAT_Tyon_White_ROC-11-851-if01-event-kbd -> ../event12 lrwxrwxrwx 1 root root 10 May 23 21:37 usb-ROCCAT_ROCCAT_Tyon_White_ROC-11-851-if02-event-joystick -> ../event13 lrwxrwxrwx 1 root root 9 May 23 21:37 usb-ROCCAT_ROCCAT_Tyon_White_ROC-11-851-mouse -> ../mouse0
https://bugs.winehq.org/show_bug.cgi?id=43125
Kai Krakow kai@kaishome.de changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |kai@kaishome.de
https://bugs.winehq.org/show_bug.cgi?id=43125
seirra blake general@sarifria.x10.bz changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |general@sarifria.x10.bz
--- Comment #1 from seirra blake general@sarifria.x10.bz --- another fellow gentoo user here, different input devices but same results using wine-staging 3.11. no crashes, but very much the same issue and yes that is what hid is an acronym for in this case. $ uname -a Linux gay.memes 4.16.0-gentoo #4 SMP PREEMPT Tue Apr 17 23:11:40 BST 2018 x86_64 AMD Ryzen 7 1800X Eight-Core Processor AuthenticAMD GNU/Linux $ grep INPUT /etc/portage/make.conf INPUT_DEVICES="keyboard mouse libinput" $ ls -l /dev/input/by-id/ total 0 lrwxrwxrwx 1 root root 10 Jul 9 00:00 usb-Logitech_Gaming_Mouse_G502_1268354F3130-event-mouse -> ../event15 lrwxrwxrwx 1 root root 10 Jul 9 00:00 usb-Logitech_Gaming_Mouse_G502_1268354F3130-if01-event-kbd -> ../event16 lrwxrwxrwx 1 root root 9 Jul 9 00:00 usb-Logitech_Gaming_Mouse_G502_1268354F3130-mouse -> ../mouse0 lrwxrwxrwx 1 root root 10 Jul 9 15:05 usb-Performance_Designed_Products_Afterglow_Wired_Controller_for_Xbox_One_000033AD39642BC1-event-joystick -> ../event17 lrwxrwxrwx 1 root root 6 Jul 9 15:05 usb-Performance_Designed_Products_Afterglow_Wired_Controller_for_Xbox_One_000033AD39642BC1-joystick -> ../js0
https://bugs.winehq.org/show_bug.cgi?id=43125
--- Comment #2 from Kai Krakow kai@kaishome.de --- I've added a discussion here but had no reply yet: https://www.winehq.org/pipermail/wine-devel/2018-July/129132.html
I'll repost here, maybe it is more visible:
I'm currently exploring the massive amounts of the following error messages I see when using my xbox controller:
002b:err:hid_report:process_hid_report Device reports coming in too fast, last report not read yet! 002b:err:hid_report:process_hid_report Device reports coming in too fast, last report not read yet! 002b:err:hid_report:process_hid_report Device reports coming in too fast, last report not read yet! [...]
The code that generates this looks a bit problematic to me.
First, it's definitely loosing HID reports here. I wonder if this also explains why my controller rarely sees missing button presses. But the issue seen here seems to mostly result from the controller generating lots and lots of axis events.
So my first thought was: Hey, if there's a buffer overrun issue then why not just replace axis reports in the buffer with the most current report for the same axes so we do not easily overwrite button reports. But looking at the code I found that there is no buffering at all. It just unconditionally overwrites the last report (writing that error message if that report was not read yet), and then continues to a while loop I do not understand at all.
@@@ void process_hid_report(DEVICE_OBJECT *device, BYTE *report, DWORD length)
if (!ext->last_report_read) ERR_(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; ext->last_report_read = FALSE;
while ((entry = RemoveHeadList(&ext->irp_queue)) != &ext->irp_queue) { IO_STACK_LOCATION *irpsp; TRACE_(hid_report)("Processing Request\n"); irp = CONTAINING_RECORD(entry, IRP, Tail.Overlay.s.ListEntry); irpsp = IoGetCurrentIrpStackLocation(irp); irp->IoStatus.u.Status = deliver_last_report(ext, irpsp->Parameters.DeviceIoControl.OutputBufferLength, irp->UserBuffer, &irp->IoStatus.Information); ext->last_report_read = TRUE; IoCompleteRequest(irp, IO_NO_INCREMENT); }
Why doesn't the while loop run before replacing the last report so it has a chance to deliver the buffered report before overwriting it? Of course the while loop would still be needed after replacing the report so it would make sense to put it into a helper.
Second, I also wonder: Doesn't the while loop potentially run more than one loop? Wouldn't it then deliver just the same last report multiple times? Where is the point in this? This would also conflict with my idea of trying to deliver the last report again before replacing it, doesn't it? What's the IRP queue anyway? Is it part of a consumer or producer?
Thus, my current understanding it that first, it looses reports, and second, it duplicates reports if it lost some before.
I see that process_hid_report() is called from the lower SDL layers in my case. Does it make sense to handle buffering there? Apparently, process_hid_report() doesn't return a result, so there's no feedback whether the HID report could deliver the report or not. Would it make sense to return the result of ext->last_report_read? That way, the SDL layer could buffer the report itself and maybe implement some logic to reduce the amount of axis reports generated. For axis reports from the joysticks, it doesn't matter if we overwrite reports as axis position is reported as an absolute value. So we could keep one buffer per axis and keep track of whether it was delivered or not, then retry next time. But this should probably go into some thread which keeps on trying to process such buffered hid reports.
https://bugs.winehq.org/show_bug.cgi?id=43125
--- Comment #3 from seirra blake general@sarifria.x10.bz --- really the impression i get from what you're saying is that there are simply just too many reports? so perhaps it needs to negotiate that 'sweet spot' where it doesn't drop any? perhaps some saved values for known gamepads with a fallback option for unknown ones where it will automatically work it out? (then perhaps prompt the user to send in a report with the values)
https://bugs.winehq.org/show_bug.cgi?id=43125
--- Comment #4 from Kai Krakow kai@kaishome.de --- (In reply to seirra blake from comment #3)
really the impression i get from what you're saying is that there are simply just too many reports? so perhaps it needs to negotiate that 'sweet spot' where it doesn't drop any? perhaps some saved values for known gamepads with a fallback option for unknown ones where it will automatically work it out? (then perhaps prompt the user to send in a report with the values)
I've got feedback from the original creator of the code.
The explanation for my instance of the error reports seems to come from a very high axis sampling rate of the xbox controllers.
So yes, there are too many reports and the driver design is a bit difficult here. Problem is to dequeue a report fast enough. But some of the called routines have a little overhead and everything is single-threaded. If you need to feed more than one reader with device reports, the overhead just grows. When the next HID report comes in, it needs to overwrite the buffer. If you would implement a queue here, your controller inputs would drift in latency which may not be wanted.
But I'll be looking into it with helper of the author. Let's see if we can come up with an improved solution.
@Nikolay: Your issue seems to be a bit different although the same (not yet invented) fix may solve it. Maybe it comes from the gaming mouse. If it has a high sampling rate, too, it may be the same issue. OTOH, I'm not sure if the mouse should be presented on winebus.sys through SDL...
BTW: Also Gentoo here... ;-)
https://bugs.winehq.org/show_bug.cgi?id=43125
--- Comment #5 from seirra blake general@sarifria.x10.bz --- (In reply to Kai Krakow from comment #4)
(In reply to seirra blake from comment #3)
really the impression i get from what you're saying is that there are simply just too many reports? so perhaps it needs to negotiate that 'sweet spot' where it doesn't drop any? perhaps some saved values for known gamepads with a fallback option for unknown ones where it will automatically work it out? (then perhaps prompt the user to send in a report with the values)
I've got feedback from the original creator of the code.
The explanation for my instance of the error reports seems to come from a very high axis sampling rate of the xbox controllers.
So yes, there are too many reports and the driver design is a bit difficult here. Problem is to dequeue a report fast enough. But some of the called routines have a little overhead and everything is single-threaded. If you need to feed more than one reader with device reports, the overhead just grows. When the next HID report comes in, it needs to overwrite the buffer. If you would implement a queue here, your controller inputs would drift in latency which may not be wanted.
But I'll be looking into it with helper of the author. Let's see if we can come up with an improved solution.
@Nikolay: Your issue seems to be a bit different although the same (not yet invented) fix may solve it. Maybe it comes from the gaming mouse. If it has a high sampling rate, too, it may be the same issue. OTOH, I'm not sure if the mouse should be presented on winebus.sys through SDL...
BTW: Also Gentoo here... ;-)
AFAIK wine's implementation only uses it for gamepads? however perhaps that driver has some behavioral quirks.
https://bugs.winehq.org/show_bug.cgi?id=43125
Konrad Rzepecki hannibal@astral.lodz.pl changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |hannibal@astral.lodz.pl
--- Comment #6 from Konrad Rzepecki hannibal@astral.lodz.pl --- My installation is also affected by this annoying messages: 0056:err:hid_report:process_hid_report Device reports coming in too fast, last report not read yet!
In my case this are mostly mouse events but sometimes also keyboard. Mouse events are not device specific. I see this messages on external USB mouse but also on internal trackpoint.
I seems appear randomly, but there are one case when they appear much more often.
I run my wine app on remotely mouted sshfs partition. This messages appears almost always when this app access files on this partition. Quite often there are dozens of them in a row.
My system is Slackware-current on Lenovo T410.
Like Kai I have looked into source:
EnterCriticalSection(&ext->report_cs); ... ... ... if (!ext->last_report_read) ERR_(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; ext->last_report_read = FALSE;
while ((entry = RemoveHeadList(&ext->irp_queue)) != &ext->irp_queue) { IO_STACK_LOCATION *irpsp; TRACE_(hid_report)("Processing Request\n"); irp = CONTAINING_RECORD(entry, IRP, Tail.Overlay.s.ListEntry); irpsp = IoGetCurrentIrpStackLocation(irp); irp->IoStatus.u.Status = deliver_last_report(ext, irpsp->Parameters.DeviceIoControl.OutputBufferLength, irp->UserBuffer, &irp->IoStatus.Information); ext->last_report_read = TRUE; IoCompleteRequest(irp, IO_NO_INCREMENT); } LeaveCriticalSection(&ext->report_cs);
This code is in critical section and only setting ext->last_report_read to FALSE is after check. So other code should not affect this at all. Only possibility I see is that this "while" is never entered so TRUE is not set. I think this line with TRUE set should be moved outside while for two reasons. 1. If list is empty TRUE is never set however there is no report to process and it should (this bug). 2. When there are more than one report after process first it is set to TRUE however it should be after last.
But since all this appear in critical section i see no reason to have this handly made "last_report_read" semaphore in code at all. However I'm not familiar with wine code so my analyses may be wrong, but I hope it help someone fix this bug. This messages in console application are really annoying...
https://bugs.winehq.org/show_bug.cgi?id=43125
--- Comment #7 from Kai Krakow kai@kaishome.de --- (In reply to Konrad Rzepecki from comment #6)
This code is in critical section and only setting ext->last_report_read to FALSE is after check. So other code should not affect this at all. Only possibility I see is that this "while" is never entered so TRUE is not set. I think this line with TRUE set should be moved outside while for two reasons.
- If list is empty TRUE is never set however there is no report to process
and it should (this bug). 2. When there are more than one report after process first it is set to TRUE however it should be after last.
But since all this appear in critical section i see no reason to have this handly made "last_report_read" semaphore in code at all. However I'm not familiar with wine code so my analyses may be wrong, but I hope it help someone fix this bug. This messages in console application are really annoying...
I'm not sure if you unterstood the code right - I did at first, too. There's no such thing as "there are more than one report". The while loop just feeds the readers, it's not delivering events down a queue, but up a subscription. Readers subscribe to events (that's the irp queue).
But maybe you are true that it should set TRUE outside the while loop - but only if anything was done. But since it's in a critical section, it doesn't really matter, I think. The outcome would be the same.
The driver itself doesn't implement a queue: It just tries to instantly deliver the report by calling process_hid_report(). If there's no reader queued yet, next time the driver sends a report, the current one will be lost. That's when you see the message.
OTOH, you probably don't want to implement a queue in the driver because otherwise your HID reports may drift in time a lot.
So the only proper way would be to accelerate the readers, that is deliver_last_report() which may have pretty high overhead as I was told.
I'm not sure what a HID report consists of: Is it single axes events and single button events? Or is it a structure of whole device state (axes position and button states)? In the latter case, an undelivered report could be coalesced into the one still sitting there, and maybe just degrade the error to a warning or remove it completely then.
I didn't have time to look into this completely but have some ideas.
Another idea of discussion: If the last report was not read yet: Should we overwrite the queued report or should be throw away the incoming report?
https://bugs.winehq.org/show_bug.cgi?id=43125
--- Comment #8 from Kai Krakow kai@kaishome.de --- (In reply to Kai Krakow from comment #7)
I'm not sure if you unterstood the code right - I did at first, too.
... That should have said "I did NOT at first, too". And "understood"... :-\
https://bugs.winehq.org/show_bug.cgi?id=43125
--- Comment #9 from Kai Krakow kai@kaishome.de --- (In reply to Kai Krakow from comment #7)
I'm not sure what a HID report consists of: Is it single axes events and single button events? Or is it a structure of whole device state (axes position and button states)? In the latter case, an undelivered report could be coalesced into the one still sitting there, and maybe just degrade the error to a warning or remove it completely then.
I didn't have time to look into this completely but have some ideas.
Another idea of discussion: If the last report was not read yet: Should we overwrite the queued report or should be throw away the incoming report?
By a quick glance into bus_sdl.c it looks like a report consists of the complete state of the device which includes all buttons and axes.
So in the end, the design of not having a queue in the driver makes sense: You just overwrite the queued state with the most current state and continue to wait for all readers to read this state.
The only chance to miss button presses is when a button is pressed and released within the same cycle of readers. So if a reader is too slow to process events, it may miss button presses. For axes, this is an even minor problem if reports are absolute.
I think it makes sense to degrade the error to a warning and maybe only warn once per cycle, with a cycle being the switching of the read status between TRUE and FALSE.
In the end, we are probably only hitting this issue because of the high sampling rates of modern devices.
https://bugs.winehq.org/show_bug.cgi?id=43125
--- Comment #10 from Konrad Rzepecki hannibal@astral.lodz.pl --- You have right I didn't see whole picture, but I think this is not needed as this code itself forbids some situations.
Les't assume that is something waiting for events in irp_queue.
- We enter critical section - Set last_report_read FALSE - A irp_queue is not empty enter while - In while mark last_report_read to TRUE - Exit while - Exit critical section.
So if is something in irp_queue report is ALWAYS, at the end, marked as read. If in meantime, other calls appear to process_hid_report they didn't see FALSE in last_report_read because wait in beginning of critical section.
Only situation that last_report_read is FALSE outside critical section is when no one waits for events in irp_queue and while is not entered. But if no one wants the report, why spamming about it is not read?
Despite all of this I think this message should be rid off. It does nothing, report is overwritten despite of it. But this message itself broke console applications messing horribly its output. I my case i almost didn't see what applications writes to console but mostly this "0051:err:hid_report:process_hid_report Device reports coming in too fast, last report not read yet!" thing.
https://bugs.winehq.org/show_bug.cgi?id=43125
--- Comment #11 from Konrad Rzepecki hannibal@astral.lodz.pl --- Created attachment 61876 --> https://bugs.winehq.org/attachment.cgi?id=61876 example of spammy behavior
This is example how this message messing console applications. Sometimes is even worse...
https://bugs.winehq.org/show_bug.cgi?id=43125
--- Comment #12 from Kai Krakow kai@kaishome.de --- (In reply to Konrad Rzepecki from comment #10)
You have right I didn't see whole picture, but I think this is not needed as this code itself forbids some situations.
Les't assume that is something waiting for events in irp_queue.
- We enter critical section
- Set last_report_read FALSE
- A irp_queue is not empty enter while
- In while mark last_report_read to TRUE
- Exit while
- Exit critical section.
So if is something in irp_queue report is ALWAYS, at the end, marked as read. If in meantime, other calls appear to process_hid_report they didn't see FALSE in last_report_read because wait in beginning of critical section.
Only situation that last_report_read is FALSE outside critical section is when no one waits for events in irp_queue and while is not entered. But if no one wants the report, why spamming about it is not read?
Despite all of this I think this message should be rid off. It does nothing, report is overwritten despite of it. But this message itself broke console applications messing horribly its output. I my case i almost didn't see what applications writes to console but mostly this "0051:err:hid_report:process_hid_report Device reports coming in too fast, last report not read yet!" thing.
I'd like to fix this in two steps:
1. Make the message less spammy: Only display the message once as long as there are no readers in irp_queue.
2. Degrade the message to debug log level: As far as I understand the code and the logic behind the delivery design, having no readers for incoming reports is not an error condition. It's a warning at most, and a pretty uninteresting even unless you're debugging things.
What do you think?
https://bugs.winehq.org/show_bug.cgi?id=43125
--- Comment #13 from Konrad Rzepecki hannibal@astral.lodz.pl ---
I'd like to fix this in two steps:
- Make the message less spammy: Only display the message once as long as
there are no readers in irp_queue.
I think this is not needed if you apply 2. This will require unnecessary code running at each call.
- Degrade the message to debug log level: As far as I understand the code
and the logic behind the delivery design, having no readers for incoming reports is not an error condition. It's a warning at most, and a pretty uninteresting even unless you're debugging things.
Good idea.
I wonder if this message isn't an artifact form time when this code was not placed in critical section...
https://bugs.winehq.org/show_bug.cgi?id=43125
--- Comment #14 from Kai Krakow kai@kaishome.de --- (In reply to Konrad Rzepecki from comment #13)
I'd like to fix this in two steps:
- Make the message less spammy: Only display the message once as long as
there are no readers in irp_queue.
I think this is not needed if you apply 2. This will require unnecessary code running at each call.
The code would be extremely simple. Spamming the message every time would be far more overhead. Have you ever compared D3D performance with spammy FIXME messages against all fixmes turned of? It's a real performance problem so such spamminess has already been fixed in many parts of Wine by the same tooling I'm planning to use.
- Degrade the message to debug log level: As far as I understand the code
and the logic behind the delivery design, having no readers for incoming reports is not an error condition. It's a warning at most, and a pretty uninteresting even unless you're debugging things.
Good idea.
I'm currently in contact with the original author of the code to see if my assumptions are right.
I wonder if this message isn't an artifact form time when this code was not placed in critical section...
I don't think there was such a time. Looking at the Git history, it's one peace of a big work all included at once. See commit 1a81022f4e6359f4d6009057db1636041eabada9: The critical section has been there with the addition of the function all at once, including the message.
https://bugs.winehq.org/show_bug.cgi?id=43125
--- Comment #15 from Konrad Rzepecki hannibal@astral.lodz.pl --- (In reply to Kai Krakow from comment #14)
(In reply to Konrad Rzepecki from comment #13)
I'd like to fix this in two steps:
- Make the message less spammy: Only display the message once as long as
there are no readers in irp_queue.
I think this is not needed if you apply 2. This will require unnecessary code running at each call.
The code would be extremely simple. Spamming the message every time would be far more overhead. Have you ever compared D3D performance with spammy FIXME messages against all fixmes turned of? It's a real performance problem so such spamminess has already been fixed in many parts of Wine by the same tooling I'm planning to use.
If you plan to add this anyway, i think i will reduce spamming only little bit. There will be no duplicates for same report. But different report still appear.
At least in my case. I think in my "spamming" irp_queue is not empty all the time. There must be something reading this reports, because otherwise I will have only this messages on screen. Readers must be there almost all the time and disappear only briefly. So periods with empty ipr_queue are (mostly) short and separated and your idea reduce spamming only a little.
I wonder if this message isn't an artifact form time when this code was not placed in critical section...
I don't think there was such a time. Looking at the Git history, it's one peace of a big work all included at once. See commit 1a81022f4e6359f4d6009057db1636041eabada9: The critical section has been there with the addition of the function all at once, including the message.
Author can have multiple versions before commit to official repository. But now nobody knows the truth.
https://bugs.winehq.org/show_bug.cgi?id=43125
--- Comment #16 from Kai Krakow kai@kaishome.de --- A proposed fix has been sent: https://www.winehq.org/pipermail/wine-devel/2018-July/129948.html
https://bugs.winehq.org/show_bug.cgi?id=43125
--- Comment #17 from Konrad Rzepecki hannibal@astral.lodz.pl --- I've applied your patch to 3.0.2 (with some problems though) and it seems working. I see no spamming messages right now. Thanks.
But, if this is possible, please apply your fix also to stable 3.0.X branch.
https://bugs.winehq.org/show_bug.cgi?id=43125
--- Comment #18 from Kai Krakow kai@kaishome.de --- Created attachment 62028 --> https://bugs.winehq.org/attachment.cgi?id=62028 backported patch
I'm not working with wine-stable so I can only give you this backported patch untested. If it works for you, I recommend taking responsibility for this patch by putting your sign-off and submitting it to wine-devel for inclusion into wine-stable.
At least, this patch compiles fine in wine-3.0.2 for me.
Thanks, Kai
https://bugs.winehq.org/show_bug.cgi?id=43125
Gijs Vermeulen gijsvrm@gmail.com changed:
What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |RESOLVED Fixed by SHA1| |d744f367d263a131feee96e103f | |b8220e8400b53 Resolution|--- |FIXED
--- Comment #19 from Gijs Vermeulen gijsvrm@gmail.com --- A slightly different version of the patch was committed as: d744f367d263a131feee96e103fb8220e8400b53 Marking FIXED.
https://bugs.winehq.org/show_bug.cgi?id=43125
Nikolay Sivov bunglehead@gmail.com changed:
What |Removed |Added ---------------------------------------------------------------------------- Component|-unknown |hid
https://bugs.winehq.org/show_bug.cgi?id=43125
Alexandre Julliard julliard@winehq.org changed:
What |Removed |Added ---------------------------------------------------------------------------- Status|RESOLVED |CLOSED
--- Comment #20 from Alexandre Julliard julliard@winehq.org --- Closing bugs fixed in 3.14.
https://bugs.winehq.org/show_bug.cgi?id=43125
Michael Stefaniuc mstefani@winehq.org changed:
What |Removed |Added ---------------------------------------------------------------------------- Target Milestone|--- |3.0.x
https://bugs.winehq.org/show_bug.cgi?id=43125
Michael Stefaniuc mstefani@winehq.org changed:
What |Removed |Added ---------------------------------------------------------------------------- Target Milestone|3.0.x |---
--- Comment #21 from Michael Stefaniuc mstefani@winehq.org --- Removing the 3.0.x milestone from bug fixes included in 3.0.4.