public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] usb: core: Fix bandwidth for devices with invalid wBytesPerInterval
@ 2026-04-02  2:14 Tao Xue
  2026-04-02  2:45 ` Alan Stern
                   ` (2 more replies)
  0 siblings, 3 replies; 14+ messages in thread
From: Tao Xue @ 2026-04-02  2:14 UTC (permalink / raw)
  To: gregkh; +Cc: linux-usb, linux-kernel, caiyadong, Tao Xue, stable

As specified in Section 4.14.2 of the xHCI Specification, the xHC
reserves bandwidth for periodic endpoints according to bInterval and
wBytesPerInterval (Max ESIT Payload).

Some peripherals report an invalid wBytesPerInterval in their device
descriptor, which is either 0 or smaller than the actual data length
transmitted. This issue is observed on ASIX AX88179 series USB 3.0
Ethernet adapters.

These errors may lead to unexpected behavior on certain USB host
controllers, causing USB peripherals to malfunction.

To address the issue, return max(wBytesPerInterval, max_payload) when
calculating bandwidth reservation.

Fixes: 9238f25d5d32 ("USB: xhci: properly set endpoint context fields for periodic eps.")
Cc: <stable@kernel.org>
Signed-off-by: Tao Xue <xuetao09@huawei.com>
---
 drivers/usb/core/usb.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index e9a10a33534c..8f2e05a5a015 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -1125,6 +1125,8 @@ EXPORT_SYMBOL_GPL(usb_free_noncoherent);
 u32 usb_endpoint_max_periodic_payload(struct usb_device *udev,
 				      const struct usb_host_endpoint *ep)
 {
+	u32 max_payload;
+
 	if (!usb_endpoint_xfer_isoc(&ep->desc) &&
 	    !usb_endpoint_xfer_int(&ep->desc))
 		return 0;
@@ -1135,7 +1137,12 @@ u32 usb_endpoint_max_periodic_payload(struct usb_device *udev,
 			return le32_to_cpu(ep->ssp_isoc_ep_comp.dwBytesPerInterval);
 		fallthrough;
 	case USB_SPEED_SUPER:
-		return le16_to_cpu(ep->ss_ep_comp.wBytesPerInterval);
+		max_payload = usb_endpoint_maxp(&ep->desc) * (ep->ss_ep_comp.bMaxBurst + 1);
+		if (usb_endpoint_xfer_isoc(&ep->desc))
+			return max_t(u32, max_payload * USB_SS_MULT(ep->ss_ep_comp.bmAttributes),
+					ep->ss_ep_comp.wBytesPerInterval);
+		else
+			return max_t(u32, max_payload, ep->ss_ep_comp.wBytesPerInterval);
 	default:
 		if (usb_endpoint_is_hs_isoc_double(udev, ep))
 			return le32_to_cpu(ep->eusb2_isoc_ep_comp.dwBytesPerInterval);
-- 
2.17.1


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

* Re: [PATCH] usb: core: Fix bandwidth for devices with invalid wBytesPerInterval
  2026-04-02  2:14 [PATCH] usb: core: Fix bandwidth for devices with invalid wBytesPerInterval Tao Xue
@ 2026-04-02  2:45 ` Alan Stern
  2026-04-02  3:51 ` Greg KH
  2026-04-02  9:44 ` Michal Pecio
  2 siblings, 0 replies; 14+ messages in thread
From: Alan Stern @ 2026-04-02  2:45 UTC (permalink / raw)
  To: Tao Xue; +Cc: gregkh, linux-usb, linux-kernel, caiyadong, stable

On Thu, Apr 02, 2026 at 10:14:00AM +0800, Tao Xue wrote:
> As specified in Section 4.14.2 of the xHCI Specification, the xHC
> reserves bandwidth for periodic endpoints according to bInterval and
> wBytesPerInterval (Max ESIT Payload).
> 
> Some peripherals report an invalid wBytesPerInterval in their device
> descriptor, which is either 0 or smaller than the actual data length
> transmitted. This issue is observed on ASIX AX88179 series USB 3.0
> Ethernet adapters.

Do we log these invalid values when we parse the endpoint and their 
companion descriptors?  We should -- and we can fix up any errors then, 
just once.

Alan Stern

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

* Re: [PATCH] usb: core: Fix bandwidth for devices with invalid wBytesPerInterval
  2026-04-02  2:14 [PATCH] usb: core: Fix bandwidth for devices with invalid wBytesPerInterval Tao Xue
  2026-04-02  2:45 ` Alan Stern
@ 2026-04-02  3:51 ` Greg KH
  2026-04-02  6:59   ` Xuetao (kirin)
  2026-04-02  9:44 ` Michal Pecio
  2 siblings, 1 reply; 14+ messages in thread
From: Greg KH @ 2026-04-02  3:51 UTC (permalink / raw)
  To: Tao Xue; +Cc: linux-usb, linux-kernel, caiyadong, stable

On Thu, Apr 02, 2026 at 10:14:00AM +0800, Tao Xue wrote:
> As specified in Section 4.14.2 of the xHCI Specification, the xHC
> reserves bandwidth for periodic endpoints according to bInterval and
> wBytesPerInterval (Max ESIT Payload).
> 
> Some peripherals report an invalid wBytesPerInterval in their device
> descriptor, which is either 0 or smaller than the actual data length
> transmitted. This issue is observed on ASIX AX88179 series USB 3.0
> Ethernet adapters.
> 
> These errors may lead to unexpected behavior on certain USB host
> controllers, causing USB peripherals to malfunction.
> 
> To address the issue, return max(wBytesPerInterval, max_payload) when
> calculating bandwidth reservation.
> 
> Fixes: 9238f25d5d32 ("USB: xhci: properly set endpoint context fields for periodic eps.")
> Cc: <stable@kernel.org>
> Signed-off-by: Tao Xue <xuetao09@huawei.com>
> ---
>  drivers/usb/core/usb.c | 9 ++++++++-
>  1 file changed, 8 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
> index e9a10a33534c..8f2e05a5a015 100644
> --- a/drivers/usb/core/usb.c
> +++ b/drivers/usb/core/usb.c
> @@ -1125,6 +1125,8 @@ EXPORT_SYMBOL_GPL(usb_free_noncoherent);
>  u32 usb_endpoint_max_periodic_payload(struct usb_device *udev,
>  				      const struct usb_host_endpoint *ep)
>  {
> +	u32 max_payload;
> +
>  	if (!usb_endpoint_xfer_isoc(&ep->desc) &&
>  	    !usb_endpoint_xfer_int(&ep->desc))
>  		return 0;
> @@ -1135,7 +1137,12 @@ u32 usb_endpoint_max_periodic_payload(struct usb_device *udev,
>  			return le32_to_cpu(ep->ssp_isoc_ep_comp.dwBytesPerInterval);
>  		fallthrough;
>  	case USB_SPEED_SUPER:
> -		return le16_to_cpu(ep->ss_ep_comp.wBytesPerInterval);
> +		max_payload = usb_endpoint_maxp(&ep->desc) * (ep->ss_ep_comp.bMaxBurst + 1);
> +		if (usb_endpoint_xfer_isoc(&ep->desc))
> +			return max_t(u32, max_payload * USB_SS_MULT(ep->ss_ep_comp.bmAttributes),
> +					ep->ss_ep_comp.wBytesPerInterval);
> +		else
> +			return max_t(u32, max_payload, ep->ss_ep_comp.wBytesPerInterval);

You dropped the conversion from le16 to cpu?  Why?

thanks,

greg k-h

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

* Re: [PATCH] usb: core: Fix bandwidth for devices with invalid wBytesPerInterval
  2026-04-02  3:51 ` Greg KH
@ 2026-04-02  6:59   ` Xuetao (kirin)
  2026-04-02  7:10     ` Greg KH
  2026-04-02 13:56     ` Alan Stern
  0 siblings, 2 replies; 14+ messages in thread
From: Xuetao (kirin) @ 2026-04-02  6:59 UTC (permalink / raw)
  To: Greg KH; +Cc: linux-usb, linux-kernel, caiyadong, stable, stern



在 2026/4/2 11:51, Greg KH 写道:
> On Thu, Apr 02, 2026 at 10:14:00AM +0800, Tao Xue wrote:
>> As specified in Section 4.14.2 of the xHCI Specification, the xHC
>> reserves bandwidth for periodic endpoints according to bInterval and
>> wBytesPerInterval (Max ESIT Payload).
>>
>> Some peripherals report an invalid wBytesPerInterval in their device
>> descriptor, which is either 0 or smaller than the actual data length
>> transmitted. This issue is observed on ASIX AX88179 series USB 3.0
>> Ethernet adapters.
>>
>> These errors may lead to unexpected behavior on certain USB host
>> controllers, causing USB peripherals to malfunction.
>>
>> To address the issue, return max(wBytesPerInterval, max_payload) when
>> calculating bandwidth reservation.
>>
>> Fixes: 9238f25d5d32 ("USB: xhci: properly set endpoint context fields for periodic eps.")
>> Cc: <stable@kernel.org>
>> Signed-off-by: Tao Xue <xuetao09@huawei.com>
>> ---
>>   drivers/usb/core/usb.c | 9 ++++++++-
>>   1 file changed, 8 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
>> index e9a10a33534c..8f2e05a5a015 100644
>> --- a/drivers/usb/core/usb.c
>> +++ b/drivers/usb/core/usb.c
>> @@ -1125,6 +1125,8 @@ EXPORT_SYMBOL_GPL(usb_free_noncoherent);
>>   u32 usb_endpoint_max_periodic_payload(struct usb_device *udev,
>>   				      const struct usb_host_endpoint *ep)
>>   {
>> +	u32 max_payload;
>> +
>>   	if (!usb_endpoint_xfer_isoc(&ep->desc) &&
>>   	    !usb_endpoint_xfer_int(&ep->desc))
>>   		return 0;
>> @@ -1135,7 +1137,12 @@ u32 usb_endpoint_max_periodic_payload(struct usb_device *udev,
>>   			return le32_to_cpu(ep->ssp_isoc_ep_comp.dwBytesPerInterval);
>>   		fallthrough;
>>   	case USB_SPEED_SUPER:
>> -		return le16_to_cpu(ep->ss_ep_comp.wBytesPerInterval);
>> +		max_payload = usb_endpoint_maxp(&ep->desc) * (ep->ss_ep_comp.bMaxBurst + 1);
>> +		if (usb_endpoint_xfer_isoc(&ep->desc))
>> +			return max_t(u32, max_payload * USB_SS_MULT(ep->ss_ep_comp.bmAttributes),
>> +					ep->ss_ep_comp.wBytesPerInterval);
>> +		else
>> +			return max_t(u32, max_payload, ep->ss_ep_comp.wBytesPerInterval);
> 
> You dropped the conversion from le16 to cpu?  Why?
> 
> thanks,
> 
> greg k-h

Hi Greg,

Thank you for the review.

1、You're right, that was an oversight. I should keep the le16_to_cpu().
Here's the corrected version:

     max_payload = usb_endpoint_maxp(&ep->desc) * 
(ep->ss_ep_comp.bMaxBurst + 1);
     if (usb_endpoint_xfer_isoc(&ep->desc))
         return max_t(u32, max_payload * 
USB_SS_MULT(ep->ss_ep_comp.bmAttributes),
                         le16_to_cpu(ep->ss_ep_comp.wBytesPerInterval));
     else
         return max_t(u32, max_payload, 
le16_to_cpu(ep->ss_ep_comp.wBytesPerInterval));

2、Following Alan's suggestion in another email, should I check whether 
wBytesPerInterval is a valid value and handle it in the 
usb_parse_ss_endpoint_companion() ?

However, when parsing the device descriptor, we do not know whether the 
actual data length transmitted by the peripheral is greater than 
wBytesPerInterval.

Therefore, would it be sufficient to only add a check for whether 
wBytesPerInterval is 0 in the existing flow, and if it is 0, set 
wBytesPerInterval to cpu_to_le16(max_tx) by default?

For example, modify it in the following way:

      if (le16_to_cpu(desc->wBytesPerInterval) > max_tx || 
le16_to_cpu(desc->wBytesPerInterval) == 0) {
         dev_notice(ddev, "%s endpoint with wBytesPerInterval of %d in "
                 "config %d interface %d altsetting %d ep %d: "
                 "setting to %d\n",
                 usb_endpoint_xfer_isoc(&ep->desc) ? "Isoc" : "Int",
                 le16_to_cpu(desc->wBytesPerInterval),
                 cfgno, inum, asnum, ep->desc.bEndpointAddress,
                 max_tx);
         ep->ss_ep_comp.wBytesPerInterval = cpu_to_le16(max_tx);
     }

  Could you please give me some advice? Thanks.

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

* Re: [PATCH] usb: core: Fix bandwidth for devices with invalid wBytesPerInterval
  2026-04-02  6:59   ` Xuetao (kirin)
@ 2026-04-02  7:10     ` Greg KH
  2026-04-02  8:26       ` Xuetao (kirin)
  2026-04-02 13:56     ` Alan Stern
  1 sibling, 1 reply; 14+ messages in thread
From: Greg KH @ 2026-04-02  7:10 UTC (permalink / raw)
  To: Xuetao (kirin); +Cc: linux-usb, linux-kernel, caiyadong, stable, stern

On Thu, Apr 02, 2026 at 02:59:35PM +0800, Xuetao (kirin) wrote:
> 
> 
> 在 2026/4/2 11:51, Greg KH 写道:
> > On Thu, Apr 02, 2026 at 10:14:00AM +0800, Tao Xue wrote:
> > > As specified in Section 4.14.2 of the xHCI Specification, the xHC
> > > reserves bandwidth for periodic endpoints according to bInterval and
> > > wBytesPerInterval (Max ESIT Payload).
> > > 
> > > Some peripherals report an invalid wBytesPerInterval in their device
> > > descriptor, which is either 0 or smaller than the actual data length
> > > transmitted. This issue is observed on ASIX AX88179 series USB 3.0
> > > Ethernet adapters.
> > > 
> > > These errors may lead to unexpected behavior on certain USB host
> > > controllers, causing USB peripherals to malfunction.
> > > 
> > > To address the issue, return max(wBytesPerInterval, max_payload) when
> > > calculating bandwidth reservation.
> > > 
> > > Fixes: 9238f25d5d32 ("USB: xhci: properly set endpoint context fields for periodic eps.")
> > > Cc: <stable@kernel.org>
> > > Signed-off-by: Tao Xue <xuetao09@huawei.com>
> > > ---
> > >   drivers/usb/core/usb.c | 9 ++++++++-
> > >   1 file changed, 8 insertions(+), 1 deletion(-)
> > > 
> > > diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
> > > index e9a10a33534c..8f2e05a5a015 100644
> > > --- a/drivers/usb/core/usb.c
> > > +++ b/drivers/usb/core/usb.c
> > > @@ -1125,6 +1125,8 @@ EXPORT_SYMBOL_GPL(usb_free_noncoherent);
> > >   u32 usb_endpoint_max_periodic_payload(struct usb_device *udev,
> > >   				      const struct usb_host_endpoint *ep)
> > >   {
> > > +	u32 max_payload;
> > > +
> > >   	if (!usb_endpoint_xfer_isoc(&ep->desc) &&
> > >   	    !usb_endpoint_xfer_int(&ep->desc))
> > >   		return 0;
> > > @@ -1135,7 +1137,12 @@ u32 usb_endpoint_max_periodic_payload(struct usb_device *udev,
> > >   			return le32_to_cpu(ep->ssp_isoc_ep_comp.dwBytesPerInterval);
> > >   		fallthrough;
> > >   	case USB_SPEED_SUPER:
> > > -		return le16_to_cpu(ep->ss_ep_comp.wBytesPerInterval);
> > > +		max_payload = usb_endpoint_maxp(&ep->desc) * (ep->ss_ep_comp.bMaxBurst + 1);
> > > +		if (usb_endpoint_xfer_isoc(&ep->desc))
> > > +			return max_t(u32, max_payload * USB_SS_MULT(ep->ss_ep_comp.bmAttributes),
> > > +					ep->ss_ep_comp.wBytesPerInterval);
> > > +		else
> > > +			return max_t(u32, max_payload, ep->ss_ep_comp.wBytesPerInterval);
> > 
> > You dropped the conversion from le16 to cpu?  Why?
> > 
> > thanks,
> > 
> > greg k-h
> 
> Hi Greg,
> 
> Thank you for the review.
> 
> 1、You're right, that was an oversight. I should keep the le16_to_cpu().
> Here's the corrected version:
> 
>     max_payload = usb_endpoint_maxp(&ep->desc) * (ep->ss_ep_comp.bMaxBurst +
> 1);
>     if (usb_endpoint_xfer_isoc(&ep->desc))
>         return max_t(u32, max_payload *
> USB_SS_MULT(ep->ss_ep_comp.bmAttributes),
>                         le16_to_cpu(ep->ss_ep_comp.wBytesPerInterval));
>     else
>         return max_t(u32, max_payload,
> le16_to_cpu(ep->ss_ep_comp.wBytesPerInterval));

That's hard to follow as it is line-wrapped, just fix it up for your
next version and I'll be glad to review it then.

> 2、Following Alan's suggestion in another email, should I check whether
> wBytesPerInterval is a valid value and handle it in the
> usb_parse_ss_endpoint_companion() ?
> 
> However, when parsing the device descriptor, we do not know whether the
> actual data length transmitted by the peripheral is greater than
> wBytesPerInterval.
> 
> Therefore, would it be sufficient to only add a check for whether
> wBytesPerInterval is 0 in the existing flow, and if it is 0, set
> wBytesPerInterval to cpu_to_le16(max_tx) by default?

No, don't override a value given by a device.  Mark the descriptor as
invalid and fail attaching to the device.

> For example, modify it in the following way:
> 
>      if (le16_to_cpu(desc->wBytesPerInterval) > max_tx ||
> le16_to_cpu(desc->wBytesPerInterval) == 0) {
>         dev_notice(ddev, "%s endpoint with wBytesPerInterval of %d in "
>                 "config %d interface %d altsetting %d ep %d: "
>                 "setting to %d\n",
>                 usb_endpoint_xfer_isoc(&ep->desc) ? "Isoc" : "Int",
>                 le16_to_cpu(desc->wBytesPerInterval),
>                 cfgno, inum, asnum, ep->desc.bEndpointAddress,
>                 max_tx);
>         ep->ss_ep_comp.wBytesPerInterval = cpu_to_le16(max_tx);
>     }

There's nothing a user can do with this type of error, and yet the
kernel is supposed to fix it up?  We should just fail it and tell the
user then, like we do for other broken descriptors.

Did you find this issue with a real device, or is this just due to
fuzzing invalid descriptor values?

thanks,

greg k-h

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

* Re: [PATCH] usb: core: Fix bandwidth for devices with invalid wBytesPerInterval
  2026-04-02  7:10     ` Greg KH
@ 2026-04-02  8:26       ` Xuetao (kirin)
  0 siblings, 0 replies; 14+ messages in thread
From: Xuetao (kirin) @ 2026-04-02  8:26 UTC (permalink / raw)
  To: Greg KH; +Cc: linux-usb, linux-kernel, caiyadong, stable, stern



在 2026/4/2 15:10, Greg KH 写道:
> On Thu, Apr 02, 2026 at 02:59:35PM +0800, Xuetao (kirin) wrote:
>>
>>
>> 在 2026/4/2 11:51, Greg KH 写道:
>>> On Thu, Apr 02, 2026 at 10:14:00AM +0800, Tao Xue wrote:
>>>> As specified in Section 4.14.2 of the xHCI Specification, the xHC
>>>> reserves bandwidth for periodic endpoints according to bInterval and
>>>> wBytesPerInterval (Max ESIT Payload).
>>>>
>>>> Some peripherals report an invalid wBytesPerInterval in their device
>>>> descriptor, which is either 0 or smaller than the actual data length
>>>> transmitted. This issue is observed on ASIX AX88179 series USB 3.0
>>>> Ethernet adapters.
>>>>
>>>> These errors may lead to unexpected behavior on certain USB host
>>>> controllers, causing USB peripherals to malfunction.
>>>>
>>>> To address the issue, return max(wBytesPerInterval, max_payload) when
>>>> calculating bandwidth reservation.
>>>>
>>>> Fixes: 9238f25d5d32 ("USB: xhci: properly set endpoint context fields for periodic eps.")
>>>> Cc: <stable@kernel.org>
>>>> Signed-off-by: Tao Xue <xuetao09@huawei.com>
>>>> ---
>>>>    drivers/usb/core/usb.c | 9 ++++++++-
>>>>    1 file changed, 8 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
>>>> index e9a10a33534c..8f2e05a5a015 100644
>>>> --- a/drivers/usb/core/usb.c
>>>> +++ b/drivers/usb/core/usb.c
>>>> @@ -1125,6 +1125,8 @@ EXPORT_SYMBOL_GPL(usb_free_noncoherent);
>>>>    u32 usb_endpoint_max_periodic_payload(struct usb_device *udev,
>>>>    				      const struct usb_host_endpoint *ep)
>>>>    {
>>>> +	u32 max_payload;
>>>> +
>>>>    	if (!usb_endpoint_xfer_isoc(&ep->desc) &&
>>>>    	    !usb_endpoint_xfer_int(&ep->desc))
>>>>    		return 0;
>>>> @@ -1135,7 +1137,12 @@ u32 usb_endpoint_max_periodic_payload(struct usb_device *udev,
>>>>    			return le32_to_cpu(ep->ssp_isoc_ep_comp.dwBytesPerInterval);
>>>>    		fallthrough;
>>>>    	case USB_SPEED_SUPER:
>>>> -		return le16_to_cpu(ep->ss_ep_comp.wBytesPerInterval);
>>>> +		max_payload = usb_endpoint_maxp(&ep->desc) * (ep->ss_ep_comp.bMaxBurst + 1);
>>>> +		if (usb_endpoint_xfer_isoc(&ep->desc))
>>>> +			return max_t(u32, max_payload * USB_SS_MULT(ep->ss_ep_comp.bmAttributes),
>>>> +					ep->ss_ep_comp.wBytesPerInterval);
>>>> +		else
>>>> +			return max_t(u32, max_payload, ep->ss_ep_comp.wBytesPerInterval);
>>>
>>> You dropped the conversion from le16 to cpu?  Why?
>>>
>>> thanks,
>>>
>>> greg k-h
>>
>> Hi Greg,
>>
>> Thank you for the review.
>>
>> 1、You're right, that was an oversight. I should keep the le16_to_cpu().
>> Here's the corrected version:
>>
>>      max_payload = usb_endpoint_maxp(&ep->desc) * (ep->ss_ep_comp.bMaxBurst +
>> 1);
>>      if (usb_endpoint_xfer_isoc(&ep->desc))
>>          return max_t(u32, max_payload *
>> USB_SS_MULT(ep->ss_ep_comp.bmAttributes),
>>                          le16_to_cpu(ep->ss_ep_comp.wBytesPerInterval));
>>      else
>>          return max_t(u32, max_payload,
>> le16_to_cpu(ep->ss_ep_comp.wBytesPerInterval));
> 
> That's hard to follow as it is line-wrapped, just fix it up for your
> next version and I'll be glad to review it then.
> 
Thank you for the review.I will submit a new patch later.

>> 2、Following Alan's suggestion in another email, should I check whether
>> wBytesPerInterval is a valid value and handle it in the
>> usb_parse_ss_endpoint_companion() ?
>>
>> However, when parsing the device descriptor, we do not know whether the
>> actual data length transmitted by the peripheral is greater than
>> wBytesPerInterval.
>>
>> Therefore, would it be sufficient to only add a check for whether
>> wBytesPerInterval is 0 in the existing flow, and if it is 0, set
>> wBytesPerInterval to cpu_to_le16(max_tx) by default?
> 
> No, don't override a value given by a device.  Mark the descriptor as
> invalid and fail attaching to the device.
> 
>> For example, modify it in the following way:
>>
>>       if (le16_to_cpu(desc->wBytesPerInterval) > max_tx ||
>> le16_to_cpu(desc->wBytesPerInterval) == 0) {
>>          dev_notice(ddev, "%s endpoint with wBytesPerInterval of %d in "
>>                  "config %d interface %d altsetting %d ep %d: "
>>                  "setting to %d\n",
>>                  usb_endpoint_xfer_isoc(&ep->desc) ? "Isoc" : "Int",
>>                  le16_to_cpu(desc->wBytesPerInterval),
>>                  cfgno, inum, asnum, ep->desc.bEndpointAddress,
>>                  max_tx);
>>          ep->ss_ep_comp.wBytesPerInterval = cpu_to_le16(max_tx);
>>      }
> 
> There's nothing a user can do with this type of error, and yet the
> kernel is supposed to fix it up?  We should just fail it and tell the
> user then, like we do for other broken descriptors.
> 
> Did you find this issue with a real device, or is this just due to
> fuzzing invalid descriptor values?
> 
> thanks,
> 
> greg k-h

This is not a fuzzing issue.I have encountered this issue on several USB 
3.0 docks (with built-in USB Ethernet adapters), such as UGREEN, 
thinkplus, and Baseus. They all use the ASIX AX88179 USB 3.0 Gigabit 
Ethernet Adapter (VID:0x0B95, PID: 0x1790). I am seeing two scenarios:

int ep:
Scenario 1:
	wMaxPacketSize = 16
	bMaxBurst = 0
	wBytesPerInterval = 8
	tx_data_len = 8/16

Scenario 2:
	wMaxPacketSize = 16
	bMaxBurst = 0
	wBytesPerInterval = 0
	tx_data_len = 8/16

These devices work perfectly on the dwc3 controller, but they 
consistently fail on another USB host controller. When I temporarily 
change wBytesPerInterval to 16, the problem is resolved.

 From the comparison results, different controllers behave differently 
when encountering invalid wBytesPerInterval values in the device 
descriptor.The dwc3 controller is tolerant of this error.



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

* Re: [PATCH] usb: core: Fix bandwidth for devices with invalid wBytesPerInterval
  2026-04-02  2:14 [PATCH] usb: core: Fix bandwidth for devices with invalid wBytesPerInterval Tao Xue
  2026-04-02  2:45 ` Alan Stern
  2026-04-02  3:51 ` Greg KH
@ 2026-04-02  9:44 ` Michal Pecio
  2026-04-02 11:55   ` Xuetao (kirin)
  2 siblings, 1 reply; 14+ messages in thread
From: Michal Pecio @ 2026-04-02  9:44 UTC (permalink / raw)
  To: Tao Xue; +Cc: gregkh, linux-usb, linux-kernel, caiyadong, stable

On Thu, 2 Apr 2026 10:14:00 +0800, Tao Xue wrote:
> As specified in Section 4.14.2 of the xHCI Specification, the xHC
> reserves bandwidth for periodic endpoints according to bInterval and
> wBytesPerInterval (Max ESIT Payload).

For SuperSpeed endpoints, yes.
This follows from USB3 spec 9.6.7.

> Some peripherals report an invalid wBytesPerInterval in their device
> descriptor, which is either 0 or smaller than the actual data length
> transmitted. This issue is observed on ASIX AX88179 series USB 3.0
> Ethernet adapters.

Damn, it really does.

      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0008  1x 8 bytes
        bInterval              11
        bMaxBurst               0
        wBytesPerInterval       0

Any other examples besides AX88179?

> These errors may lead to unexpected behavior on certain USB host
> controllers, causing USB peripherals to malfunction.

Out of curiosity, Bandwidth Overrun Error or something worse?

It's an oversight that these URBs aren't rejected with EMSGSIZE in the
first place. IIRC zero-length interrupt transfers are allowed by USB
specs and a zero-payload endpoint is probably legal per xHCI, but then
submitting non-empty URBs to it is not.

> To address the issue, return max(wBytesPerInterval, max_payload) when
> calculating bandwidth reservation.
> 
> Fixes: 9238f25d5d32 ("USB: xhci: properly set endpoint context fields for periodic eps.")
> Cc: <stable@kernel.org>
> Signed-off-by: Tao Xue <xuetao09@huawei.com>
> ---
>  drivers/usb/core/usb.c | 9 ++++++++-
>  1 file changed, 8 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
> index e9a10a33534c..8f2e05a5a015 100644
> --- a/drivers/usb/core/usb.c
> +++ b/drivers/usb/core/usb.c
> @@ -1125,6 +1125,8 @@ EXPORT_SYMBOL_GPL(usb_free_noncoherent);
>  u32 usb_endpoint_max_periodic_payload(struct usb_device *udev,
>  				      const struct usb_host_endpoint *ep)
>  {
> +	u32 max_payload;
> +
>  	if (!usb_endpoint_xfer_isoc(&ep->desc) &&
>  	    !usb_endpoint_xfer_int(&ep->desc))
>  		return 0;
> @@ -1135,7 +1137,12 @@ u32 usb_endpoint_max_periodic_payload(struct usb_device *udev,
>  			return le32_to_cpu(ep->ssp_isoc_ep_comp.dwBytesPerInterval);
>  		fallthrough;
>  	case USB_SPEED_SUPER:
> -		return le16_to_cpu(ep->ss_ep_comp.wBytesPerInterval);
> +		max_payload = usb_endpoint_maxp(&ep->desc) * (ep->ss_ep_comp.bMaxBurst + 1);
> +		if (usb_endpoint_xfer_isoc(&ep->desc))
> +			return max_t(u32, max_payload * USB_SS_MULT(ep->ss_ep_comp.bmAttributes),
> +					ep->ss_ep_comp.wBytesPerInterval);
> +		else
> +			return max_t(u32, max_payload, ep->ss_ep_comp.wBytesPerInterval);

Obviously a kludge is necessary here to make these abominable devices
work reliably with xHCI, but OTOH exceeding wBytesPerInterval violates
USB3 9.6.7 and it's unclear if all devices would be happy.

There are devices which define such odd isochronous alt settings with
apparent intent to allow fine-grained bandwidth reservation:

        wMaxPacketSize     0x0400  1x 1024 bytes
        bInterval               1
        bMaxBurst               0
        wBytesPerInterval     512

        wMaxPacketSize     0x0400  1x 1024 bytes
        bInterval               1
        bMaxBurst               0
        wBytesPerInterval    1024

        wMaxPacketSize     0x0400  1x 1024 bytes
        bInterval               1
        bMaxBurst               1  # 2 packets per interval
        wBytesPerInterval    1536

Isochronous drivers use this function to size their URBs or select the
right altsetting for given bandwidth. UVC has obeyed wBytesPerInterval
since forever with no apparent issues and UAC has recently been patched
to work like that too with no issues so far AFAIK.

Maybe start with something specific to the known bogus hardware, i.e.
interrupt endpoint with one packet and zero payload? In such case
it's high chance that the device actually meant it to be wMaxPacket.

>  	default:
>  		if (usb_endpoint_is_hs_isoc_double(udev, ep))
>  			return le32_to_cpu(ep->eusb2_isoc_ep_comp.dwBytesPerInterval);
> -- 
> 2.17.1
> 

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

* Re: [PATCH] usb: core: Fix bandwidth for devices with invalid wBytesPerInterval
  2026-04-02  9:44 ` Michal Pecio
@ 2026-04-02 11:55   ` Xuetao (kirin)
  2026-04-03  7:16     ` Michal Pecio
  0 siblings, 1 reply; 14+ messages in thread
From: Xuetao (kirin) @ 2026-04-02 11:55 UTC (permalink / raw)
  To: Michal Pecio; +Cc: gregkh, linux-usb, linux-kernel, caiyadong, stable



在 2026/4/2 17:44, Michal Pecio 写道:
> On Thu, 2 Apr 2026 10:14:00 +0800, Tao Xue wrote:
>> As specified in Section 4.14.2 of the xHCI Specification, the xHC
>> reserves bandwidth for periodic endpoints according to bInterval and
>> wBytesPerInterval (Max ESIT Payload).
> 
> For SuperSpeed endpoints, yes.
> This follows from USB3 spec 9.6.7.
> 
>> Some peripherals report an invalid wBytesPerInterval in their device
>> descriptor, which is either 0 or smaller than the actual data length
>> transmitted. This issue is observed on ASIX AX88179 series USB 3.0
>> Ethernet adapters.
> 
> Damn, it really does.
> 
>        Endpoint Descriptor:
>          bLength                 7
>          bDescriptorType         5
>          bEndpointAddress     0x81  EP 1 IN
>          bmAttributes            3
>            Transfer Type            Interrupt
>            Synch Type               None
>            Usage Type               Data
>          wMaxPacketSize     0x0008  1x 8 bytes
>          bInterval              11
>          bMaxBurst               0
>          wBytesPerInterval       0
> 
> Any other examples besides AX88179?

We tested 18 different USB 3.0 docks, but they only contained two 
different types of USB 3.0 Ethernet devices based on VID/PID.
The dwc3 controller works fine with all of the devices mentioned above. 
The other USB host controller works fine with all 12 Realtek devices,
but fails with all 6 ASIX devices.

1. Realtek USB 10/100/1000 LAN (12 devices)
All 12 devices share the same VID/PID and descriptor values.

VID = 0x0BDA, PID = 0x8153
wMaxPacketSize = 0x10
bMaxBurst = 0
wBytesPerInterval = 0x8

2. ASIX AX88179 USB 3.0 to Gigabit Ethernet Adapter (6 devices)
All 6 devices share the same VID/PID.

VID = 0x0B95, PID = 0x1790
(a) 4 devices:
wMaxPacketSize = 0x10
bMaxBurst = 0
wBytesPerInterval = 0x0

(b) 2 devices:
wMaxPacketSize = 0x10
bMaxBurst = 0
wBytesPerInterval = 0x8

We also tested 3 different USB 3.0 camera devices. On all of these 
devices, the wBytesPerInterval of all SuperSpeed isochronous endpoints 
is equal to Mult * wMaxPacketSize * (bMaxBurst + 1).

> 
>> These errors may lead to unexpected behavior on certain USB host
>> controllers, causing USB peripherals to malfunction.
> 
> Out of curiosity, Bandwidth Overrun Error or something worse?
> 

This host controller reports a Babble error.

> It's an oversight that these URBs aren't rejected with EMSGSIZE in the
> first place. IIRC zero-length interrupt transfers are allowed by USB
> specs and a zero-payload endpoint is probably legal per xHCI, but then
> submitting non-empty URBs to it is not.
> 
>> To address the issue, return max(wBytesPerInterval, max_payload) when
>> calculating bandwidth reservation.
>>
>> Fixes: 9238f25d5d32 ("USB: xhci: properly set endpoint context fields for periodic eps.")
>> Cc: <stable@kernel.org>
>> Signed-off-by: Tao Xue <xuetao09@huawei.com>
>> ---
>>   drivers/usb/core/usb.c | 9 ++++++++-
>>   1 file changed, 8 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
>> index e9a10a33534c..8f2e05a5a015 100644
>> --- a/drivers/usb/core/usb.c
>> +++ b/drivers/usb/core/usb.c
>> @@ -1125,6 +1125,8 @@ EXPORT_SYMBOL_GPL(usb_free_noncoherent);
>>   u32 usb_endpoint_max_periodic_payload(struct usb_device *udev,
>>   				      const struct usb_host_endpoint *ep)
>>   {
>> +	u32 max_payload;
>> +
>>   	if (!usb_endpoint_xfer_isoc(&ep->desc) &&
>>   	    !usb_endpoint_xfer_int(&ep->desc))
>>   		return 0;
>> @@ -1135,7 +1137,12 @@ u32 usb_endpoint_max_periodic_payload(struct usb_device *udev,
>>   			return le32_to_cpu(ep->ssp_isoc_ep_comp.dwBytesPerInterval);
>>   		fallthrough;
>>   	case USB_SPEED_SUPER:
>> -		return le16_to_cpu(ep->ss_ep_comp.wBytesPerInterval);
>> +		max_payload = usb_endpoint_maxp(&ep->desc) * (ep->ss_ep_comp.bMaxBurst + 1);
>> +		if (usb_endpoint_xfer_isoc(&ep->desc))
>> +			return max_t(u32, max_payload * USB_SS_MULT(ep->ss_ep_comp.bmAttributes),
>> +					ep->ss_ep_comp.wBytesPerInterval);
>> +		else
>> +			return max_t(u32, max_payload, ep->ss_ep_comp.wBytesPerInterval);
> 
> Obviously a kludge is necessary here to make these abominable devices
> work reliably with xHCI, but OTOH exceeding wBytesPerInterval violates
> USB3 9.6.7 and it's unclear if all devices would be happy.
> 
> There are devices which define such odd isochronous alt settings with
> apparent intent to allow fine-grained bandwidth reservation:
> 
>          wMaxPacketSize     0x0400  1x 1024 bytes
>          bInterval               1
>          bMaxBurst               0
>          wBytesPerInterval     512
> 
>          wMaxPacketSize     0x0400  1x 1024 bytes
>          bInterval               1
>          bMaxBurst               0
>          wBytesPerInterval    1024
> 
>          wMaxPacketSize     0x0400  1x 1024 bytes
>          bInterval               1
>          bMaxBurst               1  # 2 packets per interval
>          wBytesPerInterval    1536
> 
> Isochronous drivers use this function to size their URBs or select the
> right altsetting for given bandwidth. UVC has obeyed wBytesPerInterval
> since forever with no apparent issues and UAC has recently been patched
> to work like that too with no issues so far AFAIK.
> 
> Maybe start with something specific to the known bogus hardware, i.e.
> interrupt endpoint with one packet and zero payload? In such case
> it's high chance that the device actually meant it to be wMaxPacket.
> 
>>   	default:
>>   		if (usb_endpoint_is_hs_isoc_double(udev, ep))
>>   			return le32_to_cpu(ep->eusb2_isoc_ep_comp.dwBytesPerInterval);
>> -- 
>> 2.17.1
>>


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

* Re: [PATCH] usb: core: Fix bandwidth for devices with invalid wBytesPerInterval
  2026-04-02  6:59   ` Xuetao (kirin)
  2026-04-02  7:10     ` Greg KH
@ 2026-04-02 13:56     ` Alan Stern
  2026-04-02 14:09       ` Greg KH
  2026-04-02 20:17       ` Michal Pecio
  1 sibling, 2 replies; 14+ messages in thread
From: Alan Stern @ 2026-04-02 13:56 UTC (permalink / raw)
  To: Xuetao (kirin); +Cc: Greg KH, linux-usb, linux-kernel, caiyadong, stable

On Thu, Apr 02, 2026 at 02:59:35PM +0800, Xuetao (kirin) wrote:
> 2、Following Alan's suggestion in another email, should I check whether
> wBytesPerInterval is a valid value and handle it in the
> usb_parse_ss_endpoint_companion() ?

Yes, IMO.

> However, when parsing the device descriptor, we do not know whether the
> actual data length transmitted by the peripheral is greater than
> wBytesPerInterval.

Note: wBytesPerInterval is in the endpoint descriptor, not the device 
descriptor.

> Therefore, would it be sufficient to only add a check for whether
> wBytesPerInterval is 0 in the existing flow, and if it is 0, set
> wBytesPerInterval to cpu_to_le16(max_tx) by default?
> 
> For example, modify it in the following way:
> 
>      if (le16_to_cpu(desc->wBytesPerInterval) > max_tx ||
> le16_to_cpu(desc->wBytesPerInterval) == 0) {
>         dev_notice(ddev, "%s endpoint with wBytesPerInterval of %d in "
>                 "config %d interface %d altsetting %d ep %d: "
>                 "setting to %d\n",
>                 usb_endpoint_xfer_isoc(&ep->desc) ? "Isoc" : "Int",
>                 le16_to_cpu(desc->wBytesPerInterval),
>                 cfgno, inum, asnum, ep->desc.bEndpointAddress,
>                 max_tx);
>         ep->ss_ep_comp.wBytesPerInterval = cpu_to_le16(max_tx);
>     }
> 
>  Could you please give me some advice? Thanks.

Try it and see if it fixes the problems you see with the network 
adapters.

I saw the Greg said not to change the descriptors and just fail the 
device, but we already make this sort of change to correct other errors 
so there doesn't seem to be any reason not to do it here as well.  
Especially if it allows people to use devices that otherwise would not 
work.

Alan Stern

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

* Re: [PATCH] usb: core: Fix bandwidth for devices with invalid wBytesPerInterval
  2026-04-02 13:56     ` Alan Stern
@ 2026-04-02 14:09       ` Greg KH
  2026-04-02 15:03         ` Michal Pecio
  2026-04-03  1:20         ` Xuetao (kirin)
  2026-04-02 20:17       ` Michal Pecio
  1 sibling, 2 replies; 14+ messages in thread
From: Greg KH @ 2026-04-02 14:09 UTC (permalink / raw)
  To: Alan Stern; +Cc: Xuetao (kirin), linux-usb, linux-kernel, caiyadong, stable

On Thu, Apr 02, 2026 at 09:56:51AM -0400, Alan Stern wrote:
> On Thu, Apr 02, 2026 at 02:59:35PM +0800, Xuetao (kirin) wrote:
> > 2、Following Alan's suggestion in another email, should I check whether
> > wBytesPerInterval is a valid value and handle it in the
> > usb_parse_ss_endpoint_companion() ?
> 
> Yes, IMO.
> 
> > However, when parsing the device descriptor, we do not know whether the
> > actual data length transmitted by the peripheral is greater than
> > wBytesPerInterval.
> 
> Note: wBytesPerInterval is in the endpoint descriptor, not the device 
> descriptor.
> 
> > Therefore, would it be sufficient to only add a check for whether
> > wBytesPerInterval is 0 in the existing flow, and if it is 0, set
> > wBytesPerInterval to cpu_to_le16(max_tx) by default?
> > 
> > For example, modify it in the following way:
> > 
> >      if (le16_to_cpu(desc->wBytesPerInterval) > max_tx ||
> > le16_to_cpu(desc->wBytesPerInterval) == 0) {
> >         dev_notice(ddev, "%s endpoint with wBytesPerInterval of %d in "
> >                 "config %d interface %d altsetting %d ep %d: "
> >                 "setting to %d\n",
> >                 usb_endpoint_xfer_isoc(&ep->desc) ? "Isoc" : "Int",
> >                 le16_to_cpu(desc->wBytesPerInterval),
> >                 cfgno, inum, asnum, ep->desc.bEndpointAddress,
> >                 max_tx);
> >         ep->ss_ep_comp.wBytesPerInterval = cpu_to_le16(max_tx);
> >     }
> > 
> >  Could you please give me some advice? Thanks.
> 
> Try it and see if it fixes the problems you see with the network 
> adapters.
> 
> I saw the Greg said not to change the descriptors and just fail the 
> device, but we already make this sort of change to correct other errors 
> so there doesn't seem to be any reason not to do it here as well.  
> Especially if it allows people to use devices that otherwise would not 
> work.

I didn't realize this was on "real" devices, sorry.  I thought this was
only a fuzzing thing.  So yes, fix up the broken descriptor after
warning about it is the correct thing to do.

thanks,

greg k-h

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

* Re: [PATCH] usb: core: Fix bandwidth for devices with invalid wBytesPerInterval
  2026-04-02 14:09       ` Greg KH
@ 2026-04-02 15:03         ` Michal Pecio
  2026-04-03  1:20         ` Xuetao (kirin)
  1 sibling, 0 replies; 14+ messages in thread
From: Michal Pecio @ 2026-04-02 15:03 UTC (permalink / raw)
  To: Greg KH
  Cc: Alan Stern, Xuetao (kirin), linux-usb, linux-kernel, caiyadong,
	stable

On Thu, 2 Apr 2026 16:09:51 +0200, Greg KH wrote:
> I didn't realize this was on "real" devices, sorry.  I thought this
> was only a fuzzing thing.  So yes, fix up the broken descriptor after
> warning about it is the correct thing to do.

Such descriptors are not illegal per USB3 spec and they are seen in the
wild, at least on isochronous endpoints, and they were correct so far.

What's broken is that some particular device specifies less than its
driver actually submits (and presumably needs to submit for it to work).

Regards,
Michal

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

* Re: [PATCH] usb: core: Fix bandwidth for devices with invalid wBytesPerInterval
  2026-04-02 13:56     ` Alan Stern
  2026-04-02 14:09       ` Greg KH
@ 2026-04-02 20:17       ` Michal Pecio
  1 sibling, 0 replies; 14+ messages in thread
From: Michal Pecio @ 2026-04-02 20:17 UTC (permalink / raw)
  To: Alan Stern
  Cc: Xuetao (kirin), Greg KH, linux-usb, linux-kernel, caiyadong,
	stable

On Thu, 2 Apr 2026 09:56:51 -0400, Alan Stern wrote:
> On Thu, Apr 02, 2026 at 02:59:35PM +0800, Xuetao (kirin) wrote:
> > 2、Following Alan's suggestion in another email, should I check
> > whether wBytesPerInterval is a valid value and handle it in the
> > usb_parse_ss_endpoint_companion() ?  
> 
> Yes, IMO.

Not sure, this could backfire if it turns out that these workarounds
will need to become more elaborate and account for wBytesPerInterval.

These descriptors aren't blatantly invalid. USB3 9.6.7 doesn't require
that wBytesPerInterval == wMaxPacketSize * bMaxBurst * Mult.

Being greater would be blatantly invalid, but this is already being
sanitized by the descriptor parser.

> > However, when parsing the device descriptor, we do not know whether
> > the actual data length transmitted by the peripheral is greater than
> > wBytesPerInterval.  

Indeed. Device is allowed (actually: required) not to send more data
than its wBytesPerInterval on IN endpoints.

UVC driver uses this field to pick isochronous altsetting capable of
transmitting a particular payload each interval. If we overestimate,
there is risk that the device will deliver on its promise and truncate
instead of violating USB3 spec. We should rather pick a larger alt.

OTOH, when a device lies and sends more than specified, this happens.
Some HCs ignore the problem (and may overcommit bandwidth if we enable
million such endpoints), others get pedantic and return Babble Error
(my mistake, Bandwidth Overrun is specific to isochronous).


I think this patch is relatively safe for interrupt, because drivers
generally don't look at endpoint descriptors and submit URBs of class
specific size. Case in point, everything works when you override xHCI
allocation. It also works on HCs ignoring it.

Beind the pedant I am, I would restrict this to bMaxBurst==0 because
that's the known problem case and IDK off-hand what devices might use
bursting interrupt endpoints and what gotchas await there.

Maybe add a comment that it's a questionable, spec-violating hack.

Regards,
Michal 

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

* Re: [PATCH] usb: core: Fix bandwidth for devices with invalid wBytesPerInterval
  2026-04-02 14:09       ` Greg KH
  2026-04-02 15:03         ` Michal Pecio
@ 2026-04-03  1:20         ` Xuetao (kirin)
  1 sibling, 0 replies; 14+ messages in thread
From: Xuetao (kirin) @ 2026-04-03  1:20 UTC (permalink / raw)
  To: Greg KH, Alan Stern; +Cc: linux-usb, linux-kernel, caiyadong, stable



在 2026/4/2 22:09, Greg KH 写道:
> On Thu, Apr 02, 2026 at 09:56:51AM -0400, Alan Stern wrote:
>> On Thu, Apr 02, 2026 at 02:59:35PM +0800, Xuetao (kirin) wrote:
>>> 2、Following Alan's suggestion in another email, should I check whether
>>> wBytesPerInterval is a valid value and handle it in the
>>> usb_parse_ss_endpoint_companion() ?
>>
>> Yes, IMO.
>>
>>> However, when parsing the device descriptor, we do not know whether the
>>> actual data length transmitted by the peripheral is greater than
>>> wBytesPerInterval.
>>
>> Note: wBytesPerInterval is in the endpoint descriptor, not the device
>> descriptor.
>>

Thank you for your review. I will correct the description in the 
subsequent patch.

>>> Therefore, would it be sufficient to only add a check for whether
>>> wBytesPerInterval is 0 in the existing flow, and if it is 0, set
>>> wBytesPerInterval to cpu_to_le16(max_tx) by default?
>>>
>>> For example, modify it in the following way:
>>>
>>>       if (le16_to_cpu(desc->wBytesPerInterval) > max_tx ||
>>> le16_to_cpu(desc->wBytesPerInterval) == 0) {
>>>          dev_notice(ddev, "%s endpoint with wBytesPerInterval of %d in "
>>>                  "config %d interface %d altsetting %d ep %d: "
>>>                  "setting to %d\n",
>>>                  usb_endpoint_xfer_isoc(&ep->desc) ? "Isoc" : "Int",
>>>                  le16_to_cpu(desc->wBytesPerInterval),
>>>                  cfgno, inum, asnum, ep->desc.bEndpointAddress,
>>>                  max_tx);
>>>          ep->ss_ep_comp.wBytesPerInterval = cpu_to_le16(max_tx);
>>>      }
>>>
>>>   Could you please give me some advice? Thanks.
>>
>> Try it and see if it fixes the problems you see with the network
>> adapters.
>>

Okay, I will verify the effectiveness of this modification and provide 
feedback on the results.

I guess that for the scenario where wBytesPerInterval is 0, it should be 
solvable. However, for the scenario where wBytesPerInterval is 8 but the 
peripheral sends a data length greater than 8 (e.g., 16), there might be 
an issue. I will test both of the above scenarios.

>> I saw the Greg said not to change the descriptors and just fail the
>> device, but we already make this sort of change to correct other errors
>> so there doesn't seem to be any reason not to do it here as well.
>> Especially if it allows people to use devices that otherwise would not
>> work.
> 
> I didn't realize this was on "real" devices, sorry.  I thought this was
> only a fuzzing thing.  So yes, fix up the broken descriptor after
> warning about it is the correct thing to do.
> 
> thanks,
> 
> greg k-h


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

* Re: [PATCH] usb: core: Fix bandwidth for devices with invalid wBytesPerInterval
  2026-04-02 11:55   ` Xuetao (kirin)
@ 2026-04-03  7:16     ` Michal Pecio
  0 siblings, 0 replies; 14+ messages in thread
From: Michal Pecio @ 2026-04-03  7:16 UTC (permalink / raw)
  To: Xuetao (kirin); +Cc: gregkh, linux-usb, linux-kernel, caiyadong, stable

On Thu, 2 Apr 2026 19:55:16 +0800, Xuetao (kirin) wrote:
> > Any other examples besides AX88179?  
> 
> We tested 18 different USB 3.0 docks, but they only contained two 
> different types of USB 3.0 Ethernet devices based on VID/PID.
> The dwc3 controller works fine with all of the devices mentioned
> above. The other USB host controller works fine with all 12 Realtek
> devices, but fails with all 6 ASIX devices.
> 
> 1. Realtek USB 10/100/1000 LAN (12 devices)
> All 12 devices share the same VID/PID and descriptor values.
> 
> VID = 0x0BDA, PID = 0x8153
> wMaxPacketSize = 0x10
> bMaxBurst = 0
> wBytesPerInterval = 0x8

My RTL8153 has this endpoint for its default proprietary configuration:

        bEndpointAddress     0x83  EP 3 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0002  1x 2 bytes
        bInterval               8
        bMaxBurst               0
        wBytesPerInterval       2

which should be problem-free, and this for its CDC configuration:

        bEndpointAddress     0x83  EP 3 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0010  1x 16 bytes
        bInterval               8
        bMaxBurst               0
        wBytesPerInterval       8

The CDC configuration needs to be enabled with a patch, I'm not sure
if there is any other way. It will then use the r8153_ecm driver.

--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -9641,6 +9641,7 @@ static int rtl_fw_init(struct r8152 *tp)
 
 static u8 __rtl_get_hw_ver(struct usb_device *udev)
 {
+	return 0;
 	u32 ocp_data = 0;
 	__le32 *tmp;
 	u8 version;

> 2. ASIX AX88179 USB 3.0 to Gigabit Ethernet Adapter (6 devices)
> All 6 devices share the same VID/PID.
> 
> VID = 0x0B95, PID = 0x1790
> (a) 4 devices:
> wMaxPacketSize = 0x10
> bMaxBurst = 0
> wBytesPerInterval = 0x0

This looks like my AX88179 and it's obviously broken.

> (b) 2 devices:
> wMaxPacketSize = 0x10
> bMaxBurst = 0
> wBytesPerInterval = 0x8

But this is odd. When I use mine, I see that the driver submits 8 byte
URBs and they complete successfully with 8 bytes received, no babble.

ffff888100981b40 3364969734 S Ii:2:010:1 -115:1024 8 <
ffff888100981b40 3365097706 C Ii:2:010:1 0:1024 8 = a1000800 79490000

So I think this should work even with bandwidth reservation set to 8.
Can you check what happens here, before and after your patch?

Regards,
Michal

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

end of thread, other threads:[~2026-04-03  7:16 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-02  2:14 [PATCH] usb: core: Fix bandwidth for devices with invalid wBytesPerInterval Tao Xue
2026-04-02  2:45 ` Alan Stern
2026-04-02  3:51 ` Greg KH
2026-04-02  6:59   ` Xuetao (kirin)
2026-04-02  7:10     ` Greg KH
2026-04-02  8:26       ` Xuetao (kirin)
2026-04-02 13:56     ` Alan Stern
2026-04-02 14:09       ` Greg KH
2026-04-02 15:03         ` Michal Pecio
2026-04-03  1:20         ` Xuetao (kirin)
2026-04-02 20:17       ` Michal Pecio
2026-04-02  9:44 ` Michal Pecio
2026-04-02 11:55   ` Xuetao (kirin)
2026-04-03  7:16     ` Michal Pecio

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox