Author: hselasky
Date: Tue Aug 18 15:44:03 2020
New Revision: 364347
URL: https://svnweb.freebsd.org/changeset/base/364347

Log:
  Check the XHCI endpoint state before issuing XHCI endpoint commands.
  
  Differential Revision:        https://reviews.freebsd.org/D26064
  Reviewed by:  kp@ and bz@
  MFC after:    1 week
  Sponsored by: Mellanox Technologies

Modified:
  head/sys/dev/usb/controller/xhci.c

Modified: head/sys/dev/usb/controller/xhci.c
==============================================================================
--- head/sys/dev/usb/controller/xhci.c  Tue Aug 18 14:17:14 2020        
(r364346)
+++ head/sys/dev/usb/controller/xhci.c  Tue Aug 18 15:44:03 2020        
(r364347)
@@ -3808,6 +3808,28 @@ alloc_dma_set:
        }
 }
 
+static uint8_t
+xhci_get_endpoint_state(struct usb_device *udev, uint8_t epno)
+{
+       struct xhci_softc *sc = XHCI_BUS2SC(udev->bus);
+       struct usb_page_search buf_dev;
+       struct xhci_hw_dev *hdev;
+       struct xhci_dev_ctx *pdev;
+       uint32_t temp;
+
+       MPASS(epno != 0);
+
+       hdev =  &sc->sc_hw.devs[udev->controller_slot_id];
+
+       usbd_get_page(&hdev->device_pc, 0, &buf_dev);
+       pdev = buf_dev.buffer;
+       usb_pc_cpu_invalidate(&hdev->device_pc);
+
+       temp = xhci_ctx_get_le32(sc, &pdev->ctx_ep[epno - 1].dwEpCtx0);
+
+       return (XHCI_EPCTX_0_EPSTATE_GET(temp));
+}
+
 static usb_error_t
 xhci_configure_reset_endpoint(struct usb_xfer *xfer)
 {
@@ -3861,16 +3883,20 @@ 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:
         */
-
-       err = xhci_cmd_stop_ep(sc, 0, epno, index);
-
-       if (err != 0)
-               DPRINTF("Could not stop endpoint %u\n", epno);
-
-       err = xhci_cmd_reset_ep(sc, 0, epno, index);
-
-       if (err != 0)
-               DPRINTF("Could not reset endpoint %u\n", epno);
+       switch (xhci_get_endpoint_state(udev, epno)) {
+       case XHCI_EPCTX_0_EPSTATE_STOPPED:
+               break;
+       case XHCI_EPCTX_0_EPSTATE_HALTED:
+               err = xhci_cmd_reset_ep(sc, 0, epno, index);
+               if (err != 0)
+                       DPRINTF("Could not reset endpoint %u\n", epno);
+               break;
+       default:
+               err = xhci_cmd_stop_ep(sc, 0, epno, index);
+               if (err != 0)
+                       DPRINTF("Could not stop endpoint %u\n", epno);
+               break;
+       }
 
        err = xhci_cmd_set_tr_dequeue_ptr(sc,
            (pepext->physaddr + (stream_id * sizeof(struct xhci_trb) *
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to