Module Name:    src
Committed By:   bouyer
Date:           Sat Dec 14 19:26:39 UTC 2013

Modified Files:
        src/sys/dev/usb [netbsd-6]: ehci.c

Log Message:
Pull up following revision(s) (requested by skrll in ticket #990):
        sys/dev/usb/ehci.c: revision 1.221
In ehci_check_qh_intr don't treat a short control transfer as done if the
status phase is still inflight.  Let the hardware complete it.
PR/48358: Repeated low-speed USB control transfers returning short data
          fail on EHCI
PR/46696: uhub disables port where USB keyboard attached


To generate a diff of this commit:
cvs rdiff -u -r1.183.2.1 -r1.183.2.2 src/sys/dev/usb/ehci.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/usb/ehci.c
diff -u src/sys/dev/usb/ehci.c:1.183.2.1 src/sys/dev/usb/ehci.c:1.183.2.2
--- src/sys/dev/usb/ehci.c:1.183.2.1	Thu Sep 26 01:51:47 2013
+++ src/sys/dev/usb/ehci.c	Sat Dec 14 19:26:39 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: ehci.c,v 1.183.2.1 2013/09/26 01:51:47 riz Exp $ */
+/*	$NetBSD: ehci.c,v 1.183.2.2 2013/12/14 19:26:39 bouyer Exp $ */
 
 /*
  * Copyright (c) 2004-2008 The NetBSD Foundation, Inc.
@@ -52,7 +52,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.183.2.1 2013/09/26 01:51:47 riz Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.183.2.2 2013/12/14 19:26:39 bouyer Exp $");
 
 #include "ohci.h"
 #include "uhci.h"
@@ -784,9 +784,26 @@ ehci_check_qh_intr(ehci_softc_t *sc, str
 			/* Any kind of error makes the xfer done. */
 			if (status & EHCI_QTD_HALTED)
 				goto done;
-			/* We want short packets, and it is short: it's done */
-			if (EHCI_QTD_GET_BYTES(status) != 0)
+			/* Handle short packets */
+			if (EHCI_QTD_GET_BYTES(status) != 0) {
+				usbd_pipe_handle pipe = ex->xfer.pipe;
+				usb_endpoint_descriptor_t *ed =
+				    pipe->endpoint->edesc;
+				uint8_t xt = UE_GET_XFERTYPE(ed->bmAttributes);
+
+				/*
+				 * If we get here for a control transfer then
+				 * we need to let the hardware complete the
+				 * status phase.  That is, we're not done
+				 * quite yet.
+				 *
+				 * Otherwise, we're done.
+				 */
+				if (xt == UE_CONTROL) {
+					break;
+				}
 				goto done;
+			}
 		}
 		DPRINTFN(12, ("ehci_check_intr: ex=%p std=%p still active\n",
 			      ex, ex->sqtdstart));

Reply via email to