Module Name:    src
Committed By:   skrll
Date:           Sun Jan 10 10:16:00 UTC 2016

Modified Files:
        src/sys/dev/usb [nick-nhusb]: ohci.c ohcivar.h

Log Message:
Do the same loan dance with control transfers as with other transfer
types.  That is,

        Use the pipe "tail" TD as our first and loan our first TD to the
        next transfer.

Sprinkle the above comment where necessary.

Also, remove a TD from the hash list BEFORE calling into
usb_transfer_complete.  It might get reused when starting the next
transfer.


To generate a diff of this commit:
cvs rdiff -u -r1.254.2.41 -r1.254.2.42 src/sys/dev/usb/ohci.c
cvs rdiff -u -r1.55.6.11 -r1.55.6.12 src/sys/dev/usb/ohcivar.h

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/ohci.c
diff -u src/sys/dev/usb/ohci.c:1.254.2.41 src/sys/dev/usb/ohci.c:1.254.2.42
--- src/sys/dev/usb/ohci.c:1.254.2.41	Sat Jan  9 21:45:20 2016
+++ src/sys/dev/usb/ohci.c	Sun Jan 10 10:16:00 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: ohci.c,v 1.254.2.41 2016/01/09 21:45:20 skrll Exp $	*/
+/*	$NetBSD: ohci.c,v 1.254.2.42 2016/01/10 10:16:00 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.41 2016/01/09 21:45:20 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ohci.c,v 1.254.2.42 2016/01/10 10:16:00 skrll Exp $");
 
 #include "opt_usb.h"
 
@@ -1527,11 +1527,11 @@ ohci_softintr(void *v)
 
 		cc = OHCI_TD_GET_CC(O32TOH(std->td.td_flags));
 		if (cc == OHCI_CC_NO_ERROR) {
+			ohci_hash_rem_td(sc, std);
 			if (std->flags & OHCI_CALL_DONE) {
 				xfer->ux_status = USBD_NORMAL_COMPLETION;
 				usb_transfer_complete(xfer);
 			}
-			ohci_hash_rem_td(sc, std);
 		} else {
 			/*
 			 * Endpoint is halted.  First unlink all the TDs
@@ -1686,7 +1686,10 @@ ohci_device_intr_done(struct usbd_xfer *
 	    	ohci_soft_td_t *data, *last, *tail;
 		int len = xfer->ux_length;
 
-	    	/* Use "tail" TD and loan our first TD to next transfer */
+		/*
+		 * Use the pipe "tail" TD as our first and loan our first TD
+		 * to the next transfer.
+		 */
 		data = opipe->tail.td;
 		opipe->tail.td = ox->ox_stds[0];
 		ox->ox_stds[0] = data;
