• 【Linux】在Xilinx平台上实现UVC Gadget(2)- 解决dwc3驱动bug


    一、bug描述

    前文详情见
    【Linux】在Xilinx平台上实现UVC Gadget(1)

    在usb插入电脑时,开发板会瞬间报错,报错信息如下。
    经过仔细研究,dwc3驱动drivers/usb/dwc3/gadget.c存在一个bug

    在usb gadget 枚举过程中,会触发不需要的假中断,为了避免这个问题,
    需要清除DWC3_DCTL_KEEP_CONNECT位,禁用DWC3_GCTL_GBLHIBERNATIONEN休眠中断

    [  111.954284] ------------[ cut here ]------------
    [  111.958916] WARNING: CPU: 0 PID: 1095 at drivers/usb/dwc3/gadget.c:3305 dwc3_stop_active_transfer.part.0+0xc4/0xd0
    [  111.969247] Modules linked in: vivid v4l2_tpg cec g_webcam g_ffs zocl(O) dmaproxy(O) al5e(O) al5d(O) allegro(O) mali(O) xlnx_vcu regmap_mmio uio_pdrv_genirq [last unloaded: zocl]
    [  111.985179] CPU: 0 PID: 1095 Comm: irq/92-dwc3 Tainted: G           O      5.10.0-xilinx-v2021.1 #1
    [  111.994210] Hardware name: ZynqMP ZCU104 RevC (DT)
    [  111.998987] pstate: 60000085 (nZCv daIf -PAN -UAO -TCO BTYPE=--)
    [  112.004985] pc : dwc3_stop_active_transfer.part.0+0xc4/0xd0
    [  112.010549] lr : dwc3_stop_active_transfer.part.0+0x60/0xd0
    [  112.016110] sp : ffff80001239bc10
    [  112.019409] x29: ffff80001239bc10 x28: 0000000000000000 
    [  112.024712] x27: ffff000002249380 x26: ffff00000224e880 
    [  112.030015] x25: ffff800011140568 x24: ffff000004934300 
    [  112.035319] x23: ffffffffffff3f00 x22: 0000000000000001 
    [  112.040622] x21: 0000000000000000 x20: ffff000004934300 
    [  112.045926] x19: ffff000002249000 x18: fffffdfffff27a08 
    [  112.051229] x17: 0000000000000000 x16: 000000000000000e 
    [  112.056532] x15: 0000000000000000 x14: 000006160d349044 
    [  112.061836] x13: 00000000bd08a39e x12: 00000000000002d2 
    [  112.067139] x11: 0000000000000000 x10: 00000000000008e0 
    [  112.072443] x9 : ffff80001239bd10 x8 : ffff000004934c40 
    [  112.077747] x7 : 000000000000b68d x6 : 0000000000000000 
    [  112.083050] x5 : 0000000000000508 x4 : 0000000000000000 
    [  112.088353] x3 : ffffffffffff3f08 x2 : 0000000000000000 
    [  112.093657] x1 : ffff800012f00200 x0 : 00000000ffffff92 
    [  112.098961] Call trace:
    [  112.101395]  dwc3_stop_active_transfer.part.0+0xc4/0xd0
    [  112.106611]  dwc3_stop_active_transfer+0x2c/0x40
    [  112.111219]  dwc3_gadget_enter_hibernation.part.0+0xc0/0x2e0
    [  112.116860]  dwc3_gadget_enter_hibernation+0x2c/0x40
    [  112.121809]  dwc3_thread_interrupt+0x2f0/0xe5c
    [  112.126246]  irq_thread_fn+0x2c/0x90
    [  112.129811]  irq_thread+0x248/0x370
    [  112.133285]  kthread+0x124/0x130
    [  112.136505]  ret_from_fork+0x10/0x3c
    [  112.140069] ---[ end trace 5d566d21e39ee647 ]---
    [  112.253848] dwc3-xilinx ff9d0000.usb0: Failed to set power state to D3
    [  112.260367] dwc3-pmu-regulator: failed to disable: -EIO
    [  112.265585] dwc3 fe200000.dwc3: dwc3_gadget_enter_hibernation: 373 Failed to enable dwc3_pmu supply
    [  112.274619] dwc3 fe200000.dwc3: Fail in handling Hibernation Interrupt
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    二、具体修改方法

    1. 找到内核源码位置并复制到其他目录

    find . -name "gadget.c"
    
    • 1

    可以看到第1行是我们要的源代码,但是不能直接修改这个文件,因为Petalinux会自动恢复

    LeoWang@u16:/opt/work/uvc-demo/xilinx-zcu104-2021.1$ find . -name "gadget.c"
    ./build/tmp/work-shared/zynqmp-generic/kernel-source/drivers/usb/dwc3/gadget.c
    ./build/tmp/work-shared/zynqmp-generic/kernel-source/drivers/usb/cdns3/gadget.c
    ./build/tmp/work-shared/zynqmp-generic/kernel-source/drivers/usb/dwc2/gadget.c
    ./build/tmp/work/zynqmp_generic-xilinx-linux/u-boot-xlnx/v2021.01-xilinx-v2021.1+gitAUTOINC+41fc08b3fe-r0/git/board/samsung/common/gadget.c
    ./build/tmp/work/zynqmp_generic-xilinx-linux/u-boot-xlnx/v2021.01-xilinx-v2021.1+gitAUTOINC+41fc08b3fe-r0/git/drivers/usb/dwc3/gadget.c
    ./build/tmp/work/zynqmp_generic-xilinx-linux/u-boot-xlnx/v2021.01-xilinx-v2021.1+gitAUTOINC+41fc08b3fe-r0/git/drivers/usb/cdns3/gadget.c
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    把./build/tmp/work-shared/zynqmp-generic/kernel-source复制到其他文件夹
    比如我的工程目录是

    /opt/work/uvc-demo/xilinx-zcu104-2021.1
    
    • 1

    内核源码目录是

    /opt/work/uvc-demo/xilinx-zcu104-2021.1/build/tmp/work-shared/zynqmp-generic/kernel-source
    
    • 1

    最后把内核复制并改名到这个目录

    /opt/work/uvc-demo/kernel-source_leo_wang5.10
    
    • 1

    2. Petalinux里面设置使用自定义内核源码

    petalinux-config
    
    • 1

    1) 选第2个Linux Components Selection

    在这里插入图片描述

    2) 选linux-kernel,回车,选择ext-local-src

    在这里插入图片描述

    3) 设置External linux-kernel local source settings

    回车输入自己内核源码的目录
    在这里插入图片描述

    在这里插入图片描述

    3.修改gadget驱动源码

    打开文件drivers/usb/dwc3/gadget.c,找到函数
    static void dwc3_gadget_reset_interrupt(struct dwc3 *dwc)
    在if (DWC3_VER_IS_PRIOR(DWC3, 188A)) 和dwc3_reset_gadget(dwc)之间加上下面这一段

    //add by LeoWang 2022.11.20
    if (dwc->has_hibernation) {
    	reg = dwc3_readl(dwc->regs, DWC3_DCTL);
    	reg &= ~DWC3_DCTL_KEEP_CONNECT;
    	dwc3_writel(dwc->regs, DWC3_DCTL, reg);
    	reg = dwc3_readl(dwc->regs, DWC3_GCTL);
    	reg &= ~DWC3_GCTL_GBLHIBERNATIONEN;
    	dwc3_writel(dwc->regs, DWC3_GCTL, reg);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    修改后的效果如下图
    在这里插入图片描述

    Ps:
    确认在v2021.2还存在这个bug,在2022.1已经增加了这个修复
    也就是版本<=2021.2的,必须手动修改

  • 相关阅读:
    (附源码)springboot 智能停车场系统 毕业设计065415
    Vue的详细教程--基础语法【下】
    Vulnhub_CengBox
    SpringBoot 自定义注解异步记录复杂日志
    糖尿病性视网膜病变(DR)的自动化检测和分期
    如何构建城市经济大脑分析指标框架?六大分析主题
    基于eNSP的校园网设计的仿真模拟
    【官宣】游戏革命刚刚开始!
    Linux 系统服务
    【全志T113-S3_100ask】15-2 linux系统gpio模拟spi驱动屏幕——ILI9341
  • 原文地址:https://blog.csdn.net/aatu/article/details/127944649