Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
码匠许师傅
rt-thread
提交
cc9ce52b
R
rt-thread
项目概览
码匠许师傅
/
rt-thread
与 Fork 源项目一致
Fork自
RT-Thread / rt-thread
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
rt-thread
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
cc9ce52b
编写于
6月 10, 2019
作者:
lymzzyh
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[Components][USB][RNDIS] fix hotplug and "delay linkup"
上级
cf7052f6
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
171 addition
and
77 deletion
+171
-77
components/drivers/Kconfig
components/drivers/Kconfig
+7
-0
components/drivers/usb/usbdevice/class/rndis.c
components/drivers/usb/usbdevice/class/rndis.c
+155
-77
components/drivers/usb/usbdevice/class/rndis.h
components/drivers/usb/usbdevice/class/rndis.h
+9
-0
未找到文件。
components/drivers/Kconfig
浏览文件 @
cc9ce52b
...
...
@@ -640,6 +640,13 @@ menu "Using USB"
string "msc class disk name"
default "flash0"
endif
if RT_USB_DEVICE_RNDIS
config RNDIS_DELAY_LINK_UP
bool "Delay linkup media connection"
default n
endif
if RT_USB_DEVICE_HID
config RT_USB_DEVICE_HID_KEYBOARD
bool "Use to HID device as Keyboard"
...
...
components/drivers/usb/usbdevice/class/rndis.c
浏览文件 @
cc9ce52b
...
...
@@ -13,21 +13,21 @@
* 2013-07-09 aozima support respone chain list.
* 2013-07-18 aozima re-initial respone chain list when RNDIS restart.
* 2017-11-25 ZYH fix it and add OS descriptor
* 2019-06-10 ZYH fix hot plug and delay linkup
*/
#include <rtdevice.h>
#ifdef RT_USB_DEVICE_RNDIS
#include "cdc.h"
#include "rndis.h"
#include "ndis.h"
//#define RNDIS_DEBUG
//#define RNDIS_DELAY_LINK_UP
/* define RNDIS_DELAY_LINK_UP by menuconfig for delay linkup */
#define DBG_LEVEL DBG_WARNING
#define DBG_SECTION_NAME "RNDIS"
#include <rtdbg.h>
#ifdef RNDIS_DEBUG
#define RNDIS_PRINTF rt_kprintf("[RNDIS] "); rt_kprintf
#else
#define RNDIS_PRINTF(...)
#endif
/* RNDIS_DEBUG */
/* RT-Thread LWIP ethernet interface */
#include <netif/ethernetif.h>
...
...
@@ -314,7 +314,7 @@ static rt_err_t _rndis_init_response(ufunction_t func, rndis_init_msg_t msg)
if
(
(
response
==
RT_NULL
)
||
(
resp
==
RT_NULL
)
)
{
RNDIS_PRINTF
(
"%d: no memory!
\r\n
"
,
__LINE__
);
LOG_E
(
"%s,%d: no memory!"
,
__func__
,
__LINE__
);
if
(
response
!=
RT_NULL
)
rt_free
(
response
);
...
...
@@ -360,7 +360,7 @@ static rndis_query_cmplt_t _create_resp(rt_size_t size)
if
(
resp
==
RT_NULL
)
{
RNDIS_PRINTF
(
"%d: no memory!
\r\n
"
,
__LINE__
);
LOG_E
(
"%s,%d: no memory!"
,
__func__
,
__LINE__
);
return
RT_NULL
;
}
...
...
@@ -510,7 +510,7 @@ static rt_err_t _rndis_query_response(ufunction_t func,rndis_query_msg_t msg)
break
;
default:
RNDIS_PRINTF
(
"OID %X
\n
"
,
msg
->
Oid
);
LOG_W
(
"Not support OID %X
"
,
msg
->
Oid
);
ret
=
-
RT_ERROR
;
break
;
}
...
...
@@ -518,7 +518,7 @@ static rt_err_t _rndis_query_response(ufunction_t func,rndis_query_msg_t msg)
response
=
rt_malloc
(
sizeof
(
struct
rt_rndis_response
));
if
(
(
response
==
RT_NULL
)
||
(
resp
==
RT_NULL
)
)
{
RNDIS_PRINTF
(
"%d: no memory!
\r\n
"
,
__LINE__
);
LOG_E
(
"%s,%d: no memory!"
,
__func__
,
__LINE__
);
if
(
response
!=
RT_NULL
)
rt_free
(
response
);
...
...
@@ -557,7 +557,7 @@ static rt_err_t _rndis_set_response(ufunction_t func,rndis_set_msg_t msg)
if
(
(
response
==
RT_NULL
)
||
(
resp
==
RT_NULL
)
)
{
RNDIS_PRINTF
(
"%d: no memory!
\r\n
"
,
__LINE__
);
LOG_E
(
"%s,%d: no memory!"
,
__func__
,
__LINE__
);
if
(
response
!=
RT_NULL
)
rt_free
(
response
);
...
...
@@ -577,8 +577,10 @@ static rt_err_t _rndis_set_response(ufunction_t func,rndis_set_msg_t msg)
case
OID_GEN_CURRENT_PACKET_FILTER
:
oid_packet_filter
=
*
((
rt_uint32_t
*
)((
rt_uint8_t
*
)
&
(
msg
->
RequestId
)
+
\
msg
->
InformationBufferOffset
));
/* TODO: make complier happy */
oid_packet_filter
=
oid_packet_filter
;
RNDIS_PRINTF
(
"OID_GEN_CURRENT_PACKET_FILTER
\r\n
"
);
LOG_D
(
"OID_GEN_CURRENT_PACKET_FILTER"
);
#ifdef RNDIS_DELAY_LINK_UP
/* link up. */
...
...
@@ -592,6 +594,7 @@ static rt_err_t _rndis_set_response(ufunction_t func,rndis_set_msg_t msg)
break
;
default:
LOG_W
(
"Unknow rndis set 0x%02X"
,
msg
->
Oid
);
resp
->
Status
=
RNDIS_STATUS_FAILURE
;
return
RT_EOK
;
}
...
...
@@ -609,6 +612,58 @@ static rt_err_t _rndis_set_response(ufunction_t func,rndis_set_msg_t msg)
return
RT_EOK
;
}
static
rt_err_t
_rndis_reset_response
(
ufunction_t
func
,
rndis_set_msg_t
msg
)
{
struct
rndis_reset_cmplt
*
resp
;
struct
rt_rndis_response
*
response
;
response
=
rt_malloc
(
sizeof
(
struct
rt_rndis_response
));
resp
=
rt_malloc
(
sizeof
(
struct
rndis_reset_cmplt
));
if
(
(
response
==
RT_NULL
)
||
(
resp
==
RT_NULL
)
)
{
LOG_E
(
"%s,%d: no memory!"
,
__func__
,
__LINE__
);
if
(
response
!=
RT_NULL
)
rt_free
(
response
);
if
(
resp
!=
RT_NULL
)
rt_free
(
resp
);
return
-
RT_ENOMEM
;
}
/* reset packet filter */
oid_packet_filter
=
0x0000000
;
/* link down eth */
eth_device_linkchange
(
&
((
rt_rndis_eth_t
)
func
->
user_data
)
->
parent
,
RT_FALSE
);
/* reset eth rx tx */
((
rt_rndis_eth_t
)
func
->
user_data
)
->
rx_frist
=
RT_TRUE
;
((
rt_rndis_eth_t
)
func
->
user_data
)
->
rx_flag
=
RT_FALSE
;
rt_sem_release
(
&
((
rt_rndis_eth_t
)
func
->
user_data
)
->
tx_buffer_free
);
eth_device_ready
(
&
(((
rt_rndis_eth_t
)
func
->
user_data
)
->
parent
));
resp
->
MessageType
=
REMOTE_NDIS_RESET_CMPLT
;
resp
->
MessageLength
=
sizeof
(
struct
rndis_reset_cmplt
);
resp
->
Status
=
RNDIS_STATUS_SUCCESS
;
resp
->
AddressingReset
=
1
;
response
->
buffer
=
resp
;
{
rt_base_t
level
=
rt_hw_interrupt_disable
();
rt_list_insert_before
(
&
((
rt_rndis_eth_t
)
func
->
user_data
)
->
response_list
,
&
response
->
list
);
rt_hw_interrupt_enable
(
level
);
}
return
RT_EOK
;
}
static
rt_err_t
_rndis_keepalive_response
(
ufunction_t
func
,
rndis_keepalive_msg_t
msg
)
{
rndis_keepalive_cmplt_t
resp
;
...
...
@@ -619,7 +674,7 @@ static rt_err_t _rndis_keepalive_response(ufunction_t func,rndis_keepalive_msg_t
if
(
(
response
==
RT_NULL
)
||
(
resp
==
RT_NULL
)
)
{
RNDIS_PRINTF
(
"%d: no memory!
\r\n
"
,
__LINE__
);
LOG_E
(
"%s,%d: no memory!"
,
__func__
,
__LINE__
);
if
(
response
!=
RT_NULL
)
rt_free
(
response
);
...
...
@@ -652,34 +707,45 @@ static rt_err_t _rndis_msg_parser(ufunction_t func, rt_uint8_t *msg)
switch
(((
rndis_gen_msg_t
)
msg
)
->
MessageType
)
{
case
REMOTE_NDIS_INITIALIZE_MSG
:
LOG_D
(
"REMOTE_NDIS_INITIALIZE_MSG"
);
ret
=
_rndis_init_response
(
func
,
(
rndis_init_msg_t
)
msg
);
break
;
case
REMOTE_NDIS_HALT_MSG
:
RNDIS_PRINTF
(
"halt
\n
"
);
LOG_D
(
"REMOTE_NDIS_HALT_MSG
"
);
/* link down. */
eth_device_linkchange
(
&
((
rt_rndis_eth_t
)
func
->
user_data
)
->
parent
,
RT_FALSE
);
/* reset eth rx tx */
((
rt_rndis_eth_t
)
func
->
user_data
)
->
rx_frist
=
RT_TRUE
;
((
rt_rndis_eth_t
)
func
->
user_data
)
->
rx_flag
=
RT_FALSE
;
rt_sem_release
(
&
((
rt_rndis_eth_t
)
func
->
user_data
)
->
tx_buffer_free
);
eth_device_ready
(
&
(((
rt_rndis_eth_t
)
func
->
user_data
)
->
parent
));
break
;
case
REMOTE_NDIS_QUERY_MSG
:
LOG_D
(
"REMOTE_NDIS_QUERY_MSG"
);
ret
=
_rndis_query_response
(
func
,(
rndis_query_msg_t
)
msg
);
break
;
case
REMOTE_NDIS_SET_MSG
:
LOG_D
(
"REMOTE_NDIS_SET_MSG"
);
ret
=
_rndis_set_response
(
func
,(
rndis_set_msg_t
)
msg
);
RNDIS_PRINTF
(
"set
\n
"
);
break
;
case
REMOTE_NDIS_RESET_MSG
:
RNDIS_PRINTF
(
"reset
\n
"
);
LOG_D
(
"REMOTE_NDIS_RESET_MSG"
);
ret
=
_rndis_reset_response
(
func
,(
rndis_set_msg_t
)
msg
);
break
;
case
REMOTE_NDIS_KEEPALIVE_MSG
:
LOG_D
(
"REMOTE_NDIS_KEEPALIVE_MSG"
);
ret
=
_rndis_keepalive_response
(
func
,(
rndis_keepalive_msg_t
)
msg
);
break
;
default:
RNDIS_PRINTF
(
"msg %X
\n
"
,
((
rndis_gen_msg_t
)
msg
)
->
MessageType
);
LOG_W
(
"not support RNDIS msg %X
"
,
((
rndis_gen_msg_t
)
msg
)
->
MessageType
);
ret
=
-
RT_ERROR
;
break
;
}
...
...
@@ -718,7 +784,7 @@ static rt_err_t _rndis_get_encapsulated_response(ufunction_t func, ureq_t setup)
if
(
rt_list_isempty
(
&
((
rt_rndis_eth_t
)
func
->
user_data
)
->
response_list
))
{
RNDIS_PRINTF
(
"response_list is empty!
\r\n
"
);
LOG_D
(
"response_list is empty!
"
);
((
rt_rndis_eth_t
)
func
->
user_data
)
->
need_notify
=
RT_TRUE
;
return
RT_EOK
;
}
...
...
@@ -741,7 +807,7 @@ static rt_err_t _rndis_get_encapsulated_response(ufunction_t func, ureq_t setup)
{
rt_uint32_t
*
data
;
RNDIS_PRINTF
(
"auto append next response!
\r\n
"
);
LOG_I
(
"auto append next response!
"
);
data
=
(
rt_uint32_t
*
)((
rt_rndis_eth_t
)
func
->
user_data
)
->
eps
.
ep_cmd
->
buffer
;
data
[
0
]
=
RESPONSE_AVAILABLE
;
data
[
1
]
=
0
;
...
...
@@ -758,55 +824,6 @@ static rt_err_t _rndis_get_encapsulated_response(ufunction_t func, ureq_t setup)
return
RT_EOK
;
}
#ifdef RNDIS_DELAY_LINK_UP
/**
* This function will set rndis connect status.
*
* @param device the usb device object.
* @param status the connect status.
*
* @return RT_EOK on successful.
*/
static
rt_err_t
_rndis_indicate_status_msg
(
ufunction_t
func
,
rt_uint32_t
status
)
{
rndis_indicate_status_msg_t
resp
;
struct
rt_rndis_response
*
response
;
response
=
rt_malloc
(
sizeof
(
struct
rt_rndis_response
));
resp
=
rt_malloc
(
sizeof
(
struct
rndis_indicate_status_msg
));
if
(
(
response
==
RT_NULL
)
||
(
resp
==
RT_NULL
)
)
{
RNDIS_PRINTF
(
"%d: no memory!
\r\n
"
,
__LINE__
);
if
(
response
!=
RT_NULL
)
rt_free
(
response
);
if
(
resp
!=
RT_NULL
)
rt_free
(
resp
);
return
-
RT_ENOMEM
;
}
resp
->
MessageType
=
REMOTE_NDIS_INDICATE_STATUS_MSG
;
resp
->
MessageLength
=
20
;
/* sizeof(struct rndis_indicate_status_msg) */
resp
->
Status
=
status
;
resp
->
StatusBufferLength
=
0
;
resp
->
StatusBufferOffset
=
0
;
response
->
buffer
=
resp
;
{
rt_base_t
level
=
rt_hw_interrupt_disable
();
rt_list_insert_before
(
&
((
rt_rndis_eth_t
)
func
->
user_data
)
->
response_list
,
&
response
->
list
);
rt_hw_interrupt_enable
(
level
);
}
_rndis_response_available
(
func
);
return
RT_EOK
;
}
#endif
/* RNDIS_DELAY_LINK_UP */
/**
* This function will handle rndis interface request.
*
...
...
@@ -831,7 +848,7 @@ static rt_err_t _interface_handler(ufunction_t func, ureq_t setup)
break
;
default:
RNDIS_PRINTF
(
"unkown setup->request!
\r\n
"
);
LOG_W
(
"unkown setup->request 0x%02X !"
,
setup
->
bRequest
);
break
;
}
...
...
@@ -933,6 +950,8 @@ static rt_err_t _function_enable(ufunction_t func)
{
cdc_eps_t
eps
;
LOG_I
(
"plugged in"
);
eps
=
(
cdc_eps_t
)
&
((
rt_rndis_eth_t
)
func
->
user_data
)
->
eps
;
eps
->
ep_in
->
buffer
=
((
rt_rndis_eth_t
)
func
->
user_data
)
->
tx_pool
;
eps
->
ep_out
->
buffer
=
((
rt_rndis_eth_t
)
func
->
user_data
)
->
rx_pool
;
...
...
@@ -945,6 +964,7 @@ static rt_err_t _function_enable(ufunction_t func)
((
rt_rndis_eth_t
)
func
->
user_data
)
->
rx_flag
=
RT_FALSE
;
((
rt_rndis_eth_t
)
func
->
user_data
)
->
rx_frist
=
RT_TRUE
;
eth_device_ready
(
&
(((
rt_rndis_eth_t
)
func
->
user_data
)
->
parent
));
#ifdef RNDIS_DELAY_LINK_UP
/* stop link up timer. */
...
...
@@ -981,7 +1001,7 @@ static rt_err_t _function_enable(ufunction_t func)
*/
static
rt_err_t
_function_disable
(
ufunction_t
func
)
{
RNDIS_PRINTF
(
"plugged out
\n
"
);
LOG_I
(
"plugged out
"
);
#ifdef RNDIS_DELAY_LINK_UP
/* stop link up timer. */
...
...
@@ -996,7 +1016,7 @@ static rt_err_t _function_disable(ufunction_t func)
while
(
!
rt_list_isempty
(
&
((
rt_rndis_eth_t
)
func
->
user_data
)
->
response_list
))
{
response
=
(
struct
rt_rndis_response
*
)((
rt_rndis_eth_t
)
func
->
user_data
)
->
response_list
.
next
;
RNDIS_PRINTF
(
"remove resp chain list!
\r\n
"
);
LOG_D
(
"remove resp chain list!
"
);
rt_list_remove
(
&
response
->
list
);
rt_free
((
void
*
)
response
->
buffer
);
...
...
@@ -1007,8 +1027,16 @@ static rt_err_t _function_disable(ufunction_t func)
rt_hw_interrupt_enable
(
level
);
}
/* link down. */
eth_device_linkchange
(
&
((
rt_rndis_eth_t
)
func
->
user_data
)
->
parent
,
RT_FALSE
);
/* reset eth rx tx */
((
rt_rndis_eth_t
)
func
->
user_data
)
->
rx_frist
=
RT_TRUE
;
((
rt_rndis_eth_t
)
func
->
user_data
)
->
rx_flag
=
RT_FALSE
;
rt_sem_release
(
&
((
rt_rndis_eth_t
)
func
->
user_data
)
->
tx_buffer_free
);
eth_device_ready
(
&
(((
rt_rndis_eth_t
)
func
->
user_data
)
->
parent
));
return
RT_EOK
;
}
...
...
@@ -1141,14 +1169,14 @@ rt_err_t rt_rndis_eth_tx(rt_device_t dev, struct pbuf* p)
if
(
!
device
->
parent
.
link_status
)
{
RNDIS_PRINTF
(
"linkdown, drop pkg
\r\n
"
);
LOG_I
(
"linkdown, drop pkg
"
);
return
RT_EOK
;
}
RT_ASSERT
(
p
->
tot_len
<
sizeof
(
device
->
tx_buffer
));
if
(
p
->
tot_len
>
sizeof
(
device
->
tx_buffer
))
{
RNDIS_PRINTF
(
"RNDIS MTU is:%d, but the send packet size is %d
\r\n
"
,
LOG_W
(
"RNDIS MTU is:%d, but the send packet size is %d
"
,
sizeof
(
device
->
tx_buffer
),
p
->
tot_len
);
p
->
tot_len
=
sizeof
(
device
->
tx_buffer
);
}
...
...
@@ -1215,11 +1243,59 @@ const static struct rt_device_ops rndis_device_ops =
#endif
/* RT_USING_LWIP */
#ifdef RNDIS_DELAY_LINK_UP
/**
* This function will set rndis connect status.
*
* @param device the usb device object.
* @param status the connect status.
*
* @return RT_EOK on successful.
*/
static
rt_err_t
_rndis_indicate_status_msg
(
ufunction_t
func
,
rt_uint32_t
status
)
{
rndis_indicate_status_msg_t
resp
;
struct
rt_rndis_response
*
response
;
response
=
rt_malloc
(
sizeof
(
struct
rt_rndis_response
));
resp
=
rt_malloc
(
sizeof
(
struct
rndis_indicate_status_msg
));
if
(
(
response
==
RT_NULL
)
||
(
resp
==
RT_NULL
)
)
{
LOG_E
(
"%s,%d: no memory!"
,
__func__
,
__LINE__
);
if
(
response
!=
RT_NULL
)
rt_free
(
response
);
if
(
resp
!=
RT_NULL
)
rt_free
(
resp
);
return
-
RT_ENOMEM
;
}
resp
->
MessageType
=
REMOTE_NDIS_INDICATE_STATUS_MSG
;
resp
->
MessageLength
=
20
;
/* sizeof(struct rndis_indicate_status_msg) */
resp
->
Status
=
status
;
resp
->
StatusBufferLength
=
0
;
resp
->
StatusBufferOffset
=
0
;
response
->
buffer
=
resp
;
{
rt_base_t
level
=
rt_hw_interrupt_disable
();
rt_list_insert_before
(
&
((
rt_rndis_eth_t
)
func
->
user_data
)
->
response_list
,
&
response
->
list
);
rt_hw_interrupt_enable
(
level
);
}
_rndis_response_available
(
func
);
return
RT_EOK
;
}
/* the delay linkup timer handler. */
static
void
timer_timeout
(
void
*
parameter
)
{
RNDIS_PRINTF
(
"delay link up!
\r\n
"
);
_rndis_indicate_status_msg
(((
rt_rndis_eth_t
)
parameter
)
->
parent
.
parent
.
user_data
,
LOG_I
(
"delay link up!
"
);
_rndis_indicate_status_msg
(((
rt_rndis_eth_t
)
parameter
)
->
func
,
RNDIS_STATUS_MEDIA_CONNECT
);
eth_device_linkchange
(
&
((
rt_rndis_eth_t
)
parameter
)
->
parent
,
RT_TRUE
);
}
...
...
@@ -1372,4 +1448,6 @@ int rt_usbd_rndis_class_register(void)
rt_usbd_class_register
(
&
rndis_class
);
return
0
;
}
INIT_PREV_EXPORT
(
rt_usbd_rndis_class_register
);
\ No newline at end of file
INIT_PREV_EXPORT
(
rt_usbd_rndis_class_register
);
#endif
/* RT_USB_DEVICE_RNDIS */
components/drivers/usb/usbdevice/class/rndis.h
浏览文件 @
cc9ce52b
...
...
@@ -180,6 +180,15 @@ struct rndis_reset_msg
rt_uint32_t
Reserved
;
};
/* Remote NDIS Soft Reset Response */
struct
rndis_reset_cmplt
{
rt_uint32_t
MessageType
;
rt_uint32_t
MessageLength
;
rt_uint32_t
Status
;
rt_uint32_t
AddressingReset
;
};
/* Remote NDIS Indicate Status Message */
struct
rndis_indicate_status_msg
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录