⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ether.c

📁 LINUX2.4.18内核下的usb GADGET驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
#ifdef	DEV_CONFIG_CDCstatic struct usb_interface_descriptorcontrol_intf = {	.bLength =		sizeof control_intf,	.bDescriptorType =	USB_DT_INTERFACE,	.bInterfaceNumber =	0,	/* status endpoint is optional; this may be patched later */	.bNumEndpoints =	1,	.bInterfaceClass =	USB_CLASS_COMM,	.bInterfaceSubClass =	USB_CDC_SUBCLASS_ETHERNET,	.bInterfaceProtocol =	USB_CDC_PROTO_NONE,	.iInterface =		STRING_CONTROL,};#endif#ifdef	CONFIG_USB_ETH_RNDISstatic const struct usb_interface_descriptorrndis_control_intf = {	.bLength =              sizeof rndis_control_intf,	.bDescriptorType =      USB_DT_INTERFACE,	  	.bInterfaceNumber =     0,	.bNumEndpoints =        1,	.bInterfaceClass =      USB_CLASS_COMM,	.bInterfaceSubClass =   USB_CDC_SUBCLASS_ACM,	.bInterfaceProtocol =   USB_CDC_ACM_PROTO_VENDOR,	.iInterface =           STRING_RNDIS_CONTROL,};#endif#if defined(DEV_CONFIG_CDC) || defined(CONFIG_USB_ETH_RNDIS)static const struct usb_cdc_header_desc header_desc = {	.bLength =		sizeof header_desc,	.bDescriptorType =	USB_DT_CS_INTERFACE,	.bDescriptorSubType =	USB_CDC_HEADER_TYPE,	.bcdCDC =		__constant_cpu_to_le16 (0x0110),};static const struct usb_cdc_union_desc union_desc = {	.bLength =		sizeof union_desc,	.bDescriptorType =	USB_DT_CS_INTERFACE,	.bDescriptorSubType =	USB_CDC_UNION_TYPE,	.bMasterInterface0 =	0,	/* index of control interface */	.bSlaveInterface0 =	1,	/* index of DATA interface */};#endif	/* CDC || RNDIS */#ifdef	CONFIG_USB_ETH_RNDISstatic const struct usb_cdc_call_mgmt_descriptor call_mgmt_descriptor = {	.bLength =  		sizeof call_mgmt_descriptor,	.bDescriptorType = 	USB_DT_CS_INTERFACE,	.bDescriptorSubType = 	USB_CDC_CALL_MANAGEMENT_TYPE,	.bmCapabilities = 	0x00,	.bDataInterface = 	0x01,};static struct usb_cdc_acm_descriptor acm_descriptor = {	.bLength =  		sizeof acm_descriptor,	.bDescriptorType = 	USB_DT_CS_INTERFACE,	.bDescriptorSubType = 	USB_CDC_ACM_TYPE,	.bmCapabilities = 	0x00,};#endif#ifdef	DEV_CONFIG_CDCstatic const struct usb_cdc_ether_desc ether_desc = {	.bLength =		sizeof ether_desc,	.bDescriptorType =	USB_DT_CS_INTERFACE,	.bDescriptorSubType =	USB_CDC_ETHERNET_TYPE,	/* this descriptor actually adds value, surprise! */	.iMACAddress =		STRING_ETHADDR,	.bmEthernetStatistics =	__constant_cpu_to_le32 (0), /* no statistics */	.wMaxSegmentSize =	__constant_cpu_to_le16 (ETH_FRAME_LEN),	.wNumberMCFilters =	__constant_cpu_to_le16 (0),	.bNumberPowerFilters =	0,};#endif#if defined(DEV_CONFIG_CDC) || defined(CONFIG_USB_ETH_RNDIS)/* include the status endpoint if we can, even where it's optional. * use wMaxPacketSize big enough to fit CDC_NOTIFY_SPEED_CHANGE in one * packet, to simplify cancelation; and a big transfer interval, to * waste less bandwidth. * * some drivers (like Linux 2.4 cdc-ether!) "need" it to exist even * if they ignore the connect/disconnect notifications that real aether * can provide.  more advanced cdc configurations might want to support * encapsulated commands (vendor-specific, using control-OUT). * * RNDIS requires the status endpoint, since it uses that encapsulation * mechanism for its funky RPC scheme. */ #define LOG2_STATUS_INTERVAL_MSEC	5	/* 1 << 5 == 32 msec */#define STATUS_BYTECOUNT		16	/* 8 byte header + data */static struct usb_endpoint_descriptorfs_status_desc = {	.bLength =		USB_DT_ENDPOINT_SIZE,	.bDescriptorType =	USB_DT_ENDPOINT,	.bEndpointAddress =	USB_DIR_IN,	.bmAttributes =		USB_ENDPOINT_XFER_INT,	.wMaxPacketSize =	__constant_cpu_to_le16 (STATUS_BYTECOUNT),	.bInterval =		1 << LOG2_STATUS_INTERVAL_MSEC,};#endif#ifdef	DEV_CONFIG_CDC/* the default data interface has no endpoints ... */static const struct usb_interface_descriptordata_nop_intf = {	.bLength =		sizeof data_nop_intf,	.bDescriptorType =	USB_DT_INTERFACE,	.bInterfaceNumber =	1,	.bAlternateSetting =	0,	.bNumEndpoints =	0,	.bInterfaceClass =	USB_CLASS_CDC_DATA,	.bInterfaceSubClass =	0,	.bInterfaceProtocol =	0,};/* ... but the "real" data interface has two bulk endpoints */static const struct usb_interface_descriptordata_intf = {	.bLength =		sizeof data_intf,	.bDescriptorType =	USB_DT_INTERFACE,	.bInterfaceNumber =	1,	.bAlternateSetting =	1,	.bNumEndpoints =	2,	.bInterfaceClass =	USB_CLASS_CDC_DATA,	.bInterfaceSubClass =	0,	.bInterfaceProtocol =	0,	.iInterface =		STRING_DATA,};#endif#ifdef	CONFIG_USB_ETH_RNDIS/* RNDIS doesn't activate by changing to the "real" altsetting */static const struct usb_interface_descriptorrndis_data_intf = {	.bLength =		sizeof rndis_data_intf,	.bDescriptorType =	USB_DT_INTERFACE,	.bInterfaceNumber =	1,	.bAlternateSetting =	0,	.bNumEndpoints =	2,	.bInterfaceClass =	USB_CLASS_CDC_DATA,	.bInterfaceSubClass =	0,	.bInterfaceProtocol =	0,	.iInterface =		STRING_DATA,};#endif#ifdef DEV_CONFIG_SUBSET/* * "Simple" CDC-subset option is a simple vendor-neutral model that most * full speed controllers can handle:  one interface, two bulk endpoints. */static const struct usb_interface_descriptorsubset_data_intf = {	.bLength =		sizeof subset_data_intf,	.bDescriptorType =	USB_DT_INTERFACE,	.bInterfaceNumber =	0,	.bAlternateSetting =	0,	.bNumEndpoints =	2,	.bInterfaceClass =	USB_CLASS_VENDOR_SPEC,	.bInterfaceSubClass =	0,	.bInterfaceProtocol =	0,	.iInterface =		STRING_DATA,};#endif	/* SUBSET */static struct usb_endpoint_descriptorfs_source_desc = {	.bLength =		USB_DT_ENDPOINT_SIZE,	.bDescriptorType =	USB_DT_ENDPOINT,	.bEndpointAddress =	USB_DIR_IN,	.bmAttributes =		USB_ENDPOINT_XFER_BULK,};static struct usb_endpoint_descriptorfs_sink_desc = {	.bLength =		USB_DT_ENDPOINT_SIZE,	.bDescriptorType =	USB_DT_ENDPOINT,	.bEndpointAddress =	USB_DIR_OUT,	.bmAttributes =		USB_ENDPOINT_XFER_BULK,};static const struct usb_descriptor_header *fs_eth_function [11] = {	(struct usb_descriptor_header *) &otg_descriptor,#ifdef DEV_CONFIG_CDC	/* "cdc" mode descriptors */	(struct usb_descriptor_header *) &control_intf,	(struct usb_descriptor_header *) &header_desc,	(struct usb_descriptor_header *) &union_desc,	(struct usb_descriptor_header *) &ether_desc,	/* NOTE: status endpoint may need to be removed */	(struct usb_descriptor_header *) &fs_status_desc,	/* data interface, with altsetting */	(struct usb_descriptor_header *) &data_nop_intf,	(struct usb_descriptor_header *) &data_intf,	(struct usb_descriptor_header *) &fs_source_desc,	(struct usb_descriptor_header *) &fs_sink_desc,	NULL,#endif /* DEV_CONFIG_CDC */};static inline void __init fs_subset_descriptors(void){#ifdef DEV_CONFIG_SUBSET	fs_eth_function[1] = (struct usb_descriptor_header *) &subset_data_intf;	fs_eth_function[2] = (struct usb_descriptor_header *) &fs_source_desc;	fs_eth_function[3] = (struct usb_descriptor_header *) &fs_sink_desc;	fs_eth_function[4] = NULL;#else	fs_eth_function[1] = NULL;#endif}#ifdef	CONFIG_USB_ETH_RNDISstatic const struct usb_descriptor_header *fs_rndis_function [] = {	(struct usb_descriptor_header *) &otg_descriptor,	/* control interface matches ACM, not Ethernet */	(struct usb_descriptor_header *) &rndis_control_intf,	(struct usb_descriptor_header *) &header_desc,	(struct usb_descriptor_header *) &call_mgmt_descriptor,	(struct usb_descriptor_header *) &acm_descriptor,	(struct usb_descriptor_header *) &union_desc,	(struct usb_descriptor_header *) &fs_status_desc,	/* data interface has no altsetting */	(struct usb_descriptor_header *) &rndis_data_intf,	(struct usb_descriptor_header *) &fs_source_desc,	(struct usb_descriptor_header *) &fs_sink_desc,	NULL,};#endif#ifdef	CONFIG_USB_GADGET_DUALSPEED/* * usb 2.0 devices need to expose both high speed and full speed * descriptors, unless they only run at full speed. */#if defined(DEV_CONFIG_CDC) || defined(CONFIG_USB_ETH_RNDIS)static struct usb_endpoint_descriptorhs_status_desc = {	.bLength =		USB_DT_ENDPOINT_SIZE,	.bDescriptorType =	USB_DT_ENDPOINT,	.bmAttributes =		USB_ENDPOINT_XFER_INT,	.wMaxPacketSize =	__constant_cpu_to_le16 (STATUS_BYTECOUNT),	.bInterval =		LOG2_STATUS_INTERVAL_MSEC + 4,};#endif /* DEV_CONFIG_CDC */static struct usb_endpoint_descriptorhs_source_desc = {	.bLength =		USB_DT_ENDPOINT_SIZE,	.bDescriptorType =	USB_DT_ENDPOINT,	.bmAttributes =		USB_ENDPOINT_XFER_BULK,	.wMaxPacketSize =	__constant_cpu_to_le16 (512),};static struct usb_endpoint_descriptorhs_sink_desc = {	.bLength =		USB_DT_ENDPOINT_SIZE,	.bDescriptorType =	USB_DT_ENDPOINT,	.bmAttributes =		USB_ENDPOINT_XFER_BULK,	.wMaxPacketSize =	__constant_cpu_to_le16 (512),};static struct usb_qualifier_descriptordev_qualifier = {	.bLength =		sizeof dev_qualifier,	.bDescriptorType =	USB_DT_DEVICE_QUALIFIER,	.bcdUSB =		__constant_cpu_to_le16 (0x0200),	.bDeviceClass =		USB_CLASS_COMM,	.bNumConfigurations =	1,};static const struct usb_descriptor_header *hs_eth_function [11] = {	(struct usb_descriptor_header *) &otg_descriptor,#ifdef DEV_CONFIG_CDC	/* "cdc" mode descriptors */	(struct usb_descriptor_header *) &control_intf,	(struct usb_descriptor_header *) &header_desc,	(struct usb_descriptor_header *) &union_desc,	(struct usb_descriptor_header *) &ether_desc,	/* NOTE: status endpoint may need to be removed */	(struct usb_descriptor_header *) &hs_status_desc,	/* data interface, with altsetting */	(struct usb_descriptor_header *) &data_nop_intf,	(struct usb_descriptor_header *) &data_intf,	(struct usb_descriptor_header *) &hs_source_desc,	(struct usb_descriptor_header *) &hs_sink_desc,	NULL,#endif /* DEV_CONFIG_CDC */};static inline void __init hs_subset_descriptors(void){#ifdef DEV_CONFIG_SUBSET	hs_eth_function[1] = (struct usb_descriptor_header *) &subset_data_intf;	hs_eth_function[2] = (struct usb_descriptor_header *) &fs_source_desc;	hs_eth_function[3] = (struct usb_descriptor_header *) &fs_sink_desc;	hs_eth_function[4] = NULL;#else	hs_eth_function[1] = NULL;#endif}#ifdef	CONFIG_USB_ETH_RNDISstatic const struct usb_descriptor_header *hs_rndis_function [] = {	(struct usb_descriptor_header *) &otg_descriptor,	/* control interface matches ACM, not Ethernet */	(struct usb_descriptor_header *) &rndis_control_intf,	(struct usb_descriptor_header *) &header_desc,	(struct usb_descriptor_header *) &call_mgmt_descriptor,	(struct usb_descriptor_header *) &acm_descriptor,	(struct usb_descriptor_header *) &union_desc,	(struct usb_descriptor_header *) &hs_status_desc,	/* data interface has no altsetting */	(struct usb_descriptor_header *) &rndis_data_intf,	(struct usb_descriptor_header *) &hs_source_desc,	(struct usb_descriptor_header *) &hs_sink_desc,	NULL,};#endif/* maxpacket and other transfer characteristics vary by speed. */#define ep_desc(g,hs,fs) (((g)->speed==USB_SPEED_HIGH)?(hs):(fs))#else/* if there's no high speed support, maxpacket doesn't change. */#define ep_desc(g,hs,fs) fsstatic inline void __init hs_subset_descriptors(void){}#endif	/* !CONFIG_USB_GADGET_DUALSPEED *//*-------------------------------------------------------------------------*//* descriptors that are built on-demand */static char				manufacturer [50];static char				product_desc [40] = DRIVER_DESC;#ifdef	DEV_CONFIG_CDC/* address that the host will use ... usually assigned at random */static char				ethaddr [2 * ETH_ALEN + 1];#endif/* static strings, in UTF-8 */static struct usb_string		strings [] = {	{ STRING_MANUFACTURER,	manufacturer, },	{ STRING_PRODUCT,	product_desc, },	{ STRING_DATA,		"Ethernet Data", },#ifdef	DEV_CONFIG_CDC	{ STRING_CDC,		"CDC Ethernet", },	{ STRING_ETHADDR,	ethaddr, },	{ STRING_CONTROL,	"CDC Communications Control", },#endif#ifdef	DEV_CONFIG_SUBSET	{ STRING_SUBSET,	"CDC Ethernet Subset", },#endif#ifdef	CONFIG_USB_ETH_RNDIS	{ STRING_RNDIS,		"RNDIS", },	{ STRING_RNDIS_CONTROL,	"RNDIS Communications Control", },#endif	{  }		/* end of list */};static struct usb_gadget_strings	stringtab = {	.language	= 0x0409,	/* en-us */	.strings	= strings,};/* * one config, two interfaces:  control, data. * complications: class descriptors, and an altsetting. */static intconfig_buf (enum usb_device_speed speed,	u8 *buf, u8 type,	unsigned index, int is_otg){	int					len;	const struct usb_config_descriptor	*config;	const struct usb_descriptor_header	**function;#ifdef CONFIG_USB_GADGET_DUALSPEED	int				hs = (speed == USB_SPEED_HIGH);	if (type == USB_DT_OTHER_SPEED_CONFIG)		hs = !hs;#define which_fn(t)	(hs ? hs_ ## t ## _function : fs_ ## t ## _function)#else#define	which_fn(t)	(fs_ ## t ## _function)#endif	if (index >= device_desc.bNumConfigurations)		return -EINVAL;#ifdef	CONFIG_USB_ETH_RNDIS	/* list the RNDIS config first, to make Microsoft's drivers	 * happy. DOCSIS 1.0 needs this too.	 */	if (device_desc.bNumConfigurations == 2 && index == 0) {		config = &rndis_config;		function = which_fn (rndis);	} else#endif	{		config = &eth_config;		function = which_fn (eth);	}	/* for now, don't advertise srp-only devices */	if (!is_otg)		function++;	len = usb_gadget_config_buf (config, buf, USB_BUFSIZ, function);	if (len < 0)		return len;	((struct usb_config_descriptor *) buf)->bDescriptorType = type;	return len;}/*-------------------------------------------------------------------------*/static void eth_start (struct eth_dev *dev, int gfp_flags);static int alloc_requests (struct eth_dev *dev, unsigned n, int gfp_flags);#ifdef	DEV_CONFIG_CDCstatic inline int ether_alt_ep_setup (struct eth_dev *dev, struct usb_ep *ep){	const struct usb_endpoint_descriptor	*d;	/* With CDC,  the host isn't allowed to use these two data	 * endpoints in the default altsetting for the interface.	 * so we don't activate them yet.  Reset from SET_INTERFACE.	 *	 * Strictly speaking RNDIS should work the same: activation is	 * a side effect of setting a packet filter.  Deactivation is	 * from REMOTE_NDIS_HALT_MSG, reset from REMOTE_NDIS_RESET_MSG.	 */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -