hi,
On 09/15/14 23:46, Ryo ONODERA wrote:
Hi,
Our xHCI USB 3.0 driver with Intel Lynx Point/Lynx Point-LP, Renesas uPD70202
and Fresco Logic 0x1b73/0x1100 xHCI chips does not support non-root hub
as following.
I believe our xHCI driver have no non-root hub support.
I have tested some USB 1.1/2.0/3.0 hubs, and gotten same results.
Address Device Command TRB execution just after Enable Slot Command TRB
execution fails with USB Transaction Error.
I got PARAMETER error when i connected usb 2.0 thumb drive to
my uPD720200 xhci via 2.0 hub.
I have spent some weeks, but I cannot find why Address Device Command fails.
(If your want to use Intel Lynx Point/Lynx Point-LP xHC, please
apply a patch in http://gnats.netbsd.org/49076.)
I think that's because incorrect route string (always 0x0) and
incorrect root hub port is set in slot context.
Anyone have a clue for xHCI's non-root hub support?
I really need any clue for non-root hub support.
Can you try this patch?
This patch tries to add route string support for hubs.
Caveats:
- SS hub is currently not supported.
SS hub will work as HS hub.
I'm not sure both of SS and HS hub in SS hub can be
attached on one roothub port.
- Detaching hub may cause panic.
xhci may try to transfer on unplugged port.
- HUB,MTT,TTT and TT* fields in slot context is not set.
--- src/sys/dev/usb/xhci.c.orig 2014-10-03 21:18:24.0 +0900
+++ src/sys/dev/usb/xhci.c 2014-10-04 08:59:16.0 +0900
@@ -615,8 +760,12 @@ xhci_init(struct xhci_softc *sc)
XHCIHIST_FUNC(); XHCIHIST_CALLED();
+#if 0
+ sc->sc_bus.usbrev = USBREV_3_0;
+#else
/* XXX Low/Full/High speeds for now */
sc->sc_bus.usbrev = USBREV_2_0;
+#endif
cap = xhci_read_4(sc, XHCI_CAPLENGTH);
caplength = XHCI_CAP_CAPLENGTH(cap);
@@ -1139,8 +1449,7 @@ xhci_open(usbd_pipe_handle pipe)
return USBD_IOERROR;
/* Root Hub */
- if (dev->depth == 0 && dev->powersrc->portno == 0 &&
- dev->speed != USB_SPEED_SUPER) {
+ if (dev->depth == 0 && dev->powersrc->portno == 0) {
switch (ed->bEndpointAddress) {
case USB_CONTROL_ENDPOINT:
pipe->methods = &xhci_root_ctrl_methods;
@@ -1194,13 +1631,24 @@ xhci_rhpsc(struct xhci_softc * const sc,
if (xfer == NULL)
return;
- if (!(port >= sc->sc_hs_port_start &&
- port < sc->sc_hs_port_start + sc->sc_hs_port_count))
- return;
+ xfer->pipe->device->speed =
+ XHCI_PS_SPEED_GET(xhci_op_read_4(sc, XHCI_PORTSC(port)));
- port -= sc->sc_hs_port_start;
- port += 1;
- DPRINTFN(4, "hs port %u status change", port, 0, 0, 0);
+ if (port >= sc->sc_hs_port_start &&
+ port < sc->sc_hs_port_start + sc->sc_hs_port_count) {
+ port -= sc->sc_hs_port_start;
+ port += 1;
+ DPRINTFN(4, "hs port %u status change", port, 0, 0, 0);
+ } else if (port >= sc->sc_ss_port_start &&
+ port < sc->sc_ss_port_start + sc->sc_ss_port_count) {
+ port -= sc->sc_ss_port_start;
+ port += 1;
+ DPRINTFN(4, "ss port %u status change", port, 0, 0, 0);
+ } else {
+ /* cannot happen */
+ DPRINTFN(0, "port %u out of range", port, 0, 0, 0);
+ return;
+ }
p = KERNADDR(&xfer->dmabuf, 0);
memset(p, 0, xfer->length);
@@ -1468,7 +1974,7 @@ xhci_new_device(device_t parent, usbd_bu
usbd_status err;
usb_device_descriptor_t *dd;
struct usbd_device *hub;
- struct usbd_device *adev;
+ uint32_t route = 0;
int rhport = 0;
struct xhci_slot *xs;
uint32_t *cp;
@@ -1515,28 +2017,32 @@ xhci_new_device(device_t parent, usbd_bu
up->device = dev;
/* Locate root hub port */
- for (adev = dev, hub = dev;
- hub != NULL;
- adev = hub, hub = hub->myhub) {
- DPRINTFN(4, "hub %p", hub, 0, 0, 0);
- }
- DPRINTFN(4, "hub %p", hub, 0, 0, 0);
-
- if (hub != NULL) {
- for (int p = 0; p < hub->hub->hubdesc.bNbrPorts; p++) {
- if (hub->hub->ports[p].device == adev) {
- rhport = p;
- }
- }
- } else {
- rhport = port;
+ for (hub = dev; hub != NULL; hub = hub->myhub) {
+ uint32_t dep;
+
+ DPRINTFN(4, "hub %p depth %d upport %p upportno %d",
+ hub, hub->depth, hub->powersrc,
+ hub->powersrc ? hub->powersrc->portno : 0);
+
+ if (hub->powersrc == NULL)
+ continue;
+ dep = hub->depth;
+ if (dep == 0)
+ continue;
+
+ route |= hub->powersrc->portno << ((dep - 1) * 4);
}
+ DPRINTFN(4, "hub %p route %05x", hub, route, 0, 0);
+
if (s