usb

A133 USB

USB 触摸失灵问题

Posted by LXG on March 9, 2023

USB HUB 芯片

汤铭科技股份有限公司

usb_hub_fe21

a133_usb_hub

USB 驱动程序框架

Linux 内核提供了完整的 USB 驱动程序框架。USB 总线采用树形结构,在一条总线上只能有唯一的主机设备。Linux 内核从主机和设备两个角度观察 USB 总线结构。下图是 Linux 内核从主机和设备两个角度观察 USB 总线结构的示意图。

usb_arch

USB 子系统主要任务包括:

  1. 注册和管理设备驱动;
  2. USB 设备寻找驱动,并初始化和配置设备;
  3. 内核中表现设备的树形结构;
  4. 与设备交互。

驱动源码


kernel/linux-4.9/drivers/usb$ tree -L 1
.
├── atm
├── built-in.o
├── c67x00
├── chipidea
├── class
├── common
├── core                     // usb核心代码
├── dwc2
├── dwc3
├── early
├── gadget                  // usb device功能配置代码,如adb、mtp或hid等
├── host                    // AW平台控制器代码
├── image
├── isp1760
├── Kconfig
├── Makefile
├── misc
├── modules.builtin
├── modules.order
├── mon
├── musb
├── phy
├── README
├── renesas_usbhs
├── serial
├── storage
├── sunxi_usb               // AW平台otg、host与device功能自动切换管理代码
├── usbip
├── usb-skeleton.c
└── wusbcore

问题

USB 相机插入导致触摸设备无法使用


[   75.666757] usb 1-1.6: reset full-speed USB device number 5 using sunxi-ehci
[   75.860082] usb 1-1.5: new high-speed USB device number 7 using sunxi-ehci
[   76.040593] uvcvideo: Found UVC 1.00 device USB2.0_CAM1 (2c7f:4a60)
[   76.098066] input: USB2.0_CAM1 as /devices/platform/soc/5200000.ehci1-controller/usb1/1-1/1-1.5/1-1.5:1.0/input/input7

分析


Bus 001 Device 008: ID 2c7f:4a60           // usb 1-1.5 usb 相机设备
Bus 001 Device 001: ID 1d6b:0002
Bus 001 Device 003: ID 0bda:8152
Bus 001 Device 002: ID 1a40:0201
Bus 001 Device 005: ID 222a:0001           // usb 1-1.6 触摸状态 ILITEK-TP
Bus 002 Device 001: ID 1d6b:0001
Bus 001 Device 006: ID 2c7c:6002

日志源码

kernel/linux-4.9/drivers/usb/core/hub.c


static int
hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1,
                int retry_counter)
{
        -------------------------------------------------------------------

        // lixiaogang add for print debug trace
        // dump_stack();

        if (udev->speed < USB_SPEED_SUPER)
                dev_info(&udev->dev,
                                "%s %s USB device number %d using %s\n",
                                (udev->config) ? "reset" : "new", speed,
                                devnum, udev->bus->controller->driver->name);

        -------------------------------------------------------------------
}

dump_stack()


// 问题相机

