我正在制作一个 bash 脚本,将文件从一个 USB 驱动器复制到其他多个驱动器。
一台专门运行 Xubuntu 的老式机器可以毫无问题地检测到 30 个设备。它仅具有 USB 2.0 端口。
而另一台运行 Linux Mint 的现代机器一次检测不到超过 16 个驱动器。它仅具有 USB 3.0 端口。当我连接超过 16 个驱动器后,新驱动器不再显示在 lsblk 中。
可能是什么原因?
编辑:
正如 fduff 指出的,我在连接第 17 个 USB 驱动器后检查了 dmesg,它显示的是:
[ 531.519845] usb 3-9.3.2.6: new high-speed USB device number 46 using xhci_hcd
[ 531.974582] usb 3-9.3.2.6: New USB device found, idVendor=abcd, idProduct=1234
[ 531.974585] usb 3-9.3.2.6: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 531.974586] usb 3-9.3.2.6: Product: UDisk
[ 531.974587] usb 3-9.3.2.6: Manufacturer: General
[ 531.974588] usb 3-9.3.2.6: SerialNumber: Љ
[ 531.975337] usb 3-9.3.2.6: Not enough host controller resources for new device state.
[ 531.975340] usb 3-9.3.2.6: can't set config #1, error -12
这看起来像是硬件限制,但允许的 USB 设备数量并不是恒定的。
现在,例如,我无法连接超过 15 个 USB 驱动器(第 16 个 USB 驱动器出现错误 -12),之前我也曾经能够连接大约 20 个设备,并且它们都被正确发现。
我尝试使用不同的 USB 端口来跨多个 USB 控制器分散使用,但没有成功。
我的硬件规格:
MB: ASRock Z97 Extreme6
CPU: Intel Core i5-4690K
GPU: MSI GeForce GTX 960 2GB
RAM: HyperX Fury Black 8GB [2x4GB 1600MHz DDR3 CL10 DIMM]
PSU: Chieftec GPS-500A8 [500W]
Display: 2x AOC I2276VWM [IPS, 1920x1080]
HDD: WD Blue 3TB
我还使用 28 端口曼哈顿 USB 集线器: https://www.amazon.com/Manhattan-Port-USB-Hub-161718/dp/B0074024XU
一台从 LiveCD(在 USB 驱动器上)运行 Xubuntu 的低端垂死 PC 能够检测到 29 个设备(算上 LiveCD 驱动器有 30 个)并执行文件传输 - 即使它安装在 HDD 上的 Windows XP 在某些时候无法检测到28 端口集线器。那台电脑现在正在接受维修服务,因为它坏了(我打赌 PSU 或 MB)。尽管如此——它还是有效的,而闪亮的新的却无效。
答案1
这可能是与硬件相关的问题。我在上发现了这个英特尔论坛:
对于8系列主板,最大端点为96个。每个USB设备可以支持多个端点,并且可以支持的端点数量因设备而异。一旦达到最大端点,您将收到一条弹出消息;该限制不是基于支持的设备数量,而是基于端点。
并且
重要的不是设备的数量,而是这些设备使用的端点的数量。事实上,您在 USB 3.0 端口上遇到问题意味着使用了 xHCI 控制器,而不是 USB 2.0 eHCI 控制器。英特尔 xHCI 控制器的限制低于 eHCI 控制器。对于 xHCI 控制器,它有 96 个端点。听起来您已达到此端点限制。您可以使用 Microsoft 的 USB 实用程序“USBVIEW”之类的工具来显示每个 USB 设备正在使用多少个端点。
除了尝试将设备分布到多个 USB 控制器之外,您对此无能为力。当然,这取决于您的主板是否有多个 USB 控制器,以及您是否可以确定哪些物理 USB 连接器路由到哪个 USB 控制器(同样,USBVIEW 很有用)。
仔细看看论坛的帖子,很有趣。
您可以使用以下命令来查明列出了多少个端点:
lsusb -v | grep bEndpointAddress | wc -l
答案2
此问题来自底层 USB 硬件控制器,它无法处理那么多设备。 Linux 源代码显示 xHC 在尝试配置接口时返回了“资源错误”代码。 xHCI 标准的第 4.4.6 章解释了这种情况:
将所需资源变量与可用资源变量进行比较,如果结果指示命令超额订阅资源(即可用资源 - 所需资源小于 0),则该命令应不成功,并且应显示资源错误完成代码在命令完成事件中返回。有关 xHC 资源的更多信息,请参阅第 4.14.1.1 节。
我的解决方法是通过删除不需要的每个 USB 设备来释放 xHCI 资源,例如内部 USB 设备(例如蓝牙、wifi 等)和仅连接 USB 2.0 设备的 USB 3.0 集线器。
步骤如下:
- 运行一下
lsusb
看看有没有什么没用的。 - 使用 sysfs 删除未使用的设备
echo 1 > /sys/<path to device>/remove
。看一下dmesg
它如何删除设备和每个子设备。这意味着您可以在根设备上使用此命令删除整个 USB 树。 - 您现在应该能够正确插入更多设备(参见
dmesg
日志)。
要在重新启动时保持此状态,请添加 udev 规则以删除设备:
SUBSYSTEM=="usb" <your conditions to match unused devices> RUN="sh -c 'echo 1 > /sys$DEVPATH/remove'"
答案3
我无法评论,因为我没有“声誉”。但要回答:
连接 14 + 1 个 USB 驱动器(并插入鼠标、键盘和两个集线器)后,该命令返回 64 个端点。我又插入一个,它有 66 个端点。我又插入了 13 个 USB 驱动器,但最多只有 76 个端点,而 lsblk 尚未检测到这些驱动器,但仍报告为每个设备 2 个端点。也许每个设备的 2 个端点用于单独的写入和读取?
每个设备需要 2 个额外端点,端点 0 输入和输出,这些不计入 lsusb,因为所有设备都需要端点 0。此外,集线器似乎需要比报告的端点数量多一个。