当前位置:首页 > 科技新闻 > Web编程 > 正文

USB NCM usbnet 枚举流程代码分析
2021-10-20 10:31:48


USB NCM usbnet 枚举流程代码分析

一、cdc_ncm.c

在linux 驱动中,CDC NCM的驱动位于: ​​kerneldrivers etusbcdc_ncm.c​

static struct usb_driver cdc_ncm_driver = {
.name = "cdc_ncm",
.id_table = cdc_devs,
.probe = usbnet_probe,
.disconnect = usbnet_disconnect,
.suspend = usbnet_suspend,
.resume = usbnet_resume,
.reset_resume = usbnet_resume,
.supports_autosuspend = 1,
.disable_hub_initiated_lpm = 1,
};

module_usb_driver(cdc_ncm_driver);

在结构体​​cdc_ncm_driver​​中,比较重要的是​​id_table​​,​​probe​​这两个,

在​​id_table​​ 中定义了所有符合​​cdc_ncm​​设备的 ​​idVendor​​号,当​​linux​​ 枚举时检测到USB设备的​​idVendor​​在这个​​id_table​​中时,就会调用​​usbnet_probe​​进行起网操作。


1.1 struct usb_device_id结构体

在分析​​cdc_ncm​​的​​id_table​​之前,我们先来看下​​usb_device_id​​ 结构体是如何定义的:

# kernelincludelinuxmod_devicetable.h
struct usb_device_id {
/* which fields to match against? */
__u16 match_flags; //说明使用哪种匹配方式

/* Used for product specific matches; range is inclusive */
__u16 idVendor; //供应商ID
__u16 idProduct; //产品ID
__u16 bcdDevice_lo;
__u16 bcdDevice_hi;

/* Used for device class matches */
__u8 bDeviceClass; //设备类型
__u8 bDeviceSubClass; //设备子类型
__u8 bDeviceProtocol; //协议

/* Used for interface class matches */
__u8 bInterfaceClass; //接口类
__u8 bInterfaceSubClass; //接口子类
__u8 bInterfaceProtocol; //接口协议

/* Used for vendor-specific interface matches */
__u8 bInterfaceNumber;

/* not matched against */
kernel_ulong_t driver_info
__attribute__((aligned(sizeof(kernel_ulong_t)))); // NCM 驱动结构体,其中包含了收发包的函数等
};

结合结构体定义,我们来看下​​cdc_ncm​​的​​id_table​​:

static const struct usb_device_id cdc_devs[] = {
// 爱立信 F5521gw USB网卡
/* Ericsson MBM devices like F5521gw */
{ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO | USB_DEVICE_ID_MATCH_VENDOR,
//匹配方式:CLASS(设备类)、SUBCLASS(子类)、PROTOCOL(设备协议)
.idVendor = 0x0bdb, //供应商ID: 0x0bdb
.bInterfaceClass = USB_CLASS_COMM, //设备类型: 网卡类
.bInterfaceSubClass = USB_CDC_SUBCLASS_NCM, //设备子类型:NCM
.bInterfaceProtocol = USB_CDC_PROTO_NONE, //设备协议: 无
.driver_info = (unsigned long) &wwan_info, // NCM 驱动结构体,其中包含了收发包的函数等
},

/* DW5812 LTE Verizon Mobile Broadband Card Unlike DW5550 this device requires FLAG_NOARP */
{ USB_DEVICE_AND_INTERFACE_INFO(0x413c, 0x81bb,
USB_CLASS_COMM,
USB_CDC_SUBCLASS_NCM, USB_CDC_PROTO_NONE),
.driver_info = (unsigned long)&wwan_noarp_info,
},

/* DW5813 LTE AT&T Mobile Broadband Card Unlike DW5550 this device requires FLAG_NOARP */
{ USB_DEVICE_AND_INTERFACE_INFO(0x413c, 0x81bc,
USB_CLASS_COMM,
USB_CDC_SUBCLASS_NCM, USB_CDC_PROTO_NONE),
.driver_info = (unsigned long)&wwan_noarp_info,
},

/* Dell branded MBM devices like DW5550 */
{ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO | USB_DEVICE_ID_MATCH_VENDOR,
.idVendor = 0x413c,
.bInterfaceClass = USB_CLASS_COMM,
.bInterfaceSubClass = USB_CDC_SUBCLASS_NCM,
.bInterfaceProtocol = USB_CDC_PROTO_NONE,
.driver_info = (unsigned long) &wwan_info,
},

/* Toshiba branded MBM devices */
{ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO | USB_DEVICE_ID_MATCH_VENDOR,
.idVendor = 0x0930,
.bInterfaceClass = USB_CLASS_COMM,
.bInterfaceSubClass = USB_CDC_SUBCLASS_NCM,
.bInterfaceProtocol = USB_CDC_PROTO_NONE,
.driver_info = (unsigned long) &wwan_info,
},

/* tag Huawei devices as wwan */
{ USB_VENDOR_AND_INTERFACE_INFO(0x12d1,
USB_CLASS_COMM,
USB_CDC_SUBCLASS_NCM,
USB_CDC_PROTO_NONE),
.driver_info = (unsigned long)&wwan_info,
},

/* Infineon(now Intel) HSPA Modem platform */
{ USB_DEVICE_AND_INTERFACE_INFO(0x1519, 0x0443,
USB_CLASS_COMM,
USB_CDC_SUBCLASS_NCM, USB_CDC_PROTO_NONE),
.driver_info = (unsigned long)&wwan_noarp_info,
},

/* Generic CDC-NCM devices */
{ USB_INTERFACE_INFO(USB_CLASS_COMM,
USB_CDC_SUBCLASS_NCM, USB_CDC_PROTO_NONE),
.driver_info = (unsigned long)&cdc_ncm_info,
}
};
MODULE_DEVICE_TABLE(usb, cdc_devs);

