Linux-USB Archive on lore.kernel.org
 help / color / Atom feed
* [PATCH 0/1] usb: chipidea: fixes for v5.2
@ 2019-06-17  1:49 Peter Chen
  2019-06-17  1:49 ` [PATCH 1/1] usb: chipidea: udc: workaround for endpoint conflict issue Peter Chen
  0 siblings, 1 reply; 9+ messages in thread
From: Peter Chen @ 2019-06-17  1:49 UTC (permalink / raw)
  To: gregkh; +Cc: linux-usb, Peter Chen

Hi Greg,

We have found an IP bug recently, it will cause the audio device
stop working at the HUB downstream face port, and the commit can
reduce the possibilities for failures, needs to improve RTL code
to fix it totally.

Peter Chen (1):
  usb: chipidea: udc: workaround for endpoint conflict issue

 drivers/usb/chipidea/udc.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

-- 
2.14.1


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

* [PATCH 1/1] usb: chipidea: udc: workaround for endpoint conflict issue
  2019-06-17  1:49 [PATCH 0/1] usb: chipidea: fixes for v5.2 Peter Chen
@ 2019-06-17  1:49 ` Peter Chen
  0 siblings, 0 replies; 9+ messages in thread
From: Peter Chen @ 2019-06-17  1:49 UTC (permalink / raw)
  To: gregkh
  Cc: linux-usb, Peter Chen, stable, Fabio Estevam, Sergei Shtylyov, Jun Li

An endpoint conflict occurs when the USB is working in device mode
during an isochronous communication. When the endpointA IN direction
is an isochronous IN endpoint, and the host sends an IN token to
endpointA on another device, then the OUT transaction may be missed
regardless the OUT endpoint number. Generally, this occurs when the
device is connected to the host through a hub and other devices are
connected to the same hub.

The affected OUT endpoint can be either control, bulk, isochronous, or
an interrupt endpoint. After the OUT endpoint is primed, if an IN token
to the same endpoint number on another device is received, then the OUT
endpoint may be unprimed (cannot be detected by software), which causes
this endpoint to no longer respond to the host OUT token, and thus, no
corresponding interrupt occurs.

There is no good workaround for this issue, the only thing the software
could do is numbering isochronous IN from the highest endpoint since we
have observed most of device number endpoint from the lowest.

Cc: <stable@vger.kernel.org> #v3.14+
Cc: Fabio Estevam <festevam@gmail.com>
Cc: Greg KH <gregkh@linuxfoundation.org>
Cc: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
Cc: Jun Li <jun.li@nxp.com>
Signed-off-by: Peter Chen <peter.chen@nxp.com>
---
 drivers/usb/chipidea/udc.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
index 829e947cabf5..6a5ee8e6da10 100644
--- a/drivers/usb/chipidea/udc.c
+++ b/drivers/usb/chipidea/udc.c
@@ -1622,6 +1622,25 @@ static int ci_udc_pullup(struct usb_gadget *_gadget, int is_on)
 static int ci_udc_start(struct usb_gadget *gadget,
 			 struct usb_gadget_driver *driver);
 static int ci_udc_stop(struct usb_gadget *gadget);
