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

📄 rndis.c

📁 omap3 linux 2.6 用nocc去除了冗余代码
💻 C
📖 第 1 页 / 共 2 页
字号:
			 __FUNCTION__, OID, buf_len);	}	return retval;}/* * Response Functions */static int rndis_init_response (int configNr, rndis_init_msg_type *buf){	rndis_init_cmplt_type	*resp;	rndis_resp_t            *r;	if (!rndis_per_dev_params [configNr].dev) return -ENOTSUPP;	r = rndis_add_response (configNr, sizeof (rndis_init_cmplt_type));	if (!r)		return -ENOMEM;	resp = (rndis_init_cmplt_type *) r->buf;	resp->MessageType = __constant_cpu_to_le32 (			REMOTE_NDIS_INITIALIZE_CMPLT);	resp->MessageLength = __constant_cpu_to_le32 (52);	resp->RequestID = buf->RequestID; /* Still LE in msg buffer */	resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS);	resp->MajorVersion = __constant_cpu_to_le32 (RNDIS_MAJOR_VERSION);	resp->MinorVersion = __constant_cpu_to_le32 (RNDIS_MINOR_VERSION);	resp->DeviceFlags = __constant_cpu_to_le32 (RNDIS_DF_CONNECTIONLESS);	resp->Medium = __constant_cpu_to_le32 (RNDIS_MEDIUM_802_3);	resp->MaxPacketsPerTransfer = __constant_cpu_to_le32 (1);	resp->MaxTransferSize = cpu_to_le32 (		  rndis_per_dev_params [configNr].dev->mtu		+ sizeof (struct ethhdr)		+ sizeof (struct rndis_packet_msg_type)		+ 22);	resp->PacketAlignmentFactor = __constant_cpu_to_le32 (0);	resp->AFListOffset = __constant_cpu_to_le32 (0);	resp->AFListSize = __constant_cpu_to_le32 (0);	if (rndis_per_dev_params [configNr].ack)		rndis_per_dev_params [configNr].ack (			rndis_per_dev_params [configNr].dev);	return 0;}static int rndis_query_response (int configNr, rndis_query_msg_type *buf){	rndis_query_cmplt_type *resp;	rndis_resp_t            *r;	// DEBUG("%s: OID = %08X\n", __FUNCTION__, cpu_to_le32(buf->OID));	if (!rndis_per_dev_params [configNr].dev) return -ENOTSUPP;	/*	 * we need more memory:	 * gen_ndis_query_resp expects enough space for	 * rndis_query_cmplt_type followed by data.	 * oid_supported_list is the largest data reply	 */	r = rndis_add_response (configNr,		sizeof (oid_supported_list) + sizeof(rndis_query_cmplt_type));	if (!r)		return -ENOMEM;	resp = (rndis_query_cmplt_type *) r->buf;	resp->MessageType = __constant_cpu_to_le32 (REMOTE_NDIS_QUERY_CMPLT);	resp->RequestID = buf->RequestID; /* Still LE in msg buffer */	if (gen_ndis_query_resp (configNr, le32_to_cpu (buf->OID),			le32_to_cpu(buf->InformationBufferOffset)					+ 8 + (u8 *) buf,			le32_to_cpu(buf->InformationBufferLength),			r)) {		/* OID not supported */		resp->Status = __constant_cpu_to_le32 (				RNDIS_STATUS_NOT_SUPPORTED);		resp->MessageLength = __constant_cpu_to_le32 (sizeof *resp);		resp->InformationBufferLength = __constant_cpu_to_le32 (0);		resp->InformationBufferOffset = __constant_cpu_to_le32 (0);	} else		resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS);	if (rndis_per_dev_params [configNr].ack)		rndis_per_dev_params [configNr].ack (			rndis_per_dev_params [configNr].dev);	return 0;}static int rndis_set_response (int configNr, rndis_set_msg_type *buf){	u32			BufLength, BufOffset;	rndis_set_cmplt_type	*resp;	rndis_resp_t		*r;	r = rndis_add_response (configNr, sizeof (rndis_set_cmplt_type));	if (!r)		return -ENOMEM;	resp = (rndis_set_cmplt_type *) r->buf;	BufLength = le32_to_cpu (buf->InformationBufferLength);	BufOffset = le32_to_cpu (buf->InformationBufferOffset);	resp->MessageType = __constant_cpu_to_le32 (REMOTE_NDIS_SET_CMPLT);	resp->MessageLength = __constant_cpu_to_le32 (16);	resp->RequestID = buf->RequestID; /* Still LE in msg buffer */	if (gen_ndis_set_resp (configNr, le32_to_cpu (buf->OID),			((u8 *) buf) + 8 + BufOffset, BufLength, r))		resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_NOT_SUPPORTED);	else		resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS);	if (rndis_per_dev_params [configNr].ack)		rndis_per_dev_params [configNr].ack (			rndis_per_dev_params [configNr].dev);	return 0;}static int rndis_reset_response (int configNr, rndis_reset_msg_type *buf){	rndis_reset_cmplt_type	*resp;	rndis_resp_t		*r;	r = rndis_add_response (configNr, sizeof (rndis_reset_cmplt_type));	if (!r)		return -ENOMEM;	resp = (rndis_reset_cmplt_type *) r->buf;	resp->MessageType = __constant_cpu_to_le32 (REMOTE_NDIS_RESET_CMPLT);	resp->MessageLength = __constant_cpu_to_le32 (16);	resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS);	/* resent information */	resp->AddressingReset = __constant_cpu_to_le32 (1);	if (rndis_per_dev_params [configNr].ack)		rndis_per_dev_params [configNr].ack (			rndis_per_dev_params [configNr].dev);	return 0;}static int rndis_keepalive_response (int configNr,				rndis_keepalive_msg_type *buf){	rndis_keepalive_cmplt_type	*resp;	rndis_resp_t			*r;	/* host "should" check only in RNDIS_DATA_INITIALIZED state */	r = rndis_add_response (configNr, sizeof (rndis_keepalive_cmplt_type));	if (!r)		return -ENOMEM;	resp = (rndis_keepalive_cmplt_type *) r->buf;	resp->MessageType = __constant_cpu_to_le32 (			REMOTE_NDIS_KEEPALIVE_CMPLT);	resp->MessageLength = __constant_cpu_to_le32 (16);	resp->RequestID = buf->RequestID; /* Still LE in msg buffer */	resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS);	if (rndis_per_dev_params [configNr].ack)		rndis_per_dev_params [configNr].ack (			rndis_per_dev_params [configNr].dev);	return 0;}/* * Device to Host Comunication */static int rndis_indicate_status_msg (int configNr, u32 status){	rndis_indicate_status_msg_type	*resp;	rndis_resp_t			*r;	if (rndis_per_dev_params [configNr].state == RNDIS_UNINITIALIZED)		return -ENOTSUPP;	r = rndis_add_response (configNr,				sizeof (rndis_indicate_status_msg_type));	if (!r)		return -ENOMEM;	resp = (rndis_indicate_status_msg_type *) r->buf;	resp->MessageType = __constant_cpu_to_le32 (			REMOTE_NDIS_INDICATE_STATUS_MSG);	resp->MessageLength = __constant_cpu_to_le32 (20);	resp->Status = cpu_to_le32 (status);	resp->StatusBufferLength = __constant_cpu_to_le32 (0);	resp->StatusBufferOffset = __constant_cpu_to_le32 (0);	if (rndis_per_dev_params [configNr].ack)		rndis_per_dev_params [configNr].ack (			rndis_per_dev_params [configNr].dev);	return 0;}int rndis_signal_connect (int configNr){	rndis_per_dev_params [configNr].media_state			= NDIS_MEDIA_STATE_CONNECTED;	return rndis_indicate_status_msg (configNr,					  RNDIS_STATUS_MEDIA_CONNECT);}int rndis_signal_disconnect (int configNr){	rndis_per_dev_params [configNr].media_state			= NDIS_MEDIA_STATE_DISCONNECTED;	return rndis_indicate_status_msg (configNr,					  RNDIS_STATUS_MEDIA_DISCONNECT);}void rndis_uninit (int configNr){	u8 *buf;	u32 length;	if (configNr >= RNDIS_MAX_CONFIGS)		return;	rndis_per_dev_params [configNr].used = 0;	rndis_per_dev_params [configNr].state = RNDIS_UNINITIALIZED;	/* drain the response queue */	while ((buf = rndis_get_next_response(configNr, &length)))		rndis_free_response(configNr, buf);}void rndis_set_host_mac (int configNr, const u8 *addr){	rndis_per_dev_params [configNr].host_mac = addr;}/* * Message Parser */int rndis_msg_parser (u8 configNr, u8 *buf){	u32 MsgType, MsgLength;	__le32 *tmp;	struct rndis_params		*params;	if (!buf)		return -ENOMEM;	tmp = (__le32 *) buf;	MsgType   = le32_to_cpu(get_unaligned(tmp++));	MsgLength = le32_to_cpu(get_unaligned(tmp++));	if (configNr >= RNDIS_MAX_CONFIGS)		return -ENOTSUPP;	params = &rndis_per_dev_params [configNr];	/* NOTE: RNDIS is *EXTREMELY* chatty ... Windows constantly polls for	 * rx/tx statistics and link status, in addition to KEEPALIVE traffic	 * and normal HC level polling to see if there's any IN traffic.	 */	/* For USB: responses may take up to 10 seconds */	switch (MsgType) {	case REMOTE_NDIS_INITIALIZE_MSG:		DEBUG("%s: REMOTE_NDIS_INITIALIZE_MSG\n",			__FUNCTION__ );		params->state = RNDIS_INITIALIZED;		return  rndis_init_response (configNr,					(rndis_init_msg_type *) buf);	case REMOTE_NDIS_HALT_MSG:		DEBUG("%s: REMOTE_NDIS_HALT_MSG\n",			__FUNCTION__ );		params->state = RNDIS_UNINITIALIZED;		if (params->dev) {			netif_carrier_off (params->dev);			netif_stop_queue (params->dev);		}		return 0;	case REMOTE_NDIS_QUERY_MSG:		return rndis_query_response (configNr,					(rndis_query_msg_type *) buf);	case REMOTE_NDIS_SET_MSG:		return rndis_set_response (configNr,					(rndis_set_msg_type *) buf);	case REMOTE_NDIS_RESET_MSG:		DEBUG("%s: REMOTE_NDIS_RESET_MSG\n",			__FUNCTION__ );		return rndis_reset_response (configNr,					(rndis_reset_msg_type *) buf);	case REMOTE_NDIS_KEEPALIVE_MSG:		/* For USB: host does this every 5 seconds */		if (rndis_debug > 1)			DEBUG("%s: REMOTE_NDIS_KEEPALIVE_MSG\n",				__FUNCTION__ );		return rndis_keepalive_response (configNr,						 (rndis_keepalive_msg_type *)						 buf);	default:		/* At least Windows XP emits some undefined RNDIS messages.		 * In one case those messages seemed to relate to the host		 * suspending itself.		 */		printk (KERN_WARNING			"%s: unknown RNDIS message 0x%08X len %d\n",			__FUNCTION__ , MsgType, MsgLength);		{			unsigned i;			for (i = 0; i < MsgLength; i += 16) {				DEBUG ("%03d: "					" %02x %02x %02x %02x"					" %02x %02x %02x %02x"					" %02x %02x %02x %02x"					" %02x %02x %02x %02x"					"\n",					i,					buf[i], buf [i+1],						buf[i+2], buf[i+3],					buf[i+4], buf [i+5],						buf[i+6], buf[i+7],					buf[i+8], buf [i+9],						buf[i+10], buf[i+11],					buf[i+12], buf [i+13],						buf[i+14], buf[i+15]);			}		}		break;	}	return -ENOTSUPP;}int rndis_register (int (* rndis_control_ack) (struct net_device *)){	u8 i;	for (i = 0; i < RNDIS_MAX_CONFIGS; i++) {		if (!rndis_per_dev_params [i].used) {			rndis_per_dev_params [i].used = 1;			rndis_per_dev_params [i].ack = rndis_control_ack;			DEBUG("%s: configNr = %d\n", __FUNCTION__, i);			return i;		}	}	DEBUG("failed\n");	return -1;}void rndis_deregister (int configNr){	DEBUG("%s: \n", __FUNCTION__ );	if (configNr >= RNDIS_MAX_CONFIGS) return;	rndis_per_dev_params [configNr].used = 0;	return;}int rndis_set_param_dev (u8 configNr, struct net_device *dev,			 struct net_device_stats *stats,			 u16 *cdc_filter){	DEBUG("%s:\n", __FUNCTION__ );	if (!dev || !stats) return -1;	if (configNr >= RNDIS_MAX_CONFIGS) return -1;	rndis_per_dev_params [configNr].dev = dev;	rndis_per_dev_params [configNr].stats = stats;	rndis_per_dev_params [configNr].filter = cdc_filter;	return 0;}int rndis_set_param_vendor (u8 configNr, u32 vendorID, const char *vendorDescr){	DEBUG("%s:\n", __FUNCTION__ );	if (!vendorDescr) return -1;	if (configNr >= RNDIS_MAX_CONFIGS) return -1;	rndis_per_dev_params [configNr].vendorID = vendorID;	rndis_per_dev_params [configNr].vendorDescr = vendorDescr;	return 0;}int rndis_set_param_medium (u8 configNr, u32 medium, u32 speed){	DEBUG("%s: %u %u\n", __FUNCTION__, medium, speed);	if (configNr >= RNDIS_MAX_CONFIGS) return -1;	rndis_per_dev_params [configNr].medium = medium;	rndis_per_dev_params [configNr].speed = speed;	return 0;}void rndis_add_hdr (struct sk_buff *skb){	struct rndis_packet_msg_type	*header;	if (!skb)		return;	header = (void *) skb_push (skb, sizeof *header);	memset (header, 0, sizeof *header);	header->MessageType = __constant_cpu_to_le32(REMOTE_NDIS_PACKET_MSG);	header->MessageLength = cpu_to_le32(skb->len);	header->DataOffset = __constant_cpu_to_le32 (36);	header->DataLength = cpu_to_le32(skb->len - sizeof *header);}void rndis_free_response (int configNr, u8 *buf){	rndis_resp_t		*r;	struct list_head	*act, *tmp;	list_for_each_safe (act, tmp,			&(rndis_per_dev_params [configNr].resp_queue))	{		r = list_entry (act, rndis_resp_t, list);		if (r && r->buf == buf) {			list_del (&r->list);			kfree (r);		}	}}u8 *rndis_get_next_response (int configNr, u32 *length){	rndis_resp_t		*r;	struct list_head	*act, *tmp;	if (!length) return NULL;	list_for_each_safe (act, tmp,			&(rndis_per_dev_params [configNr].resp_queue))	{		r = list_entry (act, rndis_resp_t, list);		if (!r->send) {			r->send = 1;			*length = r->length;			return r->buf;		}	}	return NULL;}static rndis_resp_t *rndis_add_response (int configNr, u32 length){	rndis_resp_t	*r;	/* NOTE:  this gets copied into ether.c USB_BUFSIZ bytes ... */	r = kmalloc (sizeof (rndis_resp_t) + length, GFP_ATOMIC);	if (!r) return NULL;	r->buf = (u8 *) (r + 1);	r->length = length;	r->send = 0;	list_add_tail (&r->list,		&(rndis_per_dev_params [configNr].resp_queue));	return r;}int rndis_rm_hdr(struct sk_buff *skb){	/* tmp points to a struct rndis_packet_msg_type */	__le32		*tmp = (void *) skb->data;	/* MessageType, MessageLength */	if (__constant_cpu_to_le32(REMOTE_NDIS_PACKET_MSG)			!= get_unaligned(tmp++))		return -EINVAL;	tmp++;	/* DataOffset, DataLength */	if (!skb_pull(skb, le32_to_cpu(get_unaligned(tmp++))			+ 8 /* offset of DataOffset */))		return -EOVERFLOW;	skb_trim(skb, le32_to_cpu(get_unaligned(tmp++)));	return 0;}int __devinit rndis_init (void){	u8 i;	for (i = 0; i < RNDIS_MAX_CONFIGS; i++) {		rndis_per_dev_params [i].confignr = i;		rndis_per_dev_params [i].used = 0;		rndis_per_dev_params [i].state = RNDIS_UNINITIALIZED;		rndis_per_dev_params [i].media_state				= NDIS_MEDIA_STATE_DISCONNECTED;		INIT_LIST_HEAD (&(rndis_per_dev_params [i].resp_queue));	}	return 0;}void rndis_exit (void){}

⌨️ 快捷键说明

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