tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: xhci spec (mis?)interpretation on hubs



On 12/08/17 18:25, Sprow wrote:
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.

I didn't look too closely yet, but I'm pretty sure the upstream HS hub is required here as you stated.

Nick


Home | Main Index | Thread Index | Old Index