From 51a6923008deb97b926b203c32e52e6cd2beda3a Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 5 Apr 2021 17:19:47 +0200 Subject: [PATCH] device: Work around FreeBSD kernel bug for querying gamepad axes This is to support older kernels, which always returned 0 from successful ioctl, rather than the number of bits. This was fixed in the FreeBSD kernel trunk. --- panda/src/device/evdevInputDevice.cxx | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/panda/src/device/evdevInputDevice.cxx b/panda/src/device/evdevInputDevice.cxx index b609501797..9cf94e1dfc 100644 --- a/panda/src/device/evdevInputDevice.cxx +++ b/panda/src/device/evdevInputDevice.cxx @@ -328,7 +328,22 @@ init_device() { uint8_t axes[(ABS_MAX + 8) >> 3] = {0}; if (test_bit(EV_ABS, evtypes)) { // Check which axes are on the device. - num_bits = ioctl(_fd, EVIOCGBIT(EV_ABS, sizeof(axes)), axes) << 3; + int result = ioctl(_fd, EVIOCGBIT(EV_ABS, sizeof(axes)), axes); +#ifdef __FreeBSD__ + // Older kernels had a bug where this would always return 0, see D28218 + if (result == 0) { + for (int i = ABS_MAX; i >= 0; --i) { + if (test_bit(i, axes)) { + num_bits = i + 1; + break; + } + } + } + else +#endif + if (result > 0) { + num_bits = result << 3; + } has_axes = true; }