diff options
author | Martin Pieuchot <mpi@cvs.openbsd.org> | 2013-06-25 09:24:35 +0000 |
---|---|---|
committer | Martin Pieuchot <mpi@cvs.openbsd.org> | 2013-06-25 09:24:35 +0000 |
commit | 3791d73cae48d9978e29ca8bcdd5ffaabafe2c29 (patch) | |
tree | fcb7511e085359d81667a4dfdda0400b29f2779e | |
parent | 1092258311b4488efe6b317745090fff7f08bb93 (diff) |
Bring ohci(4) and uhci(4) in sync with ehci(4) by ensuring that a
transfer is submitted when a zero-length bulk or interrupt transfer
is requested.
This is the missing part of FreeBSD's svn r159024 that should have
been committed with ehci's r1.57.
ok uebayasi@
-rw-r--r-- | sys/dev/usb/ohci.c | 17 | ||||
-rw-r--r-- | sys/dev/usb/uhci.c | 9 |
2 files changed, 12 insertions, 14 deletions
diff --git a/sys/dev/usb/ohci.c b/sys/dev/usb/ohci.c index 4b2074cf7a2..f84fc8739af 100644 --- a/sys/dev/usb/ohci.c +++ b/sys/dev/usb/ohci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ohci.c,v 1.113 2013/05/30 16:15:02 deraadt Exp $ */ +/* $OpenBSD: ohci.c,v 1.114 2013/06/25 09:24:34 mpi Exp $ */ /* $NetBSD: ohci.c,v 1.139 2003/02/22 05:24:16 tsutsui Exp $ */ /* $FreeBSD: src/sys/dev/usb/ohci.c,v 1.22 1999/11/17 22:33:40 n_hibma Exp $ */ @@ -503,7 +503,7 @@ ohci_alloc_std_chain(struct ohci_pipe *opipe, struct ohci_softc *sc, u_int alen, int rd, struct usbd_xfer *xfer, struct ohci_soft_td *sp, struct ohci_soft_td **ep) { - struct ohci_soft_td *next, *cur; + struct ohci_soft_td *next, *cur, *end; ohci_physaddr_t dataphys, dataphysend; u_int32_t tdflags; u_int len, curlen; @@ -514,6 +514,8 @@ ohci_alloc_std_chain(struct ohci_pipe *opipe, struct ohci_softc *sc, len = alen; cur = sp; + end = NULL; + dataphys = DMAADDR(dma, 0); dataphysend = OHCI_PAGE(dataphys + len - 1); tdflags = htole32( @@ -521,7 +523,7 @@ ohci_alloc_std_chain(struct ohci_pipe *opipe, struct ohci_softc *sc, (flags & USBD_SHORT_XFER_OK ? OHCI_TD_R : 0) | OHCI_TD_NOCC | OHCI_TD_TOGGLE_CARRY | OHCI_TD_NOINTR); - for (;;) { + while (len > 0) { next = ohci_alloc_std(sc); if (next == NULL) goto nomem; @@ -558,17 +560,15 @@ ohci_alloc_std_chain(struct ohci_pipe *opipe, struct ohci_softc *sc, cur->xfer = xfer; DPRINTFN(10,("ohci_alloc_std_chain: cbp=0x%08x be=0x%08x\n", dataphys, dataphys + curlen - 1)); - if (len == 0) - break; DPRINTFN(10,("ohci_alloc_std_chain: extend chain\n")); dataphys += curlen; + end = cur; cur = next; } - if (!rd && (flags & USBD_FORCE_SHORT_XFER) && + if (!rd && ((flags & USBD_FORCE_SHORT_XFER) || alen == 0) && alen % UGETW(opipe->pipe.endpoint->edesc->wMaxPacketSize) == 0) { /* Force a 0 length transfer at the end. */ - cur = next; next = ohci_alloc_std(sc); if (next == NULL) goto nomem; @@ -582,8 +582,9 @@ ohci_alloc_std_chain(struct ohci_pipe *opipe, struct ohci_softc *sc, cur->flags = 0; cur->xfer = xfer; DPRINTFN(2,("ohci_alloc_std_chain: add 0 xfer\n")); + end = cur; } - *ep = cur; + *ep = end; return (USBD_NORMAL_COMPLETION); diff --git a/sys/dev/usb/uhci.c b/sys/dev/usb/uhci.c index d2168f094ce..ab345c2cbc5 100644 --- a/sys/dev/usb/uhci.c +++ b/sys/dev/usb/uhci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uhci.c,v 1.98 2013/05/30 16:15:02 deraadt Exp $ */ +/* $OpenBSD: uhci.c,v 1.99 2013/06/25 09:24:34 mpi Exp $ */ /* $NetBSD: uhci.c,v 1.172 2003/02/23 04:19:26 simonb Exp $ */ /* $FreeBSD: src/sys/dev/usb/uhci.c,v 1.33 1999/11/17 22:33:41 n_hibma Exp $ */ @@ -1647,14 +1647,11 @@ uhci_alloc_std_chain(struct uhci_pipe *upipe, struct uhci_softc *sc, u_int len, return (USBD_INVAL); } ntd = (len + maxp - 1) / maxp; + if (len == 0) + flags |= USBD_FORCE_SHORT_XFER; if ((flags & USBD_FORCE_SHORT_XFER) && len % maxp == 0) ntd++; DPRINTFN(10, ("uhci_alloc_std_chain: maxp=%d ntd=%d\n", maxp, ntd)); - if (ntd == 0) { - *sp = *ep = 0; - DPRINTFN(-1,("uhci_alloc_std_chain: ntd=0\n")); - return (USBD_NORMAL_COMPLETION); - } tog = upipe->nexttoggle; if (ntd % 2 == 0) tog ^= 1; |