提交 9e6dc027 编写于 作者: A Alan Stern 提交者: Zheng Zengkai

USB: gadget: dummy-hcd: Fix errors in port-reset handling

stable inclusion
from stable-5.10.11
commit 43e2ae5a7493e2d5e42639b40fdeda1f19a5138c
bugzilla: 47621

--------------------------------

commit 6e6aa61d upstream.

Commit c318840f ("USB: Gadget: dummy-hcd: Fix shift-out-of-bounds
bug") messed up the way dummy-hcd handles requests to turn on the
RESET port feature (I didn't notice that the original switch case
ended with a fallthrough).  The call to set_link_state() was
inadvertently removed, as was the code to set the USB_PORT_STAT_RESET
flag when the speed is USB2.

In addition, the original code never checked whether the port was
connected before handling the port-reset request.  There was a check
for the port being powered, but it was removed by that commit!  In
practice this doesn't matter much because the kernel doesn't try to
reset disconnected ports, but it's still bad form.

This patch fixes these problems by changing the fallthrough to break,
adding back in the missing set_link_state() call, setting the
port-reset status flag, adding a port-is-connected test, and removing
a redundant assignment statement.

Fixes: c318840f ("USB: Gadget: dummy-hcd: Fix shift-out-of-bounds bug")
CC: <stable@vger.kernel.org>
Acked-by: NFelipe Balbi <balbi@kernel.org>
Signed-off-by: NAlan Stern <stern@rowland.harvard.edu>
Link: https://lore.kernel.org/r/20210113194510.GA1290698@rowland.harvard.eduSigned-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
Acked-by: NXie XiuQi <xiexiuqi@huawei.com>
上级 b0d1592e
...@@ -2266,17 +2266,20 @@ static int dummy_hub_control( ...@@ -2266,17 +2266,20 @@ static int dummy_hub_control(
} }
fallthrough; fallthrough;
case USB_PORT_FEAT_RESET: case USB_PORT_FEAT_RESET:
if (!(dum_hcd->port_status & USB_PORT_STAT_CONNECTION))
break;
/* if it's already enabled, disable */ /* if it's already enabled, disable */
if (hcd->speed == HCD_USB3) { if (hcd->speed == HCD_USB3) {
dum_hcd->port_status = 0;
dum_hcd->port_status = dum_hcd->port_status =
(USB_SS_PORT_STAT_POWER | (USB_SS_PORT_STAT_POWER |
USB_PORT_STAT_CONNECTION | USB_PORT_STAT_CONNECTION |
USB_PORT_STAT_RESET); USB_PORT_STAT_RESET);
} else } else {
dum_hcd->port_status &= ~(USB_PORT_STAT_ENABLE dum_hcd->port_status &= ~(USB_PORT_STAT_ENABLE
| USB_PORT_STAT_LOW_SPEED | USB_PORT_STAT_LOW_SPEED
| USB_PORT_STAT_HIGH_SPEED); | USB_PORT_STAT_HIGH_SPEED);
dum_hcd->port_status |= USB_PORT_STAT_RESET;
}
/* /*
* We want to reset device status. All but the * We want to reset device status. All but the
* Self powered feature * Self powered feature
...@@ -2288,7 +2291,8 @@ static int dummy_hub_control( ...@@ -2288,7 +2291,8 @@ static int dummy_hub_control(
* interval? Is it still 50msec as for HS? * interval? Is it still 50msec as for HS?
*/ */
dum_hcd->re_timeout = jiffies + msecs_to_jiffies(50); dum_hcd->re_timeout = jiffies + msecs_to_jiffies(50);
fallthrough; set_link_state(dum_hcd);
break;
case USB_PORT_FEAT_C_CONNECTION: case USB_PORT_FEAT_C_CONNECTION:
case USB_PORT_FEAT_C_RESET: case USB_PORT_FEAT_C_RESET:
case USB_PORT_FEAT_C_ENABLE: case USB_PORT_FEAT_C_ENABLE:
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册