175 Commits

Author SHA1 Message Date
Hans de Goede
efa596d885 HID: logitech-hidpp: Move get_wireless_feature_index() check to hidpp_connect_event()
[ Upstream commit ba9de350509504fb748837b71e23d7e84c83d93c ]

Calling get_wireless_feature_index() from probe() causes
the wireless_feature_index to only get set for unifying devices which
are already connected at probe() time. It does not get set for devices
which connect later.

Fix this by moving get_wireless_feature_index() to hidpp_connect_event(),
this does not make a difference for devices connected at probe() since
probe() will queue the hidpp_connect_event() for those at probe time.

This series has been tested on the following devices:
Logitech Bluetooth Laser Travel Mouse (bluetooth, HID++ 1.0)
Logitech M720 Triathlon (bluetooth, HID++ 4.5)
Logitech M720 Triathlon (unifying, HID++ 4.5)
Logitech K400 Pro (unifying, HID++ 4.1)
Logitech K270 (eQUAD nano Lite, HID++ 2.0)
Logitech M185 (eQUAD nano Lite, HID++ 4.5)
Logitech LX501 keyboard (27 Mhz, HID++ builtin scroll-wheel, HID++ 1.0)
Logitech M-RAZ105 mouse (27 Mhz, HID++ extra mouse buttons, HID++ 1.0)

And by bentiss:
Logitech Touchpad T650 (unifying)
Logitech Touchpad T651 (bluetooth)
Logitech MX Master 3B (BLE)
Logitech G403 (plain USB / Gaming receiver)

Fixes: 0da0a63b7cba ("HID: logitech-hidpp: Support WirelessDeviceStatus connect events")
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Link: https://lore.kernel.org/r/20231010102029.111003-4-hdegoede@redhat.com
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
2023-11-20 11:59:22 +01:00
Hans de Goede
f29564e941 HID: logitech-hidpp: Revert "Don't restart communication if not necessary"
[ Upstream commit 55bf70362ffc4ddd7c8745e2fe880edac00e4aff ]

Commit 91cf9a98ae41 ("HID: logitech-hidpp: make .probe usbhid capable")
makes hidpp_probe() first call hid_hw_start(hdev, 0) to allow IO
without connecting any hid subdrivers (hid-input, hidraw).

This is done to allow to retrieve the device's name and serial number
and store these in hdev->name and hdev->uniq.

Then later on IO was stopped and started again with hid_hw_start(hdev,
HID_CONNECT_DEFAULT) connecting hid-input and hidraw after the name
and serial number have been setup.