@@ -2728,26 +2731,24 @@ ohci_device_ctrl_init(struct usbd_xfer *
 	struct ohci_xfer *ox = OHCI_XFER2OXFER(xfer);
 	usb_device_request_t *req = &xfer->ux_request;
 	ohci_softc_t *sc = OHCI_XFER2SC(xfer);
-	ohci_soft_td_t *stat, *tail;
+	ohci_soft_td_t *stat, *setup;
 	int isread = req->bmRequestType & UT_READ;
 	int len = xfer->ux_bufsize;
 	int err = ENOMEM;
 
 	OHCIHIST_FUNC(); OHCIHIST_CALLED();
 
-	/* The TD for setup will be a 'tail' from elsewhere */
-	stat = ohci_alloc_std(sc);
-	if (stat == NULL) {
+	setup = ohci_alloc_std(sc);
+	if (setup == NULL) {
 		goto bad1;
 	}
-	tail = ohci_alloc_std(sc);
-	if (tail == NULL) {
+	stat = ohci_alloc_std(sc);
+	if (stat == NULL) {
 		goto bad2;
 	}
-	tail->xfer = NULL;
 
+	ox->ox_setup = setup;
 	ox->ox_stat = stat;
-	ox->ox_tdtail = tail;
 	ox->ox_nstd = 0;
 
 	/* Set up data transaction */
@@ -2760,9 +2761,9 @@ ohci_device_ctrl_init(struct usbd_xfer *
 	return 0;
 
  bad3:
-	ohci_free_std(sc, tail);
- bad2:
 	ohci_free_std(sc, stat);
+ bad2:
+	ohci_free_std(sc, setup);
  bad1:
 	return err;
 }
@@ -2778,8 +2779,8 @@ ohci_device_ctrl_fini(struct usbd_xfer *
 	DPRINTFN(8, "xfer %p nstd %d", xfer, ox->ox_nstd, 0, 0);
 
 	mutex_enter(&sc->sc_lock);
-	if (ox->ox_tdtail != opipe->tail.td) {
-		ohci_free_std_locked(sc, ox->ox_tdtail);
+	if (ox->ox_setup != opipe->tail.td) {
+		ohci_free_std_locked(sc, ox->ox_setup);
 	}
 	for (size_t i = 0; i < ox->ox_nstd; i++) {
 		ohci_soft_td_t *std = ox->ox_stds[i];
@@ -2845,10 +2846,16 @@ ohci_device_ctrl_start(struct usbd_xfer 
 	/* Need to take lock here for pipe->tail.td */
 	mutex_enter(&sc->sc_lock);
 
+	/*
+	 * Use the pipe "tail" TD as our first and loan our first TD to the
+	 * next transfer
+	 */
 	setup = opipe->tail.td;
+	opipe->tail.td = ox->ox_setup;
+	ox->ox_setup = setup;
+
 	stat = ox->ox_stat;
-	tail = ox->ox_tdtail;
-	opipe->tail.td = tail;
+	tail = opipe->tail.td;	/* point at sentinel */
 
 	sed = opipe->sed;
 
@@ -3125,7 +3132,10 @@ ohci_device_bulk_start(struct usbd_xfer 
 
 	mutex_enter(&sc->sc_lock);
 
-	/* Use "tail" TD and loan our first TD to next transfer */
+	/*
+	 * Use the pipe "tail" TD as our first and loan our first TD to the
+	 * next transfer
+	 */
 	data = opipe->tail.td;
 	opipe->tail.td = ox->ox_stds[0];
 	ox->ox_stds[0] = data;
@@ -3319,7 +3329,10 @@ ohci_device_intr_start(struct usbd_xfer 
 
 	mutex_enter(&sc->sc_lock);
 
-	/* Use "tail" TD and loan our first TD to next transfer */
+	/*
+	 * Use the pipe "tail" TD as our first and loan our first TD to the
+	 * next transfer.
+	 */
 	data = opipe->tail.td;
 	opipe->tail.td = ox->ox_stds[0];
 	ox->ox_stds[0] = data;

Index: src/sys/dev/usb/ohcivar.h
diff -u src/sys/dev/usb/ohcivar.h:1.55.6.11 src/sys/dev/usb/ohcivar.h:1.55.6.12
--- src/sys/dev/usb/ohcivar.h:1.55.6.11	Sun Dec  6 15:39:35 2015
+++ src/sys/dev/usb/ohcivar.h	Sun Jan 10 10:16:00 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: ohcivar.h,v 1.55.6.11 2015/12/06 15:39:35 skrll Exp $	*/
+/*	$NetBSD: ohcivar.h,v 1.55.6.12 2016/01/10 10:16:00 skrll Exp $	*/
 
 /*
  * Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -146,14 +146,9 @@ typedef struct ohci_softc {
 struct ohci_xfer {
 	struct usbd_xfer xfer;
 	struct usb_task abort_task;
-	/*
-	 * The TD/iTD that is used to terminate the chain and is borrowed
-	 * by the next transfer for its first TD
-	 */
-	union {
-		ohci_soft_td_t *ox_tdtail;
-		ohci_soft_itd_t *ox_itdtail;
-	};
+	/* ctrl */
+	ohci_soft_td_t *ox_setup;
+	ohci_soft_td_t *ox_stat;
 	union {
 		/* ctrl/bulk/intr */
 		struct {
@@ -166,8 +161,6 @@ struct ohci_xfer {
 			size_t ox_nsitd;
 		};
 	};
-	/* ctrl */
-	ohci_soft_td_t *ox_stat;
 };
 
 #define OHCI_BUS2SC(bus)	((bus)->ub_hcpriv)

Reply via email to