Comment 19 for bug 995715

Revision history for this message
Dirk Porezag (dirk-porezag) wrote : Re: X defaulting keyboard locale to US at login after upgrading distribution if a Logitech Unifying Receiver is plugged in

Experienced the same bug after upgrading from 11.0 to 12.04. After some extensive debugging and researching for posts of other people (and distros) with similar problems I think the issue is as follows:

Ubuntu 12.04 comes with Kernel 3.2. 3.2 introduced the logitech_dj HID driver that is supposed to provide full support for the Logitech Unifying Receiver. Kernels < 3.2 used the generic-usb HID driver instead.

With the generic-usb driver, the kernel will create three hidraw device nodes for each unifying receiver: one for the receiver itself, one for a keyboard along with its LED indicators and one that accumulates functions for mice and consumer control devices (for example, the K340 I have has special keys for Mail, Play, on/off, etc. that are similar to a remote control). These functions seem to be contained in the USB HID report descriptor of the Unifying Receiver. Of the three hidraw device nodes, two evdev devices are created under /dev/input, one for keyboard/LED and one for mouse/consumer control and all is working well.

With the logitech-dj driver, the kernel will create one hidraw device node for the receiver itself and one device node for every physical device paired with this receiver. The input properties for each device node are derived from a set of bits that the physical device reports to the Unifying Receiver. Most keyboards I've seen happen to send at least: keyboard + LED, consumer control and system control (there is a power button function on the keyboard, too). So we have one hidraw device node (and a corresponding evdev device node under /dev/input) with keyboard, LED, consumer control and system control capabilities. Unfortunately, the consumer control part contains a key that is translated into a "HorizontalWheel" function.

Now Xorg comes into play. It uses the evdev input devices. With the generic-usb driver, it finds a keyboard and a pointer input device and attributes them to the Virtual core keyboard and Virtual core pointer, respectively, and all is fine. With the logitech-dj driver, it just finds a single input device for the keyboard (and its extra functions like consumer control) and sees that it supposedly has keyboard AND pointer functions (recall the "HorizontalWheel" issue). Based on this, Xorg seems to attribute the device to the Virtual core pointer and leaves the Virtual core keyboard without a physical device. And now it seems that Xorg ignores the keyboard layout settings configured in e.g. /etc/X11/xorg.conf.d/10-keyboard.conf if the only keyboard present is attached to the Virtual Core pointer. There is a bug report that describes this issue at https://bugs.freedesktop.org/show_bug.cgi?id=49950.

So, in short, the logitech_dj driver triggers a bug in Xorg that causes the issue.

I have tried to different fixes to resolve the issue, that both work. Both fixes are workarounds that prevent the Xorg bug to be triggered as long as it exists.

Option 1:
Get the kernel source of your current "precise" kernel and apply the following trivial fix (which is actually a backport from Linux upstream 3.4):
#------------------------
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1463,8 +1463,10 @@ static const struct hid_device_id hid_have_special_driver[] = {
  { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_DFGT_WHEEL) },
  { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G25_WHEEL) },
  { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G27_WHEEL) },
+#if IS_ENABLED(CONFIG_HID_LOGITECH_DJ)
  { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_UNIFYING_RECEIVER) },
  { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_UNIFYING_RECEIVER_2) },
+#endif
  { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WII_WHEEL) },
  { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2) },
  { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACETRAVELLER) },
#------------------------
Then disable CONFIG_HID_LOGITECH_DJ in the kernel config and build a custom kernel. Install and boot the new kernel and the issue will be fixed since the modification reinstates the pre-3.2 behavior and uses the generic-usb driver.

Option 2:
Change the logitech_dj driver to set HID_QUIRK_MULTI_INPUT for paired devices that provide both keyboard and consumer control functions. This is a little more involved, I won't include the details here since this post is too long already, but it does the trick since with this quirk definition, we get separate devices for each subfunction which makes Xorg happy.

I think Option 1 is by far the easiest way to go and when I see how many people have problems with the logitech_dj driver (look at bug reports 993827, 997479, 1000255, 991932 and 958174) I think this driver should be removed from the main distro until Xorg is happy with the devices it creates. It is extremely annoying for users of non-English keyboards to get a broken layout upon login - and the Logitech Unifying Receivers are pretty popular.