Commit 498ba2069035 ("HID: logitech-hidpp: Don't restart communication
if not necessary") changed the probe() code to only do the start with
a 0 connect-mask + restart later for unifying devices.

But for non unifying devices hdev->name and hdev->uniq are updated too.
So this change re-introduces the problem for which the start with
a 0 connect-mask + restart later behavior was introduced.

The previous patch in this series changes the unifying path to instead of
restarting IO only call hid_connect() later. This avoids possible issues
with restarting IO seen on non unifying devices.

Revert the change to limit the restart behavior to unifying devices to
fix hdev->name changing after userspace facing devices have already been
registered.

This series has been tested on the following devices:
Logitech Bluetooth Laser Travel Mouse (bluetooth, HID++ 1.0)
Logitech M720 Triathlon (bluetooth, HID++ 4.5)
Logitech M720 Triathlon (unifying, HID++ 4.5)
Logitech K400 Pro (unifying, HID++ 4.1)
Logitech K270 (eQUAD nano Lite, HID++ 2.0)
Logitech M185 (eQUAD nano Lite, HID++ 4.5)
Logitech LX501 keyboard (27 Mhz, HID++ builtin scroll-wheel, HID++ 1.0)
Logitech M-RAZ105 mouse (27 Mhz, HID++ extra mouse buttons, HID++ 1.0)

And by bentiss:
Logitech Touchpad T650 (unifying)
Logitech Touchpad T651 (bluetooth)
Logitech MX Master 3B (BLE)
Logitech G403 (plain USB / Gaming receiver)

Fixes: 498ba2069035 ("HID: logitech-hidpp: Don't restart communication if not necessary")
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Link: https://lore.kernel.org/r/20231010102029.111003-3-hdegoede@redhat.com
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
2023-11-20 11:59:22 +01:00
Hans de Goede
635caea216 HID: logitech-hidpp: Don't restart IO, instead defer hid_connect() only
[ Upstream commit 11ca0322a41920df2b462d2e45b0731e47ff475b ]

Restarting IO causes 2 problems:

1. Some devices do not like IO being restarted this was addressed in
   commit 498ba2069035 ("HID: logitech-hidpp: Don't restart communication
   if not necessary"), but that change has issues of its own and needs to
   be reverted.

2. Restarting IO and specifically calling hid_device_io_stop() causes
   received packets to be missed, which may cause connect-events to
   get missed.

Restarting IO was introduced in commit 91cf9a98ae41 ("HID: logitech-hidpp:
make .probe usbhid capable") to allow to retrieve the device's name and
serial number and store these in hdev->name and hdev->uniq before
connecting any hid subdrivers (hid-input, hidraw) exporting this info
to userspace.

But this does not require restarting IO, this merely requires deferring
calling hid_connect(). Calling hid_hw_start() with a connect-mask of
0 makes it skip calling hid_connect(), so hidpp_probe() can simply call
hid_connect() later without needing to restart IO.

Remove the stop + restart of IO and instead just call hid_connect() later
to avoid the issues caused by restarting IO.

Now that IO is no longer stopped, hid_hw_close() must be called at the end
of probe() to balance the hid_hw_open() done at the beginning probe().

This series has been tested on the following devices:
Logitech Bluetooth Laser Travel Mouse (bluetooth, HID++ 1.0)
Logitech M720 Triathlon (bluetooth, HID++ 4.5)
Logitech M720 Triathlon (unifying, HID++ 4.5)
Logitech K400 Pro (unifying, HID++ 4.1)
Logitech K270 (eQUAD nano Lite, HID++ 2.0)
Logitech M185 (eQUAD nano Lite, HID++ 4.5)
Logitech LX501 keyboard (27 Mhz, HID++ builtin scroll-wheel, HID++ 1.0)
Logitech M-RAZ105 mouse (27 Mhz, HID++ extra mouse buttons, HID++ 1.0)

And by bentiss:
Logitech Touchpad T650 (unifying)
Logitech Touchpad T651 (bluetooth)
Logitech MX Master 3B (BLE)
Logitech G403 (plain USB / Gaming receiver)

Fixes: 498ba2069035 ("HID: logitech-hidpp: Don't restart communication if not necessary")
Suggested-by: Benjamin Tissoires <bentiss@kernel.org>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Link: https://lore.kernel.org/r/20231010102029.111003-2-hdegoede@redhat.com
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
2023-11-20 11:59:22 +01:00
Hans de Goede
dac501397b HID: logitech-hidpp: Fix kernel crash on receiver USB disconnect
hidpp_connect_event() has *four* time-of-check vs time-of-use (TOCTOU)
races when it races with itself.

hidpp_connect_event() primarily runs from a workqueue but it also runs
on probe() and if a "device-connected" packet is received by the hw
when the thread running hidpp_connect_event() from probe() is waiting on
the hw, then a second thread running hidpp_connect_event() will be
started from the workqueue.

This opens the following races (note the below code is simplified):

1. Retrieving + printing the protocol (harmless race):

	if (!hidpp->protocol_major) {
		hidpp_root_get_protocol_version()
		hidpp->protocol_major = response.rap.params[0];
	}

We can actually see this race hit in the dmesg in the abrt output
attached to rhbz#2227968:

[ 3064.624215] logitech-hidpp-device 0003:046D:4071.0049: HID++ 4.5 device connected.
[ 3064.658184] logitech-hidpp-device 0003:046D:4071.0049: HID++ 4.5 device connected.

Testing with extra logging added has shown that after this the 2 threads
take turn grabbing the hw access mutex (send_mutex) so they ping-pong
through all the other TOCTOU cases managing to hit all of them:

2. Updating the name to the HIDPP name (harmless race):

	if (hidpp->name == hdev->name) {
		...
		hidpp->name = new_name;
	}

3. Initializing the power_supply class for the battery (problematic!):

hidpp_initialize_battery()
{
        if (hidpp->battery.ps)
                return 0;

	probe_battery(); /* Blocks, threads take turns executing this */

	hidpp->battery.desc.properties =
		devm_kmemdup(dev, hidpp_battery_props, cnt, GFP_KERNEL);

	hidpp->battery.ps =
		devm_power_supply_register(&hidpp->hid_dev->dev,
					   &hidpp->battery.desc, cfg);
}

4. Creating delayed input_device (potentially problematic):

	if (hidpp->delayed_input)
		return;

	hidpp->delayed_input = hidpp_allocate_input(hdev);

The really big problem here is 3. Hitting the race leads to the following
sequence:

	hidpp->battery.desc.properties =
		devm_kmemdup(dev, hidpp_battery_props, cnt, GFP_KERNEL);

	hidpp->battery.ps =
		devm_power_supply_register(&hidpp->hid_dev->dev,
					   &hidpp->battery.desc, cfg);

	...

	hidpp->battery.desc.properties =
		devm_kmemdup(dev, hidpp_battery_props, cnt, GFP_KERNEL);

	hidpp->battery.ps =
		devm_power_supply_register(&hidpp->hid_dev->dev,
					   &hidpp->battery.desc, cfg);

So now we have registered 2 power supplies for the same battery,
which looks a bit weird from userspace's pov but this is not even
the really big problem.

Notice how:

1. This is all devm-maganaged
2. The hidpp->battery.desc struct is shared between the 2 power supplies
3. hidpp->battery.desc.properties points to the result from the second
   devm_kmemdup()

This causes a use after free scenario on USB disconnect of the receiver:
1. The last registered power supply class device gets unregistered
2. The memory from the last devm_kmemdup() call gets freed,
   hidpp->battery.desc.properties now points to freed memory
3. The first registered power supply class device gets unregistered,
   this involves sending a remove uevent to userspace which invokes
   power_supply_uevent() to fill the uevent data
4. power_supply_uevent() uses hidpp->battery.desc.properties which
   now points to freed memory leading to backtraces like this one:

Sep 22 20:01:35 eric kernel: BUG: unable to handle page fault for address: ffffb2140e017f08
...
Sep 22 20:01:35 eric kernel: Workqueue: usb_hub_wq hub_event
Sep 22 20:01:35 eric kernel: RIP: 0010:power_supply_uevent+0xee/0x1d0
...
Sep 22 20:01:35 eric kernel:  ? asm_exc_page_fault+0x26/0x30
Sep 22 20:01:35 eric kernel:  ? power_supply_uevent+0xee/0x1d0
Sep 22 20:01:35 eric kernel:  ? power_supply_uevent+0x10d/0x1d0
Sep 22 20:01:35 eric kernel:  dev_uevent+0x10f/0x2d0
Sep 22 20:01:35 eric kernel:  kobject_uevent_env+0x291/0x680
Sep 22 20:01:35 eric kernel:  power_supply_unregister+0x8e/0xa0
Sep 22 20:01:35 eric kernel:  release_nodes+0x3d/0xb0
Sep 22 20:01:35 eric kernel:  devres_release_group+0xfc/0x130
Sep 22 20:01:35 eric kernel:  hid_device_remove+0x56/0xa0
Sep 22 20:01:35 eric kernel:  device_release_driver_internal+0x19f/0x200
Sep 22 20:01:35 eric kernel:  bus_remove_device+0xc6/0x130
Sep 22 20:01:35 eric kernel:  device_del+0x15c/0x3f0
Sep 22 20:01:35 eric kernel:  ? __queue_work+0x1df/0x440
Sep 22 20:01:35 eric kernel:  hid_destroy_device+0x4b/0x60
Sep 22 20:01:35 eric kernel:  logi_dj_remove+0x9a/0x100 [hid_logitech_dj 5c91534a0ead2b65e04dd799a0437e3b99b21bc4]
Sep 22 20:01:35 eric kernel:  hid_device_remove+0x44/0xa0
Sep 22 20:01:35 eric kernel:  device_release_driver_internal+0x19f/0x200
Sep 22 20:01:35 eric kernel:  bus_remove_device+0xc6/0x130
Sep 22 20:01:35 eric kernel:  device_del+0x15c/0x3f0
Sep 22 20:01:35 eric kernel:  ? __queue_work+0x1df/0x440
Sep 22 20:01:35 eric kernel:  hid_destroy_device+0x4b/0x60
Sep 22 20:01:35 eric kernel:  usbhid_disconnect+0x47/0x60 [usbhid 727dcc1c0b94e6b4418727a468398ac3bca492f3]
Sep 22 20:01:35 eric kernel:  usb_unbind_interface+0x90/0x270
Sep 22 20:01:35 eric kernel:  device_release_driver_internal+0x19f/0x200
Sep 22 20:01:35 eric kernel:  bus_remove_device+0xc6/0x130
Sep 22 20:01:35 eric kernel:  device_del+0x15c/0x3f0
Sep 22 20:01:35 eric kernel:  ? kobject_put+0xa0/0x1d0
Sep 22 20:01:35 eric kernel:  usb_disable_device+0xcd/0x1e0
Sep 22 20:01:35 eric kernel:  usb_disconnect+0xde/0x2c0
Sep 22 20:01:35 eric kernel:  usb_disconnect+0xc3/0x2c0
Sep 22 20:01:35 eric kernel:  hub_event+0xe80/0x1c10

There have been quite a few bug reports (see Link tags) about this crash.

Fix all the TOCTOU issues, including the really bad power-supply related
system crash on USB disconnect, by making probe() use the workqueue for
running hidpp_connect_event() too, so that it can never run more then once.

Link: https://bugzilla.redhat.com/show_bug.cgi?id=2227221
Link: https://bugzilla.redhat.com/show_bug.cgi?id=2227968
Link: https://bugzilla.redhat.com/show_bug.cgi?id=2227968
Link: https://bugzilla.redhat.com/show_bug.cgi?id=2242189
Link: https://bugzilla.kernel.org/show_bug.cgi?id=217412#c58
Cc: stable@vger.kernel.org
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Link: https://lore.kernel.org/r/20231005182638.3776-1-hdegoede@redhat.com
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2023-10-06 16:09:14 +02:00
Hans de Goede
2d866603e2 HID: logitech-hidpp: Add Bluetooth ID for the Logitech M720 Triathlon mouse
Using hidpp for the M720 adds battery info reporting and hires
scrolling support.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Bastien Nocera <hadess@hadess.net>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2023-09-18 16:48:19 +02:00
Benjamin Tissoires
60165ab774 HID: logitech-hidpp: rework one more time the retries attempts
Extract the internal code inside a helper function, fix the
initialization of the parameters used in the helper function
(`hidpp->answer_available` was not reset and `*response` wasn't either),
and use a `do {...} while();` loop.

Fixes: 586e8fede795 ("HID: logitech-hidpp: Retry commands when device is busy")
Cc: stable@vger.kernel.org
Reviewed-by: Bastien Nocera <hadess@hadess.net>
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Link: https://lore.kernel.org/r/20230621-logitech-fixes-v2-1-3635f7f9c8af@kernel.org
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2023-08-25 10:40:32 +02:00
Maxim Mikityanskiy
ed1fb63b6e HID: logitech-hidpp: Add support for Logitech MX Anywhere 3 mouse
Add Logitech MX Anywhere 3 connected over Bluetooth to the device table
to get hidpi scroll supported. USB connection over the Unifying receiver
is already supported by the wildcard entry LDJ_DEVICE(HID_ANY_ID).

Signed-off-by: Maxim Mikityanskiy <maxtram95@gmail.com>
Reviewed-by: Bastien Nocera <hadess@hadess.net>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2023-08-14 11:46:31 +02:00
Mavroudis Chatzilazaridis
c05b8a939a HID: logitech-hidpp: Add support for the Pro X Superlight
This patch adds support for the Pro X Superlight over wired USB.
The device now reports the status of its battery.

Co-developed-by: Filipe Laíns <lains@riseup.net>
Signed-off-by: Filipe Laíns <lains@riseup.net>
Signed-off-by: Mavroudis Chatzilazaridis <mavchatz@protonmail.com>
Reviewed-by: Bastien Nocera <hadess@hadess.net>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2023-08-14 11:34:03 +02:00
Bastien Nocera
a7156d8181 HID: logitech-hidpp: Rename HID++ "internal" error constant
As per the upstream "hidpp" helpers commit:
"
There has been some confusion about error value 5 but feature specs that
refer to it generally use NOT_ALLOWED.
"

Signed-off-by: Bastien Nocera <hadess@hadess.net>
Link: 80c3fecfcd
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2023-08-14 11:22:26 +02:00
Stuart Hayhurst
a343a7682a HID: logitech-hidpp: Add wired USB id for Logitech G502 Lightspeed
Previously, support for the G502 had been attempted in commit
'27fc32fd9417 ("HID: logitech-hidpp: add USB PID for a few more supported
mice")'

This caused some issues and was reverted by
'addf3382c47c ("Revert "HID: logitech-hidpp: add USB PID for a few more
supported mice"")'.

Since then, a new version of this mouse has been released (Lightpseed
Wireless), and works correctly.

This device has support for battery reporting with the driver

Signed-off-by: Stuart Hayhurst <stuart.a.hayhurst@gmail.com>
Reviewed-by: Bastien Nocera <hadess@hadess.net>
Link: https://lore.kernel.org/r/20230630113818.13005-1-stuart.a.hayhurst@gmail.com
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2023-07-09 12:48:45 +02:00
Mike Hommey
5fe2511126 HID: logitech-hidpp: add HIDPP_QUIRK_DELAYED_INIT for the T651.
commit 498ba2069035 ("HID: logitech-hidpp: Don't restart communication if
not necessary") put restarting communication behind that flag, and this
was apparently necessary on the T651, but the flag was not set for it.

Fixes: 498ba2069035 ("HID: logitech-hidpp: Don't restart communication if not necessary")
Cc: stable@vger.kernel.org
Signed-off-by: Mike Hommey <mh@glandium.org>
Link: https://lore.kernel.org/r/20230617230957.6mx73th4blv7owqk@glandium.org
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
2023-06-19 16:31:06 +02:00
stuarthayhurst
48aea8b445 HID: logitech-hidpp: Add USB and Bluetooth IDs for the Logitech G915 TKL Keyboard
Adds the USB and Bluetooth IDs for the Logitech G915 TKL keyboard, for device detection
For this device, this provides battery reporting on top of hid-generic

Reviewed-by: Bastien Nocera <hadess@hadess.net>
Signed-off-by: Stuart Hayhurst <stuart.a.hayhurst@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2023-06-08 16:31:42 +02:00
Benjamin Tissoires
7c28afd551 HID: hidpp: terminate retry loop on success
It seems we forgot the normal case to terminate the retry loop,
making us asking 3 times each command, which is probably a little bit
too much.

And remove the ugly "goto exit" that can be replaced by a simpler "break"

Fixes: 586e8fede795 ("HID: logitech-hidpp: Retry commands when device is busy")
Suggested-by: Mark Lord <mlord@pobox.com>
Tested-by: Mark Lord <mlord@pobox.com>
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2023-06-05 21:59:58 +02:00
Bastien Nocera
6199d23c91 HID: logitech-hidpp: Handle timeout differently from busy
If an attempt at contacting a receiver or a device fails because the
receiver or device never responds, don't restart the communication, only
restart it if the receiver or device answers that it's busy, as originally
intended.

This was the behaviour on communication timeout before commit 586e8fede795
("HID: logitech-hidpp: Retry commands when device is busy").

This fixes some overly long waits in a critical path on boot, when
checking whether the device is connected by getting its HID++ version.

Signed-off-by: Bastien Nocera <hadess@hadess.net>
Suggested-by: Mark Lord <mlord@pobox.com>
Fixes: 586e8fede795 ("HID: logitech-hidpp: Retry commands when device is busy")
Link: https://bugzilla.kernel.org/show_bug.cgi?id=217412
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2023-05-31 16:08:24 +02:00
Bastien Nocera
d9d5623f37 HID: logitech-hidpp: Set wireless_status for G935 receiver
Set the USB interface "wireless_status" for the G935 receiver when
receiving battery notifications.

This will allow sound daemons such as Pipewire or PulseAudio to know
whether or not the headset is turned on and connected.

Signed-off-by: Bastien Nocera <hadess@hadess.net>
Link: https://lore.kernel.org/r/20230302105555.51417-6-hadess@hadess.net
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
2023-04-03 13:30:48 +02:00
Bastien Nocera
4a1529f44e HID: logitech-hidpp: Add Logitech G935 headset
Add the Logitech G935 headset that uses the HID++ protocol to the
list of supported devices.

Signed-off-by: Bastien Nocera <hadess@hadess.net>
Link: https://lore.kernel.org/r/20230302105555.51417-3-hadess@hadess.net
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
2023-04-03 13:30:08 +02:00
Bastien Nocera
c361982a13 HID: logitech-hidpp: Add support for ADC measurement feature
This is used in a number of Logitech headsets to report the voltage
of the battery.

Tested on a Logitech G935.

Signed-off-by: Bastien Nocera <hadess@hadess.net>
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=216483
Link: https://lore.kernel.org/r/20230302105555.51417-2-hadess@hadess.net
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
2023-04-03 13:30:08 +02:00
Bastien Nocera
e0138763be HID: logitech-hidpp: Simplify array length check
Use the compiler to force a 100-length array, rather than check the
length after the fact.

Signed-off-by: Bastien Nocera <hadess@hadess.net>
Link: https://lore.kernel.org/r/20230302105555.51417-1-hadess@hadess.net
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
2023-04-03 13:30:08 +02:00
Bastien Nocera
5b3691d15e HID: logitech-hidpp: Reconcile USB and Unifying serials
Now that USB HID++ devices can gather a serial number that matches the
one that would be gathered when connected through a Unifying receiver,
remove the last difference by dropping the product ID as devices
usually have different product IDs when connected through USB or
Unifying.

For example, on the serials on a G903 wired/wireless mouse:
- Unifying before patch: 4067-e8-ce-cd-45
- USB before patch: c086-e8-ce-cd-45
- Unifying and USB after patch: e8-ce-cd-45

Signed-off-by: Bastien Nocera <hadess@hadess.net>
Link: https://lore.kernel.org/r/20230302130117.3975-2-hadess@hadess.net
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
2023-04-03 13:29:06 +02:00
Bastien Nocera
7ad1fe0da0 HID: logitech-hidpp: Don't use the USB serial for USB devices
For devices that support the 0x0003 feature (Device Information) version 4,
set the serial based on the output of that feature, rather than relying
on the usbhid code setting the USB serial.

This should allow the serial when connected through USB to (nearly)
match the one when connected through a unifying receiver.

For example, on the serials on a G903 wired/wireless mouse:
- Unifying: 4067-e8-ce-cd-45
- USB before patch: 017C385C3837
- USB after patch: c086-e8-ce-cd-45

Signed-off-by: Bastien Nocera <hadess@hadess.net>
Link: https://lore.kernel.org/r/20230302130117.3975-1-hadess@hadess.net
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
2023-04-03 13:29:06 +02:00
Rafał Szalecki
db50f7a398 HID: logitech-hidpp: Add support for Logitech MX Master 3S mouse
Add signature for the Logitech MX Master 3S mouse over Bluetooth.

Signed-off-by: Rafał Szalecki <perexist7@gmail.com>
Reviewed-by: Bastien Nocera <hadess@hadess.net>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2023-03-03 15:04:57 +01:00
Benjamin Tissoires
a74749efb4 Merge branch 'for-6.3/logitech' into for-linus
- HID++ fixes for scroll wheel, protocol and debug (Bastien Nocera)
- add support of Logitech G923 Xbox Edition steering wheel (Walt Holman)
2023-02-22 10:37:02 +01:00
Bastien Nocera
1b136aeb3c HID: logitech-hidpp: Add myself to authors
As discussed with HID maintainer Benjamin Tissoires, add myself to the
authors list and MAINTAINERS file.

Signed-off-by: Bastien Nocera <hadess@hadess.net>
Link: https://lore.kernel.org/r/20230209154916.462158-2-hadess@hadess.net
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
2023-02-15 11:43:48 +01:00
Bastien Nocera
586e8fede7 HID: logitech-hidpp: Retry commands when device is busy
Handle the busy error coming from the device or receiver. The
documentation says a busy error can be returned when:
"
Device (or receiver) cannot answer immediately to this request
for any reason i.e:
- already processing a request from the same or another SW
- pipe full
"

Signed-off-by: Bastien Nocera <hadess@hadess.net>
Link: https://lore.kernel.org/r/20230209154916.462158-1-hadess@hadess.net
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
2023-02-15 11:43:48 +01:00
Bastien Nocera
a47a3b7af7 HID: logitech-hidpp: Add more debug statements
This should help us figure out some hairy problems with some devices.

Signed-off-by: Bastien Nocera <hadess@hadess.net>
Link: https://lore.kernel.org/r/20230206221256.129198-1-hadess@hadess.net
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
2023-02-10 14:29:57 +01:00
Walt Holman
e8ab7a10ed HID: Add support for Logitech G923 Xbox Edition steering wheel
We get the same level of features as the regular G920.

Signed-off-by: Walt Holman <waltholman09@gmail.com>
Link: https://lore.kernel.org/r/20230207195051.16373-1-waltholman09@gmail.com
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
2023-02-10 14:29:51 +01:00
Bastien Nocera
3ab1c27f92 HID: logitech-hidpp: Add Signature M650
Add support for HID++ over Bluetooth for the Logitech Signature
M650 mouse. It comes with a dongle but can also be used over Bluetooth
without one.

Signed-off-by: Bastien Nocera <hadess@hadess.net>
Link: https://lore.kernel.org/r/20220404100311.3304-1-hadess@hadess.net
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
2023-02-10 14:29:50 +01:00
Bastien Nocera
d83956c885 HID: logitech-hidpp: Remove HIDPP_QUIRK_NO_HIDINPUT quirk
HIDPP_QUIRK_NO_HIDINPUT isn't used by any devices but still happens to
work as HIDPP_QUIRK_DELAYED_INIT is defined to the same value. Remove
HIDPP_QUIRK_NO_HIDINPUT and use HIDPP_QUIRK_DELAYED_INIT everywhere
instead.

Tested on a T650 which requires that quirk, and a number of unifying and
Bluetooth devices that don't.

Signed-off-by: Bastien Nocera <hadess@hadess.net>
Link: https://lore.kernel.org/r/20230125121723.3122-2-hadess@hadess.net
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
2023-02-10 14:29:50 +01:00
Bastien Nocera
498ba20690 HID: logitech-hidpp: Don't restart communication if not necessary
Don't stop and restart communication with the device unless we need to
modify the connect flags used because of a device quirk.

Signed-off-by: Bastien Nocera <hadess@hadess.net>
Link: https://lore.kernel.org/r/20230125121723.3122-1-hadess@hadess.net
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
2023-02-10 14:29:50 +01:00
Bastien Nocera
43551d9bea HID: logitech-hidpp: Add constants for HID++ 2.0 error codes
Add constants for HID++ 2.0 error codes listed in "Protocol HID++2.0
essential features" chapter, page 3, in
logitech_hidpp_2.0_specification_draft_2012-06-04.pdf

Signed-off-by: Bastien Nocera <hadess@hadess.net>
Link: https://lore.kernel.org/r/20221207100033.64095-1-hadess@hadess.net
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
2023-02-10 14:29:50 +01:00
Bastien Nocera
cae253d603 Revert "HID: logitech-hidpp: add a module parameter to keep firmware gestures"
Now that we're in 2022, and the majority of desktop environments can and
should support touchpad gestures through libinput, remove the legacy
module parameter that made it possible to use gestures implemented in
firmware.

This will eventually allow simplifying the driver's initialisation code.

This reverts commit 9188dbaed68a4b23dc96eba165265c08caa7dc2a.

Signed-off-by: Bastien Nocera <hadess@hadess.net>
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Link: https://lore.kernel.org/r/20221220154345.474596-1-hadess@hadess.net
2023-02-10 14:29:50 +01:00
Bastien Nocera
719acb4d3b HID: logitech-hidpp: Hard-code HID++ 1.0 fast scroll support
HID++ 1.0 devices only export whether Fast Scrolling is enabled, not
whether they are capable of it. Reinstate the original quirks for the 3
supported mice so fast scrolling works again on those devices.

Fixes: 908d325e1665 ("HID: logitech-hidpp: Detect hi-res scrolling support")
Link: https://bugzilla.kernel.org/show_bug.cgi?id=216903
Signed-off-by: Bastien Nocera <hadess@hadess.net>
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Link: https://lore.kernel.org/r/20230116130937.391441-1-hadess@hadess.net
2023-02-10 14:29:21 +01:00
Bastien Nocera
690eb7dec7 HID: logitech: Disable hi-res scrolling on USB
On some Logitech mice, such as the G903, and possibly the G403, the HID
events are generated on a different interface to the HID++ one.

If we enable hi-res through the HID++ interface, the HID interface
wouldn't know anything about it, and handle the events as if they were
regular scroll events, making the mouse unusable.

Disable hi-res scrolling on those devices until we implement scroll
events through HID++.

Signed-off-by: Bastien Nocera <hadess@hadess.net>
Tested-by: Tobias Klausmann <klausman@schwarzvogel.de>
Link: https://bugzilla.kernel.org/show_bug.cgi?id=216885
Fixes: 908d325e1665 ("HID: logitech-hidpp: Detect hi-res scrolling support")
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/r/20230203101800.139380-1-hadess@hadess.net
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
2023-02-06 10:58:15 +01:00
Bastien Nocera
0e13e7b448 HID: logitech-hidpp: Guard FF init code against non-USB devices
The Force Feedback code assumes that all the devices passed to it will
be USB devices, but that might not be the case for emulated devices.
Guard against a crash by checking the device type before poking at USB
properties.

Cc: stable@vger.kernel.org # v5.16+
Reported-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Signed-off-by: Bastien Nocera <hadess@hadess.net>
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Link: https://lore.kernel.org/r/20221215154416.111704-1-hadess@hadess.net
2022-12-19 12:06:44 +01:00
Jiri Kosina
3daac75d28 Merge branch 'for-6.2/logitech' into for-linus
- always send SwID in GetProtocolVersion for Logitech HID++ (Andreas Bergmeier)
2022-12-13 14:35:07 +01:00
Benjamin Tissoires
a9d9e46c75 Revert "HID: logitech-hidpp: Enable HID++ for all the Logitech Bluetooth devices"
This reverts commit 532223c8ac57605a10e46dc0ab23dcf01c9acb43.

As reported in [0], hid-logitech-hidpp now binds on all bluetooth mice,
but there are corner cases where hid-logitech-hidpp just gives up on
the mouse. This leads the end user with a dead mouse.

Given that we are at -rc8, we are definitively too late to find a proper
fix. We already identified 2 issues less than 24 hours after the bug
report. One in that ->match() was never designed to be used anywhere else
than in hid-generic, and the other that hid-logitech-hidpp has corner
cases where it gives up on devices it is not supposed to.

So we have no choice but postpone this patch to the next kernel release.

[0] https://lore.kernel.org/linux-input/CAJZ5v0g-_o4AqMgNwihCb0jrwrcJZfRrX=jv8aH54WNKO7QB8A@mail.gmail.com/

Reported-by: Rafael J . Wysocki <rjw@rjwysocki.net>
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2022-12-08 20:18:11 +01:00
Benjamin Tissoires
40f2432b53 Revert "HID: logitech-hidpp: Remove special-casing of Bluetooth devices"
This reverts commit 8544c812e43ab7bdf40458411b83987b8cba924d.

We need to revert commit 532223c8ac57 ("HID: logitech-hidpp: Enable HID++
for all the Logitech Bluetooth devices") because that commit might make
hid-logitech-hidpp bind on mice that are not well enough supported by
hid-logitech-hidpp, and the end result is that the probe of those mice
is now returning -ENODEV, leaving the end user with a dead mouse.

Given that commit 8544c812e43a ("HID: logitech-hidpp: Remove special-casing
of Bluetooth devices") is a direct dependency of 532223c8ac57, revert it
too.

Note that this also adapt according to commit 908d325e1665 ("HID:
logitech-hidpp: Detect hi-res scrolling support") to re-add support of
the devices that were removed from that commit too.

I have locally an MX Master and I tested this device with that revert,
ensuring we still have high-res scrolling.

Reported-by: Rafael J . Wysocki <rjw@rjwysocki.net>
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2022-12-08 20:18:11 +01:00
Andreas Bergmeier
8b7e58409b HID: logitech HID++: Send SwID in GetProtocolVersion
According to docs a SwID should be sent for GetProtocolVersion.
> 0x10.DeviceIndex.0x00.0x1n
where n is SwID.

Signed-off-by: Andreas Bergmeier <abergmeier@gmx.net>
Reviewed-by: Bastien Nocera <hadess@hadess.net>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2022-11-21 22:34:16 +01:00
Hangyu Hua
98d67f2504 hid: hid-logitech-hidpp: avoid unnecessary assignments in hidpp_connect_event
hidpp->delayed_input can't be assigned to an object that already call
input_free_device when input_register_device fails.

Fixes: c39e3d5fc9dd ("HID: logitech-hidpp: late bind the input device on wireless connection")
Signed-off-by: Hangyu Hua <hbh25y@gmail.com>
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Link: https://lore.kernel.org/r/20220812025515.19467-1-hbh25y@gmail.com
2022-09-20 11:24:30 +01:00
Bastien Nocera
908d325e16 HID: logitech-hidpp: Detect hi-res scrolling support
Rather than relying on a never-ending stream of patches for quirks.

This change will detect whether HID++ 1.0 hi-res scroll, HID++ 2.0
hi-res scroll or HID++ 2.0 hi-res scroll wheel is supported, and enable
the feature without the need for quirks.

Tested on a Logitech M705 mouse that was unsupported before this change.

[    9.365324] logitech-hidpp-device 0003:046D:406D.0006: input,hidraw3: USB HID v1.11 Mouse [Logitech M705] on usb-0000:00:14.0-4/input2:3
[   57.472434] logitech-hidpp-device 0003:046D:406D.0006: HID++ 4.5 device connected.
[   57.616429] logitech-hidpp-device 0003:046D:406D.0006: Detected HID++ 2.0 hi-res scroll wheel
[   57.712424] logitech-hidpp-device 0003:046D:406D.0006: wheel multiplier = 8

Link: https://bugzilla.kernel.org/show_bug.cgi?id=216480
Signed-off-by: Bastien Nocera <hadess@hadess.net>
Reviewed-by: Harry Cutts <hcutts@chromium.org>
Tested-by: Peter F. Patel-Schneider <pfpschneider@gmail.com>
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Link: https://lore.kernel.org/r/20220914132146.6435-1-hadess@hadess.net
2022-09-20 11:15:03 +01:00
Bastien Nocera
0799617f38 HID: logitech-hidpp: Remove hard-coded "Sw. Id." for HID++ 2.0 commands
Some HID++ 2.0 commands had correctly set a non-zero software identifier
directly as part of their function identifiers, but it's more correct to
define the function identifier and the software identifier separately
before combined them when the command is sent.

As this is now done in the previous commit, remove the hard-coded 0x1
software identifiers in the function definitions.

Signed-off-by: Bastien Nocera <hadess@hadess.net>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2022-09-07 22:07:49 +02:00
Bastien Nocera
f7b7393cc3 HID: logitech-hidpp: Fix "Sw. Id." for HID++ 2.0 commands
Always set a non-zero "Sw. Id." in the lower nibble of the Function/ASE
and Software Identifier byte in HID++ 2.0 commands.

As per the "Protocol HID++2.0 essential features" section in
https://lekensteyn.nl/files/logitech/logitech_hidpp_2.0_specification_draft_2012-06-04.pdf
"
Software identifier (4 bits, unsigned)

A number uniquely defining the software that sends a request. The
firmware must copy the software identifier in the response but does
not use it in any other ways.

0 Do not use (allows to distinguish a notification from a response).
"

Link: https://bugzilla.kernel.org/show_bug.cgi?id=215699
Signed-off-by: Bastien Nocera <hadess@hadess.net>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2022-09-07 22:07:49 +02:00
Bastien Nocera
8544c812e4 HID: logitech-hidpp: Remove special-casing of Bluetooth devices
Now that all the Logitech Bluetooth devices are probed for HID++
support, remove the handling of those 2 devices without any quirks, as
they're duplicates.

Signed-off-by: Bastien Nocera <hadess@hadess.net>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2022-09-07 22:07:49 +02:00
Bastien Nocera
532223c8ac HID: logitech-hidpp: Enable HID++ for all the Logitech Bluetooth devices
Probe for HID++ support over Bluetooth for all the Logitech Bluetooth
devices. As Logitech doesn't have a list of Bluetooth devices that
support HID++ over Bluetooth, probe every device. The HID++ driver
will fall back to plain HID if the device does not support HID++,
or to a another device-specific driver if it is part of the
unhandled_hidpp_devices array, used in the match function.

Note that this change might cause upower to export 2 batteries for
certain Bluetooth LE devices which export their battery information
through the Bluetooth BATT profile. This particular bug is tracked at:
https://gitlab.freedesktop.org/upower/upower/-/issues/166

Tested with a Logitech Signature M650 mouse, over Bluetooth

Signed-off-by: Bastien Nocera <hadess@hadess.net>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2022-09-07 22:07:49 +02:00
Xiang wangx
6431fd0151 HID: logitech-hidpp: Fix syntax errors in comments
Delete the redundant word 'in'.

Signed-off-by: Xiang wangx <wangxiang@cdjrlc.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2022-06-08 11:58:34 +02:00
Hamza Mahfooz
b23cdfbddb HID: logitech-hidpp: battery: provide CAPACITY property for newer devices
For devices that only support the BATTERY_VOLTAGE (0x1001) feature, UPower
requires the additional information provided by this patch, to set them up.

Signed-off-by: Hamza Mahfooz <someguy@effective-light.com>
Reviewed-by: Filipe Laíns <lains@riseup.net>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2021-08-20 14:32:39 +02:00
Christophe JAILLET
46dcd1cc2b HID: logitech-hidpp: Use 'atomic_inc_return' instead of hand-writing it
This function logs a warning if the workqueue gets too big.
In order to save a few cycles, use 'atomic_inc_return()' instead of an
'atomic_inc()/atomic_read()' sequence.

This axes a line of code and saves a 'atomic_read()' call.

Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2021-08-20 14:20:34 +02:00
Jiri Kosina
8f4ef88eba Merge branch 'for-5.14/logitech' into for-linus
- support for LCD menu keys + LCD brightness control on the Logitech Z-10
  speakers (with LCD) which use the same protocol as the G15 keyboards
  from Hans de Goede
2021-06-30 09:12:44 +02:00
Tom Rix
81c8bf9170 HID: logitech-hidpp: initialize level variable
Static analysis reports this representative problem

hid-logitech-hidpp.c:1356:23: warning: Assigned value is
  garbage or undefined
        hidpp->battery.level = level;
                             ^ ~~~~~

In some cases, 'level' is never set in hidpp20_battery_map_status_voltage()
Since level is not available on all hw, initialize level to unknown.

Fixes: be281368f297 ("hid-logitech-hidpp: read battery voltage from newer devices")
Signed-off-by: Tom Rix <trix@redhat.com>
Reviewed-by: Filipe Laíns <lains@riseup.net>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2021-05-27 15:40:34 +02:00
Hans de Goede
7383354ad5 HID: logitech-dj/hidpp: Add info/warn/err messages about 27 MHz keyboard encryption
By default 27 MHz Logitech keyboards send the keypresses to the receiver
in plain text. Logitech's Windows "Keyboard and Mouse settings" tool allows
configuring encryption for the keyboard wireless link.

Now there also is a Linux tool for setting this up:
https://gitlab.freedesktop.org/jwrdegoede/logitech-27mhz-keyboard-encryption-setup

Once a keyboard is paired in encrypted mode, it will no longer work with
any receiver other then the receiver it was paired with.
If a user accidentally tries to pair another keyboard with the receiver
with which a keyboard has been paired in encrypted mode, then the receiver
looses the encryption key and the originally paired keyboard will no longer
work with either that receiver, or another receiver until the keyboard's
encryption key is rewritten by another encrypted mode pairing using the
tool. Or until it is reset by following a special reset procedure.

This commit adds 3 new log messages related to 27 MHz keyboard link
encryption to the Logitech dj / hidpp drivers:

1. An info level message when keyboard encryption is being used
2. A warning message when keyboard encryption is not used
3. An error message when the encryption key has been lost and the
   keyboard will not work because of this

Messages 2. and 3. contain a link to the userspace tool to setup the
encryption. The linked page also contains instructions to clear the key
(without needing the tool) to help a user recover from the keyboard not
working in case 3.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2021-05-05 14:28:12 +02:00