On Sun, Feb 14, 2021 at 04:43:17PM +0000, Stuart Henderson wrote:
> On 2021/02/14 15:22, Marcus Glocker wrote:
> > Unfortunately I'm seeing more and more USB device breakages reported
> > the last few days related to the USB data toggle fix which we did
> > commit 2-3 weeks ago.
>
> Do you think this could this be implicated in a keyboard with 'stuck'
> keys i.e. keep repeating? I've hit it a few times recently, but didn't
> look that far back. (Nothing amiss in logs when it happens).
I don't think so since the issue also has been reported for some fido(4)
devices.
> > +/*
> > + * Workaround for OpenBSD <=6.6-current (as of 201910) bug that loses
> > + * sync of DATA0/DATA1 sequence bit across uhid open/close.
> > + * Send pings until we get a response - early pings with incorrect
> > + * sequence bits will be ignored as duplicate packets by the device.
> > + */
> > +static int
> > +terrible_ping_kludge(struct hid_openbsd *ctx)
>
> it will need to be put back in chromium too (and port revision will
> need to be bumped)
Right, the chromium diff was included, but I did forget to bump.
Index: www/chromium/Makefile
===================================================================
RCS file: /cvs/ports/www/chromium/Makefile,v
retrieving revision 1.546
diff -u -p -u -p -r1.546 Makefile
--- www/chromium/Makefile 6 Feb 2021 07:33:27 -0000 1.546
+++ www/chromium/Makefile 14 Feb 2021 19:24:08 -0000
@@ -18,6 +18,7 @@ COMMENT= Chromium browser
V= 88.0.4324.150
DISTNAME= chromium-${V}
+REVISION= 0
DISTFILES+= chromium-${V}${EXTRACT_SUFX}
Index: www/chromium/files/hid_service_fido.cc
===================================================================
RCS file: /cvs/ports/www/chromium/files/hid_service_fido.cc,v
retrieving revision 1.4
diff -u -p -u -p -r1.4 hid_service_fido.cc
--- www/chromium/files/hid_service_fido.cc 6 Feb 2021 05:05:04 -0000
1.4
+++ www/chromium/files/hid_service_fido.cc 14 Feb 2021 19:24:09 -0000
@@ -11,7 +11,10 @@
#include <sys/un.h>
#include <unistd.h>
+// TODO: remove once the missing guard in fido.h is fixed upstream.
+extern "C" {
#include <fido.h>
+}
#include <set>
#include <string>
@@ -72,6 +75,55 @@ void FinishOpen(std::unique_ptr<ConnectP
base::Bind(&CreateConnection, base::Passed(¶ms)));
}
+bool terrible_ping_kludge(int fd, const std::string &path) {
+ u_char data[256];
+ int i, n;
+ struct pollfd pfd;
+
+ for (i = 0; i < 4; i++) {
+ memset(data, 0, sizeof(data));
+ /* broadcast channel ID */
+ data[1] = 0xff;
+ data[2] = 0xff;
+ data[3] = 0xff;
+ data[4] = 0xff;
+ /* Ping command */
+ data[5] = 0x81;
+ /* One byte ping only, Vasili */
+ data[6] = 0;
+ data[7] = 1;
+ HID_LOG(EVENT) << "send ping " << i << " " << path;
+ if (write(fd, data, 64) == -1) {
+ HID_PLOG(ERROR) << "write " << path;
+ return false;
+ }
+ HID_LOG(EVENT) << "wait reply " << path;
+ memset(&pfd, 0, sizeof(pfd));
+ pfd.fd = fd;
+ pfd.events = POLLIN;
+ if ((n = poll(&pfd, 1, 100)) == -1) {
+ HID_PLOG(EVENT) << "poll " << path;
+ return false;
+ } else if (n == 0) {
+ HID_LOG(EVENT) << "timed out " << path;
+ continue;
+ }
+ if (read(fd, data, 64) == -1) {
+ HID_PLOG(ERROR) << "read " << path;
+ return false;
+ }
+ /*
+ * Ping isn't always supported on the broadcast channel,
+ * so we might get an error, but we don't care - we're
+ * synched now.
+ */
+ HID_LOG(EVENT) << "got reply " << path;
+ return true;
+ }
+ HID_LOG(ERROR) << "no response " << path;
+ return false;
+}
+
void OpenOnBlockingThread(std::unique_ptr<ConnectParams> params) {
base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
base::BlockingType::MAY_BLOCK);
@@ -85,6 +137,11 @@ void OpenOnBlockingThread(std::unique_pt
if (!device_file.IsValid()) {
HID_LOG(EVENT) << "Failed to open '" << device_node << "': "
<< base::File::ErrorToString(device_file.error_details());
+ task_runner->PostTask(FROM_HERE,
base::BindOnce(std::move(params->callback), nullptr));
+ return;
+ }
+ if (!terrible_ping_kludge(device_file.GetPlatformFile(), device_node)) {
+ HID_LOG(EVENT) << "Failed to ping " << device_node;
task_runner->PostTask(FROM_HERE,
base::BindOnce(std::move(params->callback), nullptr));
return;
}