July 29, 2015

Reloading TouchPad driver

I often switch input devices on my T420 and seems that X server doesn't like that.

The thing is that my touchpad, from time to time became weird, especially after I switch off external mouse; instead of normal mouse pointer moving, touchpad will start to scroll pages or desktops randomly and the only way to move the mouse is to use trackpad, which I don't like. Close inspection of X log reveals this:

(EE) BUG: triggered 'if (priv->num_active_touches > priv->num_slots)'
(EE) BUG: synaptics.c:2643 in UpdateTouchState()
(EE)
(EE) Backtrace:
(EE) 0: /usr/bin/X (xorg_backtrace+0x3d) [0x57b11d]
(EE) 1: /usr/lib64/xorg/modules/input/synaptics_drv.so (0x7fad4d2b6000+0x2d27) [0x7fad4d2b8d27]
(EE) 2: /usr/lib64/xorg/modules/input/synaptics_drv.so (0x7fad4d2b6000+0x4c70) [0x7fad4d2bac70]
(EE) 3: /usr/lib64/xorg/modules/input/synaptics_drv.so (0x7fad4d2b6000+0x6872) [0x7fad4d2bc872]
(EE) 4: /usr/bin/X (0x400000+0x721b8) [0x4721b8]
(EE) 5: /usr/bin/X (0x400000+0x9a2fd) [0x49a2fd]
(EE) 6: /lib64/libpthread.so.0 (0x7fad517a0000+0xf670) [0x7fad517af670]
(EE) 7: /lib64/libc.so.6 (__select+0x13) [0x7fad4f9e31d3]
(EE) 8: /usr/bin/X (WaitForSomething+0x19c) [0x57880c]
(EE) 9: /usr/bin/X (0x400000+0x35c51) [0x435c51]
(EE) 10: /usr/bin/X (0x400000+0x2546a) [0x42546a]
(EE) 11: /lib64/libc.so.6 (__libc_start_main+0xf5) [0x7fad4f913d85]
(EE) 12: /usr/bin/X (0x400000+0x257b1) [0x4257b1]

Great! Driver issue on Slackware means you will either need to wait the new release or switch to Current. Don't get me wrong, these things on Slack are pretty rare, but when they happen, you are on your own.

I tried to find any solution that can work (mainly the way how to restart Synaptics driver), but the problem is that this driver is used and loaded by X server, not linux kernel so usual modprobe/rmmod combo will not work.

There were some attempts, but these didn't work for me. Not to say those Fn combos are, presuming, Ubuntu specific stuff.

After couple of failed attempts with some crazy ideas, I though, why not try to use xinput; after all, this is THE tool for controlling X server input devices.

Hit man xinput (you do read man pages, right?) and noticed this chunk:

--list [--short || --long || --name-only || --id-only] [device]
        If no argument is given list all the input devices. If an
        argument is given, show all the features of device.  If --long
        is provided, the output  includes  detailed information about
        the capabilities of each devices. ...

Perfect! Now, I just need the way to reload those devices and couple of lines down below I saw:

--enable device
       Enable the device. This call is equivalent to
       xinput --set-prop device "Device Enabled" 1

--disable device
       Disable the device. This call is equivalent to
       xinput --set-prop device "Device Enabled" 0
					  

Awesome! Now, let we see what xinput –list will output:

⎡ Virtual core pointer                    	id=2	[master pointer  (3)]
⎜   ↳ Virtual core XTEST pointer              	id=4	[slave  pointer  (2)]
⎜   ↳ TPPS/2 IBM TrackPoint                   	id=12	[slave  pointer  (2)]
⎜   ↳ SynPS/2 Synaptics TouchPad              	id=11	[slave  pointer  (2)]
⎜   ↳ 2.4G Wireless Optical Mouse             	id=14	[slave  pointer  (2)]
⎜   ↳ HID 04f3:0103                           	id=15	[slave  pointer  (2)]
⎣ Virtual core keyboard                   	id=3	[master keyboard (2)]
    ↳ Virtual core XTEST keyboard             	id=5	[slave  keyboard (3)]
    ↳ Power Button                            	id=6	[slave  keyboard (3)]
    ↳ Video Bus                               	id=7	[slave  keyboard (3)]
    ↳ Sleep Button                            	id=8	[slave  keyboard (3)]
    ↳ Integrated Camera                       	id=9	[slave  keyboard (3)]
    ↳ AT Translated Set 2 keyboard            	id=10	[slave  keyboard (3)]
    ↳ ThinkPad Extra Buttons                  	id=13	[slave  keyboard (3)]
    ↳ HID 04f3:0103                           	id=16	[slave  keyboard (3)]

My touchpad is listed under id 11 so doing this in terminal:

$ xinput --disable 11
$ xinput --enable 11

will essentially reload the driver and make touchpad working again (looks like X will unload device driver when you disable that device). Looking at X log shows that device is found again:

...
[1824821.531] (--) synaptics: SynPS/2 Synaptics TouchPad: touchpad found
...

Instead of doing this thing manually every time, a simple shell script will help:

#!/bin/sh

id=`xinput list | sed -ne '/Synaptics/p' | cut -d'=' -f2 | awk '{print $1}'`

echo "Found TouchPad device under $id. Reloading..."
xinput disable $id
xinput enable  $id
Tags: misc