[  722.311310] CPU: 0 PID: 3 Comm: kworker/0:0 Tainted: G           O    4.9.170 #3
[  722.319662] Hardware name: sun50iw10 (DT)
[  722.324194] Workqueue: events __usb_queue_reset_device
[  722.329988] Call trace:
[  722.332752] [<ffffff800808c038>] dump_backtrace+0x0/0x2b8
[  722.338835] [<ffffff800808c314>] show_stack+0x24/0x30
[  722.344523] [<ffffff800847afe0>] dump_stack+0x90/0xb0
[  722.350210] [<ffffff80086aecd4>] hub_port_init+0x54/0xae8
[  722.356285] [<ffffff80086af8a8>] usb_reset_and_verify_device+0x140/0x650
[  722.363825] [<ffffff80086afed4>] usb_reset_device+0x11c/0x2a8
[  722.370308] [<ffffff80086bb330>] __usb_queue_reset_device+0x40/0x60
[  722.377391] [<ffffff80080c9828>] process_one_work+0x150/0x4b0
[  722.383883] [<ffffff80080c9cc4>] worker_thread+0x13c/0x4c8
[  722.390090] [<ffffff80080d06cc>] kthread+0xec/0x100
[  722.395603] [<ffffff80080834f0>] ret_from_fork+0x10/0x20
[  722.551945] CPU: 0 PID: 4908 Comm: kworker/0:1 Tainted: G           O    4.9.170 #3
[  722.560589] Hardware name: sun50iw10 (DT)
[  722.565142] Workqueue: usb_hub_wq hub_event
[  722.569882] Call trace:
[  722.572661] [<ffffff800808c038>] dump_backtrace+0x0/0x2b8
[  722.578762] [<ffffff800808c314>] show_stack+0x24/0x30
[  722.584468] [<ffffff800847afe0>] dump_stack+0x90/0xb0
[  722.590176] [<ffffff80086aecd4>] hub_port_init+0x54/0xae8
[  722.596276] [<ffffff80086b3150>] hub_event+0x8e8/0x12c8
[  722.602178] [<ffffff80080c9828>] process_one_work+0x150/0x4b0
[  722.608664] [<ffffff80080c9cc4>] worker_thread+0x13c/0x4c8
[  722.614862] [<ffffff80080d06cc>] kthread+0xec/0x100
[  722.620383] [<ffffff80080834f0>] ret_from_fork+0x10/0x20
[  722.921415] usb 1-1.6: reset full-speed USB device number 4 using sunxi-ehci
[  723.114545] usb 1-1.5: new high-speed USB device number 6 using sunxi-ehci
[  723.296824] uvcvideo: Found UVC 1.00 device USB2.0_CAM1 (2c7f:4a60)
[  723.354295] input: USB2.0_CAM1 as /devices/platform/soc/5200000.ehci1-controller/usb1/1-1/1-1.5/1-1.5:1.0/input/input6

// 无问题相机

[  819.831881] CPU: 0 PID: 4908 Comm: kworker/0:1 Tainted: G           O    4.9.170 #3
[  819.840534] Hardware name: sun50iw10 (DT)
[  819.845091] Workqueue: usb_hub_wq hub_event
[  819.849832] Call trace:
[  819.852611] [<ffffff800808c038>] dump_backtrace+0x0/0x2b8
[  819.858709] [<ffffff800808c314>] show_stack+0x24/0x30
[  819.864418] [<ffffff800847afe0>] dump_stack+0x90/0xb0
[  819.870126] [<ffffff80086aecd4>] hub_port_init+0x54/0xae8
[  819.876225] [<ffffff80086b3150>] hub_event+0x8e8/0x12c8
[  819.882127] [<ffffff80080c9828>] process_one_work+0x150/0x4b0
[  819.888614] [<ffffff80080c9cc4>] worker_thread+0x13c/0x4c8
[  819.894810] [<ffffff80080d06cc>] kthread+0xec/0x100
[  819.900321] [<ffffff80080834f0>] ret_from_fork+0x10/0x20
[  819.998001] usb 1-1.5: new high-speed USB device number 7 using sunxi-ehci
[  820.130290] uvcvideo: Found UVC 1.00 device Integrated_Webcam_HD (0c45:64ab)
[  820.185313] input: Integrated_Webcam_HD as /devices/platform/soc/5200000.ehci1-controller/usb1/1-1/1-1.5/1-1.5:1.0/input/input7

内核usb设备状态解析

USB-详解/sys/kernel/debug/usb/devices

T:Topology(拓扑结构)


T:  Bus=dd Lev=dd Prnt=dd Port=dd Cnt=dd Dev#=ddd Spd=dddd MxCh=dd
|   |      |      |       |       |      |        |        |__MaxChildren
|   |      |      |       |       |      |        |__Device Speed in Mbps
|   |      |      |       |       |      |__DeviceNumber
|   |      |      |       |       |__Count of devices at this level
|   |      |      |       |__Connector/Port on Parent for this device
|   |      |      |__Parent DeviceNumber
|   |      |__Level in topology for this bus
|   |__Bus number
|__Topology info tag

  • Bus:表示总线号。
  • Lev:表示此USB设备位于所在总线拓扑结构的层次,XHCI控制器对应的Lev=00,其下面挂接的USB网卡的Lev=01。
  • Prnt:表示父设备数量,比如XHCI控制器是root,位于最顶层,其Prnt=0,其下面挂载在HUB下的USB网卡的Prnt=01。
  • Port:此USB设备的父设备上的连接器/端口,比如USB网卡的父设备是XHCI控制器
  • Cnt:这层的枚举到的第几个USB设备,比如USB网卡的Cnt=01。
  • Dev:表示设备编号,XHCI为1,USB网卡为5,按顺序排列的,一个总线上最多挂127个;可以有多个总线。
  • Spd:设备速率,单位为Mbps