+
+/* Match ISOC IN from the highest endpoint */
+static struct usb_ep *ci_udc_match_ep(struct usb_gadget *gadget,
+			      struct usb_endpoint_descriptor *desc,
+			      struct usb_ss_ep_comp_descriptor *comp_desc)
+{
+	struct ci_hdrc *ci = container_of(gadget, struct ci_hdrc, gadget);
+	struct usb_ep *ep;
+
+	if (usb_endpoint_xfer_isoc(desc) && usb_endpoint_dir_in(desc)) {
+		list_for_each_entry_reverse(ep, &ci->gadget.ep_list, ep_list) {
+			if (ep->caps.dir_in && !ep->claimed)
+				return ep;
+		}
+	}
+
+	return NULL;
+}
+
 /**
  * Device operations part of the API to the USB controller hardware,
  * which don't involve endpoints (or i/o)
@@ -1635,6 +1654,7 @@ static const struct usb_gadget_ops usb_gadget_ops = {
 	.vbus_draw	= ci_udc_vbus_draw,
 	.udc_start	= ci_udc_start,
 	.udc_stop	= ci_udc_stop,
+	.match_ep 	= ci_udc_match_ep,
 };
 
 static int init_eps(struct ci_hdrc *ci)
-- 
2.14.1


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

* RE: [PATCH 1/1] usb: chipidea: udc: workaround for endpoint conflict issue
  2019-05-30  8:22 ` Sergei Shtylyov
@ 2019-05-30  8:48   ` Peter Chen
  0 siblings, 0 replies; 9+ messages in thread
From: Peter Chen @ 2019-05-30  8:48 UTC (permalink / raw)
  To: Sergei Shtylyov, linux-usb; +Cc: dl-linux-imx, stable, Jun Li

 
> On 30.05.2019 9:45, Peter Chen wrote:
> 
> > An endpoint conflict occurs when the USB is working in device mode
> > during an isochronous communication. When the endpointA IN direction
> > is an isochronous IN endpoint, and the host sends an IN token to
> > endpointA on another device, then the OUT transaction may be missed
> > regardless the OUT endpoint number. Generally, this occurs when the
> > device is connected to the host through a hub and other devices are
> > connected to the same hub.
> >
> > The affected OUT endpoint can be either control, bulk, isochronous, or
> > an interrupt endpoint. After the OUT endpoint is primed, if an IN
> > token to the same endpoint number on another device is received, then
> > the OUT endpoint may be unprimed (cannot be detected by software),
> > which causes this endpoint to no longer respond to the host OUT token,
> > and thus, no corresponding interrupt occurs.
> >
> > There is no good workaround for this issue, the only thing the
> > software could do is numbering isochronous IN from the highest
> > endpoint since we have observed most of device number endpoint from the
> lowest.
> >
> > Cc: <stable@vger.kernel.org> #v3.14+
> > Cc: Jun Li <jun.li@nxp.com>
> > Signed-off-by: Peter Chen <peter.chen@nxp.com>
> > ---
> > Changes for v2:
> > - Some coding style improvements
> 
>     Nothing really changed in the patch... :-/
> 
> >   drivers/usb/chipidea/udc.c | 24 ++++++++++++++++++++++++
> >   1 file changed, 24 insertions(+)
> >
> > diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
> > index 829e947cabf5..411d387a45c9 100644
> > --- a/drivers/usb/chipidea/udc.c
> > +++ b/drivers/usb/chipidea/udc.c
> > @@ -1622,6 +1622,29 @@ static int ci_udc_pullup(struct usb_gadget *_gadget,
> int is_on)
> >   static int ci_udc_start(struct usb_gadget *gadget,
> >   			 struct usb_gadget_driver *driver);
> >   static int ci_udc_stop(struct usb_gadget *gadget);
> > +
> > +
> > +/* Match ISOC IN from the highest endpoint */ static struct usb_ep
> > +*ci_udc_match_ep(struct usb_gadget *gadget,
> 
>     Here...
> 
> > +			      struct usb_endpoint_descriptor *desc,
> > +			      struct usb_ss_ep_comp_descriptor *comp_desc) {
> > +	struct ci_hdrc *ci = container_of(gadget, struct ci_hdrc, gadget);
> > +	struct usb_ep *ep;
> > +	u8 type = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
> > +
> > +	if ((type == USB_ENDPOINT_XFER_ISOC) &&
> > +		(desc->bEndpointAddress & USB_DIR_IN)) {
> 
>     ... and here.
> 
> > +		list_for_each_entry_reverse(ep, &ci->gadget.ep_list, ep_list) {
> > +			if (ep->caps.dir_in && !ep->claimed)
> > +				return ep;
> > +		}
> > +	}
> > +
> > +	return NULL;
> > +}
> > +
> >   /**
> >    * Device operations part of the API to the USB controller hardware,
> >    * which don't involve endpoints (or i/o)
> [...]
> 

Oops. I used the former patch file. sorry about that.

Peter

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

* Re: [PATCH 1/1] usb: chipidea: udc: workaround for endpoint conflict issue
  2019-05-30  6:45 Peter Chen
@ 2019-05-30  8:22 ` Sergei Shtylyov
  2019-05-30  8:48   ` Peter Chen
  0 siblings, 1 reply; 9+ messages in thread
From: Sergei Shtylyov @ 2019-05-30  8:22 UTC (permalink / raw)
  To: Peter Chen, linux-usb; +Cc: linux-imx, stable, Jun Li

Hello!

On 30.05.2019 9:45, Peter Chen wrote:

> An endpoint conflict occurs when the USB is working in device mode
> during an isochronous communication. When the endpointA IN direction
> is an isochronous IN endpoint, and the host sends an IN token to
> endpointA on another device, then the OUT transaction may be missed
> regardless the OUT endpoint number. Generally, this occurs when the
> device is connected to the host through a hub and other devices are
> connected to the same hub.
> 
> The affected OUT endpoint can be either control, bulk, isochronous, or
> an interrupt endpoint. After the OUT endpoint is primed, if an IN token
> to the same endpoint number on another device is received, then the OUT
> endpoint may be unprimed (cannot be detected by software), which causes
> this endpoint to no longer respond to the host OUT token, and thus, no
> corresponding interrupt occurs.
> 
> There is no good workaround for this issue, the only thing the software
> could do is numbering isochronous IN from the highest endpoint since we
> have observed most of device number endpoint from the lowest.
> 
> Cc: <stable@vger.kernel.org> #v3.14+
> Cc: Jun Li <jun.li@nxp.com>
> Signed-off-by: Peter Chen <peter.chen@nxp.com>
> ---
> Changes for v2:
> - Some coding style improvements

    Nothing really changed in the patch... :-/

>   drivers/usb/chipidea/udc.c | 24 ++++++++++++++++++++++++
>   1 file changed, 24 insertions(+)
> 
> diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
> index 829e947cabf5..411d387a45c9 100644
> --- a/drivers/usb/chipidea/udc.c
> +++ b/drivers/usb/chipidea/udc.c
> @@ -1622,6 +1622,29 @@ static int ci_udc_pullup(struct usb_gadget *_gadget, int is_on)
>   static int ci_udc_start(struct usb_gadget *gadget,
>   			 struct usb_gadget_driver *driver);
>   static int ci_udc_stop(struct usb_gadget *gadget);
> +
> +
> +/* Match ISOC IN from the highest endpoint */
> +static struct
> +usb_ep *ci_udc_match_ep(struct usb_gadget *gadget,

    Here...

> +			      struct usb_endpoint_descriptor *desc,
> +			      struct usb_ss_ep_comp_descriptor *comp_desc)
> +{
> +	struct ci_hdrc *ci = container_of(gadget, struct ci_hdrc, gadget);
> +	struct usb_ep *ep;
> +	u8 type = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
> +
> +	if ((type == USB_ENDPOINT_XFER_ISOC) &&
> +		(desc->bEndpointAddress & USB_DIR_IN)) {

    ... and here.

> +		list_for_each_entry_reverse(ep, &ci->gadget.ep_list, ep_list) {
> +			if (ep->caps.dir_in && !ep->claimed)
> +				return ep;
> +		}
> +	}
> +
> +	return NULL;
> +}
> +
>   /**
>    * Device operations part of the API to the USB controller hardware,
>    * which don't involve endpoints (or i/o)
[...]

MBR, Sergei

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

* [PATCH 1/1] usb: chipidea: udc: workaround for endpoint conflict issue
@ 2019-05-30  6:45 Peter Chen
  2019-05-30  8:22 ` Sergei Shtylyov
  0 siblings, 1 reply; 9+ messages in thread
From: Peter Chen @ 2019-05-30  6:45 UTC (permalink / raw)
  To: linux-usb; +Cc: linux-imx, Peter Chen, stable, Jun Li

An endpoint conflict occurs when the USB is working in device mode
during an isochronous communication. When the endpointA IN direction
is an isochronous IN endpoint, and the host sends an IN token to
endpointA on another device, then the OUT transaction may be missed
regardless the OUT endpoint number. Generally, this occurs when the
device is connected to the host through a hub and other devices are
connected to the same hub.

The affected OUT endpoint can be either control, bulk, isochronous, or
an interrupt endpoint. After the OUT endpoint is primed, if an IN token
to the same endpoint number on another device is received, then the OUT
endpoint may be unprimed (cannot be detected by software), which causes
this endpoint to no longer respond to the host OUT token, and thus, no
corresponding interrupt occurs.

There is no good workaround for this issue, the only thing the software
could do is numbering isochronous IN from the highest endpoint since we
have observed most of device number endpoint from the lowest.

Cc: <stable@vger.kernel.org> #v3.14+
Cc: Jun Li <jun.li@nxp.com>
Signed-off-by: Peter Chen <peter.chen@nxp.com>
---
Changes for v2:
- Some coding style improvements

 drivers/usb/chipidea/udc.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
index 829e947cabf5..411d387a45c9 100644
--- a/drivers/usb/chipidea/udc.c
+++ b/drivers/usb/chipidea/udc.c
@@ -1622,6 +1622,29 @@ static int ci_udc_pullup(struct usb_gadget *_gadget, int is_on)
 static int ci_udc_start(struct usb_gadget *gadget,
 			 struct usb_gadget_driver *driver);
 static int ci_udc_stop(struct usb_gadget *gadget);
+
+
+/* Match ISOC IN from the highest endpoint */
+static struct
+usb_ep *ci_udc_match_ep(struct usb_gadget *gadget,
+			      struct usb_endpoint_descriptor *desc,
+			      struct usb_ss_ep_comp_descriptor *comp_desc)
+{
+	struct ci_hdrc *ci = container_of(gadget, struct ci_hdrc, gadget);
+	struct usb_ep *ep;
+	u8 type = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
+
+	if ((type == USB_ENDPOINT_XFER_ISOC) &&
+		(desc->bEndpointAddress & USB_DIR_IN)) {
+		list_for_each_entry_reverse(ep, &ci->gadget.ep_list, ep_list) {
+			if (ep->caps.dir_in && !ep->claimed)
+				return ep;
+		}
+	}
+
+	return NULL;
+}
+
 /**
  * Device operations part of the API to the USB controller hardware,
  * which don't involve endpoints (or i/o)
@@ -1635,6 +1658,7 @@ static const struct usb_gadget_ops usb_gadget_ops = {
 	.vbus_draw	= ci_udc_vbus_draw,
 	.udc_start	= ci_udc_start,
 	.udc_stop	= ci_udc_stop,
+	.match_ep	= ci_udc_match_ep,
 };
 
 static int init_eps(struct ci_hdrc *ci)
-- 
2.14.1


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

* Re: [PATCH 1/1] usb: chipidea: udc: workaround for endpoint conflict issue
  2019-05-27  9:44   ` Peter Chen
@ 2019-05-27 11:49     ` Sergei Shtylyov
  0 siblings, 0 replies; 9+ messages in thread
From: Sergei Shtylyov @ 2019-05-27 11:49 UTC (permalink / raw)
  To: Peter Chen; +Cc: Peter Chen, linux-usb, linux-imx, stable, Jun Li

On 27.05.2019 12:44, Peter Chen wrote:

>>> An endpoint conflict occurs when the USB is working in device mode
>>> during an isochronous communication. When the endpointA IN direction
>>> is an isochronous IN endpoint, and the host sends an IN token to
>>> endpointA on another device, then the OUT transaction may be missed
>>> regardless the OUT endpoint number. Generally, this occurs when the
>>> device is connected to the host through a hub and other devices are
>>> connected to the same hub.
>>>
>>> The affected OUT endpoint can be either control, bulk, isochronous, or
>>> an interrupt endpoint. After the OUT endpoint is primed, if an IN token
>>> to the same endpoint number on another device is received, then the OUT
>>> endpoint may be unprimed (cannot be detected by software), which causes
>>> this endpoint to no longer respond to the host OUT token, and thus, no
>>> corresponding interrupt occurs.
>>>
>>> There is no good workaround for this issue, the only thing the software
>>> could do is numbering isochronous IN from the highest endpoint since we
>>> have observed most of device number endpoint from the lowest.
>>>
>>> Cc: <stable@vger.kernel.org> #v3.14+
>>> Cc: Jun Li <jun.li@nxp.com>
>>> Signed-off-by: Peter Chen <peter.chen@nxp.com>
>>> ---
>>>    drivers/usb/chipidea/udc.c | 24 ++++++++++++++++++++++++
>>>    1 file changed, 24 insertions(+)
>>>
>>> diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
>>> index 829e947cabf5..411d387a45c9 100644
>>> --- a/drivers/usb/chipidea/udc.c
>>> +++ b/drivers/usb/chipidea/udc.c
>>> @@ -1622,6 +1622,29 @@ static int ci_udc_pullup(struct usb_gadget *_gadget, int is_on)
>>>    static int ci_udc_start(struct usb_gadget *gadget,
>>>                         struct usb_gadget_driver *driver);
>>>    static int ci_udc_stop(struct usb_gadget *gadget);
>>> +
>>> +
>>> +/* Match ISOC IN from the highest endpoint */
>>> +static struct
>>
>>      Um, please break the line before the function's type is fully described.

    Mm, I meant to type "after". :-)

