diff --git a/sys/mips/cavium/usb/octusb.c b/sys/mips/cavium/usb/octusb.c index 17b7027cc610..01328c5b70ab 100644 --- a/sys/mips/cavium/usb/octusb.c +++ b/sys/mips/cavium/usb/octusb.c @@ -159,7 +159,7 @@ octusb_host_alloc_endpoint(struct octusb_td *td) sc = td->qh->sc; ep_handle = cvmx_usb_open_pipe( - &sc->sc_port[td->qh->port_index].state, + &sc->sc_port[td->qh->root_port_index].state, 0, td->qh->dev_addr, td->qh->ep_num & UE_ADDR, @@ -173,11 +173,13 @@ octusb_host_alloc_endpoint(struct octusb_td *td) td->qh->hs_hub_addr, td->qh->hs_hub_port); - if (ep_handle < 0) + if (ep_handle < 0) { + DPRINTFN(1, "cvmx_usb_open_pipe failed: %d\n", ep_handle); return (1); /* busy */ + } cvmx_usb_set_toggle( - &sc->sc_port[td->qh->port_index].state, + &sc->sc_port[td->qh->root_port_index].state, ep_handle, td->qh->ep_toggle_next); td->qh->fixup_handle = -1; @@ -206,10 +208,10 @@ octusb_host_free_endpoint(struct octusb_td *td) if (td->qh->fixup_handle >= 0) { /* cancel, if any */ - cvmx_usb_cancel(&sc->sc_port[td->qh->port_index].state, + cvmx_usb_cancel(&sc->sc_port[td->qh->root_port_index].state, td->qh->ep_handle, td->qh->fixup_handle); } - cvmx_usb_close_pipe(&sc->sc_port[td->qh->port_index].state, td->qh->ep_handle); + cvmx_usb_close_pipe(&sc->sc_port[td->qh->root_port_index].state, td->qh->ep_handle); td->qh->ep_allocated = 0; } @@ -301,7 +303,7 @@ octusb_host_control_header_tx(struct octusb_td *td) usb_pc_cpu_flush(td->qh->fixup_pc); status = cvmx_usb_submit_control( - &sc->sc_port[td->qh->port_index].state, + &sc->sc_port[td->qh->root_port_index].state, td->qh->ep_handle, td->qh->fixup_phys, td->qh->fixup_phys + 8, td->qh->fixup_len, &octusb_complete_cb, td); @@ -410,7 +412,7 @@ octusb_host_control_status_tx(struct octusb_td *td) /* start USB transfer */ status = cvmx_usb_submit_control( - &sc->sc_port[td->qh->port_index].state, + &sc->sc_port[td->qh->root_port_index].state, td->qh->ep_handle, td->qh->fixup_phys, td->qh->fixup_phys + 8, td->qh->fixup_len, &octusb_complete_cb, td); @@ -493,19 +495,19 @@ octusb_non_control_data_tx(struct octusb_td *td) td->qh->iso_pkt.length = rem; td->qh->iso_pkt.status = 0; /* start USB transfer */ - status = cvmx_usb_submit_isochronous(&sc->sc_port[td->qh->port_index].state, + status = cvmx_usb_submit_isochronous(&sc->sc_port[td->qh->root_port_index].state, td->qh->ep_handle, 1, CVMX_USB_ISOCHRONOUS_FLAGS_ALLOW_SHORT | CVMX_USB_ISOCHRONOUS_FLAGS_ASAP, 1, &td->qh->iso_pkt, td->qh->fixup_phys, rem, &octusb_complete_cb, td); break; case UE_BULK: /* start USB transfer */ - status = cvmx_usb_submit_bulk(&sc->sc_port[td->qh->port_index].state, + status = cvmx_usb_submit_bulk(&sc->sc_port[td->qh->root_port_index].state, td->qh->ep_handle, td->qh->fixup_phys, rem, &octusb_complete_cb, td); break; case UE_INTERRUPT: /* start USB transfer (interrupt or interrupt) */ - status = cvmx_usb_submit_interrupt(&sc->sc_port[td->qh->port_index].state, + status = cvmx_usb_submit_interrupt(&sc->sc_port[td->qh->root_port_index].state, td->qh->ep_handle, td->qh->fixup_phys, rem, &octusb_complete_cb, td); break; default: @@ -612,19 +614,19 @@ octusb_non_control_data_rx(struct octusb_td *td) td->qh->iso_pkt.length = rem; td->qh->iso_pkt.status = 0; /* start USB transfer */ - status = cvmx_usb_submit_isochronous(&sc->sc_port[td->qh->port_index].state, + status = cvmx_usb_submit_isochronous(&sc->sc_port[td->qh->root_port_index].state, td->qh->ep_handle, 1, CVMX_USB_ISOCHRONOUS_FLAGS_ALLOW_SHORT | CVMX_USB_ISOCHRONOUS_FLAGS_ASAP, 1, &td->qh->iso_pkt, td->qh->fixup_phys, rem, &octusb_complete_cb, td); break; case UE_BULK: /* start USB transfer */ - status = cvmx_usb_submit_bulk(&sc->sc_port[td->qh->port_index].state, + status = cvmx_usb_submit_bulk(&sc->sc_port[td->qh->root_port_index].state, td->qh->ep_handle, td->qh->fixup_phys, rem, &octusb_complete_cb, td); break; case UE_INTERRUPT: /* start USB transfer */ - status = cvmx_usb_submit_interrupt(&sc->sc_port[td->qh->port_index].state, + status = cvmx_usb_submit_interrupt(&sc->sc_port[td->qh->root_port_index].state, td->qh->ep_handle, td->qh->fixup_phys, rem, &octusb_complete_cb, td); break; default: @@ -798,7 +800,7 @@ done: xfer->endpoint->toggle_next = cvmx_usb_get_toggle( - &sc->sc_port[qh->port_index].state, + &sc->sc_port[qh->root_port_index].state, qh->ep_handle) ? 1 : 0; octusb_device_done(xfer, error); @@ -1729,6 +1731,7 @@ octusb_xfer_setup(struct usb_setup_params *parm) struct octusb_softc *sc; struct octusb_qh *qh; struct usb_xfer *xfer; + struct usb_device *hub; void *last_obj; uint32_t n; uint32_t ntd; @@ -1774,7 +1777,13 @@ octusb_xfer_setup(struct usb_setup_params *parm) qh->ep_type = xfer->endpoint->edesc->bmAttributes; qh->dev_addr = xfer->address; qh->dev_speed = usbd_get_speed(xfer->xroot->udev); - qh->port_index = xfer->xroot->udev->port_index; + qh->root_port_index = xfer->xroot->udev->port_index; + /* We need Octeon USB HUB's port index, not the local port */ + hub = xfer->xroot->udev->parent_hub; + while(hub && hub->parent_hub) { + qh->root_port_index = hub->port_index; + hub = hub->parent_hub; + } switch (xfer->endpoint->edesc->bmAttributes & UE_XFERTYPE) { case UE_INTERRUPT: diff --git a/sys/mips/cavium/usb/octusb.h b/sys/mips/cavium/usb/octusb.h index 591e071b7cbd..8b8a5e27b3ed 100644 --- a/sys/mips/cavium/usb/octusb.h +++ b/sys/mips/cavium/usb/octusb.h @@ -80,7 +80,7 @@ struct octusb_qh { uint8_t ep_num; uint8_t ep_type; uint8_t ep_toggle_next; - uint8_t port_index; + uint8_t root_port_index; uint8_t fixup_complete; uint8_t fixup_pending; uint8_t hs_hub_addr;