1.1.1 match_flags 设备类型

所有的​​match_flags​​定义在​​mod_devicetable.h​​ 中:

# kernelincludelinuxmod_devicetable.h
/* Some useful macros to use to create struct usb_device_id */
#define USB_DEVICE_ID_MATCH_VENDOR 0x0001
#define USB_DEVICE_ID_MATCH_PRODUCT 0x0002
#define USB_DEVICE_ID_MATCH_DEV_LO 0x0004
#define USB_DEVICE_ID_MATCH_DEV_HI 0x0008
#define USB_DEVICE_ID_MATCH_DEV_CLASS 0x0010
#define USB_DEVICE_ID_MATCH_DEV_SUBCLASS 0x0020
#define USB_DEVICE_ID_MATCH_DEV_PROTOCOL 0x0040
#define USB_DEVICE_ID_MATCH_INT_CLASS 0x0080
#define USB_DEVICE_ID_MATCH_INT_SUBCLASS 0x0100
#define USB_DEVICE_ID_MATCH_INT_PROTOCOL 0x0200
#define USB_DEVICE_ID_MATCH_INT_NUMBER 0x0400

1.1.2 bInterfaceClass 接口类

# kernelincludeuapilinuxusbch9.h

/* Device and/or Interface Class codes
* as found in bDeviceClass or bInterfaceClass
* and defined by www.usb.org documents */
#define USB_CLASS_PER_INTERFACE 0 /* for DeviceClass */
#define USB_CLASS_AUDIO 1 //声音设备
#define USB_CLASS_COMM 2 //调制解调器,网卡,ISDN连接
#define USB_CLASS_HID 3 //HID设备,如鼠标,键盘
#define USB_CLASS_PHYSICAL 5 //物理设备
#define USB_CLASS_STILL_IMAGE 6 //静止图像捕捉设备
#define USB_CLASS_PRINTER 7 //打印机
#define USB_CLASS_MASS_STORAGE 8 //批量存储设备
#define USB_CLASS_HUB 9 //USB HUBS
#define USB_CLASS_CDC_DATA 0x0a
#define USB_CLASS_CSCID 0x0b /* chip+ smart card */ //智能卡
#define USB_CLASS_CONTENT_SEC 0x0d /* content security */
#define USB_CLASS_VIDEO 0x0e //视频设备,如网络摄像头
#define USB_CLASS_WIRELESS_CONTROLLER 0xe0 //网络控制设备
#define USB_CLASS_MISC 0xef //杂项设备
#define USB_CLASS_APP_SPEC 0xfe
#define USB_CLASS_VENDOR_SPEC 0xff //厂商自定义的设备

#define USB_SUBCLASS_VENDOR_SPEC 0xff

wait…

本文摘自 :https://blog.51cto.com/c