>>
>>> +usb_ep *ci_udc_match_ep(struct usb_gadget *gadget,
>>> +                           struct usb_endpoint_descriptor *desc,
>>> +                           struct usb_ss_ep_comp_descriptor *comp_desc)
>>> +{
>>> +     struct ci_hdrc *ci = container_of(gadget, struct ci_hdrc, gadget);
>>> +     struct usb_ep *ep;
>>> +     u8 type = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
>>> +
>>> +     if ((type == USB_ENDPOINT_XFER_ISOC) &&
>>> +             (desc->bEndpointAddress & USB_DIR_IN)) {
>>
>>      Please add 1 more tab here, so that this line doesn't blend with the
>> following statement.
>>
>>> +             list_for_each_entry_reverse(ep, &ci->gadget.ep_list, ep_list) {
>>> +                     if (ep->caps.dir_in && !ep->claimed)
>>> +                             return ep;
>>> +             }
>>> +     }
>>> +
>>> +     return NULL;
>>> +}
>>> +
>>>    /**
>>>     * Device operations part of the API to the USB controller hardware,
>>>     * which don't involve endpoints (or i/o)
> 
> Will change both comments, thanks.

    TIA.

> Peter

MBR, Sergei

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

* Re: [PATCH 1/1] usb: chipidea: udc: workaround for endpoint conflict issue
  2019-05-27  9:02 ` Sergei Shtylyov
@ 2019-05-27  9:44   ` Peter Chen
  2019-05-27 11:49     ` Sergei Shtylyov
  0 siblings, 1 reply; 9+ messages in thread
From: Peter Chen @ 2019-05-27  9:44 UTC (permalink / raw)
  To: Sergei Shtylyov; +Cc: Peter Chen, linux-usb, linux-imx, stable, Jun Li

On Mon, May 27, 2019 at 5:04 PM Sergei Shtylyov
<sergei.shtylyov@cogentembedded.com> wrote:
>
> On 27.05.2019 10:42, Peter Chen wrote:
>
> > An endpoint conflict occurs when the USB is working in device mode
> > during an isochronous communication. When the endpointA IN direction
> > is an isochronous IN endpoint, and the host sends an IN token to
> > endpointA on another device, then the OUT transaction may be missed
> > regardless the OUT endpoint number. Generally, this occurs when the
> > device is connected to the host through a hub and other devices are
> > connected to the same hub.
> >
> > The affected OUT endpoint can be either control, bulk, isochronous, or
> > an interrupt endpoint. After the OUT endpoint is primed, if an IN token
> > to the same endpoint number on another device is received, then the OUT
> > endpoint may be unprimed (cannot be detected by software), which causes
> > this endpoint to no longer respond to the host OUT token, and thus, no
> > corresponding interrupt occurs.
> >
> > There is no good workaround for this issue, the only thing the software
> > could do is numbering isochronous IN from the highest endpoint since we
> > have observed most of device number endpoint from the lowest.
> >
> > Cc: <stable@vger.kernel.org> #v3.14+
> > Cc: Jun Li <jun.li@nxp.com>
> > Signed-off-by: Peter Chen <peter.chen@nxp.com>
> > ---
> >   drivers/usb/chipidea/udc.c | 24 ++++++++++++++++++++++++
> >   1 file changed, 24 insertions(+)
> >
> > diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
> > index 829e947cabf5..411d387a45c9 100644
> > --- a/drivers/usb/chipidea/udc.c
> > +++ b/drivers/usb/chipidea/udc.c
> > @@ -1622,6 +1622,29 @@ static int ci_udc_pullup(struct usb_gadget *_gadget, int is_on)
> >   static int ci_udc_start(struct usb_gadget *gadget,
> >                        struct usb_gadget_driver *driver);
> >   static int ci_udc_stop(struct usb_gadget *gadget);
> > +
> > +
> > +/* Match ISOC IN from the highest endpoint */
> > +static struct
>
>     Um, please break the line before the function's type is fully described.
>
> > +usb_ep *ci_udc_match_ep(struct usb_gadget *gadget,
> > +                           struct usb_endpoint_descriptor *desc,
> > +                           struct usb_ss_ep_comp_descriptor *comp_desc)
> > +{
> > +     struct ci_hdrc *ci = container_of(gadget, struct ci_hdrc, gadget);
> > +     struct usb_ep *ep;
> > +     u8 type = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
> > +
> > +     if ((type == USB_ENDPOINT_XFER_ISOC) &&
> > +             (desc->bEndpointAddress & USB_DIR_IN)) {
>
>     Please add 1 more tab here, so that this line doesn't blend with the
> following statement.
>
> > +             list_for_each_entry_reverse(ep, &ci->gadget.ep_list, ep_list) {
> > +                     if (ep->caps.dir_in && !ep->claimed)
> > +                             return ep;
> > +             }
> > +     }
> > +
> > +     return NULL;
> > +}
> > +
> >   /**
> >    * Device operations part of the API to the USB controller hardware,
> >    * which don't involve endpoints (or i/o)

Will change both comments, thanks.

Peter

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

* Re: [PATCH 1/1] usb: chipidea: udc: workaround for endpoint conflict issue
  2019-05-27  7:42 Peter Chen
@ 2019-05-27  9:02 ` Sergei Shtylyov
  2019-05-27  9:44   ` Peter Chen
  0 siblings, 1 reply; 9+ messages in thread
From: Sergei Shtylyov @ 2019-05-27  9:02 UTC (permalink / raw)
  To: Peter Chen, linux-usb; +Cc: linux-imx, stable, Jun Li

On 27.05.2019 10:42, Peter Chen wrote:

> An endpoint conflict occurs when the USB is working in device mode
> during an isochronous communication. When the endpointA IN direction
> is an isochronous IN endpoint, and the host sends an IN token to
> endpointA on another device, then the OUT transaction may be missed
> regardless the OUT endpoint number. Generally, this occurs when the
> device is connected to the host through a hub and other devices are
> connected to the same hub.
> 
> The affected OUT endpoint can be either control, bulk, isochronous, or
> an interrupt endpoint. After the OUT endpoint is primed, if an IN token
> to the same endpoint number on another device is received, then the OUT
> endpoint may be unprimed (cannot be detected by software), which causes
> this endpoint to no longer respond to the host OUT token, and thus, no
> corresponding interrupt occurs.
> 
> There is no good workaround for this issue, the only thing the software
> could do is numbering isochronous IN from the highest endpoint since we
> have observed most of device number endpoint from the lowest.
> 
> Cc: <stable@vger.kernel.org> #v3.14+
> Cc: Jun Li <jun.li@nxp.com>
> Signed-off-by: Peter Chen <peter.chen@nxp.com>
> ---
>   drivers/usb/chipidea/udc.c | 24 ++++++++++++++++++++++++
>   1 file changed, 24 insertions(+)
> 
> diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
> index 829e947cabf5..411d387a45c9 100644
> --- a/drivers/usb/chipidea/udc.c
> +++ b/drivers/usb/chipidea/udc.c
> @@ -1622,6 +1622,29 @@ static int ci_udc_pullup(struct usb_gadget *_gadget, int is_on)
>   static int ci_udc_start(struct usb_gadget *gadget,
>   			 struct usb_gadget_driver *driver);
>   static int ci_udc_stop(struct usb_gadget *gadget);
> +
> +
> +/* Match ISOC IN from the highest endpoint */
> +static struct

    Um, please break the line before the function's type is fully described.

