* TT budgeting for EHCI; accommodate 1023-byte full-speed isochronous–in endpoints
@ 2026-04-28 1:24 Brent Page
2026-04-28 21:19 ` Alan Stern
0 siblings, 1 reply; 12+ messages in thread
From: Brent Page @ 2026-04-28 1:24 UTC (permalink / raw)
To: stern; +Cc: linux-usb
Hello,
I recently encountered the ENOSPC error mentioned here (https://lkml.org/lkml/2013/2/19/482) when trying to communicate with a full-speed peripheral with one isochronous–in endpoint with a wMaxPacketSize of 1023. N.b., that patch was reverted (https://lkml.org/lkml/2013/6/18/458). I think it should be tried again with a different approach. Namely, I propose multiplying the max_tt_usecs values in ehci-sched.c by the worst-case bit-stuffing multiplier, 7/6, making them
- max_tt_usecs[] = { 125, 125, 125, 125, 125, 125, 30, 0 };
+ max_tt_usecs[] = { 145, 145, 145, 145, 145, 145, 35, 0 };
After I make this simple change, along with a few other 125->145 substitutions in ehci-sched.c, my linux tablet is able to establish a steady data link with my 1023-byte-endpoint peripheral.
Obviously, 145 us is longer than a microframe, so this best-case budget will often not reflect the times when transactions occur. But, this situation is consistent with the best-case budget in section 11.18.1 of the USB-2 spec, in which 1157 data-bytes are scheduled to occur as though no bit-stuffing necessary (i.e., the 188 bytes = 12 megabits/second * (1 byte/8 bits)* 0.125 ms that can run on the full-speed bus in a microframe are all taken taken be data-bytes). So, after the patch, max_tt_usecs is the same as the spec's best-case budget but is just scaled by (125 us / 188 bytes) = 1/(12 megabits/s) and by the 7/6 bit-stuffing multiplier to reflect the fact that the scheduling code works in bit-stuffing-inclusive bus-time instead of data-bytes.
To try to further dispel concerns stemming from 145 > 125, I'll point out that, if a given microframe is budgeted close to 145 us of TT time using the calculations in ehci-sched.c, it will sometimes be the case that the associated transactions take less than 125 us, so they will run successfully within the microframe. In particular, this will happen if the transactions require very little bit stuffing.
Previous EHCI scheduling work has also noted that obeying the spec entails the possibility of overcommitting the TT. See the comments below from https://marc.info/?l=linux-usb-devel&m=115933214319141&w=4
+/* Because EHCI cannot issue ssplits in uframe 7 and USB 2.0 does not
+ allow ssplits in uframe 6, EHCI can only generate an efficient FS
+ frame by scheduling according to best-case (not worst-case) bit
+ stuffing. Thus we purposely 'overcommit' the FS frame budget
+ within the buffering ability of the TT to buffer, and within the
+ limits of the 90/10 rule. The TT will catch up in the microframes
+ where we cannot issue start splits.
+*/
"/* Scheduling through a TT is done by byte counting, not usec
+ counting. Because we cannot issue a FS/LS start split in
+ uFrame 6 or 7, the only way to get anywhere near a full 90%
+ of a FS frame for periodic transactions is to 'overcommit'
+ the FS scheduling of each microframe [when considered by
+ usecs needed for the transfer]. This is not actually
+ overcommitting as the TT will buffer the 'excess' from any
+ uFrame and schedule it to transmit in a later uFrame. USB
+ 2.0 11.18.4: "Scheduling of split transactions is done by
+ the host (typically in software) based on a best-case
+ estimate of how the full-/low-speed transacitons can be run
+ on the downstream facing bus." */"
From,
Brent Page
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: TT budgeting for EHCI; accommodate 1023-byte full-speed isochronous–in endpoints
2026-04-28 1:24 TT budgeting for EHCI; accommodate 1023-byte full-speed isochronous–in endpoints Brent Page
@ 2026-04-28 21:19 ` Alan Stern
2026-04-29 9:36 ` Michal Pecio
0 siblings, 1 reply; 12+ messages in thread
From: Alan Stern @ 2026-04-28 21:19 UTC (permalink / raw)
To: Brent Page; +Cc: linux-usb
In the future, please tell your email client to wrap text lines after 72
columns or thereabouts. Single-line paragraphs are hard to deal with.
On Mon, Apr 27, 2026 at 06:24:58PM -0700, Brent Page wrote:
> Hello,
>
> I recently encountered the ENOSPC error mentioned here (https://lkml.org/lkml/2013/2/19/482) when trying to communicate with a full-speed peripheral with one isochronous–in endpoint with a wMaxPacketSize of 1023. N.b., that patch was reverted (https://lkml.org/lkml/2013/6/18/458). I think it should be tried again with a different approach. Namely, I propose multiplying the max_tt_usecs values in ehci-sched.c by the worst-case bit-stuffing multiplier, 7/6, making them
> - max_tt_usecs[] = { 125, 125, 125, 125, 125, 125, 30, 0 };
> + max_tt_usecs[] = { 145, 145, 145, 145, 145, 145, 35, 0 };
> After I make this simple change, along with a few other 125->145 substitutions in ehci-sched.c, my linux tablet is able to establish a steady data link with my 1023-byte-endpoint peripheral.
> Obviously, 145 us is longer than a microframe, so this best-case budget will often not reflect the times when transactions occur. But, this situation is consistent with the best-case budget in section 11.18.1 of the USB-2 spec, in which 1157 data-bytes are scheduled to occur as though no bit-stuffing necessary (i.e., the 188 bytes = 12 megabits/second * (1 byte/8 bits)* 0.125 ms that can run on the full-speed bus in a microframe are all taken taken be data-bytes). So, after the patch, max_tt_usecs is the same as the spec's best-case budget but is just scaled by (125 us / 188 bytes) = 1/(12 megabits/s) and by the 7/6 bit-stuffing multiplier to reflect the fact that the scheduling code works in bit-stuffing-inclusive bus-time instead of data-bytes.
Section 11.18.1 is a marvel of inconsistency. The text and the figure
caption say that the estimate assumes no bit-stuffing, but the formula
clearly includes a 6/7 bit-stuffing factor.
I think what it means is that the maximum number of periodic data bytes
that can be scheduled for one frame on a full-speed bus is 1157, since
transaction scheduling does have to take bit-stuffing into account. See
the formulas in section 5.11.3. Even that value is an overestimate,
because it does not reserve time for packet headers and other forms of
overhead. Figure 11-60 shows the budgeting estimate for those 1157
bytes, under the assumption that they do not need to be bit-stuffed.
Since the value of stream->ps.tt_usecs calculated in iso_stream_init()
does include the 7/6 bit-stuffing factor, it makes sense to adjust the
us-per-uframe values to reverse that effect for purposes of budgeting.
It would be more in the spirit of the spec to do the budgeting in terms
of bytes rather than microseconds, but since it's all estimates anyway
this shouldn't matter.
> To try to further dispel concerns stemming from 145 > 125, I'll point out that, if a given microframe is budgeted close to 145 us of TT time using the calculations in ehci-sched.c, it will sometimes be the case that the associated transactions take less than 125 us, so they will run successfully within the microframe. In particular, this will happen if the transactions require very little bit stuffing.
That's not a consideration. Although the spec doesn't say so
explicitly, it's clear that the budgeting calculations are only
estimates and full-speed bus transactions may actually start as much as
two microframes after their budgeted start time.
> Previous EHCI scheduling work has also noted that obeying the spec entails the possibility of overcommitting the TT. See the comments below from https://marc.info/?l=linux-usb-devel&m=115933214319141&w=4
>
> +/* Because EHCI cannot issue ssplits in uframe 7 and USB 2.0 does not
> + allow ssplits in uframe 6, EHCI can only generate an efficient FS
> + frame by scheduling according to best-case (not worst-case) bit
> + stuffing. Thus we purposely 'overcommit' the FS frame budget
> + within the buffering ability of the TT to buffer, and within the
> + limits of the 90/10 rule. The TT will catch up in the microframes
> + where we cannot issue start splits.
> +*/
>
> "/* Scheduling through a TT is done by byte counting, not usec
> + counting. Because we cannot issue a FS/LS start split in
> + uFrame 6 or 7, the only way to get anywhere near a full 90%
> + of a FS frame for periodic transactions is to 'overcommit'
> + the FS scheduling of each microframe [when considered by
> + usecs needed for the transfer]. This is not actually
> + overcommitting as the TT will buffer the 'excess' from any
> + uFrame and schedule it to transmit in a later uFrame. USB
> + 2.0 11.18.4: "Scheduling of split transactions is done by
> + the host (typically in software) based on a best-case
> + estimate of how the full-/low-speed transacitons can be run
> + on the downstream facing bus." */"
We cannot take these quotations seriously. They are 20 years old, and
they refer to code that was never accepted into the kernel.
Nevertheless, overall this is a good suggestion. Please post your patch
for further review.
Alan Stern
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: TT budgeting for EHCI; accommodate 1023-byte full-speed isochronous–in endpoints
2026-04-28 21:19 ` Alan Stern
@ 2026-04-29 9:36 ` Michal Pecio
2026-04-29 11:58 ` Michal Pecio
2026-04-29 17:56 ` Alan Stern
0 siblings, 2 replies; 12+ messages in thread
From: Michal Pecio @ 2026-04-29 9:36 UTC (permalink / raw)
To: Alan Stern; +Cc: Brent Page, linux-usb
> On Mon, Apr 27, 2026 at 06:24:58PM -0700, Brent Page wrote:
> > I recently encountered the ENOSPC error mentioned here
> > (https://lkml.org/lkml/2013/2/19/482) when trying to communicate
> > with a full-speed peripheral with one isochronous–in endpoint with
> > a wMaxPacketSize of 1023. N.b., that patch was reverted
> > (https://lkml.org/lkml/2013/6/18/458). I think it should be tried
> > again with a different approach.
Out of curiosity, what sort of device? This bug used to annoy me too at
one point, but my device was a DSL modem, not easy to experiment with.
On Tue, 28 Apr 2026 17:19:01 -0400, Alan Stern wrote:
> Section 11.18.1 is a marvel of inconsistency. The text and the
> figure caption say that the estimate assumes no bit-stuffing, but the
> formula clearly includes a 6/7 bit-stuffing factor.
I don't think it's inconsistent, it makes sense the way you explain.
> I think what it means is that the maximum number of periodic data
> bytes that can be scheduled for one frame on a full-speed bus is
> 1157, since transaction scheduling does have to take bit-stuffing
> into account. See the formulas in section 5.11.3. Even that value
> is an overestimate, because it does not reserve time for packet
> headers and other forms of overhead. Figure 11-60 shows the
> budgeting estimate for those 1157 bytes, under the assumption that
> they do not need to be bit-stuffed.
The host must schedule SSPLITs assuming no bit-stuffing to prevent TT
buffer underrun on long OUT packets. Assuming minimum/no packet headers
further minimizes downstream idle. TTs are required to buffer this.
(BTW, periodic transfers should occur before async. Could the TT run
out of periodic, do async, then get an unexpected periodic transaction
in the next uframe? What happens?)
Including packet headers for SSPLIT scheduling seems harmless unless
overestimated, but apparently it's not required. TTs must cope.
Separately, for go/no-go (ENOSPC) decisions, the host should consider
all overhead in order to guarantee >10% downstream time for async.
Max payload is still close to 1157 because it may be just two packets.
That's how I see it.
> Since the value of stream->ps.tt_usecs calculated in
> iso_stream_init() does include the 7/6 bit-stuffing factor, it makes
> sense to adjust the us-per-uframe values to reverse that effect for
> purposes of budgeting. It would be more in the spirit of the spec to
> do the budgeting in terms of bytes rather than microseconds, but
> since it's all estimates anyway this shouldn't matter.
Not entirely sure about it, *if* these computations are later used to
schedule SSPLIT or CSPLIT transactions. That needs to be exact IMO.
Does anyone understand why the previous attempt at enabling 1023 byte
isoc IN resulted in isoc OUT corruption?
BTW, does ehci-hcd support scheduling CSPLITs to Y0 of the next frame?
It's an edge case which likely won't occur with one 1023 byte endpoint,
but it may occur with more periodic endpoints and unlucky bit stuffing
or with periodic BW limit carefully increased for testing purposes.
Regards,
Michal
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: TT budgeting for EHCI; accommodate 1023-byte full-speed isochronous–in endpoints
2026-04-29 9:36 ` Michal Pecio
@ 2026-04-29 11:58 ` Michal Pecio
2026-04-29 17:56 ` Alan Stern
1 sibling, 0 replies; 12+ messages in thread
From: Michal Pecio @ 2026-04-29 11:58 UTC (permalink / raw)
To: Alan Stern; +Cc: Brent Page, linux-usb
On Wed, 29 Apr 2026 11:36:04 +0200, Michal Pecio wrote:
> The host must schedule SSPLITs assuming no bit-stuffing to prevent TT
> buffer underrun on long OUT packets. Assuming minimum/no packet headers
> further minimizes downstream idle. TTs are required to buffer this.
>
> (BTW, periodic transfers should occur before async. Could the TT run
> out of periodic, do async, then get an unexpected periodic transaction
> in the next uframe? What happens?)
>
> Including packet headers for SSPLIT scheduling seems harmless unless
> overestimated, but apparently it's not required. TTs must cope.
Or maybe not, because 11.18.2 states that "budgeting" includes packet
overhead and think time. And TT must handle gaps in periodic schedule
due to short transfers and deal with not knowing whether there will be
periodic transfers in the next uframe till the last moment.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: TT budgeting for EHCI; accommodate 1023-byte full-speed isochronous–in endpoints
2026-04-29 9:36 ` Michal Pecio
2026-04-29 11:58 ` Michal Pecio
@ 2026-04-29 17:56 ` Alan Stern
2026-04-29 19:24 ` Michal Pecio
1 sibling, 1 reply; 12+ messages in thread
From: Alan Stern @ 2026-04-29 17:56 UTC (permalink / raw)
To: Michal Pecio; +Cc: Brent Page, linux-usb
On Wed, Apr 29, 2026 at 11:36:04AM +0200, Michal Pecio wrote:
> The host must schedule SSPLITs assuming no bit-stuffing to prevent TT
> buffer underrun on long OUT packets. Assuming minimum/no packet headers
> further minimizes downstream idle. TTs are required to buffer this.
There's a difference between scheduling and budgeting; it sounds like
you are mixing them up. Roughly speaking, scheduling refers to when
transactions actually take place whereas budgeting is concerned with
when a full/low-speed transaction's SSPLITs and CSPLITs take place.
So the host budgets SSPLITs, it doesn't schedule them. (Well, I suppose
it does also schedule them, because we don't want to send too many
SSPLITs to too many different hubs and TTs in any one microframe and
thereby overload the high-speed bus, but that's not what we're talking
about here.) TT buffer underrun on long OUT transactions doesn't take
place, because even if only, say, 10 bytes from the start of a 500-byte
isochronous transaction are budgeted for a particular microframe, the
host controller will send a full 188 data bytes in the SSPLIT
transaction.
> (BTW, periodic transfers should occur before async. Could the TT run
> out of periodic, do async, then get an unexpected periodic transaction
> in the next uframe? What happens?)
This can't happen as long as each SSPLIT transfers the smaller of 188
bytes or the number of bytes remaining.
> Including packet headers for SSPLIT scheduling seems harmless unless
> overestimated, but apparently it's not required. TTs must cope.
Again, budgeting not scheduling, but yes.
> Separately, for go/no-go (ENOSPC) decisions, the host should consider
> all overhead in order to guarantee >10% downstream time for async.
It does. That's scheduling, not budgeting. Both have to be taken into
account.
> Max payload is still close to 1157 because it may be just two packets.
Well, on the full-speed bus there has to be an OUT packet (3 bytes).
Each data packet has to have a PID byte and 2 CRC bytes (another 3).
Isochronous transactions don't have handshakes, but interrupt
transactions do (one more byte). Also, each packet has to start with a
SYNC field (one byte). Then there's EOP (End Of Packet) signalling,
inter-packet delays, and turnaround delays, which are hard to add up.
Plus time required for the SOF packet. Taking it all together, I don't
think you can realistically squeeze more than 1140 periodic data bytes
into a frame, probably less.
> That's how I see it.
>
> > Since the value of stream->ps.tt_usecs calculated in
> > iso_stream_init() does include the 7/6 bit-stuffing factor, it makes
> > sense to adjust the us-per-uframe values to reverse that effect for
> > purposes of budgeting. It would be more in the spirit of the spec to
> > do the budgeting in terms of bytes rather than microseconds, but
> > since it's all estimates anyway this shouldn't matter.
>
> Not entirely sure about it, *if* these computations are later used to
> schedule SSPLIT or CSPLIT transactions. That needs to be exact IMO.
The ps.tt_usecs values are the number of microseconds required behind
the TT, on the full-speed bus. They are used for scheduling on that bus
and for budgeting, but not for scheduling on the high-speed bus. See
the definition of struct ehci_per_sched in host/ehci.h.
> Does anyone understand why the previous attempt at enabling 1023 byte
> isoc IN resulted in isoc OUT corruption?
I don't know if we ever figured it out. It probably had to do with
running up against the limitations of the implementation in ehci-hcd.
> BTW, does ehci-hcd support scheduling CSPLITs to Y0 of the next frame?
> It's an edge case which likely won't occur with one 1023 byte endpoint,
> but it may occur with more periodic endpoints and unlucky bit stuffing
> or with periodic BW limit carefully increased for testing purposes.
It does not support CSPLITs in Y7 of the current frame or Y0 of the next
frame. This is one of those limitations just mentioned. Adding support
would complicate the driver considerably and yield relatively little
benefit now that xHCI is so widespread.
And yes, this does mean that there are some loads ehci-hcd simply can't
handle even though in theory they ought to work. A realistic example is
having large isochronous transfers going on along with some interrupt
transfers; it's not uncommon for audio devices to include both sorts of
endpoints. Ironically, these things work better with an OHCI or UHCI
controller than they do with ehci-hcd.
(IMO the USB-IF misjudged the design for split transactions, putting too
much of the burden on the host controller driver software instead of the
TT hardware. They could have required TTs to have considerably larger
buffers; it would have made things a lot simpler. But no doubt they
were constrained by the hardware's capabilities back then.)
Alan Stern
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: TT budgeting for EHCI; accommodate 1023-byte full-speed isochronous–in endpoints
2026-04-29 17:56 ` Alan Stern
@ 2026-04-29 19:24 ` Michal Pecio
2026-04-29 19:32 ` Alan Stern
0 siblings, 1 reply; 12+ messages in thread
From: Michal Pecio @ 2026-04-29 19:24 UTC (permalink / raw)
To: Alan Stern; +Cc: Brent Page, linux-usb
On Wed, 29 Apr 2026 13:56:01 -0400, Alan Stern wrote:
> On Wed, Apr 29, 2026 at 11:36:04AM +0200, Michal Pecio wrote:
> > The host must schedule SSPLITs assuming no bit-stuffing to prevent TT
> > buffer underrun on long OUT packets. Assuming minimum/no packet headers
> > further minimizes downstream idle. TTs are required to buffer this.
>
> There's a difference between scheduling and budgeting; it sounds like
> you are mixing them up. Roughly speaking, scheduling refers to when
> transactions actually take place whereas budgeting is concerned with
> when a full/low-speed transaction's SSPLITs and CSPLITs take place.
I meant "scheduling" in the sense 11.18.2 and fig 11-61 use this term -
deciding which uframe to execute SSPLITs in. Of course it's practically
equivalent to "budgeting" the downstream transaction, so fair enough.
And what I really meant is that OUT SSPLITs must carry 188 byte payload
each and their count must be appropriate, that's all. If EHCI HW always
sends 188 bytes (if available) without babysitting, that's great.
> > (BTW, periodic transfers should occur before async. Could the TT run
> > out of periodic, do async, then get an unexpected periodic
> > transaction in the next uframe? What happens?)
>
> This can't happen as long as each SSPLIT transfers the smaller of 188
> bytes or the number of bytes remaining.
Yes, but per spec transfers are budgeted based on wMaxPacketSize and
actual SSPLITs may be shorter, while subsequent transfers may still
remain budgeted into a future uframe.
So it seems that TT must cope with gaps. Maybe it's allowed to fill
them with async? I don't know, I haven't found clear answer yet.
> > Including packet headers for SSPLIT scheduling seems harmless unless
> > overestimated, but apparently it's not required. TTs must cope.
>
> Again, budgeting not scheduling, but yes.
As mentioned in the followup correction email, it seems to be required.
If nothing else, it ensures the 16 transactions per uframe limit. Not
sure if blind budgeting solely by limiting data bytes and transactions
per uframe would work as well. Probably not worth finding out.
> > BTW, does ehci-hcd support scheduling CSPLITs to Y0 of the next
> > frame? It's an edge case which likely won't occur with one 1023
> > byte endpoint, but it may occur with more periodic endpoints and
> > unlucky bit stuffing or with periodic BW limit carefully increased
> > for testing purposes.
>
> It does not support CSPLITs in Y7 of the current frame or Y0 of the
> next frame. This is one of those limitations just mentioned.
Then I think it doesn't support 1023 byte packets at all. 1023/188=5.4
and if worst case bit stuffing factor is 7/6 then up to 6.3 uframes of
transfer time. Completion in Y5 or Y6 and CSPLIT required in Y7.
IOW, you play Russian Roulette with bit stuffing if you enable this.
> Adding support would complicate the driver considerably and yield
> relatively little benefit now that xHCI is so widespread.
Fun fact: not all xHCI supports it either.
Regards,
Michal
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: TT budgeting for EHCI; accommodate 1023-byte full-speed isochronous–in endpoints
2026-04-29 19:24 ` Michal Pecio
@ 2026-04-29 19:32 ` Alan Stern
2026-04-29 19:52 ` Brent Page
2026-04-29 20:04 ` Michal Pecio
0 siblings, 2 replies; 12+ messages in thread
From: Alan Stern @ 2026-04-29 19:32 UTC (permalink / raw)
To: Michal Pecio; +Cc: Brent Page, linux-usb
On Wed, Apr 29, 2026 at 09:24:08PM +0200, Michal Pecio wrote:
> On Wed, 29 Apr 2026 13:56:01 -0400, Alan Stern wrote:
> > On Wed, Apr 29, 2026 at 11:36:04AM +0200, Michal Pecio wrote:
> > > The host must schedule SSPLITs assuming no bit-stuffing to prevent TT
> > > buffer underrun on long OUT packets. Assuming minimum/no packet headers
> > > further minimizes downstream idle. TTs are required to buffer this.
> >
> > There's a difference between scheduling and budgeting; it sounds like
> > you are mixing them up. Roughly speaking, scheduling refers to when
> > transactions actually take place whereas budgeting is concerned with
> > when a full/low-speed transaction's SSPLITs and CSPLITs take place.
>
> I meant "scheduling" in the sense 11.18.2 and fig 11-61 use this term -
> deciding which uframe to execute SSPLITs in. Of course it's practically
> equivalent to "budgeting" the downstream transaction, so fair enough.
>
> And what I really meant is that OUT SSPLITs must carry 188 byte payload
> each and their count must be appropriate, that's all. If EHCI HW always
> sends 188 bytes (if available) without babysitting, that's great.
Okay. And yes, that's what it does.
> > > (BTW, periodic transfers should occur before async. Could the TT run
> > > out of periodic, do async, then get an unexpected periodic
> > > transaction in the next uframe? What happens?)
> >
> > This can't happen as long as each SSPLIT transfers the smaller of 188
> > bytes or the number of bytes remaining.
>
> Yes, but per spec transfers are budgeted based on wMaxPacketSize and
> actual SSPLITs may be shorter, while subsequent transfers may still
> remain budgeted into a future uframe.
The actual SSPLIT will be shorter only if it is a short transfer (that
is, shorter than the maxpacket size). Hence there won't be a subsequent
transactions in a future uframe, even if some are budgeted there.
> So it seems that TT must cope with gaps. Maybe it's allowed to fill
> them with async? I don't know, I haven't found clear answer yet.
No, it won't happen.
> > > Including packet headers for SSPLIT scheduling seems harmless unless
> > > overestimated, but apparently it's not required. TTs must cope.
> >
> > Again, budgeting not scheduling, but yes.
>
> As mentioned in the followup correction email, it seems to be required.
> If nothing else, it ensures the 16 transactions per uframe limit. Not
> sure if blind budgeting solely by limiting data bytes and transactions
> per uframe would work as well. Probably not worth finding out.
>
> > > BTW, does ehci-hcd support scheduling CSPLITs to Y0 of the next
> > > frame? It's an edge case which likely won't occur with one 1023
> > > byte endpoint, but it may occur with more periodic endpoints and
> > > unlucky bit stuffing or with periodic BW limit carefully increased
> > > for testing purposes.
> >
> > It does not support CSPLITs in Y7 of the current frame or Y0 of the
> > next frame. This is one of those limitations just mentioned.
>
> Then I think it doesn't support 1023 byte packets at all. 1023/188=5.4
> and if worst case bit stuffing factor is 7/6 then up to 6.3 uframes of
> transfer time. Completion in Y5 or Y6 and CSPLIT required in Y7.
For iso-IN, that's right.
> IOW, you play Russian Roulette with bit stuffing if you enable this.
The driver is not perfect. No doubt about it.
> > Adding support would complicate the driver considerably and yield
> > relatively little benefit now that xHCI is so widespread.
>
> Fun fact: not all xHCI supports it either.
Heh. I'm a little surprised the xHCI implementors were able to do all
this scheduling in hardware in the first place; it's not an easy
problem.
Alan Stern
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: TT budgeting for EHCI; accommodate 1023-byte full-speed isochronous–in endpoints
2026-04-29 19:32 ` Alan Stern
@ 2026-04-29 19:52 ` Brent Page
2026-04-30 2:27 ` Alan Stern
2026-04-29 20:04 ` Michal Pecio
1 sibling, 1 reply; 12+ messages in thread
From: Brent Page @ 2026-04-29 19:52 UTC (permalink / raw)
To: Alan Stern; +Cc: Michal Pecio, linux-usb
> In the future, please tell your email client to wrap text lines after 72
> columns or thereabouts. Single-line paragraphs are hard to deal with.
Roger that
>>> I recently encountered the ENOSPC error mentioned here
>>> (https://lkml.org/lkml/2013/2/19/482) when trying to communicate
>>> with a full-speed peripheral with one isochronous–in endpoint with
>>> a wMaxPacketSize of 1023. N.b., that patch was reverted
>>> (https://lkml.org/lkml/2013/6/18/458). I think it should be tried
>>> again with a different approach.
>
> Out of curiosity, what sort of device? This bug used to annoy me too at
> one point, but my device was a DSL modem, not easy to experiment with.
It is an open-source oscilloscope/function generator/spectrum
analyzer/logic analyzer called Labrador (https://espotek.com/labrador/)
> Does anyone understand why the previous attempt at enabling 1023 byte
> isoc IN resulted in isoc OUT corruption?
I haven't been able to figure it out. At first I thought that maybe it
led to SSPLITs being illegally scheduled in Y6 (USB-2 spec 11.18.14.1),
but I think that "if ((start % 8) >= 6) continue;" near line 1525 of
ehci-sched.c prevents that. I checked, and that line was also in the
kernel at the time of the patch.
> BTW, does ehci-hcd support scheduling CSPLITs to Y0 of the next frame?
> It's an edge case which likely won't occur with one 1023 byte endpoint,
> but it may occur with more periodic endpoints and unlucky bit stuffing
> or with periodic BW limit carefully increased for testing purposes.
Yes, I am also worried about edge cases that could potentially crop up
as a result of my proposed patch. With the patch, for one 1023-byte
isochronous-in endpoint, the CSPLIT mask is 11111100 and the SSPLIT mask
is 00000001. I gleaned these from the debug log "ep 81: reserve iso @
0+8 (0.0+1) [1/21 us] mask fc01". By all indications, the right-most
bit is earliest in time in these masks. Also, I'm nearly certain that
these are in H-frame terms, as opposed to B-frame terms (illustrated in
Fig 4-21 of the EHCI-1 spec). This CSPLIT mask is consistent with the
first sentence of 11.18.4.3.c in USB-2, "For isochronous IN full-speed
transactions, for each microframe in which the full-speed transaction is
budgeted, a complete-split must be scheduled for each following
microframe. " Ceil(1023/188)=6, so the transaction is budgeted to run
in uframes 1-6 (0-indexed H_frame terms), and csplits are appropriately
scheduled in uframes 2-7. However, according to paragraph 3 of
11.18.4.3.c, an additional csplit should be scheduled in Y0 of the next
frame - I'm guessing this is the sort of thing that would require an
FSTN? And maybe not following this rule could lead to problems if there
are other transactions in the pipeline?
There are a few other things that I'm trying to figure out. The "case 2b"
bullet point of 4.12.13.1 of the EHCI-1 spec says that "This case can
only occur for a very large isochronous IN... Software must enforce this
rule by scheduling the large transaction first. Large is defined to be
anything larger than 579 byte maximum packet size." Is this being
enforced at the moment in ehci-sched.c? I could see it possibly
becoming relevant if ehci-sched.c becomes more permissive towards large
transactions. Tangentially, why are there no csplits scheduled for the
458-byte transaction enumerated in
https://bugzilla.kernel.org/show_bug.cgi?id=218544 ? Tracing through
the ehci-sched.c code, I cannot figure out how you don't get at least
3=ceil(458 * 7/6 / 188) 1s in the csplit mask.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: TT budgeting for EHCI; accommodate 1023-byte full-speed isochronous–in endpoints
2026-04-29 19:32 ` Alan Stern
2026-04-29 19:52 ` Brent Page
@ 2026-04-29 20:04 ` Michal Pecio
2026-04-30 1:47 ` Alan Stern
1 sibling, 1 reply; 12+ messages in thread
From: Michal Pecio @ 2026-04-29 20:04 UTC (permalink / raw)
To: Alan Stern; +Cc: Brent Page, linux-usb
On Wed, 29 Apr 2026 15:32:07 -0400, Alan Stern wrote:
> On Wed, Apr 29, 2026 at 09:24:08PM +0200, Michal Pecio wrote:
> > Yes, but per spec transfers are budgeted based on wMaxPacketSize and
> > actual SSPLITs may be shorter, while subsequent transfers may still
> > remain budgeted into a future uframe.
>
> The actual SSPLIT will be shorter only if it is a short transfer
> (that is, shorter than the maxpacket size). Hence there won't be a
> subsequent transactions in a future uframe, even if some are budgeted
> there.
Not for this endpoint, but another one may be budgeted next. Say, two
isoc endpoints with 188 byte budget each. In Y0 EP1 moves one byte and
leaves some time unused, near the end of Y0 EP2 SSPLIT arrives for Y1.
Seems legal, so I don't think TT can assume that it has seen the end of
periodic transfers when its queue runs empty. IDK what it does then.
> > Then I think it doesn't support 1023 byte packets at all.
> > 1023/188=5.4 and if worst case bit stuffing factor is 7/6 then up
> > to 6.3 uframes of transfer time. Completion in Y5 or Y6 and CSPLIT
> > required in Y7.
>
> For iso-IN, that's right.
>
> > IOW, you play Russian Roulette with bit stuffing if you enable
> > this.
>
> The driver is not perfect. No doubt about it.
This raises question how much sense there is in patches enabling such
endpoints. Maybe worth it for OUT, if they currently don't work. Or for
fans of RR, if there are no other side effects :)
> > > Adding support would complicate the driver considerably and yield
> > > relatively little benefit now that xHCI is so widespread.
> >
> > Fun fact: not all xHCI supports it either.
>
> Heh. I'm a little surprised the xHCI implementors were able to do
> all this scheduling in hardware in the first place; it's not an easy
> problem.
It's firmware on some 8051 or similar monstrosity. Often upgradeable.
Often upgrades exist, presumably for valid reasons.
Regards,
Michal
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: TT budgeting for EHCI; accommodate 1023-byte full-speed isochronous–in endpoints
2026-04-29 20:04 ` Michal Pecio
@ 2026-04-30 1:47 ` Alan Stern
0 siblings, 0 replies; 12+ messages in thread
From: Alan Stern @ 2026-04-30 1:47 UTC (permalink / raw)
To: Michal Pecio; +Cc: Brent Page, linux-usb
On Wed, Apr 29, 2026 at 10:04:59PM +0200, Michal Pecio wrote:
> On Wed, 29 Apr 2026 15:32:07 -0400, Alan Stern wrote:
> > On Wed, Apr 29, 2026 at 09:24:08PM +0200, Michal Pecio wrote:
> > > Yes, but per spec transfers are budgeted based on wMaxPacketSize and
> > > actual SSPLITs may be shorter, while subsequent transfers may still
> > > remain budgeted into a future uframe.
> >
> > The actual SSPLIT will be shorter only if it is a short transfer
> > (that is, shorter than the maxpacket size). Hence there won't be a
> > subsequent transactions in a future uframe, even if some are budgeted
> > there.
>
> Not for this endpoint, but another one may be budgeted next. Say, two
> isoc endpoints with 188 byte budget each. In Y0 EP1 moves one byte and
> leaves some time unused, near the end of Y0 EP2 SSPLIT arrives for Y1.
>
> Seems legal, so I don't think TT can assume that it has seen the end of
> periodic transfers when its queue runs empty. IDK what it does then.
It uses the spare time to carry out control/bulk transactions. Those
are limited in size to 64 bytes, so they can't delay the next periodic
transaction all that much.
Besides, the spec just says that the HCD has to reserve 90% of the
bandwidth for periodic transfers. It doesn't say that the periodic
transfers actually have to use up the entire 90%.
> > > Then I think it doesn't support 1023 byte packets at all.
> > > 1023/188=5.4 and if worst case bit stuffing factor is 7/6 then up
> > > to 6.3 uframes of transfer time. Completion in Y5 or Y6 and CSPLIT
> > > required in Y7.
> >
> > For iso-IN, that's right.
> >
> > > IOW, you play Russian Roulette with bit stuffing if you enable
> > > this.
> >
> > The driver is not perfect. No doubt about it.
>
> This raises question how much sense there is in patches enabling such
> endpoints. Maybe worth it for OUT, if they currently don't work. Or for
> fans of RR, if there are no other side effects :)
Iso-OUT doesn't use CSPLITs, so the problem doesn't arise for them. But
it could come up if a big iso-OUT transfer is followed by a few
interrupt transfers. And of course, it matters for iso-IN.
Alan Stern
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: TT budgeting for EHCI; accommodate 1023-byte full-speed isochronous–in endpoints
2026-04-29 19:52 ` Brent Page
@ 2026-04-30 2:27 ` Alan Stern
2026-04-30 6:46 ` Brent Page
0 siblings, 1 reply; 12+ messages in thread
From: Alan Stern @ 2026-04-30 2:27 UTC (permalink / raw)
To: Brent Page; +Cc: Michal Pecio, linux-usb
On Wed, Apr 29, 2026 at 12:52:09PM -0700, Brent Page wrote:
> > BTW, does ehci-hcd support scheduling CSPLITs to Y0 of the next frame?
> > It's an edge case which likely won't occur with one 1023 byte endpoint,
> > but it may occur with more periodic endpoints and unlucky bit stuffing
> > or with periodic BW limit carefully increased for testing purposes.
>
> Yes, I am also worried about edge cases that could potentially crop up
> as a result of my proposed patch. With the patch, for one 1023-byte
> isochronous-in endpoint, the CSPLIT mask is 11111100 and the SSPLIT mask
> is 00000001. I gleaned these from the debug log "ep 81: reserve iso @
> 0+8 (0.0+1) [1/21 us] mask fc01". By all indications, the right-most
> bit is earliest in time in these masks. Also, I'm nearly certain that
> these are in H-frame terms, as opposed to B-frame terms (illustrated in
> Fig 4-21 of the EHCI-1 spec).
Yes for both: little-endian bit order and H-frame terms.
> This CSPLIT mask is consistent with the
> first sentence of 11.18.4.3.c in USB-2, "For isochronous IN full-speed
> transactions, for each microframe in which the full-speed transaction is
> budgeted, a complete-split must be scheduled for each following
> microframe. " Ceil(1023/188)=6, so the transaction is budgeted to run
> in uframes 1-6 (0-indexed H_frame terms), and csplits are appropriately
> scheduled in uframes 2-7. However, according to paragraph 3 of
> 11.18.4.3.c, an additional csplit should be scheduled in Y0 of the next
> frame - I'm guessing this is the sort of thing that would require an
> FSTN?
No; FSTNs are for interrupt transfers. But it would require extra siTD
nodes with backpointers, complicating the allocation and deallocation
algorithms. That wouldn't be so hard to add, but I have never felt the
urge to do it.
> And maybe not following this rule could lead to problems if there
> are other transactions in the pipeline?
Or if a lot of bit-stuffing is needed.
> There are a few other things that I'm trying to figure out. The "case 2b"
> bullet point of 4.12.13.1 of the EHCI-1 spec says that "This case can
> only occur for a very large isochronous IN... Software must enforce this
> rule by scheduling the large transaction first. Large is defined to be
> anything larger than 579 byte maximum packet size." Is this being
> enforced at the moment in ehci-sched.c?
I don't think so. Bandwidth is allocated to endpoints as they are
added, and the driver does not go back and try to rearrange the schedule
if something doesn't fit right. It most certainly does not try to
change the allocation for endpoints that are currently in use.
> I could see it possibly
> becoming relevant if ehci-sched.c becomes more permissive towards large
> transactions. Tangentially, why are there no csplits scheduled for the
> 458-byte transaction enumerated in
> https://bugzilla.kernel.org/show_bug.cgi?id=218544 ? Tracing through
> the ehci-sched.c code, I cannot figure out how you don't get at least
> 3=ceil(458 * 7/6 / 188) 1s in the csplit mask.
Was that an isochronous-OUT transaction? Those things don't use CSPLITs
at all.
Alan Stern
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: TT budgeting for EHCI; accommodate 1023-byte full-speed isochronous–in endpoints
2026-04-30 2:27 ` Alan Stern
@ 2026-04-30 6:46 ` Brent Page
0 siblings, 0 replies; 12+ messages in thread
From: Brent Page @ 2026-04-30 6:46 UTC (permalink / raw)
To: Alan Stern; +Cc: Michal Pecio, linux-usb
> On Apr 29, 2026, at 7:27 PM, Alan Stern <stern@rowland.harvard.edu> wrote:
>
>> an additional csplit should be scheduled in Y0 of the next
>> frame - I'm guessing this is the sort of thing that would require an
>> FSTN?
>
> No; FSTNs are for interrupt transfers. But it would require extra siTD
> nodes with backpointers, complicating the allocation and deallocation
> algorithms. That wouldn't be so hard to add, but I have never felt the
> urge to do it.
Hmm, I may try to take a crack at it so that my previous proposal to inflate
the values of max_tt_usecs will always work if the bus just contains one
1023-byte iso-IN endpoint. That is, the goal would be to fix
>> Then I think it doesn't support 1023 byte packets at all.
>> 1023/188=5.4 and if worst case bit stuffing factor is 7/6 then up
>> to 6.3 uframes of transfer time. Completion in Y5 or Y6 and CSPLIT
>> required in Y7.
__________________________
>> The "case 2b"bullet point of 4.12.13.1 of the EHCI-1 spec says that
>> "This case can only occur for a very large isochronous IN... Software
>> must enforce this rule by scheduling the large transaction first. Large
>> is defined to be anything larger than 579 byte maximum packet size."
>> Is this being enforced at the moment in ehci-sched.c?
>
> I don't think so. Bandwidth is allocated to endpoints as they are
> added, and the driver does not go back and try to rearrange the schedule
> if something doesn't fit right. It most certainly does not try to
> change the allocation for endpoints that are currently in use.
It might be easy to do now that the budgeting is done working backwards
starting with the latest uframe (as of
https://marc.info/?l=linux-usb&m=131973404328622). Pretty much, if the
byte count exceeds 579, see if the transaction can fit starting in
uframe 0. If not, because the scheduling worked backwards to begin
with, there's no way that the schedule could be re-arranged to make the
large transaction fit while obeying the quoted rule.
Clearly, 579 is just about half the 1157
maximum_periodic_bytes_per_frame mentioned in 11.18.1, but I can't think
of why that's the threshold for a large transaction. Sure, the
threshold guarantees that having 2 large transactions is impossible, but
that still doesn't seem to be important in the context of the reasoning
given in EHCI-1: 4.12.13.1.
>> Tangentially, why are there no csplits scheduled for the
>> 458-byte transaction enumerated in
>> https://bugzilla.kernel.org/show_bug.cgi?id=218544 ? Tracing through
>> the ehci-sched.c code, I cannot figure out how you don't get at least
>> 3=ceil(458 * 7/6 / 188) 1s in the csplit mask.
>
> Was that an isochronous-OUT transaction? Those things don't use CSPLITs
> at all.
Ah yeah, it was an iso-OUT.
From,
Brent Page
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2026-04-30 6:46 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-28 1:24 TT budgeting for EHCI; accommodate 1023-byte full-speed isochronous–in endpoints Brent Page
2026-04-28 21:19 ` Alan Stern
2026-04-29 9:36 ` Michal Pecio
2026-04-29 11:58 ` Michal Pecio
2026-04-29 17:56 ` Alan Stern
2026-04-29 19:24 ` Michal Pecio
2026-04-29 19:32 ` Alan Stern
2026-04-29 19:52 ` Brent Page
2026-04-30 2:27 ` Alan Stern
2026-04-30 6:46 ` Brent Page
2026-04-29 20:04 ` Michal Pecio
2026-04-30 1:47 ` Alan Stern
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox