How does XHCI handle USB Interrupt In endpoint polling?

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
LennyColt
Posts: 2
Joined: Tue Jul 07, 2026 12:51 pm

How does XHCI handle USB Interrupt In endpoint polling?

Post by LennyColt »

I read @BenLunt's book on USB which is excellent on how OHCI, UHCI, and EHCI handle interrupt endpoints. Basically you have a frame list. You have a bunch of queues for 1ms, 2ms, 4ms, 8ms and so on and you link them into the framelist. So the 1ms one is linked in every entry, the 2ms ever second entry, 4ms every 4th and so on.

Now Ben mentions how XHCI does things in a better way. I actually re-read the book and I still can't figure out how this is done. The book seems like it's missing a chapter on how the USB stack looks for XHCI but it has it for OHCI, UHCI, and EHCI.
BenLunt wrote: ↑Sun Aug 30, 2020 7:20 pm As for the other two controllers, I feel that xHCI finally got it right, while EHCI was a kludge of backward compatibility and modern devices. Therefore, if I had to choose which of the four, I would choose in the following order, best/easiest to worst/most difficult--again, just being my opinion:

xHCI, OHCI, UHCI, EHCI.

Note that most new computers will include only an xHCI, since it will handle all speeds, where as the other controllers are speed specific.

Ben
- http://www.fysnet.net/the_universal_serial_bus.htm
User avatar
BenLunt
Member
Member
Posts: 1039
Joined: Sat Nov 22, 2014 6:33 pm
Location: USA
Contact:

Re: How does XHCI handle USB Interrupt In endpoint polling?

Post by BenLunt »

Hi, and thank you for the kind words.

You are right, the OHCI, UHCI, and EHCI, all have periodical schedules that allow you to place TDs in specified Queues to be executed at a specific interval.

However, with xHCI, that last word, "interval" is the key. I give a small description on page 10-12, but after looking, you are absolutely right, I don't give as much detail as I did for the other three controllers. I will make a note and make sure to add information in the next edition.

With that being said, the Interval field (in the Endpoint's Context Structure) defines "the period between consecutive requests to a USB endpoint to send or receive data, expressed in 125 μs. increments." (quoted from the specs)

Imagine simply having to place an interval in a field in a context structure and the hardware does the rest... :-) Kind of makes my comment about the xHCI finally getting it right, shine a bit. :-)

This interval field is ignored by Super-speed bulk and control endpoints, but is used by all other types and speeds.

The interval field allows the hardware to have a "schedule" from 4.096 seconds (interval = 15) to almost zero seconds (interval = 0) expressed in 125uS units. However, not all devices (endpoints) support interval values of zero. "The legal range of values is 3 to 11 for Full- or Low-speed Interrupt endpoints (1 to 256 ms.) and 0 to 15 for all other endpoint types (125 μs. to 4096 ms.)", again quoted from the specs.

For more information, see Section 6.2.3.6 (page 339), in the xHCI specification (v1.00.11.117).

Again, thank you for the kind words. I appreciate them.

If you have any more questions, please feel free to post here.

Ben
- https://www.fysnet.net/osdesign_book_series.htm
LennyColt
Posts: 2
Joined: Tue Jul 07, 2026 12:51 pm

Re: How does XHCI handle USB Interrupt In endpoint polling?

Post by LennyColt »

BenLunt wrote: ↑Tue Aug 11, 2026 5:27 pm Imagine simply having to place an interval in a field in a context structure and the hardware does the rest... :-) Kind of makes my comment about the xHCI finally getting it right, shine a bit. :-)
I must admit a lot of searching led me to this thread

https://forum.osdev.org/viewtopic.php?p=309603#p309603
BenLunt wrote: ↑Tue Oct 06, 2020 10:22 am Here is one way of doing it, not necessarily the best, nor the worst. Just one way of doing it.

What if you place three Transfer TRBs, one Transfer Event TRB, two more Transfer TRBs, and ring the door bell (once)?

When your driver receives the EVENT TRB on the Event ring, you can determine that it is coming from the INTERRUPT ring, telling you that you only have two more TRBs on that ring, therefore indicating that you need to insert another set of TDs on that ring, including an Event TRB.

With the Event mechanism of the xHCI, the controller can indicate to your driver that you need to do something. In this case, add more TRBs to the transfer ring. This way there is no polling of the schedule. You can let the controller handle all of the events. Hence the name.

Place a few transfer TRBs (also called Transfer Descriptors when one or more TRBs are used for one transfer) on the ring and include a Transfer Event TRB. Then the driver that handles the EVENT ring can place more TDs on the interrupt ring. It is a good idea to place the Transfer Event TRB in the middle of the TRBs so that it is not the last TRB. This way, if the EVENT ring driver is "late", you still have a few intervals remaining before you run out of TDs.

Does this make sense? Of course this means you have to have an EVENT handler installed, passing messages between rings, but I hope you get the idea.

One more note is that since the interval will most likely never change, i.e.: a mouse will always have an interval of 16ms (for example), you can place 128 TRBs on its ring before you use the event TRB. In fact, the more TRBs you use before an Event TRB, the less your driver has to consume CPU bandwidth. If you have a ring of 4096 entries, use them all before an Event is used.

There are a few more specifics that must be followed, but this should give you an idea.
Ben
Which explains it pretty well. I think you should add a chapter evangelising why XHCI finally gets it right and makes host controller drivers easier to write

And beyond simplifying the HCD it does seem that way. It's like more of the USB stack in handled by hardware. And it seems more SMP friendly because you can have different threads talking in parallel to different devices, or even different endpoints on the same device. And having the XHCI controller assigning addresses seems like it's more virtualisation friendly because you don't need to do a mapping from the USB device address the VM sees and the one the hardware actually uses. And it does USB 1.0, 2.0, 3.0 and even 4.0 and later standards.
User avatar
BenLunt
Member
Member
Posts: 1039
Joined: Sat Nov 22, 2014 6:33 pm
Location: USA
Contact:

Re: How does XHCI handle USB Interrupt In endpoint polling?

Post by BenLunt »

I have made some notes and will for sure include more information on this specific subject in future edition.

Thank you for your comments, I appreciate them.

Ben
Post Reply