- USB 通信设备类
- USB Dongle 拨号
Defined Class Codes
例如:
02h
Communications and CDC Control08h
Mass Storage09h
Hub0Ah
CDC-DataEFh
Miscellaneous
Linux4.9 include/uapi/linux/usb/ch9.h
可以看到各个定义值
Communications Class Subclass Codes
USB 的 CDC 类是 USB 通信设备类(Communication Device Class)的简称。CDC 类是 USB 组织定义的一类专门给各种通信设备(电信通信设备和中速网络通信设备)使用的 USB 子类。
具体列表见文档 Universal Serial Bus Class Definitions for Communications Devices 4.3章节:
00h
RESERVED01h
Direct Line Control Model [USBPSTN1.2]02h
Abstract Control Model [USBPSTN1.2]03h
Telephone Control Model [USBPSTN1.2]04h
Multi-Channel Control Model [USBISDN1.2]05h
CAPI Control Model [USBISDN1.2]06h
Ethernet Networking Control Model [USBECM1.2]07h
ATM Networking Control Model [USBATM1.2]08h
Wireless Handset Control Model [USBWMC1.1]09h
Device Management [USBWMC1.1]0Ah
Mobile Direct Line Model [USBWMC1.1]0Bh
OBEX [USBWMC1.1]0Ch
Ethernet Emulation Model [USBEEM1.0]0Dh
Network Control Model [USBNCM1.0]0Eh
Mobile Broadband Interface Model [USBMBIM1.0]0Dh-7Fh
RESERVED (future use)80-FEh
RESERVED (vendor specific)
Linux4.9 内核实现
构造 USB 设备宏定义
/**
* USB_INTERFACE_INFO - macro used to describe a class of usb interfaces
* @cl: bInterfaceClass value
* @sc: bInterfaceSubClass value
* @pr: bInterfaceProtocol value
*
* This macro is used to create a struct usb_device_id that matches a
* specific class of interfaces.
*/
#define USB_INTERFACE_INFO(cl, sc, pr) \
.match_flags = USB_DEVICE_ID_MATCH_INT_INFO, \
.bInterfaceClass = (cl), \
.bInterfaceSubClass = (sc), \
.bInterfaceProtocol = (pr)
例如:
/* Telit LE922A6 in MBIM composition */
{ USB_DEVICE_AND_INTERFACE_INFO(0x1bc7, 0x1041, USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE),
.driver_info = (unsigned long)&cdc_mbim_info_avoid_altsetting_toggle,
},
{
USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_EEM,
USB_CDC_PROTO_EEM),
.driver_info = (unsigned long) &eem_info,
},
/* Telit LE910 V2 */
{ USB_DEVICE_AND_INTERFACE_INFO(0x1bc7, 0x0036,
USB_CLASS_COMM,
USB_CDC_SUBCLASS_NCM, USB_CDC_PROTO_NONE),
.driver_info = (unsigned long)&wwan_noarp_info,
},
内核文件
$ find -name "cdc_*"
./include/linux/usb/cdc_ncm.h
./drivers/net/usb/cdc_mbim.c
./drivers/net/usb/cdc_ncm.c
./drivers/net/usb/cdc_ether.c
./drivers/net/usb/cdc_eem.c
./drivers/net/usb/cdc_ether.o
./drivers/net/usb/cdc_subset.c
./Documentation/networking/cdc_mbim.txt
Rndis
在文件 drivers/net/usb/rndis_host.c
中发现如下代码
static const struct usb_device_id products [] = {
{
/* 2Wire HomePortal 1000SW */
USB_DEVICE_AND_INTERFACE_INFO(0x1630, 0x0042,
USB_CLASS_COMM, 2 /* ACM */, 0x0ff),
.driver_info = (unsigned long) &rndis_poll_status_info,
}, {
/* RNDIS is MSFT's un-official variant of CDC ACM */
USB_INTERFACE_INFO(USB_CLASS_COMM, 2 /* ACM */, 0x0ff),
.driver_info = (unsigned long) &rndis_info,
}, {
/* "ActiveSync" is an undocumented variant of RNDIS, used in WM5 */
USB_INTERFACE_INFO(USB_CLASS_MISC, 1, 1),
.driver_info = (unsigned long) &rndis_poll_status_info,
}, {
/* RNDIS for tethering */
USB_INTERFACE_INFO(USB_CLASS_WIRELESS_CONTROLLER, 1, 3),
.driver_info = (unsigned long) &rndis_info,
},
{ }, // END
};
MODULE_DEVICE_TABLE(usb, products);
RNDIS是一个以太网端口 ( Ethernet port )。最开始是微软控制的,用以取代 CDC Ethernet 的协议。Linux 支持它仅仅是因为微软不支持 CDC以太网标准。
USB Dongle 拨号
Many modern (and most LTE) usb modems provide qmi, mbim, ncm, rndis protocol for connection instead of legacy ppp protocol, they are faster and better, overall recommended. For more information:
- qmi and mbim, see How To Use LTE modem in QMI mode for WAN connection
- ncm, see How To Use LTE modem in NCM mode for WAN connection
- rndis, see How To Use LTE modem in RNDIS mode for WAN connection
内核设备列表
USB 设备需要关心 ProductID
和 VendorID
,用于表示某一种具体的设备,例如文件 unusual_devs.h
列举了非常规设备列表,表示这些设备需要特殊处理
/*
* Reported by fangxiaozhi <huananhu@huawei.com>
* This brings the HUAWEI data card devices into multi-port mode
*/
UNUSUAL_DEV( 0x12d1, 0x1001, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
UNUSUAL_DEV( 0x12d1, 0x1003, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
Add New USB Dongle
在内核中增加普通 USB Dongle 设备,修改 drivers/usb/serial/option.c
中的数组 option_ids
{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1C0B, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1C05, 0xff, 0xff, 0xff) },