USB HUB 芯片
USB 驱动程序框架
Linux 内核提供了完整的 USB 驱动程序框架。USB 总线采用树形结构,在一条总线上只能有唯一的主机设备。Linux 内核从主机和设备两个角度观察 USB 总线结构。下图是 Linux 内核从主机和设备两个角度观察 USB 总线结构的示意图。
USB 子系统主要任务包括:
- 注册和管理设备驱动;
- USB 设备寻找驱动,并初始化和配置设备;
- 内核中表现设备的树形结构;
- 与设备交互。
驱动源码
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