2013/05/02

Debug Linux Kernel Module: hid-multitouch



最近在看 Linux Kernel module: hid-multitouch 的問題,在這裡將相關用到的 debug 技巧紀錄下來。

(內容會有點零亂不全,畢竟相關資料小弟沒看幾天)


USB 裝置連線問題


舉凡 USB 插上後沒預期反應可先確認裝置是否有被 USB Hub 偵測到,可用 lsusb 或 dmesg 查看 log。如下
$ dmesg | tail
[ 1589.450251] usb 2-1.2: new full-speed USB device number 5 using ehci_hcd
[ 1589.547043] input: Logitech USB Receiver as /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0/input/input14
[ 1589.547234] generic-usb 0003:046D:C52E.0009: input,hidraw1: USB HID v1.11 Keyboard [Logitech USB Receiver] on usb-0000:00:1d.0-1.2/input0
[ 1589.549531] input: Logitech USB Receiver as /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.1/input/input15
[ 1589.549852] generic-usb 0003:046D:C52E.000A: input,hiddev0,hidraw2: USB HID v1.11 Mouse [Logitech USB Receiver] on usb-0000:00:1d.0-1.2/input1

看起來有被偵測到。再用 lsusb 看一下 USB 列表,有時會再下 -vv 看一些 USB 的參數,像 USB 3.0 or 2.1(參數 bcdUSB)。
$ lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 002: ID 8087:0024 Intel Corp. Integrated Rate Matching Hub
Bus 002 Device 002: ID 8087:0024 Intel Corp. Integrated Rate Matching Hub
Bus 001 Device 003: ID 0a5c:21d7 Broadcom Corp.
Bus 001 Device 006: ID 2149:2003
Bus 001 Device 005: ID 0c45:649c Microdia
Bus 002 Device 005: ID 046d:c52e Logitech, Inc.


USB 封包監聽


如果很不幸的,問題是發生在 driver/kernel 或更底層的問題,以及大大們有能力弄懂 USB protocol 的話,可以用 wireshark and usbmon 來監聽 USB traffic。安裝/打開 wireshark 之前,要先做一些前置動作

$ # 掛 usbmon
$ sudo modprobe usbmomn
$ # 掛 debugfs, 如果已掛上了就不用做
$ mount -t debugfs / /sys/kernel/debug

接著打開 wireshark,就會看到多了幾個可監聽的 USB hubs 可以選,如第一張圖。


driver 沒上(熱插拔)


請先自己想辦法找到對應的 driver,再手動 insmod 即可。要找的方法很多,而且因裝置而異,我這裡就不提了。

通常最常遇到的只是 driver 內沒包含裝置的 vendor and product ID,可以先用 sysfs 內的 new_id 來先做測試,如下
$ # 先把 driver 掛上
$ sudo modprobe hid-multitouch
$ # 接著用 lsusb 確認 vendor and product id
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 002: ID 8087:0024 Intel Corp. Integrated Rate Matching Hub
Bus 002 Device 002: ID 8087:0024 Intel Corp. Integrated Rate Matching Hub
Bus 001 Device 003: ID 0a5c:21d7 Broadcom Corp.
Bus 001 Device 006: ID 2149:2003
Bus 001 Device 005: ID 0c45:649c Microdia
Bus 002 Device 005: ID 046d:c52e Logitech, Inc.
$ # 看到了觸控裝置 2149:2003
$ echo 2149 2003 > /sys/module/hid_multitouch/drivers/hid\:hid-multitouch/new_id

到這裡這隻 driver 應該就起作用了。緊接著,若想以後能自動插入 driver 可修改 udev 的 rules,如下:
$ cat /etc/udev/rules.d/41-hid-multitouch.rules
SUBSYSTEM=="usb", ATTRS{idVendor}=="2149", ATTRS{idProduct}=="2003", RUN+="/bin/sh /etc/udev/load_hid_multitouch.sh $env{ID_VENDOR_ID} $env{ID_MODEL_ID}"


input event 監聽


若是 driver 掛上了,行為有點不如預期,可能是有些 input event 會自動消失或是不準的,可以用 evtest 來監看所有的 input event。

$ sudo evtest /dev/input/event11
Input driver version is 1.0.1
Input device ID: bus 0x3 vendor 0x2149 product 0x2003 version 0x110
Input device name: "Advanced Silicon S.A. CoolTouch(TM) System"
Supported events:
  Event type 0 (EV_SYN)
  Event type 1 (EV_KEY)
    Event code 330 (BTN_TOUCH)
  Event type 3 (EV_ABS)
    Event code 0 (ABS_X)
      Value   9104
      Min        0
      Max    32767
    Event code 1 (ABS_Y)
      Value  18364
      Min        0
      Max    32767
    Event code 47 (ABS_MT_SLOT)
      Value      0
      Min        0
      Max        9
    Event code 53 (ABS_MT_POSITION_X)
      Value      0
      Min        0
      Max    32767
    Event code 54 (ABS_MT_POSITION_Y)
      Value      0
      Min        0
      Max    32767
    Event code 57 (ABS_MT_TRACKING_ID)
      Value      0
      Min        0
      Max    65535
Testing ... (interrupt to exit)
Event: time 1367477844.348301, type 3 (EV_ABS), code 57 (ABS_MT_TRACKING_ID), value 50
Event: time 1367477844.348303, type 3 (EV_ABS), code 53 (ABS_MT_POSITION_X), value 9655
Event: time 1367477844.348303, type 3 (EV_ABS), code 54 (ABS_MT_POSITION_Y), value 10190
Event: time 1367477844.348313, type 1 (EV_KEY), code 330 (BTN_TOUCH), value 1
Event: time 1367477844.348315, type 3 (EV_ABS), code 0 (ABS_X), value 9655
Event: time 1367477844.348315, type 3 (EV_ABS), code 1 (ABS_Y), value 10190
Event: time 1367477844.348316, -------------- SYN_REPORT ------------
Event: time 1367477844.493292, type 3 (EV_ABS), code 57 (ABS_MT_TRACKING_ID), value -1
Event: time 1367477844.493301, type 1 (EV_KEY), code 330 (BTN_TOUCH), value 0
Event: time 1367477844.493302, -------------- SYN_REPORT ------------

最後的問題有可能是出現在 driver or application,這就看自己的造化了。小弟我遇到的問題是都有,還好 upstream 都解了。最後提一下,在看 driver 前除了有基本的知識外,舉例來說在解 USB HID multitouch driver 時,最好可以從 USB protocol 到 hid-multitouch 都有基本的了解,USB protocol 網上資料一堆,hid-multitouch 則看 kernel 裡的 Documentation/input/multi-touch-protocol.txt 即可。

(唉,解 bug 花的時間沒寫文章的多)

Reference

No comments: