* [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; 21+ 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] 21+ 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; 21+ 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] 21+ 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; 21+ 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] 21+ 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; 21+ 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] 21+ 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; 21+ 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] 21+ 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; 21+ 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] 21+ 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 ` [PATCH] usb: core: Fix bandwidth for devices with invalid wBytesPerInterval Michal Pecio 1 sibling, 2 replies; 21+ 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] 21+ 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 ` [PATCH] usb: core: Fix bandwidth for devices with invalid wBytesPerInterval Michal Pecio 1 sibling, 2 replies; 21+ 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] 21+ 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; 21+ 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] 21+ 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) 2026-04-22 13:26 ` Xuetao (kirin) 1 sibling, 1 reply; 21+ 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] 21+ messages in thread
* Re: [PATCH] usb: core: Fix bandwidth for devices with invalid wBytesPerInterval 2026-04-03 1:20 ` Xuetao (kirin) @ 2026-04-22 13:26 ` Xuetao (kirin) 2026-04-23 9:05 ` Michal Pecio 0 siblings, 1 reply; 21+ messages in thread From: Xuetao (kirin) @ 2026-04-22 13:26 UTC (permalink / raw) To: Greg KH, Alan Stern Cc: linux-usb, linux-kernel, caiyadong, stable, Michal Pecio 在 2026/4/3 9:20, Xuetao (kirin) 写道: > > > 在 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. > By adding debug and capturing USB protocol analyzer traces, I have identified the pattern of this issue: 1. Why doesn't the Realtek USB 3.0 network adapter have this problem? Realtek has two different types of interrupt endpoints: (1) wMaxPacketSize = 0x10, bMaxBurst = 0, wBytesPerInterval = 0x8 (2) wMaxPacketSize = 0x2, bMaxBurst = 0, wBytesPerInterval = 0x2 The Realtek network adapter uses the r8152.c driver. In rtl8152_open() -> usb_submit_urb(tp->intr_urb, GFP_KERNEL), the length of tp->intr_urb is fixed at 0x2. The Realtek USB 3.0 network adapter uses the endpoint with wBytesPerInterval = 0x2 for network status queries. Since wBytesPerInterval = wMaxPacketSize × (bMaxBurst + 1) = 2, there is no problem. 2. The ASIX AX88179 USB 3.0 network adapter exhibits two different symptoms: ASIX AX88179 has two different interrupt endpoint descriptors: (1) wMaxPacketSize = 0x10, bMaxBurst = 0, wBytesPerInterval = 0x0 (2) wMaxPacketSize = 0x10, bMaxBurst = 0, wBytesPerInterval = 0x8 The ASIX AX88179 network adapter uses the ax88179_178a.c driver. In usbnet_open() -> usbnet_status_start() -> usb_submit_urb(dev->interrupt, mem_flags), the length of dev->interrupt is 0x10. (1) When wBytesPerInterval = 0x8: When the software submits the INT URB, the host controller can normally send an INT IN request. If the device returns data length ≤ 8 bytes, the host and device interact normally, and the network works. However, if the network adapter responds within one interval with a packet carrying 16 bytes of data, a specific host controller reports a babble error, causing network failure. (2) When wBytesPerInterval = 0x0: The host controller does not reserve any bandwidth for the device. When the software submits the INT URB, a specific host controller does not issue an INT IN request to the device, nor does it report an error to the software. The device controller never receives the INT IN request, so the network fails. Verification results: Patch 1: In usb_parse_ss_endpoint_companion(), if the interrupt endpoint's wBytesPerInterval is 0, set wBytesPerInterval to wMaxPacketSize × (bMaxBurst + 1). Result 1: This resolves the issue for ASIX AX88179 adapters with wBytesPerInterval = 0. However, for the scenario where wBytesPerInterval = 0x8, wMaxPacketSize = 0x10, and the device returns a 16-byte data payload, a babble error still occurs. Patch 2: In xhci_get_max_esit_payload(), when udev->speed >= USB_SPEED_SUPER, for interrupt endpoints return the maximum value between ep->ss_ep_comp.wBytesPerInterval and (max_burst + 1) × max_packet. Result 2: This resolves both scenarios described above. The only downside is that this modification may cause the host to waste a small amount of bandwidth. > 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] 21+ messages in thread
* Re: [PATCH] usb: core: Fix bandwidth for devices with invalid wBytesPerInterval 2026-04-22 13:26 ` Xuetao (kirin) @ 2026-04-23 9:05 ` Michal Pecio 2026-04-23 9:06 ` [PATCH 1/2] usb: core: Fix root hub descriptor wBytesPerInterval Michal Pecio 0 siblings, 1 reply; 21+ messages in thread From: Michal Pecio @ 2026-04-23 9:05 UTC (permalink / raw) To: Xuetao (kirin) Cc: Greg KH, Alan Stern, linux-usb, linux-kernel, caiyadong, stable On Wed, 22 Apr 2026 21:26:23 +0800, Xuetao (kirin) wrote: > By adding debug and capturing USB protocol analyzer traces, I have > identified the pattern of this issue: > > 1. Why doesn't the Realtek USB 3.0 network adapter have this problem? > > Realtek has two different types of interrupt endpoints: > (1) wMaxPacketSize = 0x10, bMaxBurst = 0, wBytesPerInterval = 0x8 > (2) wMaxPacketSize = 0x2, bMaxBurst = 0, wBytesPerInterval = 0x2 > > The Realtek network adapter uses the r8152.c driver. In > rtl8152_open() -> usb_submit_urb(tp->intr_urb, GFP_KERNEL), the > length of tp->intr_urb is fixed at 0x2. > The Realtek USB 3.0 network adapter uses the endpoint with > wBytesPerInterval = 0x2 for network status queries. Since > wBytesPerInterval = wMaxPacketSize × (bMaxBurst + 1) = 2, there is no > problem. ... until it's switched to its CDC configuration with a kernel patch, then there is a problem. That CDC endpoint sends more than 8 bytes. CDC is used as fallback on chip revs not yet supported by r8152 and we aren't sure if future chips will fix their descriptors. > 2. The ASIX AX88179 USB 3.0 network adapter exhibits two different > symptoms: > > ASIX AX88179 has two different interrupt endpoint descriptors: > (1) wMaxPacketSize = 0x10, bMaxBurst = 0, wBytesPerInterval = 0x0 > (2) wMaxPacketSize = 0x10, bMaxBurst = 0, wBytesPerInterval = 0x8 > > The ASIX AX88179 network adapter uses the ax88179_178a.c driver. In > usbnet_open() -> usbnet_status_start() -> > usb_submit_urb(dev->interrupt, mem_flags), the length of > dev->interrupt is 0x10. > > (1) When wBytesPerInterval = 0x8: When the software submits the INT > URB, the host controller can normally send an INT IN request. If the > device returns data length ≤ 8 bytes, the host and device interact > normally, and the network works. > However, if the network adapter responds within one interval with a > packet carrying 16 bytes of data, a specific host controller reports > a babble error, causing network failure. > > (2) When wBytesPerInterval = 0x0: The host controller does not > reserve any bandwidth for the device. When the software submits the > INT URB, a specific host controller does not issue an INT IN request > to the device, nor does it report an error to the software. I think it's a HW bug because USB specs allow zero-length interrupt transfers, though an inconsequential one if no device uses them. These patches will work around it, because zero wMaxPacketSize is disallowed by USB3 spec (though not by earlier ones) so wBPI will always increase to at least 1. > Verification results: > > Patch 1: > In usb_parse_ss_endpoint_companion(), if the interrupt endpoint's > wBytesPerInterval is 0, set wBytesPerInterval to wMaxPacketSize × > (bMaxBurst + 1). > > Result 1: > This resolves the issue for ASIX AX88179 adapters with > wBytesPerInterval = 0. However, for the scenario where > wBytesPerInterval = 0x8, wMaxPacketSize = 0x10, and the device > returns a 16-byte data payload, a babble error still occurs. And it will be same thing for RTL8153 CDC. This is too strict. > Patch 2: > In xhci_get_max_esit_payload(), when udev->speed >= USB_SPEED_SUPER, > for interrupt endpoints return the maximum value between > ep->ss_ep_comp.wBytesPerInterval and (max_burst + 1) × max_packet. > > Result 2: > This resolves both scenarios described above. The only downside is > that this modification may cause the host to waste a small amount of > bandwidth. I wrote a small patch which adds very similar logic to usb_parse_ss_endpoint_companion(). This has two benefits: 1. Backportability - ESIT payload code has been refactored recently. 2. We can easily log when the tweak is performed, once per device. Maybe some HW vendors will notice and clean up their act. Regards, Michal ^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 1/2] usb: core: Fix root hub descriptor wBytesPerInterval 2026-04-23 9:05 ` Michal Pecio @ 2026-04-23 9:06 ` Michal Pecio 2026-04-23 9:09 ` [PATCH 2/2] usb: core: Fix up Interrupt IN endpoints with bogus wBytesPerInterval Michal Pecio 0 siblings, 1 reply; 21+ messages in thread From: Michal Pecio @ 2026-04-23 9:06 UTC (permalink / raw) To: Xuetao (kirin) Cc: Greg KH, Alan Stern, linux-usb, linux-kernel, caiyadong, stable Per USB3 9.6.7, it's "the total number of bytes this endpoint will transfer every service interval". There seems to be no good reason to have wBytesPerInterval < wMaxPacketSize - either one is too low or the other too high. Here, wBytesPerInterval is too low for hubs with more than 15 ports and xHCI spec allows such root hubs. This is inconsequential for emulated root hubs, but we may want to override and log suspiciously low wBytesPerInterval in descriptors, so fix this to prevent nuisance warnings. Signed-off-by: Michal Pecio <michal.pecio@gmail.com> --- drivers/usb/core/hcd.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 89221f1ce769..fc8130f94ca5 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -339,7 +339,8 @@ static const u8 ss_rh_config_descriptor[] = { /* Companion */ 0x00, /* __u8 ss_bMaxBurst; allows 1 TX between ACKs */ 0x00, /* __u8 ss_bmAttributes; 1 packet per service interval */ - 0x02, 0x00 /* __le16 ss_wBytesPerInterval; 15 bits for max 15 ports */ + /* __le16 ss_wBytesPerInterval; same as wMaxPacketSize */ + (USB_MAXCHILDREN + 1 + 7) / 8, 0x00, }; /* authorized_default behaviour: -- 2.48.1 ^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 2/2] usb: core: Fix up Interrupt IN endpoints with bogus wBytesPerInterval 2026-04-23 9:06 ` [PATCH 1/2] usb: core: Fix root hub descriptor wBytesPerInterval Michal Pecio @ 2026-04-23 9:09 ` Michal Pecio 2026-04-23 14:04 ` Alan Stern 0 siblings, 1 reply; 21+ messages in thread From: Michal Pecio @ 2026-04-23 9:09 UTC (permalink / raw) To: Xuetao (kirin) Cc: Greg KH, Alan Stern, linux-usb, linux-kernel, caiyadong, stable Tao Xue found that some common devices violate USB3 section 9.6.7 by reporting wBytesPerInterval lower than the size of packets they actually send. I confirmed that AX88179 may set it to 0 and RTL8153 CDC configuration sets it to 8 but sends both 8 and 16 byte packets: S Ii:11:007:3 -115:128 16 < C Ii:11:007:3 0:128 8 = a1000000 01000000 S Ii:11:007:3 -115:128 16 < C Ii:11:007:3 0:128 16 = a12a0000 01000800 00000000 00000000 Most xHCI host controllers neglect interrupt bandwidth reservations and let such devices exceed theirs, some fail the URB with EOVERFLOW. Assume that wBytesPerInterval lower than wMaxPacketSize is bogus and increase it to the worst case maximum on interrupt IN endpoints. This solves xHCI problems and appears to have no other effect. Interrupt transfers are not limited to one interval and drivers submit URBs of class defined size without looking at wBytesPerInterval. Any multi- interval transfer is considered terminated by a packet shorter than wMaxPacketSize regardless of wBytesPerInterval - see USB3 8.10.3. Stay in spec on OUT endpoints and isochronous. No buggy devices are known and we don't want to risk sending more data than the device is prepared to handle or confusing isoc drivers regarding altsetting capacities guaranteed by the device itself. And don't complain when wMaxPacketSize <= wBytesPerInterval < wMaxPacketSize * (bMaxBurst+1) because enabling this seems to be the exact goal of the spec. Reported-by: Tao Xue <xuetao09@huawei.com> Closes: https://lore.kernel.org/linux-usb/20260402021400.28853-1-xuetao09@huawei.com/ Cc: stable@vger.kernel.org Signed-off-by: Michal Pecio <michal.pecio@gmail.com> --- Note: Compared to original suggestion, this is a conservative patch which only addresses known broken devices and tries to minimize disruption for spec compliant ones. drivers/usb/core/config.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c index 6a1fd967e0a6..bdd912627bac 100644 --- a/drivers/usb/core/config.c +++ b/drivers/usb/core/config.c @@ -191,7 +191,14 @@ static void usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno, (desc->bMaxBurst + 1); else max_tx = 999999; - if (le16_to_cpu(desc->wBytesPerInterval) > max_tx) { + /* + * wBytesPerInterval > max_tx is bogus, but USB3 spec doesn't forbid the opposite. + * Experience shows that wBytesPerInterval < wMaxPacketSize on common interrupt IN + * endpoints is usually bogus too, and recent HCs enforce interrupt BW limits. + */ + if (le16_to_cpu(desc->wBytesPerInterval) > max_tx || + (le16_to_cpu(desc->wBytesPerInterval) < usb_endpoint_maxp(&ep->desc) && + usb_endpoint_xfer_int(&ep->desc) && usb_endpoint_dir_in(&ep->desc))) { dev_notice(ddev, "%s endpoint with wBytesPerInterval of %d in " "config %d interface %d altsetting %d ep %d: " "setting to %d\n", -- 2.48.1 ^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [PATCH 2/2] usb: core: Fix up Interrupt IN endpoints with bogus wBytesPerInterval 2026-04-23 9:09 ` [PATCH 2/2] usb: core: Fix up Interrupt IN endpoints with bogus wBytesPerInterval Michal Pecio @ 2026-04-23 14:04 ` Alan Stern 2026-04-23 14:55 ` Xuetao (kirin) 0 siblings, 1 reply; 21+ messages in thread From: Alan Stern @ 2026-04-23 14:04 UTC (permalink / raw) To: Michal Pecio Cc: Xuetao (kirin), Greg KH, linux-usb, linux-kernel, caiyadong, stable On Thu, Apr 23, 2026 at 11:09:59AM +0200, Michal Pecio wrote: > Tao Xue found that some common devices violate USB3 section 9.6.7 > by reporting wBytesPerInterval lower than the size of packets they > actually send. I confirmed that AX88179 may set it to 0 and RTL8153 > CDC configuration sets it to 8 but sends both 8 and 16 byte packets: > > S Ii:11:007:3 -115:128 16 < > C Ii:11:007:3 0:128 8 = a1000000 01000000 > S Ii:11:007:3 -115:128 16 < > C Ii:11:007:3 0:128 16 = a12a0000 01000800 00000000 00000000 > > Most xHCI host controllers neglect interrupt bandwidth reservations > and let such devices exceed theirs, some fail the URB with EOVERFLOW. > > Assume that wBytesPerInterval lower than wMaxPacketSize is bogus and > increase it to the worst case maximum on interrupt IN endpoints. This > solves xHCI problems and appears to have no other effect. Interrupt > transfers are not limited to one interval and drivers submit URBs of > class defined size without looking at wBytesPerInterval. Any multi- > interval transfer is considered terminated by a packet shorter than > wMaxPacketSize regardless of wBytesPerInterval - see USB3 8.10.3. > > Stay in spec on OUT endpoints and isochronous. No buggy devices are > known and we don't want to risk sending more data than the device > is prepared to handle or confusing isoc drivers regarding altsetting > capacities guaranteed by the device itself. And don't complain when > wMaxPacketSize <= wBytesPerInterval < wMaxPacketSize * (bMaxBurst+1) > because enabling this seems to be the exact goal of the spec. > > Reported-by: Tao Xue <xuetao09@huawei.com> > Closes: https://lore.kernel.org/linux-usb/20260402021400.28853-1-xuetao09@huawei.com/ > Cc: stable@vger.kernel.org > Signed-off-by: Michal Pecio <michal.pecio@gmail.com> > --- > > Note: > Compared to original suggestion, this is a conservative patch which > only addresses known broken devices and tries to minimize disruption > for spec compliant ones. > > drivers/usb/core/config.c | 9 ++++++++- > 1 file changed, 8 insertions(+), 1 deletion(-) > > diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c > index 6a1fd967e0a6..bdd912627bac 100644 > --- a/drivers/usb/core/config.c > +++ b/drivers/usb/core/config.c > @@ -191,7 +191,14 @@ static void usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno, > (desc->bMaxBurst + 1); > else > max_tx = 999999; > - if (le16_to_cpu(desc->wBytesPerInterval) > max_tx) { > + /* > + * wBytesPerInterval > max_tx is bogus, but USB3 spec doesn't forbid the opposite. > + * Experience shows that wBytesPerInterval < wMaxPacketSize on common interrupt IN > + * endpoints is usually bogus too, and recent HCs enforce interrupt BW limits. > + */ > + if (le16_to_cpu(desc->wBytesPerInterval) > max_tx || > + (le16_to_cpu(desc->wBytesPerInterval) < usb_endpoint_maxp(&ep->desc) && > + usb_endpoint_xfer_int(&ep->desc) && usb_endpoint_dir_in(&ep->desc)) You can use usb_endpoint_is_int_in() here. Alan Stern ) { > dev_notice(ddev, "%s endpoint with wBytesPerInterval of %d in " > "config %d interface %d altsetting %d ep %d: " > "setting to %d\n", > -- > 2.48.1 ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 2/2] usb: core: Fix up Interrupt IN endpoints with bogus wBytesPerInterval 2026-04-23 14:04 ` Alan Stern @ 2026-04-23 14:55 ` Xuetao (kirin) 0 siblings, 0 replies; 21+ messages in thread From: Xuetao (kirin) @ 2026-04-23 14:55 UTC (permalink / raw) To: Alan Stern, Michal Pecio Cc: Greg KH, linux-usb, linux-kernel, caiyadong, stable 在 2026/4/23 22:04, Alan Stern 写道: > On Thu, Apr 23, 2026 at 11:09:59AM +0200, Michal Pecio wrote: >> Tao Xue found that some common devices violate USB3 section 9.6.7 >> by reporting wBytesPerInterval lower than the size of packets they >> actually send. I confirmed that AX88179 may set it to 0 and RTL8153 >> CDC configuration sets it to 8 but sends both 8 and 16 byte packets: >> >> S Ii:11:007:3 -115:128 16 < >> C Ii:11:007:3 0:128 8 = a1000000 01000000 >> S Ii:11:007:3 -115:128 16 < >> C Ii:11:007:3 0:128 16 = a12a0000 01000800 00000000 00000000 >> >> Most xHCI host controllers neglect interrupt bandwidth reservations >> and let such devices exceed theirs, some fail the URB with EOVERFLOW. >> >> Assume that wBytesPerInterval lower than wMaxPacketSize is bogus and >> increase it to the worst case maximum on interrupt IN endpoints. This >> solves xHCI problems and appears to have no other effect. Interrupt >> transfers are not limited to one interval and drivers submit URBs of >> class defined size without looking at wBytesPerInterval. Any multi- >> interval transfer is considered terminated by a packet shorter than >> wMaxPacketSize regardless of wBytesPerInterval - see USB3 8.10.3. >> >> Stay in spec on OUT endpoints and isochronous. No buggy devices are >> known and we don't want to risk sending more data than the device >> is prepared to handle or confusing isoc drivers regarding altsetting >> capacities guaranteed by the device itself. And don't complain when >> wMaxPacketSize <= wBytesPerInterval < wMaxPacketSize * (bMaxBurst+1) >> because enabling this seems to be the exact goal of the spec. >> >> Reported-by: Tao Xue <xuetao09@huawei.com> >> Closes: https://lore.kernel.org/linux-usb/20260402021400.28853-1-xuetao09@huawei.com/ >> Cc: stable@vger.kernel.org >> Signed-off-by: Michal Pecio <michal.pecio@gmail.com> >> --- >> >> Note: >> Compared to original suggestion, this is a conservative patch which >> only addresses known broken devices and tries to minimize disruption >> for spec compliant ones. >> >> drivers/usb/core/config.c | 9 ++++++++- >> 1 file changed, 8 insertions(+), 1 deletion(-) >> >> diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c >> index 6a1fd967e0a6..bdd912627bac 100644 >> --- a/drivers/usb/core/config.c >> +++ b/drivers/usb/core/config.c >> @@ -191,7 +191,14 @@ static void usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno, >> (desc->bMaxBurst + 1); >> else >> max_tx = 999999; >> - if (le16_to_cpu(desc->wBytesPerInterval) > max_tx) { >> + /* >> + * wBytesPerInterval > max_tx is bogus, but USB3 spec doesn't forbid the opposite. >> + * Experience shows that wBytesPerInterval < wMaxPacketSize on common interrupt IN >> + * endpoints is usually bogus too, and recent HCs enforce interrupt BW limits. >> + */ >> + if (le16_to_cpu(desc->wBytesPerInterval) > max_tx || >> + (le16_to_cpu(desc->wBytesPerInterval) < usb_endpoint_maxp(&ep->desc) && >> + usb_endpoint_xfer_int(&ep->desc) && usb_endpoint_dir_in(&ep->desc)) > You can use usb_endpoint_is_int_in() here. > > Alan Stern I tested the current patch, and it resolves the issue I encountered before. I believe this patch is effective. I also just tested the modification that replaces usb_endpoint_xfer_int(&ep->desc) && usb_endpoint_dir_in(&ep->desc) with usb_endpoint_is_int_in(&ep->desc), and it works as well. > > ) { >> dev_notice(ddev, "%s endpoint with wBytesPerInterval of %d in " >> "config %d interface %d altsetting %d ep %d: " >> "setting to %d\n", >> -- >> 2.48.1 ^ permalink raw reply [flat|nested] 21+ 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; 21+ 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] 21+ 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; 21+ 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] 21+ 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; 21+ 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] 21+ 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 2026-04-22 6:32 ` Michal Pecio 0 siblings, 1 reply; 21+ 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] 21+ messages in thread
* Re: [PATCH] usb: core: Fix bandwidth for devices with invalid wBytesPerInterval 2026-04-03 7:16 ` Michal Pecio @ 2026-04-22 6:32 ` Michal Pecio 0 siblings, 0 replies; 21+ messages in thread From: Michal Pecio @ 2026-04-22 6:32 UTC (permalink / raw) To: Xuetao (kirin); +Cc: gregkh, linux-usb, linux-kernel, caiyadong, stable On Fri, 3 Apr 2026 09:16:21 +0200, Michal Pecio wrote: > 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. I think this issue hasn't been solved yet? > > 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. I have done some experimentation with RTL8153 CDC configuration and found that it responds with 8 and 16 byte packets alternately: # modprobe usbmon # cat /sys/kernel/debug/usb/usbmon/0u # ifconfig eth1 up [...] ffff88812bcc1600 364545038 S Ii:11:007:3 -115:128 16 < ffff88812bcc1600 364577011 C Ii:11:007:3 0:128 8 = a1000000 01000000 ffff88812bcc1600 364577037 S Ii:11:007:3 -115:128 16 < ffff88812bcc1600 364608979 C Ii:11:007:3 0:128 16 = a12a0000 01000800 00000000 00000000 I'm curious how your HC would treat this, because technically it should interpret the first packet of wBytesPerInterval size as a partial transfer and continue the same URB in the next interval, then complete it with babble due to 16B packet exceeding both wBPI and URB capacity. Other HCs work like that if I do the opposite and reduce wMaxPacketSize to match wBytesPerInterval. We would need to perform this alternative fixup for devices where wBytesPerInterval is correct and 16B transfers are sent as two 8B packets oven two intervals, while wMaxPacketSize is more than wBPI. I hope no such insane devices exist. Currently, they wouldn't work on the vast majority of HCs. > > 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. My driver submits 8B URBs because my AX88179 has wMaxPacketSize of 8. On your device usbnet would submit 16B URBs. So I'm curious, how much does your AX88179 send in response to those URBs? Regards, Michal ^ permalink raw reply [flat|nested] 21+ messages in thread
end of thread, other threads:[~2026-04-23 14:55 UTC | newest] Thread overview: 21+ 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-22 13:26 ` Xuetao (kirin) 2026-04-23 9:05 ` Michal Pecio 2026-04-23 9:06 ` [PATCH 1/2] usb: core: Fix root hub descriptor wBytesPerInterval Michal Pecio 2026-04-23 9:09 ` [PATCH 2/2] usb: core: Fix up Interrupt IN endpoints with bogus wBytesPerInterval Michal Pecio 2026-04-23 14:04 ` Alan Stern 2026-04-23 14:55 ` Xuetao (kirin) 2026-04-02 20:17 ` [PATCH] usb: core: Fix bandwidth for devices with invalid wBytesPerInterval Michal Pecio 2026-04-02 9:44 ` Michal Pecio 2026-04-02 11:55 ` Xuetao (kirin) 2026-04-03 7:16 ` Michal Pecio 2026-04-22 6:32 ` Michal Pecio
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox