On 4/19/22 13:36, Mahesh Vardhamanaiah wrote:
Hi HPS,

Please find the diff below for the error prints.


[maheshmv@svl-bsdx-02 /b/maheshmv/usb_issue/src]$ git diff 
sys/dev/usb/controller/xhci.c
diff --git a/sys/dev/usb/controller/xhci.c b/sys/dev/usb/controller/xhci.c
index 70a73dcc94c..fa7c1062ada 100644
--- a/sys/dev/usb/controller/xhci.c
+++ b/sys/dev/usb/controller/xhci.c
@@ -3895,6 +3895,7 @@ xhci_configure_reset_endpoint(struct usb_xfer *xfer)
          * Get the endpoint into the stopped state according to the
          * endpoint context state diagram in the XHCI specification:
          */
+#if 0
         switch (xhci_get_endpoint_state(udev, epno)) {
         case XHCI_EPCTX_0_EPSTATE_DISABLED:
                  break;
@@ -3909,8 +3910,25 @@ xhci_configure_reset_endpoint(struct usb_xfer *xfer)
                 err = xhci_cmd_stop_ep(sc, 0, epno, index);
                 if (err != 0)
                         DPRINTF("Could not stop endpoint %u\n", epno);
+               /*
+                * Need to reset the data toggle, because stop
+                * endpoint doesn't do that:
+                */
+               err = xhci_cmd_reset_ep(sc, 0, epno, index);
+               if (err != 0)
+                       DPRINTF("Mahesh Could not reset endpoint %u\n", epno);
                 break;
         }
+#endif
+
+       device_printf(sc->sc_bus.parent, "MMV endpoint %u state %x\n", epno, 
xhci_get_endpoint_state(udev, epno));
+       err = xhci_cmd_stop_ep(sc, 0, epno, index);
+       if (err !=0)
+               device_printf(sc->sc_bus.parent, "MMV Could not stop endpoint %u err 
%x\n", epno, err);
+
+       err = xhci_cmd_reset_ep(sc, 0, epno, index);
+       if (err !=0)
+               device_printf(sc->sc_bus.parent, "MMV Could not reset endpoint %u 
err %x\n", epno, err);

         err = xhci_cmd_set_tr_dequeue_ptr(sc,
             (pepext->physaddr + (stream_id * sizeof(struct xhci_trb) *



Hi,

Can you check on your side where the USB_ERR_NO_PIPE comes from? I cannot find it?

xhci_cmd_reset_ep() looks like this:

static usb_error_t
xhci_cmd_reset_ep(struct xhci_softc *sc, uint8_t preserve,
    uint8_t ep_id, uint8_t slot_id)
{
        struct xhci_trb trb;
        uint32_t temp;

        DPRINTF("\n");

        trb.qwTrb0 = 0;
        trb.dwTrb2 = 0;
        temp = XHCI_TRB_3_TYPE_SET(XHCI_TRB_TYPE_RESET_EP) |
            XHCI_TRB_3_SLOT_SET(slot_id) |
            XHCI_TRB_3_EP_SET(ep_id);

        if (preserve)
                temp |= XHCI_TRB_3_PRSV_BIT;

        trb.dwTrb3 = htole32(temp);

        return (xhci_do_command(sc, &trb, 100 /* ms */));
}

static usb_error_t
xhci_do_command(struct xhci_softc *sc, struct xhci_trb *trb, uint16_t timeout_ms)
{
        struct usb_page_search buf_res;
        struct xhci_hw_root *phwr;
        uint64_t addr;
        uint32_t temp;
        uint8_t i;
        uint8_t j;
        uint8_t timeout = 0;
        int err;

        XHCI_CMD_ASSERT_LOCKED(sc);

        /* get hardware root structure */

        usbd_get_page(&sc->sc_hw.root_pc, 0, &buf_res);

        phwr = buf_res.buffer;

        /* Queue command */

        USB_BUS_LOCK(&sc->sc_bus);
retry:
        i = sc->sc_command_idx;
        j = sc->sc_command_ccs;

        DPRINTFN(10, "command[%u] = %u (0x%016llx, 0x%08lx, 0x%08lx)\n",
            i, XHCI_TRB_3_TYPE_GET(le32toh(trb->dwTrb3)),
            (long long)le64toh(trb->qwTrb0),
            (long)le32toh(trb->dwTrb2),
            (long)le32toh(trb->dwTrb3));

        phwr->hwr_commands[i].qwTrb0 = trb->qwTrb0;
        phwr->hwr_commands[i].dwTrb2 = trb->dwTrb2;

        usb_pc_cpu_flush(&sc->sc_hw.root_pc);

        temp = trb->dwTrb3;

        if (j)
                temp |= htole32(XHCI_TRB_3_CYCLE_BIT);
        else
                temp &= ~htole32(XHCI_TRB_3_CYCLE_BIT);

        temp &= ~htole32(XHCI_TRB_3_TC_BIT);

        phwr->hwr_commands[i].dwTrb3 = temp;

        usb_pc_cpu_flush(&sc->sc_hw.root_pc);

        addr = buf_res.physaddr;
        addr += (uintptr_t)&((struct xhci_hw_root *)0)->hwr_commands[i];

        sc->sc_cmd_addr = htole64(addr);

        i++;

        if (i == (XHCI_MAX_COMMANDS - 1)) {

                if (j) {
                        temp = htole32(XHCI_TRB_3_TC_BIT |
                            XHCI_TRB_3_TYPE_SET(XHCI_TRB_TYPE_LINK) |
                            XHCI_TRB_3_CYCLE_BIT);
                } else {
                        temp = htole32(XHCI_TRB_3_TC_BIT |
                            XHCI_TRB_3_TYPE_SET(XHCI_TRB_TYPE_LINK));
                }

                phwr->hwr_commands[i].dwTrb3 = temp;

                usb_pc_cpu_flush(&sc->sc_hw.root_pc);

                i = 0;
                j ^= 1;
        }

        sc->sc_command_idx = i;
        sc->sc_command_ccs = j;

        XWRITE4(sc, door, XHCI_DOORBELL(0), 0);

        err = cv_timedwait(&sc->sc_cmd_cv, &sc->sc_bus.bus_mtx,
            USB_MS_TO_TICKS(timeout_ms));

        /*
         * In some error cases event interrupts are not generated.
         * Poll one time to see if the command has completed.
         */
        if (err != 0 && xhci_interrupt_poll(sc) != 0) {
                DPRINTF("Command was completed when polling\n");
                err = 0;
        }
        if (err != 0) {
                DPRINTF("Command timeout!\n");
                /*
                 * After some weeks of continuous operation, it has
                 * been observed that the ASMedia Technology, ASM1042
                 * SuperSpeed USB Host Controller can suddenly stop
                 * accepting commands via the command queue. Try to
                 * first reset the command queue. If that fails do a
                 * host controller reset.
                 */
                if (timeout == 0 &&
                    xhci_reset_command_queue_locked(sc) == 0) {
                        temp = le32toh(trb->dwTrb3);

                        /*
                         * Avoid infinite XHCI reset loops if the set
                         * address command fails to respond due to a
                         * non-enumerating device:
                         */
                        if (XHCI_TRB_3_TYPE_GET(temp) == XHCI_TRB_TYPE_ADDRESS_DEVICE 
&&
                            (temp & XHCI_TRB_3_BSR_BIT) == 0) {
                                DPRINTF("Set address timeout\n");
                        } else {
                                timeout = 1;
                                goto retry;
                        }
                } else {
                        DPRINTF("Controller reset!\n");
                        usb_bus_reset_async_locked(&sc->sc_bus);
                }
                err = USB_ERR_TIMEOUT;
                trb->dwTrb2 = 0;
                trb->dwTrb3 = 0;
        } else {
                temp = le32toh(sc->sc_cmd_result[0]);
                if (XHCI_TRB_2_ERROR_GET(temp) != XHCI_TRB_ERROR_SUCCESS)
                        err = USB_ERR_IOERROR;

                trb->dwTrb2 = sc->sc_cmd_result[0];
                trb->dwTrb3 = sc->sc_cmd_result[1];
        }

        USB_BUS_UNLOCK(&sc->sc_bus);

        return (err);
}

--HPS

Reply via email to