OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Mar 28, 2024 8:43 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 6 posts ] 
Author Message
 Post subject: XHCI: Address Device command fails for devices behind a hub
PostPosted: Sun Feb 12, 2023 8:29 am 
Offline
Member
Member
User avatar

Joined: Sun Apr 30, 2017 12:16 pm
Posts: 68
Location: Poland
Hi,

as stated in the title, I've a problem with the Address Device command failing with an USB transaction error for devices that are behind a hub. According to the XHCI spec this means that the SET_ADDRESS request has failed, but I can't think of a reason why.
I've tried a few of HS, FS and LS devices, and noticed that it only fails for HS devices. One thing also worth noting is that one device I tried is an USB 3 SSD, which is addressed correctly when plugged into an USB 3 root port, and yet fails when plugged into the USB 2 hub port.

I've observed this on a Raspberry Pi 4, which uses the VL805 XHCI controller, which has an integrated 4 port USB 2 hub (which is the main reason for implementing hub support right now), and I unfortunately don't have any other USB 2 HS hubs (only an FS one).

The code for the XHCI driver can be found here: https://github.com/qookei/managarm/tree/rpi4/drivers/usb/hcds/xhci/src, and the USB hub driver code is here https://github.com/qookei/managarm/blob/rpi4/protocols/usb/src/hub.cpp.
One point of interest is the place the device is actually addressed: https://github.com/qookei/managarm/blob/rpi4/drivers/usb/hcds/xhci/src/main.cpp#L830-L902

For reference, here are the logs produced by this code:
Image

_________________
Working on managarm.


Top
 Profile  
 
 Post subject: Re: XHCI: Address Device command fails for devices behind a
PostPosted: Sun Feb 12, 2023 1:00 pm 
Offline
Member
Member
User avatar

Joined: Sat Nov 22, 2014 6:33 pm
Posts: 934
Location: USA
When you are setting the address of the device, you aren't actually sending the SET_ADDRESS request, correct? xHCI does not allow the SET_ADDRESS request to populate the bus.

You must send the Set Address command twice, once to set the address of the device (Block bit set), then a little bit later to let the xHCI send the SET_ADDRESS request (Block bit clear).

Also, since it is only happening on High-speed devices, it probably isn't with your "addressDevice()" code. It probably is something else pertaining to the way you set your CONTEXTs with high-speed devices.

Is the hub a high-speed hub? You say you only have a full-speed hub. Remember, a high-speed device plugged into a full-speed hub is now a full-speed device. You have to account for this.

Ben


Top
 Profile  
 
 Post subject: Re: XHCI: Address Device command fails for devices behind a
PostPosted: Sun Feb 12, 2023 2:27 pm 
Offline
Member
Member
User avatar

Joined: Sun Apr 30, 2017 12:16 pm
Posts: 68
Location: Poland
Hi Ben, thanks for responding.

BenLunt wrote:
When you are setting the address of the device, you aren't actually sending the SET_ADDRESS request, correct? xHCI does not allow the SET_ADDRESS request to populate the bus.

Correct, I'm letting the controller do it via the Address Device command. I only mentioned it because the spec says that that error happens when the SET_ADDRESS request failed (stall or such).

BenLunt wrote:
You must send the Set Address command twice, once to set the address of the device (Block bit set), then a little bit later to let the xHCI send the SET_ADDRESS request (Block bit clear).

Could you expand on what the correct order of commands to the controller would be? Currently my code does:
1. Enable Slot,
2. Address Device (with the slot and EP1 contexts set up in the input context) with BSR=0

And afterwards carries on with the device, it reads the device descriptor to get the class, vendor and product IDs etc, and finally at the request of a class/device-specific driver reads more descriptors, sets up other EPs as per the configuration descriptor (via the Configure Endpoint command), and sets the configuration via SET_CONFIGURATION request.

As mentioned this order of things works for one of the USB 3 devices I tried when plugged into an USB 3 root port instead of the HS hub, so it is probably indeed likely that this is not the problem in this case.

BenLunt wrote:
Also, since it is only happening on High-speed devices, it probably isn't with your "addressDevice()" code. It probably is something else pertaining to the way you set your CONTEXTs with high-speed devices.

As far as I can tell the only difference is that LS/FS devices require the hub slot and port number fields filled out for split transactions, and for HS those fields should be 0, which is what I do in my code.

BenLunt wrote:
Is the hub a high-speed hub? You say you only have a full-speed hub. Remember, a high-speed device plugged into a full-speed hub is now a full-speed device. You have to account for this.

The hub I was testing with is integrated into the XHCI controller chip, which has only one USB 2 root port, and an integrated 4 port hub (but 4 USB 3 root ports and no hub on those). The FS hub I mentioned is a standalone one, and I only mentioned it to say I can't test other HS hubs or on any other controller etc.

_________________
Working on managarm.


Top
 Profile  
 
 Post subject: Re: XHCI: Address Device command fails for devices behind a
PostPosted: Sun Feb 12, 2023 3:54 pm 
Offline
Member
Member

Joined: Wed Oct 01, 2008 1:55 pm
Posts: 3191
I'm more inclined to think that the hub is handled incorrectly. USB 2 hubs must be programmed correctly, which include the speed of the device connected to ports. The hub itself is running as an USB 2 device, but the hub ports either are directly connected or go through a transaction interface that converts to lower speed. This is not automatic. I think that is why certain device types works while other doesn't.


Top
 Profile  
 
 Post subject: Re: XHCI: Address Device command fails for devices behind a
PostPosted: Sun Feb 19, 2023 5:22 pm 
Offline
Member
Member

Joined: Sat Nov 21, 2009 5:11 pm
Posts: 852
Quote:
You must send the Set Address command twice, once to set the address of the device (Block bit set), then a little bit later to let the xHCI send the SET_ADDRESS request (Block bit clear).

This is usually not required. The BSR bit exists only as a workaround for some broken device or devices which the specification does not name, which require a nonstandard initialization sequence.


Top
 Profile  
 
 Post subject: Re: XHCI: Address Device command fails for devices behind a
PostPosted: Sun Feb 19, 2023 6:44 pm 
Offline
Member
Member
User avatar

Joined: Sat Nov 22, 2014 6:33 pm
Posts: 934
Location: USA
Gigasoft wrote:
Quote:
You must send the Set Address command twice, once to set the address of the device (Block bit set), then a little bit later to let the xHCI send the SET_ADDRESS request (Block bit clear).

This is usually not required. The BSR bit exists only as a workaround for some broken device or devices which the specification does not name, which require a nonstandard initialization sequence.

And you are absolutely correct. However, how do you know that the user hasn't plugged one of these broken devices into the port? This is the reason for the multiple calls. :-)
Sending the address command once, works on most devices, while sending it twice (as I suggest) works on most devices "plus" those broken devices. I have witnessed this personally.

Cheers,
Ben


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 6 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: SemrushBot [Bot] and 66 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group