Hi,
I've been having a look on a USB analyser at a class of hubs that don't seem
to work on a driver based on
src/sys/dev/usb/xhci.c
Comparing the dialogue for a non XHCI controller I see the issue is that the
cascade of hubs is HS->FS->LS. The GetDescriptor of the LS device never makes
it through. It happens to be a KVM which presents a fake keyboard/mouse HID
plugged into port 3 of a 4 port (FS) hub, which I've then plugged into a HS
hub, which is itself attached to the root hub (ie. the XHCI root hub is in
USB2 mode).
Looking in the XHCI spec I think I see the problem. The text in table 59 is
badly worded, it says
"If this device is LS/FS and connected through a HS hub, then this field
contains...of the parent HS hub"
The 'parent' isn't the immediately adjacent (as in parent/child relationship)
hub, I think the operative word is *through*, and it really means the first
ancestor which is HS, but not necessarily adjacent. The footnote (a) sort of
says that, by defining the 'parent' as the point where there's a transition
from HS to FS/LS signalling.
For example, with
HS(1)->HS(2)->FS(3)->FS(4)->FS(5)->LS
it would be hub 2, not 5.
Looking at the driver we have:
if (myhsport && myhub && myhub->ud_depth &&
myhub->ud_speed == USB_SPEED_HIGH &&
(speed == USB_SPEED_LOW || speed == USB_SPEED_FULL)) {
ttportnum = myhsport->up_portno;
tthubslot = myhsport->up_parent->ud_addr;
} else {
ttportnum = 0;
tthubslot = 0;
}
The check of myhub->ud_speed looks wrong, because that's checking the
adjacent hub (5 in my example). As a result the expression evaluates to false
and the ttportnum & tthubslot are 0, which blocks the controller from routing
the GetDescriptor properly.