---
# System prepended metadata

title: Linux USB Devices Limits
tags: [技術分享]

---

# Linux USB Devices Limits

## Maximum USB Devices Supported
USB 規範規定，每個 USB 裝置在總線上都需要一個 7 位的「裝置地址」（Device Address），數值範圍是 1～127，所以理論上同一個 USB 總線最多可掛 127 個裝置。如果系統偵測到的裝置數量超過了這個範圍，可能就會有部份裝置無法被分配到地址，或在 lsusb 清單中無法看到。

在較舊的內核版本（如 2.6.x）中，通常可以在 USB 第 9 章看到相關的標準定義（例如 USB_DEVICE_MAX_ADDRESS）

`./include/uapi/linux/usb/ch9.h`

在後續的內核版本中，已移除了這個明確的宏定義，改為直接依照 USB 規範默認裝置地址上限為 127，或者在驅動程式內部寫死 (硬編碼) 這個數值。

`./drivers/usb/cdns3/cdns3-gadget.h` (用於 Cadence USB 3.0 gadget 驅動。)
![image](https://hackmd.io/_uploads/r1-AuEMTkx.png)

`./drivers/usb/gadget/udc/cdns2/cdns2-gadget.h` (用於 Cadence USB 2.0 gadget 驅動。)
![image](https://hackmd.io/_uploads/SyknDVzTyl.png)


## HID Devices (hiddev / hidraw) Limits
Linux 裡針對 HID（Human Interface Device）有兩種介面：
* hidraw：提供「原始（raw）HID 報告」的存取方式，應用程式可以直接操作原始資料。
* hiddev：是較舊的介面，用來對 HID 裝置進行較高階的操作。
在常規情況下，系統內部對 hidraw 以及 hiddev 裝置數量是有所限制，超過數量的 HID 裝置就無法分配到 hidraw/hiddev 介面。
---

### hiddev 上限
在 hiddev 的 driver 中可以看到相關定義:
* 啟用 CONFIG_USB_DYNAMIC_MINORS，上限為 256 個裝置（從 minor 0 開始）。
* 停用 CONFIG_USB_DYNAMIC_MINORS，上限為 16 個裝置（從 minor 96 開始）。

` ./drivers/hid/usbhid/hiddev.c`

![image](https://hackmd.io/_uploads/rkaPVVzTke.png)
---

### hidraw 上限
在 hidraw 的 driver 中可以看到，其參數的 buffer 大小都使用 HIDRAW_MAX_DEVICES 為依據，

`./drivers/hid/hidraw.c`
![image](https://hackmd.io/_uploads/HkYBLNz61x.png)

而 HIDRAW_MAX_DEVICES 則是被定義在 linux 的內核本身當中

`./include/linux/hidraw.h`
![image](https://hackmd.io/_uploads/rkXKHNzTJx.png)

## USB BUS Limits

而在少數高密度 USB 佈署（例如多顆 xHCI 控制器、同時具備 USB2/USB3 root hub、多板卡/多橋接）中，Linux kernel 對「可註冊的 USB 匯流排（bus）」數量以可能成為瓶頸。kernel 核心碼對此有一個上限參數 USB_MAXBUS，預設多為 64；若系統中的主機控制器（每個 roothub 視為一條 bus）總數超過此上限，後續的控制器可能無法被正常註冊，導致裝置無法枚舉，這個關於 USB_MAXBUS 上限的設置，被寫在 kernel 中的:

`./drivers/usb/core/hcd.c`
![image](https://hackmd.io/_uploads/rJfGQBEKlg.png)


## 總結
以上設定都是 Linux 內核中的預設值，若需要支援更多設備或更大的緩衝區，需自行下載 Linux 的開放代碼做修改，並重新編譯 Linux 內核。

