public inbox for linux-usb@vger.kernel.org
 help / color / mirror / Atom feed
From: Michal Pecio <michal.pecio@gmail.com>
To: Tao Xue <xuetao09@huawei.com>
Cc: <gregkh@linuxfoundation.org>, <linux-usb@vger.kernel.org>,
	<linux-kernel@vger.kernel.org>, <caiyadong@huawei.com>,
	<stable@kernel.org>
Subject: Re: [PATCH] usb: core: Fix bandwidth for devices with invalid wBytesPerInterval
Date: Thu, 2 Apr 2026 11:44:21 +0200	[thread overview]
Message-ID: <20260402114421.738e375a.michal.pecio@gmail.com> (raw)
In-Reply-To: <20260402021400.28853-1-xuetao09@huawei.com>

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
> 

  parent reply	other threads:[~2026-04-02  9:44 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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 [this message]
2026-04-02 11:55   ` Xuetao (kirin)
2026-04-03  7:16     ` Michal Pecio

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260402114421.738e375a.michal.pecio@gmail.com \
    --to=michal.pecio@gmail.com \
    --cc=caiyadong@huawei.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=stable@kernel.org \
    --cc=xuetao09@huawei.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox