linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] usb: core: Fix side effect of clear port feature in hub port reset
@ 2015-09-01  7:31 hyunho747.kim
  2015-09-01 14:14 ` Alan Stern
  0 siblings, 1 reply; 2+ messages in thread
From: hyunho747.kim @ 2015-09-01  7:31 UTC (permalink / raw)
  To: Alan Stern; +Cc: linux-kernel, hyunho747.kim

After successful port reset by set_port_feature, some devices show
immediate link connection which generates port connect change interrupt.
But, the next step is an unconditional usb_clear_port_feature
and this flow always clears USB_PORT_FEAT_C_CONNECTION bit in port status
though next kick_khubd is reserved by link connection interrupt.
This flow can make an ambiguous state in the next port_evnet operation,
port_status is connected state such as 0x203 but
port_change is zero value caused by the previous clear port feature.
So, port_event can't call hub_port_connect_change and
there is no other way to peform connect procedure.

Signed-off-by: hyunho747.kim <hyunho747.kim@lge.com>
---
 drivers/usb/core/hub.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 73dfa19..4508aff 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -2761,18 +2761,21 @@ static int hub_port_reset(struct usb_hub *hub, int port1,
 
 		/* Check for disconnect or reset */
 		if (status == 0 || status == -ENOTCONN || status == -ENODEV) {
-			usb_clear_port_feature(hub->hdev, port1,
+			if (status)
+				usb_clear_port_feature(hub->hdev, port1,
 					USB_PORT_FEAT_C_RESET);
 
 			if (!hub_is_superspeed(hub->hdev))
 				goto done;
 
-			usb_clear_port_feature(hub->hdev, port1,
+			if (status) {
+				usb_clear_port_feature(hub->hdev, port1,
 					USB_PORT_FEAT_C_BH_PORT_RESET);
-			usb_clear_port_feature(hub->hdev, port1,
+				usb_clear_port_feature(hub->hdev, port1,
 					USB_PORT_FEAT_C_PORT_LINK_STATE);
-			usb_clear_port_feature(hub->hdev, port1,
+				usb_clear_port_feature(hub->hdev, port1,
 					USB_PORT_FEAT_C_CONNECTION);
+			}
 
 			/*
 			 * If a USB 3.0 device migrates from reset to an error
-- 
2.2.1


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH] usb: core: Fix side effect of clear port feature in hub port reset
  2015-09-01  7:31 [PATCH] usb: core: Fix side effect of clear port feature in hub port reset hyunho747.kim
@ 2015-09-01 14:14 ` Alan Stern
  0 siblings, 0 replies; 2+ messages in thread
From: Alan Stern @ 2015-09-01 14:14 UTC (permalink / raw)
  To: hyunho747.kim; +Cc: USB list, Kernel development list

On Tue, 1 Sep 2015, hyunho747.kim wrote:

> After successful port reset by set_port_feature, some devices show
> immediate link connection which generates port connect change interrupt.
> But, the next step is an unconditional usb_clear_port_feature
> and this flow always clears USB_PORT_FEAT_C_CONNECTION bit in port status
> though next kick_khubd is reserved by link connection interrupt.
> This flow can make an ambiguous state in the next port_evnet operation,
> port_status is connected state such as 0x203 but
> port_change is zero value caused by the previous clear port feature.
> So, port_event can't call hub_port_connect_change and
> there is no other way to peform connect procedure.

It sounds like you have not read this comment in hub_port_wait_reset():

	/* bomb out completely if the connection bounced.  A USB 3.0
	 * connection may bounce if multiple warm resets were issued,
	 * but the device may have successfully re-connected. Ignore it.
	 */

I agree that clearing the USB_PORT_FEAT_C_CONNECTION bit after reading
the port status can cause a race.  However I don't think your solution
is the correct one.

> Signed-off-by: hyunho747.kim <hyunho747.kim@lge.com>

You need to put a real name here, not an email address.  I suspect your 
real name isn't "hyunho747.kim".

> ---
>  drivers/usb/core/hub.c | 11 +++++++----
>  1 file changed, 7 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
> index 73dfa19..4508aff 100644
> --- a/drivers/usb/core/hub.c
> +++ b/drivers/usb/core/hub.c
> @@ -2761,18 +2761,21 @@ static int hub_port_reset(struct usb_hub *hub, int port1,
>  
>  		/* Check for disconnect or reset */
>  		if (status == 0 || status == -ENOTCONN || status == -ENODEV) {
> -			usb_clear_port_feature(hub->hdev, port1,
> +			if (status)
> +				usb_clear_port_feature(hub->hdev, port1,
>  					USB_PORT_FEAT_C_RESET);

What is the reason for this change?  Clearing the USB_PORT_FEAT_C_RESET 
bit won't cause any problems.

>  			if (!hub_is_superspeed(hub->hdev))
>  				goto done;
>  
> -			usb_clear_port_feature(hub->hdev, port1,
> +			if (status) {
> +				usb_clear_port_feature(hub->hdev, port1,
>  					USB_PORT_FEAT_C_BH_PORT_RESET);

And what is the reason for this change?

> -			usb_clear_port_feature(hub->hdev, port1,
> +				usb_clear_port_feature(hub->hdev, port1,
>  					USB_PORT_FEAT_C_PORT_LINK_STATE);
> -			usb_clear_port_feature(hub->hdev, port1,
> +				usb_clear_port_feature(hub->hdev, port1,
>  					USB_PORT_FEAT_C_CONNECTION);
> +			}

I'm not so sure about these changes.  The bits definitely do need to be 
cleared at some point, but this may not be the right place to clear 
them.  Or maybe we need to check that the port is still enabled after 
the bits have been cleared.

You need to think more carefully about this patch.

Alan Stern


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2015-09-01 14:14 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-09-01  7:31 [PATCH] usb: core: Fix side effect of clear port feature in hub port reset hyunho747.kim
2015-09-01 14:14 ` Alan Stern

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).