> +usb_ep *ci_udc_match_ep(struct usb_gadget *gadget,
> +			      struct usb_endpoint_descriptor *desc,
> +			      struct usb_ss_ep_comp_descriptor *comp_desc)
> +{
> +	struct ci_hdrc *ci = container_of(gadget, struct ci_hdrc, gadget);
> +	struct usb_ep *ep;
> +	u8 type = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
> +
> +	if ((type == USB_ENDPOINT_XFER_ISOC) &&
> +		(desc->bEndpointAddress & USB_DIR_IN)) {

    Please add 1 more tab here, so that this line doesn't blend with the 
following statement.

> +		list_for_each_entry_reverse(ep, &ci->gadget.ep_list, ep_list) {
> +			if (ep->caps.dir_in && !ep->claimed)
> +				return ep;
> +		}
> +	}
> +
> +	return NULL;
> +}
> +
>   /**
>    * Device operations part of the API to the USB controller hardware,
>    * which don't involve endpoints (or i/o)
[...]

MBR, Sergei

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

* [PATCH 1/1] usb: chipidea: udc: workaround for endpoint conflict issue
@ 2019-05-27  7:42 Peter Chen
  2019-05-27  9:02 ` Sergei Shtylyov
  0 siblings, 1 reply; 9+ messages in thread
From: Peter Chen @ 2019-05-27  7:42 UTC (permalink / raw)
  To: linux-usb; +Cc: linux-imx, Peter Chen, stable, Jun Li

An endpoint conflict occurs when the USB is working in device mode
during an isochronous communication. When the endpointA IN direction
is an isochronous IN endpoint, and the host sends an IN token to
endpointA on another device, then the OUT transaction may be missed
regardless the OUT endpoint number. Generally, this occurs when the
device is connected to the host through a hub and other devices are
connected to the same hub.

The affected OUT endpoint can be either control, bulk, isochronous, or
an interrupt endpoint. After the OUT endpoint is primed, if an IN token
to the same endpoint number on another device is received, then the OUT
endpoint may be unprimed (cannot be detected by software), which causes
this endpoint to no longer respond to the host OUT token, and thus, no
corresponding interrupt occurs.

There is no good workaround for this issue, the only thing the software
could do is numbering isochronous IN from the highest endpoint since we
have observed most of device number endpoint from the lowest.

Cc: <stable@vger.kernel.org> #v3.14+
Cc: Jun Li <jun.li@nxp.com>
Signed-off-by: Peter Chen <peter.chen@nxp.com>
---
 drivers/usb/chipidea/udc.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
index 829e947cabf5..411d387a45c9 100644
--- a/drivers/usb/chipidea/udc.c
+++ b/drivers/usb/chipidea/udc.c
@@ -1622,6 +1622,29 @@ static int ci_udc_pullup(struct usb_gadget *_gadget, int is_on)
 static int ci_udc_start(struct usb_gadget *gadget,
 			 struct usb_gadget_driver *driver);
 static int ci_udc_stop(struct usb_gadget *gadget);
+
+
+/* Match ISOC IN from the highest endpoint */
+static struct
+usb_ep *ci_udc_match_ep(struct usb_gadget *gadget,
+			      struct usb_endpoint_descriptor *desc,
+			      struct usb_ss_ep_comp_descriptor *comp_desc)
+{
+	struct ci_hdrc *ci = container_of(gadget, struct ci_hdrc, gadget);
+	struct usb_ep *ep;
+	u8 type = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
+
+	if ((type == USB_ENDPOINT_XFER_ISOC) &&
+		(desc->bEndpointAddress & USB_DIR_IN)) {
+		list_for_each_entry_reverse(ep, &ci->gadget.ep_list, ep_list) {
+			if (ep->caps.dir_in && !ep->claimed)
+				return ep;
+		}
+	}
+
+	return NULL;
+}
+
 /**
  * Device operations part of the API to the USB controller hardware,
  * which don't involve endpoints (or i/o)
@@ -1635,6 +1658,7 @@ static const struct usb_gadget_ops usb_gadget_ops = {
 	.vbus_draw	= ci_udc_vbus_draw,
 	.udc_start	= ci_udc_start,
 	.udc_stop	= ci_udc_stop,
+	.match_ep	= ci_udc_match_ep,
 };
 
 static int init_eps(struct ci_hdrc *ci)
-- 
2.14.1


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

end of thread, back to index

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-06-17  1:49 [PATCH 0/1] usb: chipidea: fixes for v5.2 Peter Chen
2019-06-17  1:49 ` [PATCH 1/1] usb: chipidea: udc: workaround for endpoint conflict issue Peter Chen
  -- strict thread matches above, loose matches on Subject: below --
2019-05-30  6:45 Peter Chen
2019-05-30  8:22 ` Sergei Shtylyov
2019-05-30  8:48   ` Peter Chen
2019-05-27  7:42 Peter Chen
2019-05-27  9:02 ` Sergei Shtylyov
2019-05-27  9:44   ` Peter Chen
2019-05-27 11:49     ` Sergei Shtylyov

Linux-USB Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-usb/0 linux-usb/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-usb linux-usb/ https://lore.kernel.org/linux-usb \
		linux-usb@vger.kernel.org linux-usb@archiver.kernel.org
	public-inbox-index linux-usb


Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-usb


AGPL code for this site: git clone https://public-inbox.org/ public-inbox