为什么 Linux 将 USB 主控制器的供应商列为“Linux Foundation”?

为什么 Linux 将 USB 主控制器的供应商列为“Linux Foundation”?

在 USB 主控制器连接到 PCI/PCIE 总线的任何 PC 上,我会看到以下内容:

$ cat /sys/bus/usb/devices/usb1/{idVendor,idProduct,manufacturer,product,serial}
1d6b
0002
Linux 4.14.157-amd64-x32 ehci_hcd
EHCI Host Controller
0000:00:1a.0

即,EHCI 主机控制器(在本例中具有 PCI 设备位置0000:00:1a.0)由一组虚假的字符串描述符和供应商/产品标识符表示。查找供应商 ID 1d6busb.ids发现它对应于 Linux Foundation。 (lsusb将其列为“Linux Foundation 2.0 root hub”。)但是所引用的 PCI 设备serial是真实的,并且具有以下属性:

$ cat /sys/bus/pci/devices/0000:00:1a.0/{vendor,device}
0x8086
0x8c2d

查找这些 ID,pci.ids我们可以发现它是 Intel 8 系列/C220 系列芯片组系列 USB EHCI(与所说的相同lspci)。来自真正硬件制造商的真正硬件。

那么为什么 Linux 用一些奇怪的 id 集来表示这个 Intel 硬件呢?我确实意识到 PCI 和 USB 供应商/产品 id 可能会发生冲突,因此不可能使用 PCI 命名空间中的 id 启动 USB 设备树。但为什么是字符串描述符呢?

我的猜测是,这是因为名为“*HCI Host Controller”的整个 USB 实体是一个虚构的实体。但另一方面,它似乎有一个地址(始终=1),该地址从未分配给该总线上新连接的设备。所以看起来这个 USB 实体可能是真实存在的。但这个保留地址也可能只是一种记账方式。

我的猜测正确吗?作为 USB 实体的主机控制器完全是虚构的吗?它是否从未作为线路上的实际可寻址设备出现?或者是否有一些真实的东西,我们实际上可以向其发送标准 USB 请求,而不是让内核简单地模拟它们的处理?

答案1

Linux 有一个抽象,可以让主机控制器驱动程序共享代码。作为评论drivers/usb/core/hcd.c说:

 * USB Host Controller Driver framework
 *
 * Plugs into usbcore (usb_bus) and lets HCDs share code, minimizing
 * HCD-specific behaviors/bugs.
 *
 * This does error checks, tracks devices and urbs, and delegates to a
 * "hc_driver" only for code (and data) that really needs to know about
 * hardware differences.  That includes root hub registers, i/o queues,
 * and so on ... but as little else as possible.
 *
 * Shared code includes most of the "root hub" code (these are emulated,
 * though each HC's hardware works differently) and PCI glue, plus request
 * tracking overhead.  The HCD code should only block on spinlocks or on
 * hardware handshaking; blocking on software events (such as other kernel
 * threads releasing resources, or completing actions) is all generic.
 *
 * Happens the USB 2.0 spec says this would be invisible inside the "USBD",
 * and includes mostly a "HCDI" (HCD Interface) along with some APIs used
 * only by the hub driver ... and that neither should be seen or used by
 * usb client device drivers.
 *

USB 设备地址 1 被分配给 中的根集线器register_root_hub(),如该函数上方的注释所示:

 * register_root_hub - called by usb_add_hcd() to register a root hub
 * @hcd: host controller for this root hub
 *
 * This function registers the root hub with the USB subsystem.  It sets up
 * the device properly in the device tree and then calls usb_new_device()
 * to register the usb device.  It also assigns the root hub's USB address
 * (always 1).

数据库证实了这一点usb.ids,数据库表明对于供应商 ID,1d6b产品 ID 1、2、3 分别对应于 1.1、2.0、3.0 根集线器。

我们在该设备的 Linux 设备树中拥有的是 USB 主控制器(真实设备)和 USB 根集线器(也是真实设备)的混合体,由上面讨论的 USB HCD 框架抽象出来。

现在,一些具有 xHCI 的现代系统也具有 EHCI 控制器,这些控制器具有英特尔公司集成速率匹配中心始终依附。这些不是根集线器,它们的地址为 2,而不是 1。英特尔手册,第 5.19.1 章:

The Hubs convert low and full-speed traffic into high-speed traffic.

相关内容