On 2019-12-31 01:23, [email protected] wrote:
Dell Customer Communication - Confidential

Hi HPS,

It's already in stopped status. I am also confusing on the root cause.
I attached the test application and my patch for the xhci stop xfer workaround 
solution.
The confusing points:
1. cancel xfer error can be reproduced on all CCID smart readers (I have tested 
three different model of readers);
2. keyboard has similar endpoint attribution, while I can't reproduce similar 
problem on the keyboard;


Hi,

I suspect it is the newer XHCI hardware which has some additional checks. Can you verify if the XHCI controller in your computer accept multiple configure_ep() commands? The state diagram in the XHCI specification does not say you cannot do this, but I imagine this might be causing it.

The XHCI driver in FreeBSD configure one and one endpoint and not all at the same time.

Can you try the attached patch instead of yours?

--HPS
Index: sys/dev/usb/controller/xhci.c
===================================================================
--- sys/dev/usb/controller/xhci.c	(revision 356220)
+++ sys/dev/usb/controller/xhci.c	(working copy)
@@ -3838,6 +3838,7 @@
 	struct usb_page_cache *pcinp;
 	usb_error_t err;
 	usb_stream_t stream_id;
+	uint32_t mask;
 	uint8_t index;
 	uint8_t epno;
 
@@ -3903,16 +3904,20 @@
 	 * endpoint context state diagram in the XHCI specification:
 	 */
 
-	xhci_configure_mask(udev, (1U << epno) | 1U, 0);
+	mask = (1U << epno);
+	xhci_configure_mask(udev, mask | 1U, 0);
 
-	if (epno > 1)
+	if (!(sc->sc_hw.devs[index].ep_configured & mask)) {
+		sc->sc_hw.devs[index].ep_configured |= mask;
 		err = xhci_cmd_configure_ep(sc, buf_inp.physaddr, 0, index);
-	else
+	} else {
 		err = xhci_cmd_evaluate_ctx(sc, buf_inp.physaddr, index);
+	}
 
-	if (err != 0)
-		DPRINTF("Could not configure endpoint %u\n", epno);
-
+	if (err != 0) {
+		DPRINTF("Could not configure "
+		    "endpoint %u at slot %u.\n", epno, index);
+	}
 	XHCI_CMD_UNLOCK(sc);
 
 	return (0);
@@ -4273,6 +4278,7 @@
 
 		/* set default state */
 		sc->sc_hw.devs[index].state = XHCI_ST_DEFAULT;
+		sc->sc_hw.devs[index].ep_configured = 3U;
 
 		/* reset number of contexts */
 		sc->sc_hw.devs[index].context_num = 0;
@@ -4290,6 +4296,7 @@
 			break;
 
 		sc->sc_hw.devs[index].state = XHCI_ST_ADDRESSED;
+		sc->sc_hw.devs[index].ep_configured = 3U;
 
 		/* set configure mask to slot only */
 		xhci_configure_mask(udev, 1, 0);
@@ -4304,11 +4311,19 @@
 		break;
 
 	case USB_STATE_CONFIGURED:
-		if (sc->sc_hw.devs[index].state == XHCI_ST_CONFIGURED)
-			break;
+		if (sc->sc_hw.devs[index].state == XHCI_ST_CONFIGURED) {
+			/* deconfigure all endpoints, except EP0 */
+			err = xhci_cmd_configure_ep(sc, 0, 1, index);
 
+			if (err) {
+				DPRINTF("Failed to deconfigure "
+				    "slot %u.\n", index);
+			}
+		}
+
 		/* set configured state */
 		sc->sc_hw.devs[index].state = XHCI_ST_CONFIGURED;
+		sc->sc_hw.devs[index].ep_configured = 3U;
 
 		/* reset number of contexts */
 		sc->sc_hw.devs[index].context_num = 0;
Index: sys/dev/usb/controller/xhci.h
===================================================================
--- sys/dev/usb/controller/xhci.h	(revision 356220)
+++ sys/dev/usb/controller/xhci.h	(working copy)
@@ -408,6 +408,8 @@
 
 	struct xhci_endpoint_ext endp[XHCI_MAX_ENDPOINTS];
 
+	uint32_t		ep_configured;
+
 	uint8_t			state;
 	uint8_t			nports;
 	uint8_t			tt;
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-usb
To unsubscribe, send any mail to "[email protected]"

Reply via email to