On 12.08.2021 06:37, Mark Kane wrote:
> On 2021-08-11 17:12, Vladimir Kondratyev wrote:
>> On 10.08.2021 07:03, Mark Kane wrote:
>>> # usbhid-dump
>>> 000:003:000:DESCRIPTOR 1628551474.564813
>>> 8D 0F 00 09 42 09 32 15 00 25 01 95 02 75 01 81
>>> 02 95 06 75 01 81 03 05 01 09 30 75 10 95 01 A4
>>> 55 00 65 00 36 00 00 46 00 00 16 1E 00 26 C8 0F
>>> 81 02 09 31 16 3C 00 26
>> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>> This one looks like corrupted fragment of touch device HID report
>> descriptor. Check wires, USB port, device itself and so on. Most
>> probably, it is a standard eGalax HID device with some USB transport
>> problems.
>
> That is very interesting and a good catch. I have been using the same
> cable and USB port across all tests for consistency. This same #2 screen
> connected with the same cable to an identical machine running Linux
> 4.4.0-104 we get a much longer HID report descriptor:
>
> linux# lsusb
> Bus 001 Device 005: ID 05e3:0608 Genesys Logic, Inc. Hub
> Bus 001 Device 004: ID 04ca:004f Lite-On Technology Corp. SK-9020 keyboard
> Bus 001 Device 003: ID 0eef:0001 D-WAV Scientific Co., Ltd eGalax
> TouchScreen
> Bus 001 Device 002: ID 8087:07e6 Intel Corp.
> Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
> linux# usbhid-dump
> 001:004:001:DESCRIPTOR 1628727550.064013
> 05 0C 09 01 A1 01 85 01 19 00 2A 3C 02 15 00 26
> 3C 02 95 01 75 10 81 00 C0 05 01 09 80 A1 01 85
> 02 19 81 29 83 25 01 75 01 95 03 81 02 95 05 81
> 01 C0
>
> 001:004:000:DESCRIPTOR 1628727550.066916
> 05 01 09 06 A1 01 05 07 19 E0 29 E7 15 00 25 01
> 95 08 75 01 81 02 95 08 75 01 81 01 05 08 19 01
> 29 03 95 03 75 01 91 02 95 01 75 05 91 01 05 07
> 19 00 2A FF 00 15 00 26 FF 00 95 06 75 08 81 00
> C0
>
> 001:003:000:DESCRIPTOR 1628727550.070850
> 05 01 09 01 A1 01 85 01 09 01 A1 00 05 09 19 01
> 29 02 15 00 25 01 95 02 75 01 81 02 95 01 75 06
> 81 01 05 01 09 30 09 31 16 2A 00 26 BD 07 36 00
> 00 46 FF 0F 66 00 00 75 10 95 02 81 02 C0 C0 05
> 0D 09 04 A1 01 85 02 09 20 A1 00 09 42 09 32 15
> 00 25 01 95 02 75 01 81 02 95 06 75 01 81 03 05
> 01 09 30 75 10 95 01 A4 55 00 65 00 36 00 00 46
> 00 00 16 1E 00 26 C8 0F 81 02 09 31 16 3C 00 26
> C3 0F 36 00 00 46 00 00 81 02 B4 C0 C0
> linux#
>
This report descriptor looks good and differs from post 2014 one. It
belongs to device which uses legacy MS stylus protocol. I attached a
patch which implements support for it in hpen(4) driver. Also it is
applicable to post 2014 devices as they have stylus top level collection
too.
> Touch on this screen fully works on Linux using the binary EETI driver.
> Could there be something different about the USB controller in some of
> these screens that is causing the corruption on FreeBSD? If there is any
> other info to gather from either install I'm happy to.
I do not khow how to debug this issue. May be hselasky can help here.
I can offer a workaround. Simple tool to upload fixed pre-2014 report
descriptor in to HID core through hidraw(4) interface.
Just compile it and run using proper /dev/hidraw# device node path as
parameter:
# cc -o setrdesc setrdesc.c
# ./setrdesc /dev/hidraw0
Don't forget to kldload hidraw.ko before.
> Here are some other tests with the patches. All that don't work have the
> same shorter descriptor report.
>
> Jul 2011 - doesn't work, same truncated report descriptor
> Sep 2011 - doesn't work, same truncated report descriptor
> Nov 2012 - doesn't work, same truncated report descriptor
> Mar 2013 - doesn't work, same truncated report descriptor
> Jul 2013 - doesn't work, same truncated report descriptor
> Sep 2014 - works with patches
> Sep 2014 #2 - works with patches
> Nov 2014 - works with patches
> Feb 2015 - works with patches
> Oct 2018 - works with patches
> Oct 2018 #2 - works with patches
> Feb 2020 - works with patches
> Feb 2020 - works with patches
> Feb 2021 - works with patches
>
> And some more data from Linux in case it is helpful. event5 didn't hear
> events, event7 and event14 both did:
>
event5 is dummy mouse which forces cursor appearance on Windows 7 and 8
event7 is real HID device. Something very similar would appear in
FreeBSD if both hpen.patch and setrdesc.c would work.
event14 - is something artificial created by binary driver.
> linux# evemu-record
> Available devices:
> /dev/input/event0: Power Button
> /dev/input/event1: Sleep Button
> /dev/input/event2: Power Button
> /dev/input/event3: Lite-On Technology Corp. USB Multimedia Keyboard
> /dev/input/event4: Lite-On Technology Corp. USB Multimedia Keyboard
> /dev/input/event5: eGalax Inc. USB TouchController
> /dev/input/event6: Video Bus
> /dev/input/event7: eGalax Inc. USB TouchController
> /dev/input/event8: HDA Intel PCH Mic
> /dev/input/event9: HDA Intel PCH Line Out
> /dev/input/event10: HDA Intel PCH Headphone
> /dev/input/event11: HDA Intel PCH HDMI/DP,pcm=3
> /dev/input/event12: HDA Intel PCH HDMI/DP,pcm=7
> /dev/input/event13: HDA Intel PCH HDMI/DP,pcm=8
> /dev/input/event14: eGalaxTouch Virtual Device for Single
> Select the device event number [0-14]: 7
> # EVEMU 1.2
> # Input device name: "eGalax Inc. USB TouchController"
> # Input device ID: bus 0x03 vendor 0xeef product 0x01 version 0x210
> # Supported events:
> # Event type 0 (EV_SYN)
> # Event code 0 (SYN_REPORT)
> # Event code 1 (SYN_CONFIG)
> # Event code 2 (SYN_MT_REPORT)
> # Event code 3 (SYN_DROPPED)
> # Event code 4 ((null))
> # Event code 5 ((null))
> # Event code 6 ((null))
> # Event code 7 ((null))
> # Event code 8 ((null))
> # Event code 9 ((null))
> # Event code 10 ((null))
> # Event code 11 ((null))
> # Event code 12 ((null))
> # Event code 13 ((null))
> # Event code 14 ((null))
> # Event type 1 (EV_KEY)
> # Event code 320 (BTN_TOOL_PEN)
> # Event code 330 (BTN_TOUCH)
> # Event type 3 (EV_ABS)
> # Event code 0 (ABS_X)
> # Value 2069
> # Min 30
> # Max 4040
> # Fuzz 0
> # Flat 0
> # Resolution 0
> # Event code 1 (ABS_Y)
> # Value 2503
> # Min 60
> # Max 4035
> # Fuzz 0
> # Flat 0
> # Resolution 0
> # Event type 4 (EV_MSC)
> # Event code 4 (MSC_SCAN)
> # Properties:
> N: eGalax Inc. USB TouchController
> I: 0003 0eef 0001 0210
> P: 00 00 00 00 00 00 00 00
> B: 00 0b 00 00 00 00 00 00 00
> B: 01 00 00 00 00 00 00 00 00
> B: 01 00 00 00 00 00 00 00 00
> B: 01 00 00 00 00 00 00 00 00
> B: 01 00 00 00 00 00 00 00 00
> B: 01 00 00 00 00 00 00 00 00
> B: 01 01 04 00 00 00 00 00 00
> B: 01 00 00 00 00 00 00 00 00
> B: 01 00 00 00 00 00 00 00 00
> B: 01 00 00 00 00 00 00 00 00
> B: 01 00 00 00 00 00 00 00 00
> B: 01 00 00 00 00 00 00 00 00
> B: 01 00 00 00 00 00 00 00 00
> B: 02 00 00 00 00 00 00 00 00
> B: 03 03 00 00 00 00 00 00 00
> B: 04 10 00 00 00 00 00 00 00
> B: 05 00 00 00 00 00 00 00 00
> B: 11 00 00 00 00 00 00 00 00
> B: 12 00 00 00 00 00 00 00 00
> B: 14 00 00 00 00 00 00 00 00
> B: 15 00 00 00 00 00 00 00 00
> B: 15 00 00 00 00 00 00 00 00
> A: 00 30 4040 0 0 0
> A: 01 60 4035 0 0 0
> ################################
> # Waiting for events #
> ################################
> E: 0.000000 0004 0004 852034 # EV_MSC / MSC_SCAN 852034
> E: 0.000000 0001 014a 0001 # EV_KEY / BTN_TOUCH 1
> E: 0.000000 0003 0000 1533 # EV_ABS / ABS_X 1533
> E: 0.000000 0003 0001 2343 # EV_ABS / ABS_Y 2343
> E: 0.000000 0000 0000 0000 # ------------ SYN_REPORT (0) ----------
> E: 0.006000 0003 0001 2345 # EV_ABS / ABS_Y 2345
> E: 0.006000 0000 0000 0000 # ------------ SYN_REPORT (0) ----------
> E: 0.010005 0003 0000 1532 # EV_ABS / ABS_X 1532
> E: 0.010005 0003 0001 2358 # EV_ABS / ABS_Y 2358
> E: 0.010005 0000 0000 0000 # ------------ SYN_REPORT (0) ----------
> E: 0.016010 0003 0000 1529 # EV_ABS / ABS_X 1529
> E: 0.016010 0003 0001 2370 # EV_ABS / ABS_Y 2370
> E: 0.016010 0000 0000 0000 # ------------ SYN_REPORT (0) ----------
> E: 0.021998 0003 0000 1528 # EV_ABS / ABS_X 1528
> E: 0.021998 0003 0001 2378 # EV_ABS / ABS_Y 2378
> E: 0.021998 0000 0000 0000 # ------------ SYN_REPORT (0) ----------
> E: 0.028003 0003 0000 1527 # EV_ABS / ABS_X 1527
> E: 0.028003 0000 0000 0000 # ------------ SYN_REPORT (0) ----------
> E: 0.034000 0003 0000 1526 # EV_ABS / ABS_X 1526
> E: 0.034000 0003 0001 2382 # EV_ABS / ABS_Y 2382
> E: 0.034000 0000 0000 0000 # ------------ SYN_REPORT (0) ----------
> E: 0.042003 0003 0001 2387 # EV_ABS / ABS_Y 2387
> E: 0.042003 0000 0000 0000 # ------------ SYN_REPORT (0) ----------
> E: 0.050018 0003 0000 1525 # EV_ABS / ABS_X 1525
> E: 0.050018 0003 0001 2386 # EV_ABS / ABS_Y 2386
> E: 0.050018 0000 0000 0000 # ------------ SYN_REPORT (0) ----------
> E: 0.058013 0003 0000 1524 # EV_ABS / ABS_X 1524
> E: 0.058013 0000 0000 0000 # ------------ SYN_REPORT (0) ----------
> E: 0.074006 0003 0000 1523 # EV_ABS / ABS_X 1523
> E: 0.074006 0003 0001 2387 # EV_ABS / ABS_Y 2387
> E: 0.074006 0000 0000 0000 # ------------ SYN_REPORT (0) ----------
> E: 0.089999 0003 0001 2388 # EV_ABS / ABS_Y 2388
> E: 0.089999 0000 0000 0000 # ------------ SYN_REPORT (0) ----------
> E: 0.123988 0003 0000 1522 # EV_ABS / ABS_X 1522
> E: 0.123988 0003 0001 2395 # EV_ABS / ABS_Y 2395
> E: 0.123988 0000 0000 0000 # ------------ SYN_REPORT (0) ----------
> E: 0.139999 0003 0001 2405 # EV_ABS / ABS_Y 2405
> E: 0.139999 0000 0000 0000 # ------------ SYN_REPORT (0) ----------
> E: 0.156001 0003 0000 1523 # EV_ABS / ABS_X 1523
> E: 0.156001 0003 0001 2403 # EV_ABS / ABS_Y 2403
> E: 0.156001 0000 0000 0000 # ------------ SYN_REPORT (0) ----------
> E: 0.172000 0003 0000 1524 # EV_ABS / ABS_X 1524
> E: 0.172000 0003 0001 2393 # EV_ABS / ABS_Y 2393
> E: 0.172000 0000 0000 0000 # ------------ SYN_REPORT (0) ----------
> E: 0.187999 0003 0000 1527 # EV_ABS / ABS_X 1527
> E: 0.187999 0003 0001 2392 # EV_ABS / ABS_Y 2392
> E: 0.187999 0000 0000 0000 # ------------ SYN_REPORT (0) ----------
> E: 0.211989 0004 0004 852034 # EV_MSC / MSC_SCAN 852034
> E: 0.211989 0001 014a 0000 # EV_KEY / BTN_TOUCH 0
> E: 0.211989 0000 0000 0000 # ------------ SYN_REPORT (0) ----------
> ^Clinux# evemu-record
> Available devices:
> /dev/input/event0: Power Button
> /dev/input/event1: Sleep Button
> /dev/input/event2: Power Button
> /dev/input/event3: Lite-On Technology Corp. USB Multimedia Keyboard
> /dev/input/event4: Lite-On Technology Corp. USB Multimedia Keyboard
> /dev/input/event5: eGalax Inc. USB TouchController
> /dev/input/event6: Video Bus
> /dev/input/event7: eGalax Inc. USB TouchController
> /dev/input/event8: HDA Intel PCH Mic
> /dev/input/event9: HDA Intel PCH Line Out
> /dev/input/event10: HDA Intel PCH Headphone
> /dev/input/event11: HDA Intel PCH HDMI/DP,pcm=3
> /dev/input/event12: HDA Intel PCH HDMI/DP,pcm=7
> /dev/input/event13: HDA Intel PCH HDMI/DP,pcm=8
> /dev/input/event14: eGalaxTouch Virtual Device for Single
> Select the device event number [0-14]: 14
> # EVEMU 1.2
> # Input device name: "eGalaxTouch Virtual Device for Single"
> # Input device ID: bus 0x06 vendor 0xeef product 0x10 version 0x01
> # Supported events:
> # Event type 0 (EV_SYN)
> # Event code 0 (SYN_REPORT)
> # Event code 1 (SYN_CONFIG)
> # Event code 2 (SYN_MT_REPORT)
> # Event code 3 (SYN_DROPPED)
> # Event code 4 ((null))
> # Event code 5 ((null))
> # Event code 6 ((null))
> # Event code 7 ((null))
> # Event code 8 ((null))
> # Event code 9 ((null))
> # Event code 10 ((null))
> # Event code 11 ((null))
> # Event code 12 ((null))
> # Event code 13 ((null))
> # Event code 14 ((null))
> # Event type 1 (EV_KEY)
> # Event code 272 (BTN_LEFT)
> # Event code 273 (BTN_RIGHT)
> # Event code 276 (BTN_EXTRA)
> # Event type 3 (EV_ABS)
> # Event code 0 (ABS_X)
> # Value 766
> # Min 0
> # Max 2047
> # Fuzz 0
> # Flat 0
> # Resolution 0
> # Event code 1 (ABS_Y)
> # Value 875
> # Min 0
> # Max 2047
> # Fuzz 0
> # Flat 0
> # Resolution 0
> # Event code 3 (ABS_RX)
> # Value 0
> # Min 0
> # Max 2047
> # Fuzz 0
> # Flat 0
> # Resolution 0
> # Event code 4 (ABS_RY)
> # Value 0
> # Min 0
> # Max 2047
> # Fuzz 0
> # Flat 0
> # Resolution 0
> # Properties:
> # Property type 1 (INPUT_PROP_DIRECT)
> N: eGalaxTouch Virtual Device for Single
> I: 0006 0eef 0010 0001
> P: 02 00 00 00 00 00 00 00
> B: 00 0b 00 00 00 00 00 00 00
> B: 01 00 00 00 00 00 00 00 00
> B: 01 00 00 00 00 00 00 00 00
> B: 01 00 00 00 00 00 00 00 00
> B: 01 00 00 00 00 00 00 00 00
> B: 01 00 00 13 00 00 00 00 00
> B: 01 00 00 00 00 00 00 00 00
> B: 01 00 00 00 00 00 00 00 00
> B: 01 00 00 00 00 00 00 00 00
> B: 01 00 00 00 00 00 00 00 00
> B: 01 00 00 00 00 00 00 00 00
> B: 01 00 00 00 00 00 00 00 00
> B: 01 00 00 00 00 00 00 00 00
> B: 02 00 00 00 00 00 00 00 00
> B: 03 1b 00 00 00 00 00 00 00
> B: 04 00 00 00 00 00 00 00 00
> B: 05 00 00 00 00 00 00 00 00
> B: 11 00 00 00 00 00 00 00 00
> B: 12 00 00 00 00 00 00 00 00
> B: 14 00 00 00 00 00 00 00 00
> B: 15 00 00 00 00 00 00 00 00
> B: 15 00 00 00 00 00 00 00 00
> A: 00 0 2047 0 0 0
> A: 01 0 2047 0 0 0
> A: 03 0 2047 0 0 0
> A: 04 0 2047 0 0 0
> ################################
> # Waiting for events #
> ################################
> E: 0.000000 0003 0000 0650 # EV_ABS / ABS_X 650
> E: 0.000000 0003 0001 1576 # EV_ABS / ABS_Y 1576
> E: 0.000000 0001 0110 0001 # EV_KEY / BTN_LEFT 1
> E: 0.000000 0000 0000 0000 # ------------ SYN_REPORT (0) ----------
> E: 0.000018 0001 0110 0000 # EV_KEY / BTN_LEFT 0
> E: 0.000018 0000 0000 0000 # ------------ SYN_REPORT (0) ----------
> E: 0.517999 0003 0000 1328 # EV_ABS / ABS_X 1328
> E: 0.517999 0003 0001 1461 # EV_ABS / ABS_Y 1461
> E: 0.517999 0001 0110 0001 # EV_KEY / BTN_LEFT 1
> E: 0.517999 0000 0000 0000 # ------------ SYN_REPORT (0) ----------
> E: 0.518116 0001 0110 0000 # EV_KEY / BTN_LEFT 0
> E: 0.518116 0000 0000 0000 # ------------ SYN_REPORT (0) ----------
> E: 0.968004 0003 0000 0788 # EV_ABS / ABS_X 788
> E: 0.968004 0003 0001 1335 # EV_ABS / ABS_Y 1335
> E: 0.968004 0001 0110 0001 # EV_KEY / BTN_LEFT 1
> E: 0.968004 0000 0000 0000 # ------------ SYN_REPORT (0) ----------
> E: 0.968163 0001 0110 0000 # EV_KEY / BTN_LEFT 0
> E: 0.968163 0000 0000 0000 # ------------ SYN_REPORT (0) ----------
> E: 1.405991 0003 0000 0998 # EV_ABS / ABS_X 998
> E: 1.405991 0003 0001 1254 # EV_ABS / ABS_Y 1254
> E: 1.405991 0001 0110 0001 # EV_KEY / BTN_LEFT 1
> E: 1.405991 0000 0000 0000 # ------------ SYN_REPORT (0) ----------
> E: 1.406007 0001 0110 0000 # EV_KEY / BTN_LEFT 0
> E: 1.406007 0000 0000 0000 # ------------ SYN_REPORT (0) ----------
> E: 2.077987 0003 0000 1097 # EV_ABS / ABS_X 1097
> E: 2.077987 0003 0001 1216 # EV_ABS / ABS_Y 1216
> E: 2.077987 0001 0110 0001 # EV_KEY / BTN_LEFT 1
> E: 2.077987 0000 0000 0000 # ------------ SYN_REPORT (0) ----------
> E: 2.078097 0001 0110 0000 # EV_KEY / BTN_LEFT 0
> E: 2.078097 0000 0000 0000 # ------------ SYN_REPORT (0) ----------
> E: 2.527981 0003 0000 1400 # EV_ABS / ABS_X 1400
> E: 2.527981 0003 0001 1393 # EV_ABS / ABS_Y 1393
> E: 2.527981 0001 0110 0001 # EV_KEY / BTN_LEFT 1
> E: 2.527981 0000 0000 0000 # ------------ SYN_REPORT (0) ----------
> E: 2.527999 0001 0110 0000 # EV_KEY / BTN_LEFT 0
> E: 2.527999 0000 0000 0000 # ------------ SYN_REPORT (0) ----------
> E: 2.879992 0003 0000 0791 # EV_ABS / ABS_X 791
> E: 2.879992 0003 0001 1276 # EV_ABS / ABS_Y 1276
> E: 2.879992 0001 0110 0001 # EV_KEY / BTN_LEFT 1
> E: 2.879992 0000 0000 0000 # ------------ SYN_REPORT (0) ----------
> E: 2.880014 0001 0110 0000 # EV_KEY / BTN_LEFT 0
> E: 2.880014 0000 0000 0000 # ------------ SYN_REPORT (0) ----------
> E: 3.402001 0003 0000 0890 # EV_ABS / ABS_X 890
> E: 3.402001 0003 0001 0894 # EV_ABS / ABS_Y 894
> E: 3.402001 0001 0110 0001 # EV_KEY / BTN_LEFT 1
> E: 3.402001 0000 0000 0000 # ------------ SYN_REPORT (0) ----------
> E: 3.402116 0001 0110 0000 # EV_KEY / BTN_LEFT 0
> E: 3.402116 0000 0000 0000 # ------------ SYN_REPORT (0) ----------
> linux#
>
> -------
>
> lsusb -v:
>
> Bus 001 Device 003: ID 0eef:0001 D-WAV Scientific Co., Ltd eGalax
> TouchScreen
> Device Descriptor:
> bLength 18
> bDescriptorType 1
> bcdUSB 1.10
> bDeviceClass 0 (Defined at Interface level)
> bDeviceSubClass 0
> bDeviceProtocol 0
> bMaxPacketSize0 64
> idVendor 0x0eef D-WAV Scientific Co., Ltd
> idProduct 0x0001 eGalax TouchScreen
> bcdDevice 1.00
> iManufacturer 1 eGalax Inc.
> iProduct 2 USB TouchController
> iSerial 0
> bNumConfigurations 1
> Configuration Descriptor:
> bLength 9
> bDescriptorType 2
> wTotalLength 34
> bNumInterfaces 1
> bConfigurationValue 1
> iConfiguration 1 eGalax Inc.
> bmAttributes 0xa0
> (Bus Powered)
> Remote Wakeup
> MaxPower 100mA
> Interface Descriptor:
> bLength 9
> bDescriptorType 4
> bInterfaceNumber 0
> bAlternateSetting 0
> bNumEndpoints 1
> bInterfaceClass 3 Human Interface Device
> bInterfaceSubClass 0 No Subclass
> bInterfaceProtocol 0 None
> iInterface 0
> HID Device Descriptor:
> bLength 9
> bDescriptorType 33
> bcdHID 2.10
> bCountryCode 0 Not supported
> bNumDescriptors 1
> bDescriptorType 34 Report
> wDescriptorLength 141
> Report Descriptors:
> ** UNAVAILABLE **
> Endpoint Descriptor:
> bLength 7
> bDescriptorType 5
> bEndpointAddress 0x81 EP 1 IN
> bmAttributes 3
> Transfer Type Interrupt
> Synch Type None
> Usage Type Data
> wMaxPacketSize 0x0008 1x 8 bytes
> bInterval 3
> Device Status: 0x0000
> (Bus Powered)
--
WBR
Vladimir Kondratyev
diff --git a/sys/dev/hid/hidbus.c b/sys/dev/hid/hidbus.c
index 58d19a2a4d7..69f3d391163 100644
--- a/sys/dev/hid/hidbus.c
+++ b/sys/dev/hid/hidbus.c
@@ -172,6 +172,25 @@ hidbus_locate(const void *desc, hid_size_t size, int32_t u, enum hid_kind k,
return (0);
}
+bool
+hidbus_is_collection(const void *desc, hid_size_t size, int32_t usage,
+ uint8_t tlc_index)
+{
+ struct hid_data *d;
+ struct hid_item h;
+ bool ret = false;
+
+ d = hid_start_parse(desc, size, 0);
+ HIDBUS_FOREACH_ITEM(d, &h, tlc_index) {
+ if (h.kind == hid_collection && h.usage == usage) {
+ ret = true;
+ break;
+ }
+ }
+ hid_end_parse(d);
+ return (ret);
+}
+
static device_t
hidbus_add_child(device_t dev, u_int order, const char *name, int unit)
{
diff --git a/sys/dev/hid/hidbus.h b/sys/dev/hid/hidbus.h
index 05911fff573..d4324a2dc39 100644
--- a/sys/dev/hid/hidbus.h
+++ b/sys/dev/hid/hidbus.h
@@ -152,6 +152,7 @@ int hidbus_locate(const void *desc, hid_size_t size, int32_t u,
enum hid_kind k, uint8_t tlc_index, uint8_t index,
struct hid_location *loc, uint32_t *flags, uint8_t *id,
struct hid_absinfo *ai);
+bool hidbus_is_collection(const void *, hid_size_t, int32_t, uint8_t);
const struct hid_device_id *hidbus_lookup_id(device_t,
const struct hid_device_id *, int);
diff --git a/sys/dev/hid/hidmap.c b/sys/dev/hid/hidmap.c
index 46e789fa7ce..d787b298b41 100644
--- a/sys/dev/hid/hidmap.c
+++ b/sys/dev/hid/hidmap.c
@@ -451,7 +451,8 @@ hidmap_probe_hid_descr(void *d_ptr, hid_size_t d_len, uint8_t tlc_index,
bool do_free = false;
if (caps == NULL) {
- caps = malloc(HIDMAP_CAPS_SZ(nitems_map), M_DEVBUF, M_WAITOK);
+ caps = malloc(HIDMAP_CAPS_SZ(nitems_map), M_DEVBUF,
+ M_WAITOK | M_ZERO);
do_free = true;
} else
bzero (caps, HIDMAP_CAPS_SZ(nitems_map));
@@ -481,7 +482,10 @@ hidmap_probe_hid_descr(void *d_ptr, hid_size_t d_len, uint8_t tlc_index,
/* Check that all mandatory usages are present in report descriptor */
if (items != 0) {
for (i = 0; i < nitems_map; i++) {
- if (map[i].required && isclr(caps, i)) {
+ KASSERT(!(map[i].required && map[i].forbidden),
+ ("both required & forbidden item flags are set"));
+ if ((map[i].required && isclr(caps, i)) ||
+ (map[i].forbidden && isset(caps, i))) {
items = 0;
break;
}
diff --git a/sys/dev/hid/hidmap.h b/sys/dev/hid/hidmap.h
index 6ac23b3dc4e..62888109263 100644
--- a/sys/dev/hid/hidmap.h
+++ b/sys/dev/hid/hidmap.h
@@ -62,6 +62,8 @@ typedef int hidmap_cb_t(HIDMAP_CB_ARGS);
/* These helpers can be used at any stage of any callbacks */
#define HIDMAP_CB_GET_STATE(...) \
((hm == NULL) ? HIDMAP_CB_IS_PROBING : hm->cb_state)
+#define HIDMAP_CB_GET_DEV(...) \
+ (hm == NULL ? NULL : hm->dev)
#define HIDMAP_CB_GET_SOFTC(...) \
(hm == NULL ? NULL : device_get_softc(hm->dev))
#define HIDMAP_CB_GET_EVDEV(...) \
@@ -98,7 +100,8 @@ struct hidmap_item {
bool has_cb:1;
bool final_cb:1;
bool invert_value:1;
- u_int reserved:10;
+ bool forbidden:1; /* Forbidden by driver */
+ u_int reserved:9;
};
#define HIDMAP_ANY(_page, _usage, _type, _code) \
diff --git a/sys/dev/hid/hms.c b/sys/dev/hid/hms.c
index 94267b3fcd5..0f60eec86a4 100644
--- a/sys/dev/hid/hms.c
+++ b/sys/dev/hid/hms.c
@@ -109,6 +109,7 @@ static const struct hidmap_item hms_map_wheel_rev[] = {
/* A match on these entries will load hms */
static const struct hid_device_id hms_devs[] = {
+ { HID_TLC(HUP_GENERIC_DESKTOP, HUG_POINTER) },
{ HID_TLC(HUP_GENERIC_DESKTOP, HUG_MOUSE) },
};
diff --git a/sys/dev/hid/hpen.c b/sys/dev/hid/hpen.c
index 1d505e14089..8a86b95b102 100644
--- a/sys/dev/hid/hpen.c
+++ b/sys/dev/hid/hpen.c
@@ -72,44 +72,43 @@ static hidmap_cb_t hpen_final_pen_cb;
HIDMAP_ABS_CB(HUP_DIGITIZERS, HUD_##usage, &cb)
/* Generic map digitizer page map according to hut1_12v2.pdf */
-static const struct hidmap_item hpen_map_digi[] = {
+static const struct hidmap_item hpen_map_pen[] = {
{ HPEN_MAP_ABS_GD(X, ABS_X), .required = true },
{ HPEN_MAP_ABS_GD(Y, ABS_Y), .required = true },
{ HPEN_MAP_ABS( TIP_PRESSURE, ABS_PRESSURE) },
{ HPEN_MAP_ABS( X_TILT, ABS_TILT_X) },
{ HPEN_MAP_ABS( Y_TILT, ABS_TILT_Y) },
+ { HPEN_MAP_ABS( CONTACTID, 0), .forbidden = true },
+ { HPEN_MAP_ABS( CONTACTCOUNT, 0), .forbidden = true },
{ HPEN_MAP_ABS_CB(BATTERY_STRENGTH, hpen_battery_strenght_cb) },
{ HPEN_MAP_BUT( TOUCH, BTN_TOUCH) },
{ HPEN_MAP_BUT( TIP_SWITCH, BTN_TOUCH) },
{ HPEN_MAP_BUT( SEC_TIP_SWITCH, BTN_TOUCH) },
- { HPEN_MAP_BUT( IN_RANGE, BTN_TOOL_PEN) },
{ HPEN_MAP_BUT( BARREL_SWITCH, BTN_STYLUS) },
{ HPEN_MAP_BUT( INVERT, BTN_TOOL_RUBBER) },
{ HPEN_MAP_BUT( ERASER, BTN_TOUCH) },
{ HPEN_MAP_BUT( TABLET_PICK, BTN_STYLUS2) },
{ HPEN_MAP_BUT( SEC_BARREL_SWITCH,BTN_STYLUS2) },
- { HIDMAP_FINAL_CB( &hpen_final_digi_cb) },
+ { HIDMAP_FINAL_CB( &hpen_final_pen_cb) },
};
-/* Microsoft-standardized pen support */
-static const struct hidmap_item hpen_map_pen[] = {
- { HPEN_MAP_ABS_GD(X, ABS_X), .required = true },
- { HPEN_MAP_ABS_GD(Y, ABS_Y), .required = true },
- { HPEN_MAP_ABS( TIP_PRESSURE, ABS_PRESSURE), .required = true },
- { HPEN_MAP_ABS( X_TILT, ABS_TILT_X) },
- { HPEN_MAP_ABS( Y_TILT, ABS_TILT_Y) },
- { HPEN_MAP_ABS_CB(BATTERY_STRENGTH, hpen_battery_strenght_cb) },
- { HPEN_MAP_BUT( TIP_SWITCH, BTN_TOUCH), .required = true },
- { HPEN_MAP_BUT( IN_RANGE, BTN_TOOL_PEN), .required = true },
- { HPEN_MAP_BUT( BARREL_SWITCH, BTN_STYLUS) },
- { HPEN_MAP_BUT( INVERT, BTN_TOOL_RUBBER), .required = true },
- { HPEN_MAP_BUT( ERASER, BTN_TOUCH), .required = true },
- { HIDMAP_FINAL_CB( &hpen_final_pen_cb) },
+static const struct hidmap_item hpen_map_stylus[] = {
+ { HPEN_MAP_BUT( IN_RANGE, BTN_TOOL_PEN) },
+};
+static const struct hidmap_item hpen_map_finger[] = {
+ { HPEN_MAP_BUT( IN_RANGE, BTN_TOOL_FINGER) },
};
static const struct hid_device_id hpen_devs[] = {
{ HID_TLC(HUP_DIGITIZERS, HUD_DIGITIZER) },
{ HID_TLC(HUP_DIGITIZERS, HUD_PEN) },
+ { HID_TLC(HUP_DIGITIZERS, HUD_TOUCHSCREEN),
+ HID_BVP(BUS_USB, USB_VENDOR_EGALAX, USB_PRODUCT_EGALAX_TPANEL) },
+};
+
+/* Do not autoload legacy pen driver for all touchscreen */
+static const struct hid_device_id hpen_devs_no_load[] = {
+ { HID_TLC(HUP_DIGITIZERS, HUD_TOUCHSCREEN) },
};
static int
@@ -134,25 +133,18 @@ hpen_battery_strenght_cb(HIDMAP_CB_ARGS)
return (0);
}
-static int
-hpen_final_digi_cb(HIDMAP_CB_ARGS)
-{
- struct evdev_dev *evdev = HIDMAP_CB_GET_EVDEV();
-
- if (HIDMAP_CB_GET_STATE() == HIDMAP_CB_IS_ATTACHING)
- evdev_support_prop(evdev, INPUT_PROP_POINTER);
-
- /* Do not execute callback at interrupt handler and detach */
- return (ENOSYS);
-}
-
static int
hpen_final_pen_cb(HIDMAP_CB_ARGS)
{
struct evdev_dev *evdev = HIDMAP_CB_GET_EVDEV();
- if (HIDMAP_CB_GET_STATE() == HIDMAP_CB_IS_ATTACHING)
- evdev_support_prop(evdev, INPUT_PROP_DIRECT);
+ if (HIDMAP_CB_GET_STATE() == HIDMAP_CB_IS_ATTACHING) {
+ if (hidbus_get_usage(HIDMAP_CB_GET_DEV()) ==
+ HID_USAGE2(HUP_DIGITIZERS, HUD_DIGITIZER))
+ evdev_support_prop(evdev, INPUT_PROP_POINTER);
+ else
+ evdev_support_prop(evdev, INPUT_PROP_DIRECT);
+ }
/* Do not execute callback at interrupt handler and detach */
return (ENOSYS);
@@ -185,24 +177,39 @@ static int
hpen_probe(device_t dev)
{
struct hidmap *hm = device_get_softc(dev);
+ const char *desc;
+ void *d_ptr;
+ hid_size_t d_len;
int error;
- bool is_pen;
- error = HIDBUS_LOOKUP_DRIVER_INFO(dev, hpen_devs);
- if (error != 0)
- return (error);
+ if (HIDBUS_LOOKUP_DRIVER_INFO(dev, hpen_devs_no_load) != 0) {
+ error = HIDBUS_LOOKUP_DRIVER_INFO(dev, hpen_devs);
+ if (error != 0)
+ return (error);
+ }
hidmap_set_dev(hm, dev);
- /* Check if report descriptor belongs to a HID tablet device */
- is_pen = hidbus_get_usage(dev) == HID_USAGE2(HUP_DIGITIZERS, HUD_PEN);
- error = is_pen
- ? HIDMAP_ADD_MAP(hm, hpen_map_pen, NULL)
- : HIDMAP_ADD_MAP(hm, hpen_map_digi, NULL);
+ /* Check if report descriptor belongs to a HID pen device */
+ error = HIDMAP_ADD_MAP(hm, hpen_map_pen, NULL);
if (error != 0)
return (error);
- hidbus_set_desc(dev, is_pen ? "Pen" : "Digitizer");
+ if (hid_get_report_descr(dev, &d_ptr, &d_len) != 0)
+ return (ENXIO);
+
+ if (hidbus_is_collection(d_ptr, d_len,
+ HID_USAGE2(HUP_DIGITIZERS, HUD_FINGER), hidbus_get_index(dev))) {
+ HIDMAP_ADD_MAP(hm, hpen_map_finger, NULL);
+ desc = "TouchScreen";
+ } else {
+ HIDMAP_ADD_MAP(hm, hpen_map_stylus, NULL);
+ desc = "Pen";
+ }
+ if (hidbus_get_usage(dev) == HID_USAGE2(HUP_DIGITIZERS, HUD_DIGITIZER))
+ desc = "Digitizer";
+
+ hidbus_set_desc(dev, desc);
return (BUS_PROBE_DEFAULT);
}
#include <sys/ioctl.h>
#include <errno.h>
#include <fcntl.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <dev/hid/hidraw.h>
static char rdesc[] = {
0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
0x09, 0x01, // Usage (Pointer)
0xA1, 0x01, // Collection (Application)
0x85, 0x01, // Report ID (1)
0x09, 0x01, // Usage (Pointer)
0xA1, 0x00, // Collection (Physical)
0x05, 0x09, // Usage Page (Button)
0x19, 0x01, // Usage Minimum (0x01)
0x29, 0x02, // Usage Maximum (0x02)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
0x95, 0x02, // Report Count (2)
0x75, 0x01, // Report Size (1)
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x95, 0x01, // Report Count (1)
0x75, 0x06, // Report Size (6)
0x81, 0x01, // Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
0x09, 0x30, // Usage (X)
0x09, 0x31, // Usage (Y)
0x16, 0x2A, 0x00, // Logical Minimum (42)
0x26, 0xBD, 0x07, // Logical Maximum (1981)
0x36, 0x00, 0x00, // Physical Minimum (0)
0x46, 0xFF, 0x0F, // Physical Maximum (4095)
0x66, 0x00, 0x00, // Unit (None)
0x75, 0x10, // Report Size (16)
0x95, 0x02, // Report Count (2)
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0xC0, // End Collection
0xC0, // End Collection
0x05, 0x0D, // Usage Page (Digitizer)
0x09, 0x04, // Usage (Touch Screen)
0xA1, 0x01, // Collection (Application)
0x85, 0x02, // Report ID (2)
0x09, 0x20, // Usage (Stylus)
0xA1, 0x00, // Collection (Physical)
0x09, 0x42, // Usage (Tip Switch)
0x09, 0x32, // Usage (In Range)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
0x95, 0x02, // Report Count (2)
0x75, 0x01, // Report Size (1)
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x95, 0x06, // Report Count (6)
0x75, 0x01, // Report Size (1)
0x81, 0x03, // Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
0x09, 0x30, // Usage (X)
0x75, 0x10, // Report Size (16)
0x95, 0x01, // Report Count (1)
0xA4, // Push
0x55, 0x00, // Unit Exponent (0)
0x65, 0x00, // Unit (None)
0x36, 0x00, 0x00, // Physical Minimum (0)
0x46, 0x00, 0x00, // Physical Maximum (0)
0x16, 0x1E, 0x00, // Logical Minimum (30)
0x26, 0xC8, 0x0F, // Logical Maximum (4040)
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x09, 0x31, // Usage (Y)
0x16, 0x3C, 0x00, // Logical Minimum (60)
0x26, 0xC3, 0x0F, // Logical Maximum (4035)
0x36, 0x00, 0x00, // Physical Minimum (0)
0x46, 0x00, 0x00, // Physical Maximum (0)
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0xB4, // Pop
0xC0, // End Collection
0xC0, // End Collection
};
int
main(int argc, char *argv[])
{
static const struct hidraw_gen_descriptor hd = {
.hgd_data = rdesc,
.hgd_maxlen = sizeof(rdesc),
};
int fd, res;
char *cdev;
cdev = argc > 1 ? argv[1] : "/dev/hidraw0";
fd = open(cdev, O_WRONLY);
if (fd < 0) {
perror("open failed");
exit(1);
}
res = ioctl(fd, HIDRAW_SET_REPORT_DESC, &hd);
close(fd);
if (res < 0) {
perror("ioctl failed");
exit(1);
}
return(0);
}