# 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 內核。