- USB 通信设备类
- USB Dongle 拨号
Defined Class Codes
例如:
02hCommunications and CDC Control08hMass Storage09hHub0AhCDC-DataEFhMiscellaneous
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章节:
00hRESERVED01hDirect Line Control Model [USBPSTN1.2]02hAbstract Control Model [USBPSTN1.2]03hTelephone Control Model [USBPSTN1.2]04hMulti-Channel Control Model [USBISDN1.2]05hCAPI Control Model [USBISDN1.2]06hEthernet Networking Control Model [USBECM1.2]07hATM Networking Control Model [USBATM1.2]08hWireless Handset Control Model [USBWMC1.1]09hDevice Management [USBWMC1.1]0AhMobile Direct Line Model [USBWMC1.1]0BhOBEX [USBWMC1.1]0ChEthernet Emulation Model [USBEEM1.0]0DhNetwork Control Model [USBNCM1.0]0EhMobile Broadband Interface Model [USBMBIM1.0]0Dh-7FhRESERVED (future use)80-FEhRESERVED (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) },