Module Name:    src
Committed By:   skrll
Date:           Thu Mar 17 09:04:53 UTC 2016

Modified Files:
        src/sys/dev/usb [nick-nhusb]: ehci.c ehcivar.h ohci.c uhci.c uhcivar.h
            usbdi.c usbdivar.h
        src/sys/external/bsd/dwc2 [nick-nhusb]: dwc2.c

Log Message:
All HCDs were fighting the seriaisation of transfers in usbdi.c for isoc
transfers.  Instead allow the HCDs to specify which pipes can handle
removing this serialisation and apply it appropriately.

dwctwo(4) can handle this for all transfer types, but only enable
bulk/isoc for now.


To generate a diff of this commit:
cvs rdiff -u -r1.234.2.91 -r1.234.2.92 src/sys/dev/usb/ehci.c
cvs rdiff -u -r1.42.14.22 -r1.42.14.23 src/sys/dev/usb/ehcivar.h
cvs rdiff -u -r1.254.2.58 -r1.254.2.59 src/sys/dev/usb/ohci.c
cvs rdiff -u -r1.264.4.67 -r1.264.4.68 src/sys/dev/usb/uhci.c
cvs rdiff -u -r1.52.14.16 -r1.52.14.17 src/sys/dev/usb/uhcivar.h
cvs rdiff -u -r1.162.2.43 -r1.162.2.44 src/sys/dev/usb/usbdi.c
cvs rdiff -u -r1.109.2.24 -r1.109.2.25 src/sys/dev/usb/usbdivar.h
cvs rdiff -u -r1.32.2.23 -r1.32.2.24 src/sys/external/bsd/dwc2/dwc2.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.234.2.91 src/sys/dev/usb/ehci.c:1.234.2.92
--- src/sys/dev/usb/ehci.c:1.234.2.91	Sun Feb 28 09:16:20 2016
+++ src/sys/dev/usb/ehci.c	Thu Mar 17 09:04:53 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: ehci.c,v 1.234.2.91 2016/02/28 09:16:20 skrll Exp $ */
+/*	$NetBSD: ehci.c,v 1.234.2.92 2016/03/17 09:04:53 skrll Exp $ */
 
 /*
  * Copyright (c) 2004-2012 The NetBSD Foundation, Inc.
@@ -53,7 +53,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.234.2.91 2016/02/28 09:16:20 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.234.2.92 2016/03/17 09:04:53 skrll Exp $");
 
 #include "ohci.h"
 #include "uhci.h"
@@ -209,7 +209,6 @@ Static void		ehci_device_intr_done(struc
 Static int		ehci_device_isoc_init(struct usbd_xfer *);
 Static void		ehci_device_isoc_fini(struct usbd_xfer *);
 Static usbd_status	ehci_device_isoc_transfer(struct usbd_xfer *);
-Static usbd_status	ehci_device_isoc_start(struct usbd_xfer *);
 Static void		ehci_device_isoc_abort(struct usbd_xfer *);
 Static void		ehci_device_isoc_close(struct usbd_pipe *);
 Static void		ehci_device_isoc_done(struct usbd_xfer *);
@@ -217,7 +216,6 @@ Static void		ehci_device_isoc_done(struc
 Static int		ehci_device_fs_isoc_init(struct usbd_xfer *);
 Static void		ehci_device_fs_isoc_fini(struct usbd_xfer *);
 Static usbd_status	ehci_device_fs_isoc_transfer(struct usbd_xfer *);
-Static usbd_status	ehci_device_fs_isoc_start(struct usbd_xfer *);
 Static void		ehci_device_fs_isoc_abort(struct usbd_xfer *);
 Static void		ehci_device_fs_isoc_close(struct usbd_pipe *);
 Static void		ehci_device_fs_isoc_done(struct usbd_xfer *);
@@ -366,7 +364,6 @@ Static const struct usbd_pipe_methods eh
 	.upm_init =	ehci_device_isoc_init,
 	.upm_fini =	ehci_device_isoc_fini,
 	.upm_transfer =	ehci_device_isoc_transfer,
-	.upm_start =	ehci_device_isoc_start,
 	.upm_abort =	ehci_device_isoc_abort,
 	.upm_close =	ehci_device_isoc_close,
 	.upm_cleartoggle =	ehci_noop,
@@ -377,7 +374,6 @@ Static const struct usbd_pipe_methods eh
 	.upm_init =	ehci_device_fs_isoc_init,
 	.upm_fini =	ehci_device_fs_isoc_fini,
 	.upm_transfer =	ehci_device_fs_isoc_transfer,
-	.upm_start =	ehci_device_fs_isoc_start,
 	.upm_abort =	ehci_device_fs_isoc_abort,
 	.upm_close =	ehci_device_fs_isoc_close,
 	.upm_cleartoggle = ehci_noop,
@@ -2066,6 +2062,7 @@ ehci_open(struct usbd_pipe *pipe)
 			goto bad;
 		break;
 	case UE_ISOCHRONOUS:
+		pipe->up_serialise = false;
 		if (speed == EHCI_QH_SPEED_HIGH)
 			pipe->up_methods = &ehci_device_isoc_methods;
 		else
@@ -4368,22 +4365,14 @@ Static usbd_status
 ehci_device_fs_isoc_transfer(struct usbd_xfer *xfer)
 {
 	ehci_softc_t *sc = EHCI_XFER2SC(xfer);
-	usbd_status err;
+	usbd_status __diagused err;
 
 	mutex_enter(&sc->sc_lock);
 	err = usb_insert_transfer(xfer);
 	mutex_exit(&sc->sc_lock);
 
-	if (err && err != USBD_IN_PROGRESS)
-		return err;
-
-	return ehci_device_fs_isoc_start(xfer);
-}
+	KASSERT(err == USBD_NORMAL_COMPLETION);
 
-Static usbd_status
-ehci_device_fs_isoc_start(struct usbd_xfer *xfer)
-{
-	ehci_softc_t *sc = EHCI_XFER2SC(xfer);
 	struct ehci_pipe *epipe = EHCI_XFER2EPIPE(xfer);;
 	struct usbd_device *dev = xfer->ux_pipe->up_dev;;
 	struct ehci_xfer *exfer = EHCI_XFER2EXFER(xfer);
@@ -4399,16 +4388,6 @@ ehci_device_fs_isoc_start(struct usbd_xf
 	sitd = NULL;
 	total_length = 0;
 
-	/*
-	 * To allow continuous transfers, above we start all transfers
-	 * immediately. However, we're still going to get usbd_start_next call
-	 * this when another xfer completes. So, check if this is already
-	 * in progress or not
-	 */
-
- 	if (exfer->ex_isrunning) {
-		return USBD_IN_PROGRESS;
-	}
 
 	USBHIST_LOG(ehcidebug, "xfer %p len %d flags %d",
 	    xfer, xfer->ux_length, xfer->ux_flags, 0);