B:Bandwidth(带宽信息)


B:  Alloc=ddd/ddd us (xx%), #Int=ddd, #Iso=ddd
|   |                       |         |__Number of isochronous requests
|   |                       |__Number of interrupt requests
|   |__Total Bandwidth allocated to this bus
|__Bandwidth info tag

只用于USB Host控制器,它被虚拟为一个root hub

  • Alloc:该总线分配得到的带宽。宽带分配在使用中是一个近似值,此值表示一帧需要多少ms。
  • Int:中断请求数
  • Iso:同步请求数,USB有四大传输,中断、控制、批量和同步。

D:Device descriptor info(设备描述符信息)


D:  Ver=x.xx Cls=xx(sssss) Sub=xx Prot=xx MxPS=dd #Cfgs=dd
|   |        |             |      |       |       |__NumberConfigurations
|   |        |             |      |       |__MaxPacketSize of Default Endpoint
|   |        |             |      |__DeviceProtocol
|   |        |             |__DeviceSubClass
|   |        |__DeviceClass
|   |__Device USB version
|__Device info tag #1

  • Ver:USB协议版本,比如Ver=3.00。
  • Cls:由USB-IF(USB Implementers Forum)分配的设备类类码,Hub对应09;厂家自定义的为ff;如果该字段为0x00,表示由接口描述符bInterfaceClass来指定。
  • Sub:设备子类,USB子类代码,由USB-IF分配。
  • Prot:设备协议码,由USB-IF分配。如果D的Cls和Sub都为00,则该字段也必须为00,采用I的Prot=50

例子


cat sys/kernel/debug/usb/devices                                                                                                                                                                                  

// ----------------------------EHCI 控制器-------------------------
T:  Bus=01 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#=  1 Spd=480  MxCh= 1
B:  Alloc=  5/800 us ( 1%), #Int=  5, #Iso=  0
D:  Ver= 2.00 Cls=09(hub  ) Sub=00 Prot=00 MxPS=64 #Cfgs=  1
P:  Vendor=1d6b ProdID=0002 Rev= 4.09
S:  Manufacturer=Linux 4.9.170 ehci_hcd
S:  Product=SW USB2.0 'Enhanced' Host Controller (EHCI) Driver
S:  SerialNumber=sunxi-ehci
C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=  0mA
I:* If#= 0 Alt= 0 #EPs= 1 Cls=09(hub  ) Sub=00 Prot=00 Driver=hub
E:  Ad=81(I) Atr=03(Int.) MxPS=   4 Ivl=256ms

// ----------------------------USB 2.0 Hub 总共七个------------------
T:  Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#=  2 Spd=480  MxCh= 7
D:  Ver= 2.00 Cls=09(hub  ) Sub=00 Prot=02 MxPS=64 #Cfgs=  1
P:  Vendor=1a40 ProdID=0201 Rev= 1.00
S:  Product=USB 2.0 Hub [MTT]
C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=100mA
I:  If#= 0 Alt= 0 #EPs= 1 Cls=09(hub  ) Sub=00 Prot=01 Driver=hub
E:  Ad=81(I) Atr=03(Int.) MxPS=   1 Ivl=256ms
I:* If#= 0 Alt= 1 #EPs= 1 Cls=09(hub  ) Sub=00 Prot=02 Driver=hub
E:  Ad=81(I) Atr=03(Int.) MxPS=   1 Ivl=256ms

// ------------------------------以太网卡usb--------------------------
T:  Bus=01 Lev=02 Prnt=02 Port=02 Cnt=01 Dev#=  3 Spd=480  MxCh= 0
D:  Ver= 2.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs=  2
P:  Vendor=0bda ProdID=8152 Rev=20.00
S:  Manufacturer=Realtek
S:  Product=USB 10/100 LAN
S:  SerialNumber=000000000000
C:* #Ifs= 1 Cfg#= 1 Atr=a0 MxPwr=100mA
I:* If#= 0 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=00 Driver=r8152
E:  Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=83(I) Atr=03(Int.) MxPS=   2 Ivl=16ms

