This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] Linux/TUSB3410:USB3.0 xHCI 主机的批量传输错误

Guru**** 2487425 points
Other Parts Discussed in Thread: TUSB3410

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/interface-group/interface/f/interface-forum/673242/linux-tusb3410-bulk-transfer-error-with-usb3-0-xhci-hosts

器件型号:TUSB3410

工具/软件:Linux

大家好、

我已经测试了我们的 USB 到使用 TUSB3410的串行产品。 当我使用 USB3.0主机(xHCI 驱动程序)进行测试时、可能会出现数据包丢失、但使用 USB2.0主机时测试正常。

使用 USB3.0主机传输大数据(8KB)时、很容易重现

Linux 内核3.11和内核4.13具有相同的问题。 此外、我已经通过连接 USB 协议分析器工具进行了测试、它显示 USB 主机将整个数据发送到器件而不会丢失数据包、但器件会丢失要发送的数据包。 因此、我想知道这是否是 TUSB3410与 USB3.0主机兼容的问题。

此致、

CT

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    CT、
    无论是 USB2.0主机还是 USB3.0主机、TUSB3410始终全速连接、您的 USB3.0主机都将使用其 USB2.0 "部分"来枚举和操作 TUSB3410。

    能否在主机控制器上检查 xHCI 驱动程序?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好 CT、

    您使用的是什么 USB3.0主机? 这可能是 xHCI 主机的问题。

    此致、
    Roberto
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Roberto 和 Peter:

    我键入`lsusb -t`、它显示 USB 主机控制器是 xhci_hcd。

    # lsusb -t
    /:总线03.端口1:dev 1、class=root_hub、Driver=xhci_hcd/4p、480M
    ||端口3:DEV 3,如果为0,则为 Class=厂商特定类,Driver=mxu11x0,12M 

    如果是 xHCI 主机问题、如何解释 CATC (USB 协议分析器)从 USB 主机接收全部数据、但 USB 设备发送的数据包丢失?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您能否提供 CATC 跟踪?

    此致、
    JMMN
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    JMMN、您好!

    以下是两个 CATC 文件、其中包括 XHCI 和 EHCI 跟踪。

    XHCI 跟踪从 USB3.0主机获取8192个字节、然后发送到 USB 器件、但8192的前64个字节未从 USB 器件发出。  

    EHCI 跟踪几乎与 XHCI 跟踪相同、但结果正常。

    e2e.ti.com/.../uport11x0_5F00_usb3_5F00_ubuntu17_5F00_xhci.usb

    e2e.ti.com/.../uport11x0_5F00_usb3_5F00_ubuntu17_5F00_ehci.usb

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好 CT、

    XHCI 开始批量传输到端点1、数据切换位为1而不是0。 由于数据切换错误、TUSB3410可能会对第一个数据包进行散列。 请检查更新的驱动程序。

    根据 USB 2.0规范:

    5.8.5批量传输数据序列
    批量传输使用数据切换位、这些位仅在成功传输完成后切换至
    当由于错误而重新尝试处理时、保持发送器和接收器之间的同步。 批量传输
    当端点由一个适当的控制传输配置时、事务被初始化为 DATA0。
    主机还将启动与 DATA0的第一个批量传输。

    此致、
    JMMN
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    JMMN、您好!

    感谢您的回复。

    我认为你是对的! 我在阅读完您的帖子后进行了几次测试、测试结果与您说的一样-每当数据切换位为1时、第一个数据包丢失。

    但是,我注意到驱动程序的`open()`函数中已经有一个变通办法,可以重置数据切换:

    /*重置批量端点上的数据切换以解决
    *主机控制器中的错误,其中某些情况会发生不同步*/
    usb_clear_halt (dev、port->write_话 术->pipe);
    usb_clear_halt (dev、port->read_话 术->pipe); 

    如果我们已经应用了此变通办法、为什么仍然会发生这种情况?

    应该更新哪些驱动程序? xHCI 驱动程序? TI_USB_3410驱动程序?

    此致、

    CT

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    CT、
    如果 EHCI 正常工作、则表明 xHCI 驱动程序和/或 xHCI 主机控制器本身使用错误切换时出现问题。 正如您所说的、ti_USB_3410已经有一个权变措施来尝试修复数据切换、但它似乎在您正在使用的特定 xHCI 主机上不起作用。 我只能建议更新 xHCI 驱动程序或尝试不同的 xHCI 主机控制器。
    此致、
    Brian
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我发现 XHCI 不能真正复位端点...

    static void xhci_endpoint_reset (struct usb_hcd *hcd,
    struct usb_host_endpoint *ep)
    {
    struct xhci_hcd *xhci;
    
    xhci = hci_to-xhci (hcd);
    
    //
    *我们可能需要在 xhci 4.8.1中实施 config EP cmd 注意:
    *仅
    在端点状态下发出重置命令。 如果软件希望重置
    未处于暂停状态的端点的数据切换或序列*号、则软件
    *可以为
    目标端点发出配置端点命令、并设置 Drop 和 Add 位*。 处于已停止状态。
    //
    
    //*目前只需打印调试即可跟随该情况*/
    xhci_dbg (xhci,"Endpoint 0x%x EP reset called called\n",
    EP->desc.bEndpointAddress);
    } 

    与 EHCI_终结 点_RESET()不同,它调用 USB_settoggle ()以重置数据切换。

    是否有人知道如何以 替代方式执行软件复位?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    在内核 v3.11中,该函数实际上调用 xhci_queue_reset_ep(),它 发出一个复位端点 TRB,该端点应复位数据切换。  我不知道 为什么在更高的内核版本中删除此内容。  这似乎是一个不完整的变化。

    /*处理停止的端点。 内核应该已经发送了控制消息
    *来清除停止条件。 但是、我们需要使 xHCI 硬件
    *重置其序列号、因为在
    清除 HALT 条件后、器件将需要一个*零的序列号。
    *上下文:IN_INTERRUPT
    */
    void xhci_endpoint_reset(struct usb_hcd * hcd、
    struct usb_host_endpoint *ep)
    {
    struct xhci_hcd * xhci;
    struct usb_device * udev;
    unsigned int ep_index;
    unsigned long flags;
    int ret;
    struct xhci_virt_ep * virt_ep;
    
    xhci = hcd_TO_xhci(hcd);
    udev =(struct usb_device *) EP->hcp->hcpriv;//
    使用根集线器端点调用(或未添加
    *带有 xhci_add_endpoint()
    *
    的
    
    
    
    
    	端点调用) EP->hcp->hcp<!xcp_endcp_hru&n<xep->ed<th<xec<th<xp>end_end<x_hru&n=>ed>q>x、end<xec<th<xec<e<xep>end_end_hru&n<xp>end<x_end<x_hru&n<xep>end<xp<x_end<x_end<e<x_hr>end<x_end<xp>[hru&n<\cn<xp>[hru&r
    			
    return;
    }
    if (usb_endpoint_xfer_control(&EP->desc)){
    	xhci_dbg(xhci、"控制端点停止已处理。\n");
    return;
    }
    
    xhci_dbg(xhci、"队列重置端点命令\n");
    spin_lock_irqsave(&xhci->slot
    、dev_ret_id、xhci、"ret_reset_ages");xhci = xhci、xhci、xhci、xret = xHCI、xHCI、<uci、EP_INDEX);
    /*
    无法更改环去队列指针、直到它转换到
    *已停止状态(仅在成功执行 RESET 端点
    *命令时)。 希望最后一个命令能起作用!
    //
    if (!ret){
    	xhci_clean_stopped_ring(xhci、udev、 ep_index);
    	kfree(virt_ep->stopped_td);
    	xhci_ring _cmd_db(xhci);
    }
    virt_EP->Stopped_TD = NULL;
    virt_EP->Stopped_TRB = NULL;
    virt_EP->Stopped_stream = 0;
    spin_unlock_irqrestore(&xhci->lock、flags);
    
    如果(RET)
    	xhci_warn(xhci、"FIXME 分配新的环段\n");
    }
    
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我认为即使在内核 v3.11或更旧版本中、我们仍然无法通过软件重置数据切换、因为 xhci 驱动程序在不处于 HALT 状态时拒绝重置。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    CT、
    是的、您回答正确。 如果 EP 未根据 xHCI 0.96规范处于暂停状态、xHCI 主机将拒绝 RESET EP 命令。 我唯一的其他建议是在重置端点之前尝试"xhci_queue_stop_endpoint()"。 似乎 Linux 社区正在努力解决此问题: www.spinics.net/.../msg166890.html
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    谢谢、Brian。

    除了等待 Linux 社区、我们似乎无法做任何其他事情。
    顺便说一下、我想知道使用 TUSB3410的其他人是否有同样的问题?
    和... 为什么我们的 USB 产品在 Windows 上与 xHCI 一起运行时工作良好? (我已经分析了 USB 监听器、我们的 USB 产品接受 Windows 上第一个数据包的 DATA0和 Data1。)

    此致、
    CT
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    CT、

    这是我第一次听说这个问题。  您是否在 Windows 上使用与 Linux 相同的 PC 进行测试?   我 想确保我们将 结果与相同的 xHCI 主机控制器和器件进行比较。  您能否在  相同 的测试条件下为 Windows 和 Linux 发送跟踪?   必须存在一些差异、因为如果数据包流 相同、我们的器件的行为不应有所不同。

    此致、

    Brian  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Brian、

    以下是 Win10和 Ubuntu 上相同 USB 主机(和相同主板)的跟踪:

    e2e.ti.com/.../win10_5F00_xhci_5F00_bulk_5F00_out_5F00_256_5F00_bytes.usb

    e2e.ti.com/.../ubuntu_5F00_xhci_5F00_bulk_5F00_out_5F00_256_5F00_bytes.usb

    我尝试在相同的测试条件下进行测试、但设备驱动程序和测试程序毕竟在 Windows 和 Linux 之间是不同的。

    这两条迹线显示我向 USB 设备发送了256字节、两个数据切换位都以 Data1开头、但仅在连接到 Ubuntu 的 USB 设备中丢失。

    此致、

    CT

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    CT、

    我无法很好地比较迹线。  在 Ubuntu 跟踪中、我看到一个清除功能 ENDPT 停止、该功能会将切换复位为零、然后向该端点的第一个事务是切换= 1时的批量输出传输、这是不正确的。  

    对于 Windows 跟踪、我没有看到任何清除功能 ENDPT 暂停、因此使用1的数据切换可能是可以的(之前的批量输出可能使用了切换= 0、但我在跟踪中看不到它)。  是 Windows 从不发出清除功能 ENDPT HALT、还是未捕获。

    您能否捕获显示清除功能 ENDPT 暂停的 Windows 跟踪、然后在该跟踪后将第一个批量输出传输到器件?

    此致、
    Brian

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Brian、

    您说得对、我从器件初始化到端口打开捕获了一些跟踪、并且 Windows 上没有 clear_feature ender_halt。

    很奇怪、Windows 设备驱动程序不需要清除功能、而 Linux 驱动程序需要清除功能。

    我知道 USB_clear_halt ()中调用的端点复位在 Linux 上的 XHCI 和 EHCI 之间是不同的、因此在 XHCI 上数据切换不会设置为零。  

    但是、当我们将 Linux 与 Windows 进行比较时、我们只是不知道为什么 Linux 设备驱动程序需要此变通办法、而 Windows 驱动程序似乎不需要相同的 USB 设备。

    此致、

    CT

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 CT、

    这就是问题所在。 在 USB_clear_halt ()中、Linux 向器件发送清除功能、这会导致器件将其切换为零、但 USB_reset_end点()实际上不会复位 xHCI 主机的切换。 您可能可以通过注释掉 ti_usb3410_5052. c:TI_open()中的 USB_clear_halt ()调用来解决此问题。 我也不确定该复位的历史记录、因此更改可能会导致一些 EHCI 主机出现问题。 正确的修复方法是让 xHCI 驱动程序维护人员修复复位功能、以便它实际上执行真正的复位、而不是仅打印调试。

    此致、
    Brian

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好 Brian、

    感谢您介绍 USB_clear_halt ()和 clear 功能。 你让我更清楚。

    我曾尝试在 open()中注释掉 USB_clear_halt (),但即使在 EHCI 主机中,批量传输也会变得异常。 是否可以在不使用 USB_clear_halt ()的情况下修复 Linux 设备驱动程序? 我认为 Windows 中的驱动程序在没有明确功能的情况下可以正常工作、Linux 也应该如此。

    此致、
    CT
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    CT、

    我同意、如果 Windows 可以工作、那么 Linux 也应该工作。 尽管如此,我对 Linux 驱动程序堆栈或者他们为什么需要 USB_clear_halt ()来提出解决方案的根本原因并不了解。 我尝试向驱动程序开发人员发送电子邮件,但没有得到任何响应。 很抱歉、我没有更多帮助。

    此致、
    Brian
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    大家好、

    我有一个权变措施、到目前为止、它对我来说是可以的。 只需在端口 open()中调用 USB_set_interface()。

    符合 USB 2.0规范。 9.1.1.5:  

    9.1.1.5已配置
    在使用 USB 设备的功能之前,必须先配置设备。 设备的数据
    透视,配置涉及正确处理非零的 SetConfiguration()请求
    配置值。 配置设备或更改备用设置会导致所有状态和
    与受影响接口中的端点关联的配置值将设置为其默认值。
    这包括使用数据切换到值 DATA0来设置任何端点的数据切换。

    虽然 xHCI 在调用 USB_clear_halt ()时拒绝复位端点、但我们仍然可以使用 USB_set_interface()来初始化切换序列。

    我将以下代码放在 open()的开头:

    /*重置批量端点上的数据切换以解决
    以下问题:*主机控制器中的错误,某些情况下会发生不同步*/
    USB_clear_halt (dev、port->write_话 术->pipe);
    USB_clear_halt (dev、port->read_话 术->pipe);
    USB_set_interface (dev、
    dev->config->interface[0]->cur_altsetting->desc.iInterface、
    dev->config->interface[0]-> cur_altsetting->desc.bAlternateSetting); 

    希望这可以帮助任何可能遭受类似问题的人。

    此致、

    CT