@@ -4604,8 +4583,6 @@ ehci_device_fs_isoc_start(struct usbd_xf
 	epipe->isoc.cur_xfers++;
 	epipe->isoc.next_frame = frindex;
 
-	exfer->ex_isrunning = true;
-
 	ehci_add_intr_list(sc, exfer);
 	xfer->ux_status = USBD_IN_PROGRESS;
 
@@ -4646,10 +4623,7 @@ ehci_device_fs_isoc_done(struct usbd_xfe
 	KASSERT(mutex_owned(&sc->sc_lock));
 
 	epipe->isoc.cur_xfers--;
-	if (exfer->ex_isrunning) {
-		ehci_remove_sitd_chain(sc, exfer->ex_itdstart);
-		exfer->ex_isrunning = false;
-	}
+	ehci_remove_sitd_chain(sc, exfer->ex_itdstart);
 
 	usb_syncmem(&xfer->ux_dmabuf, 0, xfer->ux_length,
 	    BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
@@ -4681,7 +4655,6 @@ ehci_device_isoc_init(struct usbd_xfer *
 	KASSERT(exfer->ex_isdone);
 
 	exfer->ex_type = EX_ISOC;
-	exfer->ex_isrunning = false;
 
 	/*
 	 * Step 1: Allocate and initialize itds, how many do we need?
@@ -4770,22 +4743,15 @@ Static usbd_status
 ehci_device_isoc_transfer(struct usbd_xfer *xfer)
 {
 	ehci_softc_t *sc = EHCI_XFER2SC(xfer);
-	usbd_status err;
+	usbd_status __diagused err;
 
 	mutex_enter(&sc->sc_lock);
 	err = usb_insert_transfer(xfer);
 	mutex_exit(&sc->sc_lock);
-	if (err && err != USBD_IN_PROGRESS)
-		return err;
 
-	return ehci_device_isoc_start(xfer);
-}
+	KASSERT(err == USBD_NORMAL_COMPLETION);
 
-Static usbd_status
-ehci_device_isoc_start(struct usbd_xfer *xfer)
-{
 	struct ehci_pipe *epipe = EHCI_XFER2EPIPE(xfer);
-	ehci_softc_t *sc = EHCI_XFER2SC(xfer);
 	struct ehci_xfer *exfer = EHCI_XFER2EXFER(xfer);
 	ehci_soft_itd_t *itd, *prev;
 	usb_dma_t *dma_buf;
@@ -4801,17 +4767,6 @@ ehci_device_isoc_start(struct usbd_xfer 
 	trans_count = 0;
 	total_length = 0;
 
-	/*
-	 * To allow continuous transfers, above we start all transfers
-	 * immediately. However, we're still going to get usbd_start_next call
-	 * this when another xfer completes. So, check if this is already
-	 * in progress or not
-	 */
-
-	if (exfer->ex_isrunning) {
-		return USBD_IN_PROGRESS;
-	}
-
 	USBHIST_LOG(ehcidebug, "xfer %p flags %d", xfer, xfer->ux_flags, 0, 0);
 
 	if (sc->sc_dying)
@@ -5027,8 +4982,6 @@ ehci_device_isoc_start(struct usbd_xfer 
 	epipe->isoc.cur_xfers++;
 	epipe->isoc.next_frame = frindex;
 
-	exfer->ex_isrunning = true;
-
 	ehci_add_intr_list(sc, exfer);
 	xfer->ux_status = USBD_IN_PROGRESS;
 
@@ -5069,10 +5022,7 @@ ehci_device_isoc_done(struct usbd_xfer *
 	KASSERT(mutex_owned(&sc->sc_lock));
 
 	epipe->isoc.cur_xfers--;
-	if (exfer->ex_isrunning) {
-		ehci_remove_itd_chain(sc, exfer->ex_sitdstart);
-		exfer->ex_isrunning = false;
-	}
+	ehci_remove_itd_chain(sc, exfer->ex_sitdstart);
 	usb_syncmem(&xfer->ux_dmabuf, 0, xfer->ux_length,
 	    BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
 }

Index: src/sys/dev/usb/ehcivar.h
diff -u src/sys/dev/usb/ehcivar.h:1.42.14.22 src/sys/dev/usb/ehcivar.h:1.42.14.23
--- src/sys/dev/usb/ehcivar.h:1.42.14.22	Sun Jan 10 16:49:29 2016
+++ src/sys/dev/usb/ehcivar.h	Thu Mar 17 09:04:53 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: ehcivar.h,v 1.42.14.22 2016/01/10 16:49:29 skrll Exp $ */
+/*	$NetBSD: ehcivar.h,v 1.42.14.23 2016/03/17 09:04:53 skrll Exp $ */
 
 /*
  * Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -103,14 +103,10 @@ struct ehci_xfer {
 		EX_ISOC,
 		EX_FS_ISOC
 	} ex_type;
-	union {
-		/* ctrl/bulk/intr */
-		struct {
-			ehci_soft_qtd_t **ex_sqtds;
-			size_t ex_nsqtd;
-		};
-		/* isoc */
-		bool ex_isrunning;
+	/* ctrl/bulk/intr */
+	struct {
+		ehci_soft_qtd_t **ex_sqtds;
+		size_t ex_nsqtd;
 	};
 	union {
 		/* ctrl */

Index: src/sys/dev/usb/ohci.c
diff -u src/sys/dev/usb/ohci.c:1.254.2.58 src/sys/dev/usb/ohci.c:1.254.2.59
--- src/sys/dev/usb/ohci.c:1.254.2.58	Sun Mar 13 07:11:01 2016
+++ src/sys/dev/usb/ohci.c	Thu Mar 17 09:04:53 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: ohci.c,v 1.254.2.58 2016/03/13 07:11:01 skrll Exp $	*/
+/*	$NetBSD: ohci.c,v 1.254.2.59 2016/03/17 09:04:53 skrll Exp $	*/
 
 /*
  * Copyright (c) 1998, 2004, 2005, 2012 The NetBSD Foundation, Inc.
@@ -41,7 +41,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ohci.c,v 1.254.2.58 2016/03/13 07:11:01 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ohci.c,v 1.254.2.59 2016/03/17 09:04:53 skrll Exp $");
 
 #include "opt_usb.h"
 
@@ -74,7 +74,7 @@ __KERNEL_RCSID(0, "$NetBSD: ohci.c,v 1.2
 #ifndef OHCI_DEBUG
 #define ohcidebug 0
 #else
-static int ohcidebug = 0;
+static int ohcidebug = 10;
 
 SYSCTL_SETUP(sysctl_hw_ohci_setup, "sysctl hw.ohci setup")
 {
@@ -205,7 +205,6 @@ Static void		ohci_device_intr_done(struc
 Static int		ohci_device_isoc_init(struct usbd_xfer *);
 Static void		ohci_device_isoc_fini(struct usbd_xfer *);
 Static usbd_status	ohci_device_isoc_transfer(struct usbd_xfer *);
-Static usbd_status	ohci_device_isoc_start(struct usbd_xfer *);
 Static void		ohci_device_isoc_abort(struct usbd_xfer *);
 Static void		ohci_device_isoc_close(struct usbd_pipe *);
 Static void		ohci_device_isoc_done(struct usbd_xfer *);
@@ -337,7 +336,6 @@ Static const struct usbd_pipe_methods oh
 	.upm_init =	ohci_device_isoc_init,
 	.upm_fini =	ohci_device_isoc_fini,
 	.upm_transfer =	ohci_device_isoc_transfer,
-	.upm_start =	ohci_device_isoc_start,
 	.upm_abort =	ohci_device_isoc_abort,
 	.upm_close =	ohci_device_isoc_close,
 	.upm_cleartoggle =	ohci_noop,
@@ -2218,6 +2216,7 @@ ohci_open(struct usbd_pipe *pipe)
 				goto bad;
 			break;
 		case UE_ISOCHRONOUS:
+			pipe->up_serialise = false;
 			pipe->up_methods = &ohci_device_isoc_methods;
 			return ohci_setup_isoc(pipe);
 		case UE_BULK:
@@ -3541,7 +3540,7 @@ usbd_status
 ohci_device_isoc_transfer(struct usbd_xfer *xfer)
 {
 	ohci_softc_t *sc = OHCI_XFER2SC(xfer);
-	usbd_status err;
+	usbd_status __diagused err;
 
 	OHCIHIST_FUNC(); OHCIHIST_CALLED();
 
@@ -3552,20 +3551,13 @@ ohci_device_isoc_transfer(struct usbd_xf
 	err = usb_insert_transfer(xfer);
 	mutex_exit(&sc->sc_lock);
 
-	/* bail out on error, */
-	if (err && err != USBD_IN_PROGRESS)
-		return err;
-
-	/* XXX should check inuse here */
+	KASSERT(err == USBD_NORMAL_COMPLETION);
 
 	/* insert into schedule, */
 	ohci_device_isoc_enter(xfer);
 
 	/* and start if the pipe wasn't running */
-	if (!err)
-		ohci_device_isoc_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue));
-
-	return err;
+	return USBD_IN_PROGRESS;
 }
 
 void
@@ -3702,34 +3694,6 @@ ohci_device_isoc_enter(struct usbd_xfer 
 	mutex_exit(&sc->sc_lock);
 }
 
-usbd_status
-ohci_device_isoc_start(struct usbd_xfer *xfer)
-{
-	ohci_softc_t *sc = OHCI_XFER2SC(xfer);
-
-	OHCIHIST_FUNC(); OHCIHIST_CALLED();
-	DPRINTFN(5, "xfer=%p", xfer, 0, 0, 0);
-
-	mutex_enter(&sc->sc_lock);
-
-	if (sc->sc_dying) {
-		mutex_exit(&sc->sc_lock);
-		return USBD_IOERROR;
-	}
-
-
-#ifdef DIAGNOSTIC
-	if (xfer->ux_status != USBD_IN_PROGRESS)
-		printf("ohci_device_isoc_start: not in progress %p\n", xfer);
-#endif
-
-	/* XXX anything to do? */
-
-	mutex_exit(&sc->sc_lock);
-
-	return USBD_IN_PROGRESS;
-}
-
 void
 ohci_device_isoc_abort(struct usbd_xfer *xfer)
 {

Index: src/sys/dev/usb/uhci.c
diff -u src/sys/dev/usb/uhci.c:1.264.4.67 src/sys/dev/usb/uhci.c:1.264.4.68
--- src/sys/dev/usb/uhci.c:1.264.4.67	Thu Mar 17 07:59:45 2016
+++ src/sys/dev/usb/uhci.c	Thu Mar 17 09:04:53 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: uhci.c,v 1.264.4.67 2016/03/17 07:59:45 skrll Exp $	*/
+/*	$NetBSD: uhci.c,v 1.264.4.68 2016/03/17 09:04:53 skrll Exp $	*/
 
 /*
  * Copyright (c) 1998, 2004, 2011, 2012 The NetBSD Foundation, Inc.
@@ -42,7 +42,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uhci.c,v 1.264.4.67 2016/03/17 07:59:45 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uhci.c,v 1.264.4.68 2016/03/17 09:04:53 skrll Exp $");
 
 #include "opt_usb.h"
 
@@ -205,7 +205,6 @@ Static void		uhci_add_loop(uhci_softc_t 
 Static void		uhci_rem_loop(uhci_softc_t *);
 
 Static usbd_status	uhci_setup_isoc(struct usbd_pipe *);
-Static void		uhci_device_isoc_enter(struct usbd_xfer *);
 
 Static struct usbd_xfer *
 			uhci_allocx(struct usbd_bus *, unsigned int);
@@ -379,7 +378,6 @@ const struct usbd_pipe_methods uhci_devi
 	.upm_init =	uhci_device_isoc_init,
 	.upm_fini =	uhci_device_isoc_fini,
 	.upm_transfer =	uhci_device_isoc_transfer,
-	.upm_start =	uhci_device_isoc_start,
 	.upm_abort =	uhci_device_isoc_abort,
 	.upm_close =	uhci_device_isoc_close,
 	.upm_cleartoggle =	uhci_noop,
@@ -3006,7 +3004,7 @@ usbd_status
 uhci_device_isoc_transfer(struct usbd_xfer *xfer)
 {
 	uhci_softc_t *sc = UHCI_XFER2SC(xfer);
-	usbd_status err;
+	usbd_status err __diagused;
 
 	UHCIHIST_FUNC(); UHCIHIST_CALLED();
 	DPRINTFN(5, "xfer=%p", xfer, 0, 0, 0);
@@ -3016,40 +3014,23 @@ uhci_device_isoc_transfer(struct usbd_xf
 	err = usb_insert_transfer(xfer);
 	mutex_exit(&sc->sc_lock);
 
-	/* bail out on error, */
-	if (err && err != USBD_IN_PROGRESS)
-		return err;
-
-	/* XXX should check inuse here */
+	KASSERT(err == USBD_NORMAL_COMPLETION);
 
 	/* insert into schedule, */
-	uhci_device_isoc_enter(xfer);
 
-	/* and start if the pipe wasn't running */
-	if (!err)
-		uhci_device_isoc_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue));
-
-	return err;
-}
-
-void
-uhci_device_isoc_enter(struct usbd_xfer *xfer)
-{
-	uhci_softc_t *sc = UHCI_XFER2SC(xfer);
 	struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(xfer->ux_pipe);
 	struct uhci_xfer *ux = UHCI_XFER2UXFER(xfer);
 	struct isoc *isoc = &upipe->isoc;
-	uhci_soft_td_t *std;
+	uhci_soft_td_t *std = NULL;
 	uint32_t buf, len, status, offs;
 	int i, next, nframes;
 	int rd = UE_GET_DIR(upipe->pipe.up_endpoint->ue_edesc->bEndpointAddress) == UE_DIR_IN;
 
-	UHCIHIST_FUNC(); UHCIHIST_CALLED();
 	DPRINTFN(5, "used=%d next=%d xfer=%p nframes=%d",
 	    isoc->inuse, isoc->next, xfer, xfer->ux_nframes);
 
 	if (sc->sc_dying)
-		return;
+		return USBD_IOERROR;
 
 	if (xfer->ux_status == USBD_IN_PROGRESS) {
 		/* This request has already been entered into the frame list */
@@ -3062,6 +3043,8 @@ uhci_device_isoc_enter(struct usbd_xfer 
 		printf("%s: overflow!\n", __func__);
 #endif
 
+	KASSERT(xfer->ux_nframes != 0);
+
 	mutex_enter(&sc->sc_lock);
 	next = isoc->next;
 	if (next == -1) {
@@ -3108,44 +3091,9 @@ uhci_device_isoc_enter(struct usbd_xfer 
 	isoc->next = next;
 	isoc->inuse += xfer->ux_nframes;
 
-	mutex_exit(&sc->sc_lock);
-}
-
-usbd_status
-uhci_device_isoc_start(struct usbd_xfer *xfer)
-{
-	struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(xfer->ux_pipe);
-	uhci_softc_t *sc = UHCI_XFER2SC(xfer);
-	struct uhci_xfer *ux = UHCI_XFER2UXFER(xfer);
-	uhci_soft_td_t *end;
-	int i;
-
-	UHCIHIST_FUNC(); UHCIHIST_CALLED();
-	DPRINTFN(5, "xfer=%p", xfer, 0, 0, 0);
-
-	mutex_enter(&sc->sc_lock);
-
-	if (sc->sc_dying) {
-		mutex_exit(&sc->sc_lock);
-		return USBD_IOERROR;
-	}
-
-#ifdef DIAGNOSTIC
-	if (xfer->ux_status != USBD_IN_PROGRESS)
-		printf("%s: not in progress %p\n", __func__, xfer);
-#endif
-
-	/* Find the last TD */
-	i = UHCI_XFER2UXFER(xfer)->ux_curframe + xfer->ux_nframes;
-	if (i >= UHCI_VFRAMELIST_COUNT)
-		i -= UHCI_VFRAMELIST_COUNT;
-	end = upipe->isoc.stds[i];
-
-	KASSERT(end != NULL);
-
 	/* Set up interrupt info. */
-	ux->ux_stdstart = end;
-	ux->ux_stdend = end;
+	ux->ux_stdstart = std;
+	ux->ux_stdend = std;
 
 	KASSERT(ux->ux_isdone);
 #ifdef DIAGNOSTIC
@@ -3681,6 +3629,7 @@ uhci_open(struct usbd_pipe *pipe)
 				ival = ed->bInterval;
 			return uhci_device_setintr(sc, upipe, ival);
 		case UE_ISOCHRONOUS:
+			pipe->up_serialise = false;
 			pipe->up_methods = &uhci_device_isoc_methods;
 			return uhci_setup_isoc(pipe);
 		case UE_BULK:

Index: src/sys/dev/usb/uhcivar.h
diff -u src/sys/dev/usb/uhcivar.h:1.52.14.16 src/sys/dev/usb/uhcivar.h:1.52.14.17
--- src/sys/dev/usb/uhcivar.h:1.52.14.16	Tue Nov 10 08:44:09 2015
+++ src/sys/dev/usb/uhcivar.h	Thu Mar 17 09:04:53 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: uhcivar.h,v 1.52.14.16 2015/11/10 08:44:09 skrll Exp $	*/
+/*	$NetBSD: uhcivar.h,v 1.52.14.17 2016/03/17 09:04:53 skrll Exp $	*/
 
 /*
  * Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -65,14 +65,10 @@ struct uhci_xfer {
 	enum {
 		UX_NONE, UX_CTRL, UX_BULK, UX_INTR, UX_ISOC
 	} ux_type;
-	union {
-		/* ctrl/bulk/intr */
-		struct {
-			uhci_soft_td_t **ux_stds;
-			size_t ux_nstd;
-		};
-		/* isoc */
-		bool ux_isrunning;
+	/* ctrl/bulk/intr */
+	struct {
+		uhci_soft_td_t **ux_stds;
+		size_t ux_nstd;
 	};
 	union {
 		/* ctrl */

Index: src/sys/dev/usb/usbdi.c
diff -u src/sys/dev/usb/usbdi.c:1.162.2.43 src/sys/dev/usb/usbdi.c:1.162.2.44
--- src/sys/dev/usb/usbdi.c:1.162.2.43	Sun Feb 28 09:16:20 2016
+++ src/sys/dev/usb/usbdi.c	Thu Mar 17 09:04:53 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: usbdi.c,v 1.162.2.43 2016/02/28 09:16:20 skrll Exp $	*/
+/*	$NetBSD: usbdi.c,v 1.162.2.44 2016/03/17 09:04:53 skrll Exp $	*/
 
 /*
  * Copyright (c) 1998, 2012, 2015 The NetBSD Foundation, Inc.
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: usbdi.c,v 1.162.2.43 2016/02/28 09:16:20 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: usbdi.c,v 1.162.2.44 2016/03/17 09:04:53 skrll Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -331,7 +331,8 @@ usbd_transfer(struct usbd_xfer *xfer)
 		 */
 		usbd_lock_pipe(pipe);
 		SIMPLEQ_REMOVE_HEAD(&pipe->up_queue, ux_next);
-		usbd_start_next(pipe);
+		if (pipe->up_serialise)
+			usbd_start_next(pipe);
 		usbd_unlock_pipe(pipe);
 	}
 
@@ -988,7 +989,7 @@ usb_transfer_complete(struct usbd_xfer *
 		if (erred && pipe->up_iface != NULL)	/* not control pipe */
 			pipe->up_running = 0;
 	}
-	if (pipe->up_running)
+	if (pipe->up_running && pipe->up_serialise)
 		usbd_start_next(pipe);
 }
 
@@ -1011,7 +1012,7 @@ usb_insert_transfer(struct usbd_xfer *xf
 	xfer->ux_state = XFER_ONQU;
 #endif
 	SIMPLEQ_INSERT_TAIL(&pipe->up_queue, xfer, ux_next);
-	if (pipe->up_running)
+	if (pipe->up_running && pipe->up_serialise)
 		err = USBD_IN_PROGRESS;
 	else {
 		pipe->up_running = 1;
@@ -1033,6 +1034,7 @@ usbd_start_next(struct usbd_pipe *pipe)
 	KASSERT(pipe != NULL);
 	KASSERT(pipe->up_methods != NULL);
 	KASSERT(pipe->up_methods->upm_start != NULL);
+	KASSERT(pipe->up_serialise == true);
 
 	int polling = pipe->up_dev->ud_bus->ub_usepolling;
 	KASSERT(polling || mutex_owned(pipe->up_dev->ud_bus->ub_lock));

Index: src/sys/dev/usb/usbdivar.h
diff -u src/sys/dev/usb/usbdivar.h:1.109.2.24 src/sys/dev/usb/usbdivar.h:1.109.2.25
--- src/sys/dev/usb/usbdivar.h:1.109.2.24	Sun Mar  6 10:25:31 2016
+++ src/sys/dev/usb/usbdivar.h	Thu Mar 17 09:04:53 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: usbdivar.h,v 1.109.2.24 2016/03/06 10:25:31 skrll Exp $	*/
+/*	$NetBSD: usbdivar.h,v 1.109.2.25 2016/03/17 09:04:53 skrll Exp $	*/
 
 /*
  * Copyright (c) 1998, 2012 The NetBSD Foundation, Inc.
@@ -222,6 +222,7 @@ struct usbd_pipe {
 	struct usbd_endpoint   *up_endpoint;
 	char			up_running;
 	char			up_aborting;
+	bool			up_serialise;
 	SIMPLEQ_HEAD(, usbd_xfer) up_queue;
 	LIST_ENTRY(usbd_pipe)	up_next;
 	struct usb_task		up_async_task;

Index: src/sys/external/bsd/dwc2/dwc2.c
diff -u src/sys/external/bsd/dwc2/dwc2.c:1.32.2.23 src/sys/external/bsd/dwc2/dwc2.c:1.32.2.24
--- src/sys/external/bsd/dwc2/dwc2.c:1.32.2.23	Sat Mar  5 13:03:00 2016
+++ src/sys/external/bsd/dwc2/dwc2.c	Thu Mar 17 09:04:53 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: dwc2.c,v 1.32.2.23 2016/03/05 13:03:00 skrll Exp $	*/
+/*	$NetBSD: dwc2.c,v 1.32.2.24 2016/03/17 09:04:53 skrll Exp $	*/
 
 /*-
  * Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: dwc2.c,v 1.32.2.23 2016/03/05 13:03:00 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: dwc2.c,v 1.32.2.24 2016/03/17 09:04:53 skrll Exp $");
 
 #include "opt_usb.h"
 
@@ -104,7 +104,6 @@ Static void		dwc2_device_ctrl_close(stru
 Static void		dwc2_device_ctrl_done(struct usbd_xfer *);
 
 Static usbd_status	dwc2_device_bulk_transfer(struct usbd_xfer *);
-Static usbd_status	dwc2_device_bulk_start(struct usbd_xfer *);
 Static void		dwc2_device_bulk_abort(struct usbd_xfer *);
 Static void		dwc2_device_bulk_close(struct usbd_pipe *);
 Static void		dwc2_device_bulk_done(struct usbd_xfer *);
@@ -116,7 +115,6 @@ Static void		dwc2_device_intr_close(stru
 Static void		dwc2_device_intr_done(struct usbd_xfer *);
 
 Static usbd_status	dwc2_device_isoc_transfer(struct usbd_xfer *);
-Static usbd_status	dwc2_device_isoc_start(struct usbd_xfer *);
 Static void		dwc2_device_isoc_abort(struct usbd_xfer *);
 Static void		dwc2_device_isoc_close(struct usbd_pipe *);
 Static void		dwc2_device_isoc_done(struct usbd_xfer *);
@@ -187,7 +185,6 @@ Static const struct usbd_pipe_methods dw
 
 Static const struct usbd_pipe_methods dwc2_device_bulk_methods = {
 	.upm_transfer =	dwc2_device_bulk_transfer,
-	.upm_start =	dwc2_device_bulk_start,
 	.upm_abort =	dwc2_device_bulk_abort,
 	.upm_close =	dwc2_device_bulk_close,
 	.upm_cleartoggle =	dwc2_device_clear_toggle,
@@ -196,7 +193,6 @@ Static const struct usbd_pipe_methods dw
 
 Static const struct usbd_pipe_methods dwc2_device_isoc_methods = {
 	.upm_transfer =	dwc2_device_isoc_transfer,
-	.upm_start =	dwc2_device_isoc_start,
 	.upm_abort =	dwc2_device_isoc_abort,
 	.upm_close =	dwc2_device_isoc_close,
 	.upm_cleartoggle =	dwc2_noop,
@@ -435,9 +431,11 @@ dwc2_open(struct usbd_pipe *pipe)
 		pipe->up_methods = &dwc2_device_intr_methods;
 		break;
 	case UE_ISOCHRONOUS:
+		pipe->up_serialise = false;
 		pipe->up_methods = &dwc2_device_isoc_methods;
 		break;
 	case UE_BULK:
+		pipe->up_serialise = false;
 		pipe->up_methods = &dwc2_device_bulk_methods;
 		break;
 	default:
@@ -790,22 +788,9 @@ dwc2_device_bulk_transfer(struct usbd_xf
 	/* Insert last in queue. */
 	mutex_enter(&sc->sc_lock);
 	err = usb_insert_transfer(xfer);
-	mutex_exit(&sc->sc_lock);
-	if (err)
-		return err;
 
-	/* Pipe isn't running, start first */
-	return dwc2_device_bulk_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue));
-}
+	KASSERT(err == USBD_NORMAL_COMPLETION);
 
-Static usbd_status
-dwc2_device_bulk_start(struct usbd_xfer *xfer)
-{
-	struct dwc2_softc *sc = DWC2_XFER2SC(xfer);
-	usbd_status err;
-
-	DPRINTF("xfer=%p\n", xfer);
-	mutex_enter(&sc->sc_lock);
 	xfer->ux_status = USBD_IN_PROGRESS;
 	err = dwc2_device_start(xfer);
 	mutex_exit(&sc->sc_lock);
@@ -929,23 +914,9 @@ dwc2_device_isoc_transfer(struct usbd_xf
 	/* Insert last in queue. */
 	mutex_enter(&sc->sc_lock);
 	err = usb_insert_transfer(xfer);
-	mutex_exit(&sc->sc_lock);
-	if (err)
-		return err;
-
-	/* Pipe isn't running, start first */
-	return dwc2_device_isoc_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue));
-}
 
-usbd_status
-dwc2_device_isoc_start(struct usbd_xfer *xfer)
-{
-	struct dwc2_pipe *dpipe = DWC2_XFER2DPIPE(xfer);
-	struct usbd_device *dev = dpipe->pipe.up_dev;
-	struct dwc2_softc *sc = dev->ud_bus->ub_hcpriv;
-	usbd_status err;
+	KASSERT(err == USBD_NORMAL_COMPLETION);
 
-	mutex_enter(&sc->sc_lock);
 	xfer->ux_status = USBD_IN_PROGRESS;
 	err = dwc2_device_start(xfer);
 	mutex_exit(&sc->sc_lock);

Reply via email to