// -----------------------------4G模组usb-----------------------------
T:  Bus=01 Lev=02 Prnt=02 Port=03 Cnt=02 Dev#=  5 Spd=480  MxCh= 0
D:  Ver= 2.00 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs=  1
P:  Vendor=2c7c ProdID=6002 Rev= 3.18
S:  Manufacturer=Android
S:  Product=Android
S:  SerialNumber=0000
C:* #Ifs= 5 Cfg#= 1 Atr=e0 MxPwr=500mA
A:  FirstIf#= 0 IfCount= 2 Cls=02(comm.) Sub=06 Prot=00
I:* If#= 0 Alt= 0 #EPs= 1 Cls=02(comm.) Sub=06 Prot=00 Driver=cdc_ether
E:  Ad=87(I) Atr=03(Int.) MxPS=  64 Ivl=4096ms
I:  If#= 1 Alt= 0 #EPs= 0 Cls=0a(data ) Sub=00 Prot=00 Driver=cdc_ether
I:* If#= 1 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=cdc_ether


//------------------------------USB相机-------------------------------
T:  Bus=01 Lev=02 Prnt=02 Port=04 Cnt=03 Dev#=  6 Spd=480  MxCh= 0
D:  Ver= 2.00 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs=  1
P:  Vendor=2c7f ProdID=4a60 Rev= 0.00
S:  Manufacturer=USB Camera
S:  Product=USB2.0_CAM1
S:  SerialNumber=USB Camera
C:* #Ifs= 2 Cfg#= 1 Atr=80 MxPwr=500mA
A:  FirstIf#= 0 IfCount= 2 Cls=0e(video) Sub=03 Prot=00
I:* If#= 0 Alt= 0 #EPs= 1 Cls=0e(video) Sub=01 Prot=00 Driver=uvcvideo
E:  Ad=83(I) Atr=03(Int.) MxPS=  16 Ivl=4ms
I:* If#= 1 Alt= 0 #EPs= 0 Cls=0e(video) Sub=02 Prot=00 Driver=uvcvideo
I:  If#= 1 Alt= 1 #EPs= 1 Cls=0e(video) Sub=02 Prot=00 Driver=uvcvideo
E:  Ad=81(I) Atr=05(Isoc) MxPS= 128 Ivl=125us
// -----------------------------USB触摸-------------------------------
T:  Bus=01 Lev=02 Prnt=02 Port=05 Cnt=04 Dev#=  4 Spd=12   MxCh= 0
D:  Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs=  1
P:  Vendor=222a ProdID=0001 Rev= 0.00
S:  Manufacturer=ILITEK
S:  Product=ILITEK-TP
C:* #Ifs= 2 Cfg#= 1 Atr=a0 MxPwr=400mA
I:* If#= 0 Alt= 0 #EPs= 1 Cls=03(HID  ) Sub=00 Prot=00 Driver=usbhid
E:  Ad=82(I) Atr=03(Int.) MxPS=  64 Ivl=1ms
I:* If#= 1 Alt= 0 #EPs= 1 Cls=03(HID  ) Sub=00 Prot=00 Driver=usbhid
E:  Ad=81(I) Atr=03(Int.) MxPS=  64 Ivl=1ms

//----------------------------------------------------------------------
// sunxi-ohci USB 1.1 控制器
T:  Bus=02 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#=  1 Spd=12   MxCh= 1
B:  Alloc=  0/900 us ( 0%), #Int=  0, #Iso=  0
D:  Ver= 1.10 Cls=09(hub  ) Sub=00 Prot=00 MxPS=64 #Cfgs=  1
P:  Vendor=1d6b ProdID=0001 Rev= 4.09
S:  Manufacturer=Linux 4.9.170 ohci_hcd
S:  Product=SW USB2.0 'Open' Host Controller (OHCI) Driver
S:  SerialNumber=sunxi-ohci
C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=  0mA
I:* If#= 0 Alt= 0 #EPs= 1 Cls=09(hub  ) Sub=00 Prot=00 Driver=hub
E:  Ad=81(I) Atr=03(Int.) MxPS=   2 Ivl=255ms


命令行重连usb设备


// 先解绑
echo '1-1.6' > sys/bus/usb/drivers/usb/unbind

// 再绑定
echo '1-1.6' > sys/bus/usb/drivers/usb/bind