Sun Jan 10 10:16:00 2016 UTC ()
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.


(skrll)
diff -r1.254.2.41 -r1.254.2.42 src/sys/dev/usb/ohci.c
diff -r1.55.6.11 -r1.55.6.12 src/sys/dev/usb/ohcivar.h

cvs diff -r1.254.2.41 -r1.254.2.42 src/sys/dev/usb/ohci.c (expand / switch to unified diff)

--- src/sys/dev/usb/ohci.c 2016/01/09 21:45:20 1.254.2.41
+++ src/sys/dev/usb/ohci.c 2016/01/10 10:16:00 1.254.2.42
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: ohci.c,v 1.254.2.41 2016/01/09 21:45:20 skrll Exp $ */ 1/* $NetBSD: ohci.c,v 1.254.2.42 2016/01/10 10:16:00 skrll Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1998, 2004, 2005, 2012 The NetBSD Foundation, Inc. 4 * Copyright (c) 1998, 2004, 2005, 2012 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Lennart Augustsson (lennart@augustsson.net) at 8 * by Lennart Augustsson (lennart@augustsson.net) at
9 * Carlstedt Research & Technology, Jared D. McNeill (jmcneill@invisible.ca) 9 * Carlstedt Research & Technology, Jared D. McNeill (jmcneill@invisible.ca)
10 * and Matthew R. Green (mrg@eterna.com.au). 10 * and Matthew R. Green (mrg@eterna.com.au).
11 * This code is derived from software contributed to The NetBSD Foundation 11 * This code is derived from software contributed to The NetBSD Foundation
12 * by Charles M. Hannum. 12 * by Charles M. Hannum.
13 * 13 *
14 * Redistribution and use in source and binary forms, with or without 14 * Redistribution and use in source and binary forms, with or without
@@ -31,27 +31,27 @@ @@ -31,27 +31,27 @@
31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 * POSSIBILITY OF SUCH DAMAGE. 33 * POSSIBILITY OF SUCH DAMAGE.
34 */ 34 */
35 35
36/* 36/*
37 * USB Open Host Controller driver. 37 * USB Open Host Controller driver.
38 * 38 *
39 * OHCI spec: http://www.compaq.com/productinfo/development/openhci.html 39 * OHCI spec: http://www.compaq.com/productinfo/development/openhci.html
40 * USB spec: http://www.usb.org/developers/docs/ 40 * USB spec: http://www.usb.org/developers/docs/
41 */ 41 */
42 42
43#include <sys/cdefs.h> 43#include <sys/cdefs.h>
44__KERNEL_RCSID(0, "$NetBSD: ohci.c,v 1.254.2.41 2016/01/09 21:45:20 skrll Exp $"); 44__KERNEL_RCSID(0, "$NetBSD: ohci.c,v 1.254.2.42 2016/01/10 10:16:00 skrll Exp $");
45 45
46#include "opt_usb.h" 46#include "opt_usb.h"
47 47
48#include <sys/param.h> 48#include <sys/param.h>
49 49
50#include <sys/cpu.h> 50#include <sys/cpu.h>
51#include <sys/device.h> 51#include <sys/device.h>
52#include <sys/kernel.h> 52#include <sys/kernel.h>
53#include <sys/kmem.h> 53#include <sys/kmem.h>
54#include <sys/proc.h> 54#include <sys/proc.h>
55#include <sys/queue.h> 55#include <sys/queue.h>
56#include <sys/select.h> 56#include <sys/select.h>
57#include <sys/sysctl.h> 57#include <sys/sysctl.h>
@@ -1517,31 +1517,31 @@ ohci_softintr(void *v) @@ -1517,31 +1517,31 @@ ohci_softintr(void *v)
1517 } 1517 }
1518 callout_stop(&xfer->ux_callout); 1518 callout_stop(&xfer->ux_callout);
1519 1519
1520 len = std->len; 1520 len = std->len;
1521 if (std->td.td_cbp != 0) 1521 if (std->td.td_cbp != 0)
1522 len -= O32TOH(std->td.td_be) - 1522 len -= O32TOH(std->td.td_be) -
1523 O32TOH(std->td.td_cbp) + 1; 1523 O32TOH(std->td.td_cbp) + 1;
1524 DPRINTFN(10, "len=%d, flags=0x%x", len, std->flags, 0, 0); 1524 DPRINTFN(10, "len=%d, flags=0x%x", len, std->flags, 0, 0);
1525 if (std->flags & OHCI_ADD_LEN) 1525 if (std->flags & OHCI_ADD_LEN)
1526 xfer->ux_actlen += len; 1526 xfer->ux_actlen += len;
1527 1527
1528 cc = OHCI_TD_GET_CC(O32TOH(std->td.td_flags)); 1528 cc = OHCI_TD_GET_CC(O32TOH(std->td.td_flags));
1529 if (cc == OHCI_CC_NO_ERROR) { 1529 if (cc == OHCI_CC_NO_ERROR) {
 1530 ohci_hash_rem_td(sc, std);
1530 if (std->flags & OHCI_CALL_DONE) { 1531 if (std->flags & OHCI_CALL_DONE) {
1531 xfer->ux_status = USBD_NORMAL_COMPLETION; 1532 xfer->ux_status = USBD_NORMAL_COMPLETION;
1532 usb_transfer_complete(xfer); 1533 usb_transfer_complete(xfer);
1533 } 1534 }
1534 ohci_hash_rem_td(sc, std); 
1535 } else { 1535 } else {
1536 /* 1536 /*
1537 * Endpoint is halted. First unlink all the TDs 1537 * Endpoint is halted. First unlink all the TDs
1538 * belonging to the failed transfer, and then restart 1538 * belonging to the failed transfer, and then restart
1539 * the endpoint. 1539 * the endpoint.
1540 */ 1540 */
1541 ohci_soft_td_t *p, *n; 1541 ohci_soft_td_t *p, *n;
1542 opipe = OHCI_PIPE2OPIPE(xfer->ux_pipe); 1542 opipe = OHCI_PIPE2OPIPE(xfer->ux_pipe);
1543 1543
1544 DPRINTFN(15, "error cc=%d", 1544 DPRINTFN(15, "error cc=%d",
1545 OHCI_TD_GET_CC(O32TOH(std->td.td_flags)), 0, 0, 0); 1545 OHCI_TD_GET_CC(O32TOH(std->td.td_flags)), 0, 0, 0);
1546 1546
1547 /* remove xfer's TDs from the hash */ 1547 /* remove xfer's TDs from the hash */
@@ -1676,27 +1676,30 @@ ohci_device_intr_done(struct usbd_xfer * @@ -1676,27 +1676,30 @@ ohci_device_intr_done(struct usbd_xfer *
1676 (UE_GET_DIR(xfer->ux_pipe->up_endpoint->ue_edesc->bEndpointAddress) == UE_DIR_IN); 1676 (UE_GET_DIR(xfer->ux_pipe->up_endpoint->ue_edesc->bEndpointAddress) == UE_DIR_IN);
1677 1677
1678 OHCIHIST_FUNC(); OHCIHIST_CALLED(); 1678 OHCIHIST_FUNC(); OHCIHIST_CALLED();
1679 DPRINTFN(10, "xfer=%p, actlen=%d", xfer, xfer->ux_actlen, 0, 0); 1679 DPRINTFN(10, "xfer=%p, actlen=%d", xfer, xfer->ux_actlen, 0, 0);
1680 1680
1681 KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); 1681 KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock));
1682 1682
1683 usb_syncmem(&xfer->ux_dmabuf, 0, xfer->ux_length, 1683 usb_syncmem(&xfer->ux_dmabuf, 0, xfer->ux_length,
1684 isread ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); 1684 isread ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
1685 if (xfer->ux_pipe->up_repeat) { 1685 if (xfer->ux_pipe->up_repeat) {
1686 ohci_soft_td_t *data, *last, *tail; 1686 ohci_soft_td_t *data, *last, *tail;
1687 int len = xfer->ux_length; 1687 int len = xfer->ux_length;
1688 1688
1689 /* Use "tail" TD and loan our first TD to next transfer */ 1689 /*
 1690 * Use the pipe "tail" TD as our first and loan our first TD
 1691 * to the next transfer.
 1692 */
1690 data = opipe->tail.td; 1693 data = opipe->tail.td;
1691 opipe->tail.td = ox->ox_stds[0]; 1694 opipe->tail.td = ox->ox_stds[0];
1692 ox->ox_stds[0] = data; 1695 ox->ox_stds[0] = data;
1693 ohci_reset_std_chain(sc, xfer, len, isread, data, &last); 1696 ohci_reset_std_chain(sc, xfer, len, isread, data, &last);
1694 1697
1695 tail = opipe->tail.td; /* point at sentinel */ 1698 tail = opipe->tail.td; /* point at sentinel */
1696 memset(&tail->td, 0, sizeof(tail->td)); 1699 memset(&tail->td, 0, sizeof(tail->td));
1697 tail->nexttd = NULL; 1700 tail->nexttd = NULL;
1698 tail->xfer = NULL; 1701 tail->xfer = NULL;
1699 usb_syncmem(&tail->dma, tail->offs, sizeof(tail->td), 1702 usb_syncmem(&tail->dma, tail->offs, sizeof(tail->td),
1700 BUS_DMASYNC_PREWRITE); 1703 BUS_DMASYNC_PREWRITE);
1701 1704
1702 /* We want interrupt at the end of the transfer. */ 1705 /* We want interrupt at the end of the transfer. */
@@ -2718,78 +2721,76 @@ ohci_root_intr_close(struct usbd_pipe *p @@ -2718,78 +2721,76 @@ ohci_root_intr_close(struct usbd_pipe *p
2718 OHCIHIST_FUNC(); OHCIHIST_CALLED(); 2721 OHCIHIST_FUNC(); OHCIHIST_CALLED();
2719 2722
2720 sc->sc_intrxfer = NULL; 2723 sc->sc_intrxfer = NULL;
2721} 2724}
2722 2725
2723/************************/ 2726/************************/
2724 2727
2725int 2728int
2726ohci_device_ctrl_init(struct usbd_xfer *xfer) 2729ohci_device_ctrl_init(struct usbd_xfer *xfer)
2727{ 2730{
2728 struct ohci_xfer *ox = OHCI_XFER2OXFER(xfer); 2731 struct ohci_xfer *ox = OHCI_XFER2OXFER(xfer);
2729 usb_device_request_t *req = &xfer->ux_request; 2732 usb_device_request_t *req = &xfer->ux_request;
2730 ohci_softc_t *sc = OHCI_XFER2SC(xfer); 2733 ohci_softc_t *sc = OHCI_XFER2SC(xfer);
2731 ohci_soft_td_t *stat, *tail; 2734 ohci_soft_td_t *stat, *setup;
2732 int isread = req->bmRequestType & UT_READ; 2735 int isread = req->bmRequestType & UT_READ;
2733 int len = xfer->ux_bufsize; 2736 int len = xfer->ux_bufsize;
2734 int err = ENOMEM; 2737 int err = ENOMEM;
2735 2738
2736 OHCIHIST_FUNC(); OHCIHIST_CALLED(); 2739 OHCIHIST_FUNC(); OHCIHIST_CALLED();
2737 2740
2738 /* The TD for setup will be a 'tail' from elsewhere */ 2741 setup = ohci_alloc_std(sc);
2739 stat = ohci_alloc_std(sc); 2742 if (setup == NULL) {
2740 if (stat == NULL) { 
2741 goto bad1; 2743 goto bad1;
2742 } 2744 }
2743 tail = ohci_alloc_std(sc); 2745 stat = ohci_alloc_std(sc);
2744 if (tail == NULL) { 2746 if (stat == NULL) {
2745 goto bad2; 2747 goto bad2;
2746 } 2748 }
2747 tail->xfer = NULL; 
2748 2749
 2750 ox->ox_setup = setup;
2749 ox->ox_stat = stat; 2751 ox->ox_stat = stat;
2750 ox->ox_tdtail = tail; 
2751 ox->ox_nstd = 0; 2752 ox->ox_nstd = 0;
2752 2753
2753 /* Set up data transaction */ 2754 /* Set up data transaction */
2754 if (len != 0) { 2755 if (len != 0) {
2755 err = ohci_alloc_std_chain(sc, xfer, len, isread); 2756 err = ohci_alloc_std_chain(sc, xfer, len, isread);
2756 if (err) { 2757 if (err) {
2757 goto bad3; 2758 goto bad3;
2758 } 2759 }
2759 } 2760 }
2760 return 0; 2761 return 0;
2761 2762
2762 bad3: 2763 bad3:
2763 ohci_free_std(sc, tail); 
2764 bad2: 
2765 ohci_free_std(sc, stat); 2764 ohci_free_std(sc, stat);
 2765 bad2:
 2766 ohci_free_std(sc, setup);
2766 bad1: 2767 bad1:
2767 return err; 2768 return err;
2768} 2769}
2769 2770
2770void 2771void
2771ohci_device_ctrl_fini(struct usbd_xfer *xfer) 2772ohci_device_ctrl_fini(struct usbd_xfer *xfer)
2772{ 2773{
2773 struct ohci_xfer *ox = OHCI_XFER2OXFER(xfer); 2774 struct ohci_xfer *ox = OHCI_XFER2OXFER(xfer);
2774 ohci_softc_t *sc = OHCI_XFER2SC(xfer); 2775 ohci_softc_t *sc = OHCI_XFER2SC(xfer);
2775 struct ohci_pipe *opipe = OHCI_PIPE2OPIPE(xfer->ux_pipe); 2776 struct ohci_pipe *opipe = OHCI_PIPE2OPIPE(xfer->ux_pipe);
2776 2777
2777 OHCIHIST_FUNC(); OHCIHIST_CALLED(); 2778 OHCIHIST_FUNC(); OHCIHIST_CALLED();
2778 DPRINTFN(8, "xfer %p nstd %d", xfer, ox->ox_nstd, 0, 0); 2779 DPRINTFN(8, "xfer %p nstd %d", xfer, ox->ox_nstd, 0, 0);
2779 2780
2780 mutex_enter(&sc->sc_lock); 2781 mutex_enter(&sc->sc_lock);
2781 if (ox->ox_tdtail != opipe->tail.td) { 2782 if (ox->ox_setup != opipe->tail.td) {
2782 ohci_free_std_locked(sc, ox->ox_tdtail); 2783 ohci_free_std_locked(sc, ox->ox_setup);
2783 } 2784 }
2784 for (size_t i = 0; i < ox->ox_nstd; i++) { 2785 for (size_t i = 0; i < ox->ox_nstd; i++) {
2785 ohci_soft_td_t *std = ox->ox_stds[i]; 2786 ohci_soft_td_t *std = ox->ox_stds[i];
2786 if (std == NULL) 2787 if (std == NULL)
2787 break; 2788 break;
2788 ohci_free_std_locked(sc, std); 2789 ohci_free_std_locked(sc, std);
2789 } 2790 }
2790 ohci_free_std_locked(sc, ox->ox_stat); 2791 ohci_free_std_locked(sc, ox->ox_stat);
2791 mutex_exit(&sc->sc_lock); 2792 mutex_exit(&sc->sc_lock);
2792 2793
2793 if (ox->ox_nstd) { 2794 if (ox->ox_nstd) {
2794 const size_t sz = sizeof(ohci_soft_td_t *) * ox->ox_nstd; 2795 const size_t sz = sizeof(ohci_soft_td_t *) * ox->ox_nstd;
2795 kmem_free(ox->ox_stds, sz); 2796 kmem_free(ox->ox_stds, sz);
@@ -2835,30 +2836,36 @@ ohci_device_ctrl_start(struct usbd_xfer  @@ -2835,30 +2836,36 @@ ohci_device_ctrl_start(struct usbd_xfer
2835 2836
2836 isread = req->bmRequestType & UT_READ; 2837 isread = req->bmRequestType & UT_READ;
2837 len = UGETW(req->wLength); 2838 len = UGETW(req->wLength);
2838 2839
2839 DPRINTF("xfer=%p len=%d, addr=%d, endpt=%d", xfer, len, dev->ud_addr, 2840 DPRINTF("xfer=%p len=%d, addr=%d, endpt=%d", xfer, len, dev->ud_addr,
2840 opipe->pipe.up_endpoint->ue_edesc->bEndpointAddress); 2841 opipe->pipe.up_endpoint->ue_edesc->bEndpointAddress);
2841 DPRINTF("type=0x%02x, request=0x%02x, wValue=0x%04x, wIndex=0x%04x", 2842 DPRINTF("type=0x%02x, request=0x%02x, wValue=0x%04x, wIndex=0x%04x",
2842 req->bmRequestType, req->bRequest, UGETW(req->wValue), 2843 req->bmRequestType, req->bRequest, UGETW(req->wValue),
2843 UGETW(req->wIndex)); 2844 UGETW(req->wIndex));
2844 2845
2845 /* Need to take lock here for pipe->tail.td */ 2846 /* Need to take lock here for pipe->tail.td */
2846 mutex_enter(&sc->sc_lock); 2847 mutex_enter(&sc->sc_lock);
2847 2848
 2849 /*
 2850 * Use the pipe "tail" TD as our first and loan our first TD to the
 2851 * next transfer
 2852 */
2848 setup = opipe->tail.td; 2853 setup = opipe->tail.td;
 2854 opipe->tail.td = ox->ox_setup;
 2855 ox->ox_setup = setup;
 2856
2849 stat = ox->ox_stat; 2857 stat = ox->ox_stat;
2850 tail = ox->ox_tdtail; 2858 tail = opipe->tail.td; /* point at sentinel */
2851 opipe->tail.td = tail; 
2852 2859
2853 sed = opipe->sed; 2860 sed = opipe->sed;
2854 2861
2855 KASSERTMSG(OHCI_ED_GET_FA(O32TOH(sed->ed.ed_flags)) == dev->ud_addr, 2862 KASSERTMSG(OHCI_ED_GET_FA(O32TOH(sed->ed.ed_flags)) == dev->ud_addr,
2856 "address ED %d pipe %d\n", 2863 "address ED %d pipe %d\n",
2857 OHCI_ED_GET_FA(O32TOH(sed->ed.ed_flags)), dev->ud_addr); 2864 OHCI_ED_GET_FA(O32TOH(sed->ed.ed_flags)), dev->ud_addr);
2858 KASSERTMSG(OHCI_ED_GET_MAXP(O32TOH(sed->ed.ed_flags)) == 2865 KASSERTMSG(OHCI_ED_GET_MAXP(O32TOH(sed->ed.ed_flags)) ==
2859 UGETW(opipe->pipe.up_endpoint->ue_edesc->wMaxPacketSize), 2866 UGETW(opipe->pipe.up_endpoint->ue_edesc->wMaxPacketSize),
2860 "MPL ED %d pipe %d\n", 2867 "MPL ED %d pipe %d\n",
2861 OHCI_ED_GET_MAXP(O32TOH(sed->ed.ed_flags)), 2868 OHCI_ED_GET_MAXP(O32TOH(sed->ed.ed_flags)),
2862 UGETW(opipe->pipe.up_endpoint->ue_edesc->wMaxPacketSize)); 2869 UGETW(opipe->pipe.up_endpoint->ue_edesc->wMaxPacketSize));
2863 2870
2864 /* next will point to data if len != 0 */ 2871 /* next will point to data if len != 0 */
@@ -3115,27 +3122,30 @@ ohci_device_bulk_start(struct usbd_xfer  @@ -3115,27 +3122,30 @@ ohci_device_bulk_start(struct usbd_xfer
3115 KASSERT(!(xfer->ux_rqflags & URQ_REQUEST)); 3122 KASSERT(!(xfer->ux_rqflags & URQ_REQUEST));
3116 3123
3117 len = xfer->ux_length; 3124 len = xfer->ux_length;
3118 endpt = xfer->ux_pipe->up_endpoint->ue_edesc->bEndpointAddress; 3125 endpt = xfer->ux_pipe->up_endpoint->ue_edesc->bEndpointAddress;
3119 isread = UE_GET_DIR(endpt) == UE_DIR_IN; 3126 isread = UE_GET_DIR(endpt) == UE_DIR_IN;
3120 sed = opipe->sed; 3127 sed = opipe->sed;
3121 3128
3122 DPRINTFN(4, "xfer=%p len=%d isread=%d flags=%d", xfer, len, isread, 3129 DPRINTFN(4, "xfer=%p len=%d isread=%d flags=%d", xfer, len, isread,
3123 xfer->ux_flags); 3130 xfer->ux_flags);
3124 DPRINTFN(4, "endpt=%d", endpt, 0, 0, 0); 3131 DPRINTFN(4, "endpt=%d", endpt, 0, 0, 0);
3125 3132
3126 mutex_enter(&sc->sc_lock); 3133 mutex_enter(&sc->sc_lock);
3127 3134
3128 /* Use "tail" TD and loan our first TD to next transfer */ 3135 /*
 3136 * Use the pipe "tail" TD as our first and loan our first TD to the
 3137 * next transfer
 3138 */
3129 data = opipe->tail.td; 3139 data = opipe->tail.td;
3130 opipe->tail.td = ox->ox_stds[0]; 3140 opipe->tail.td = ox->ox_stds[0];
3131 ox->ox_stds[0] = data; 3141 ox->ox_stds[0] = data;
3132 ohci_reset_std_chain(sc, xfer, len, isread, data, &last); 3142 ohci_reset_std_chain(sc, xfer, len, isread, data, &last);
3133 3143
3134 tail = opipe->tail.td; /* point at sentinel */ 3144 tail = opipe->tail.td; /* point at sentinel */
3135 memset(&tail->td, 0, sizeof(tail->td)); 3145 memset(&tail->td, 0, sizeof(tail->td));
3136 tail->nexttd = NULL; 3146 tail->nexttd = NULL;
3137 tail->xfer = NULL; 3147 tail->xfer = NULL;
3138 usb_syncmem(&tail->dma, tail->offs, sizeof(tail->td), 3148 usb_syncmem(&tail->dma, tail->offs, sizeof(tail->td),
3139 BUS_DMASYNC_PREWRITE); 3149 BUS_DMASYNC_PREWRITE);
3140 xfer->ux_hcpriv = data; 3150 xfer->ux_hcpriv = data;
3141 3151
@@ -3309,27 +3319,30 @@ ohci_device_intr_start(struct usbd_xfer  @@ -3309,27 +3319,30 @@ ohci_device_intr_start(struct usbd_xfer
3309 return USBD_IOERROR; 3319 return USBD_IOERROR;
3310 3320
3311 DPRINTFN(3, "xfer=%p len=%d flags=%d priv=%p", xfer, xfer->ux_length, 3321 DPRINTFN(3, "xfer=%p len=%d flags=%d priv=%p", xfer, xfer->ux_length,
3312 xfer->ux_flags, xfer->ux_priv); 3322 xfer->ux_flags, xfer->ux_priv);
3313 3323
3314 KASSERT(!(xfer->ux_rqflags & URQ_REQUEST)); 3324 KASSERT(!(xfer->ux_rqflags & URQ_REQUEST));
3315 3325
3316 len = xfer->ux_length; 3326 len = xfer->ux_length;
3317 endpt = xfer->ux_pipe->up_endpoint->ue_edesc->bEndpointAddress; 3327 endpt = xfer->ux_pipe->up_endpoint->ue_edesc->bEndpointAddress;
3318 isread = UE_GET_DIR(endpt) == UE_DIR_IN; 3328 isread = UE_GET_DIR(endpt) == UE_DIR_IN;
3319 3329
3320 mutex_enter(&sc->sc_lock); 3330 mutex_enter(&sc->sc_lock);
3321 3331
3322 /* Use "tail" TD and loan our first TD to next transfer */ 3332 /*
 3333 * Use the pipe "tail" TD as our first and loan our first TD to the
 3334 * next transfer.
 3335 */
3323 data = opipe->tail.td; 3336 data = opipe->tail.td;
3324 opipe->tail.td = ox->ox_stds[0]; 3337 opipe->tail.td = ox->ox_stds[0];
3325 ox->ox_stds[0] = data; 3338 ox->ox_stds[0] = data;
3326 ohci_reset_std_chain(sc, xfer, len, isread, data, &last); 3339 ohci_reset_std_chain(sc, xfer, len, isread, data, &last);
3327 3340
3328 tail = opipe->tail.td; /* point at sentinel */ 3341 tail = opipe->tail.td; /* point at sentinel */
3329 memset(&tail->td, 0, sizeof(tail->td)); 3342 memset(&tail->td, 0, sizeof(tail->td));
3330 tail->nexttd = NULL; 3343 tail->nexttd = NULL;
3331 tail->xfer = NULL; 3344 tail->xfer = NULL;
3332 usb_syncmem(&tail->dma, tail->offs, sizeof(tail->td), 3345 usb_syncmem(&tail->dma, tail->offs, sizeof(tail->td),
3333 BUS_DMASYNC_PREWRITE); 3346 BUS_DMASYNC_PREWRITE);
3334 xfer->ux_hcpriv = data; 3347 xfer->ux_hcpriv = data;
3335 3348

cvs diff -r1.55.6.11 -r1.55.6.12 src/sys/dev/usb/ohcivar.h (expand / switch to unified diff)

--- src/sys/dev/usb/ohcivar.h 2015/12/06 15:39:35 1.55.6.11
+++ src/sys/dev/usb/ohcivar.h 2016/01/10 10:16:00 1.55.6.12
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: ohcivar.h,v 1.55.6.11 2015/12/06 15:39:35 skrll Exp $ */ 1/* $NetBSD: ohcivar.h,v 1.55.6.12 2016/01/10 10:16:00 skrll Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1998 The NetBSD Foundation, Inc. 4 * Copyright (c) 1998 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Lennart Augustsson (lennart@augustsson.net) at 8 * by Lennart Augustsson (lennart@augustsson.net) at
9 * Carlstedt Research & Technology. 9 * Carlstedt Research & Technology.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions 12 * modification, are permitted provided that the following conditions
13 * are met: 13 * are met:
14 * 1. Redistributions of source code must retain the above copyright 14 * 1. Redistributions of source code must retain the above copyright
@@ -136,48 +136,41 @@ typedef struct ohci_softc { @@ -136,48 +136,41 @@ typedef struct ohci_softc {
136 uint32_t sc_intre; 136 uint32_t sc_intre;
137 137
138 u_int sc_overrun_cnt; 138 u_int sc_overrun_cnt;
139 struct timeval sc_overrun_ntc; 139 struct timeval sc_overrun_ntc;
140 140
141 struct callout sc_tmo_rhsc; 141 struct callout sc_tmo_rhsc;
142 device_t sc_child; 142 device_t sc_child;
143 char sc_dying; 143 char sc_dying;
144} ohci_softc_t; 144} ohci_softc_t;
145 145
146struct ohci_xfer { 146struct ohci_xfer {
147 struct usbd_xfer xfer; 147 struct usbd_xfer xfer;
148 struct usb_task abort_task; 148 struct usb_task abort_task;
149 /* 149 /* ctrl */
150 * The TD/iTD that is used to terminate the chain and is borrowed 150 ohci_soft_td_t *ox_setup;
151 * by the next transfer for its first TD 151 ohci_soft_td_t *ox_stat;
152 */ 
153 union { 
154 ohci_soft_td_t *ox_tdtail; 
155 ohci_soft_itd_t *ox_itdtail; 
156 }; 
157 union { 152 union {
158 /* ctrl/bulk/intr */ 153 /* ctrl/bulk/intr */
159 struct { 154 struct {
160 ohci_soft_td_t **ox_stds; 155 ohci_soft_td_t **ox_stds;
161 size_t ox_nstd; 156 size_t ox_nstd;
162 }; 157 };
163 /* isoc */ 158 /* isoc */
164 struct { 159 struct {
165 ohci_soft_itd_t **ox_sitds; 160 ohci_soft_itd_t **ox_sitds;
166 size_t ox_nsitd; 161 size_t ox_nsitd;
167 }; 162 };
168 }; 163 };
169 /* ctrl */ 
170 ohci_soft_td_t *ox_stat; 
171}; 164};
172 165
173#define OHCI_BUS2SC(bus) ((bus)->ub_hcpriv) 166#define OHCI_BUS2SC(bus) ((bus)->ub_hcpriv)
174#define OHCI_PIPE2SC(pipe) OHCI_BUS2SC((pipe)->up_dev->ud_bus) 167#define OHCI_PIPE2SC(pipe) OHCI_BUS2SC((pipe)->up_dev->ud_bus)
175#define OHCI_XFER2SC(xfer) OHCI_BUS2SC((xfer)->ux_bus) 168#define OHCI_XFER2SC(xfer) OHCI_BUS2SC((xfer)->ux_bus)
176 169
177#define OHCI_XFER2OXFER(xfer) ((struct ohci_xfer *)(xfer)) 170#define OHCI_XFER2OXFER(xfer) ((struct ohci_xfer *)(xfer))
178#define OHCI_PIPE2OPIPE(pipe) ((struct ohci_pipe *)(pipe)) 171#define OHCI_PIPE2OPIPE(pipe) ((struct ohci_pipe *)(pipe))
179 172
180int ohci_init(ohci_softc_t *); 173int ohci_init(ohci_softc_t *);
181int ohci_intr(void *); 174int ohci_intr(void *);
182int ohci_detach(ohci_softc_t *, int); 175int ohci_detach(ohci_softc_t *, int);
183bool ohci_shutdown(device_t, int); 176bool ohci_shutdown(device_t, int);