Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 2 Sep 2020 10:11:21 +0000 (UTC)
From:      Hans Petter Selasky <hselasky@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org
Subject:   svn commit: r365240 - stable/11/sys/dev/usb/controller
Message-ID:  <202009021011.082ABLcE004436@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: hselasky
Date: Wed Sep  2 10:11:21 2020
New Revision: 365240
URL: https://svnweb.freebsd.org/changeset/base/365240

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

Modified:
  stable/11/sys/dev/usb/controller/xhci.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/dev/usb/controller/xhci.c
==============================================================================
--- stable/11/sys/dev/usb/controller/xhci.c	Wed Sep  2 10:10:28 2020	(r365239)
+++ stable/11/sys/dev/usb/controller/xhci.c	Wed Sep  2 10:11:21 2020	(r365240)
@@ -3807,6 +3807,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)
 {
@@ -3860,16 +3882,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) *



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202009021011.082ABLcE004436>