summaryrefslogtreecommitdiff
path: root/sys/dev/usb/ehci.c
diff options
context:
space:
mode:
authorChristopher Pascoe <pascoe@cvs.openbsd.org>2006-05-30 19:21:08 +0000
committerChristopher Pascoe <pascoe@cvs.openbsd.org>2006-05-30 19:21:08 +0000
commit3f84eba7dce46d0e35b8634e816dd743de2c27d9 (patch)
tree8d56301775840acf8668a28ce35e5873573fcbce /sys/dev/usb/ehci.c
parentf58045fbd8e6599859a773544d3d00818b930c9f (diff)
If a zero-length bulk or interrupt transfer is requested then assume
USBD_FORCE_SHORT_XFER to ensure that we actually build and execute a transfer. Based on changes in FreeBSD rev1.47
Diffstat (limited to 'sys/dev/usb/ehci.c')
-rw-r--r--sys/dev/usb/ehci.c25
1 files changed, 13 insertions, 12 deletions
diff --git a/sys/dev/usb/ehci.c b/sys/dev/usb/ehci.c
index 8cd5bec3edc..8289d3ade57 100644
--- a/sys/dev/usb/ehci.c
+++ b/sys/dev/usb/ehci.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ehci.c,v 1.56 2006/05/29 04:02:10 pascoe Exp $ */
+/* $OpenBSD: ehci.c,v 1.57 2006/05/30 19:21:07 pascoe Exp $ */
/* $NetBSD: ehci.c,v 1.66 2004/06/30 03:11:56 mycroft Exp $ */
/*
@@ -2238,9 +2238,8 @@ ehci_alloc_sqtd_chain(struct ehci_pipe *epipe, ehci_softc_t *sc, int alen,
ehci_physaddr_t dataphys, dataphyspage, dataphyslastpage, nextphys;
u_int32_t qtdstatus;
int len, curlen, mps;
- int i, tog;
+ int i, tog, forceshort;
usb_dma_t *dma = &xfer->dmabuf;
- u_int16_t flags = xfer->flags;
DPRINTFN(alen<4*4096,("ehci_alloc_sqtd_chain: start len=%d\n", alen));
@@ -2253,6 +2252,8 @@ ehci_alloc_sqtd_chain(struct ehci_pipe *epipe, ehci_softc_t *sc, int alen,
mps = UGETW(epipe->pipe.endpoint->edesc->wMaxPacketSize);
tog = epipe->nexttoggle;
qtdstatus |= EHCI_QTD_SET_TOGGLE(tog);
+ forceshort = ((xfer->flags & USBD_FORCE_SHORT_XFER) || len == 0) &&
+ len % mps == 0;
cur = ehci_alloc_sqtd(sc);
*sp = cur;
@@ -2298,9 +2299,7 @@ ehci_alloc_sqtd_chain(struct ehci_pipe *epipe, ehci_softc_t *sc, int alen,
* or if force last short transfer flag is set and we're
* allocating a multiple of the max packet size.
*/
- if (len != 0 ||
- ((curlen % mps) == 0 && !rd && curlen != 0 &&
- (flags & USBD_FORCE_SHORT_XFER))) {
+ if (len != 0 || forceshort) {
next = ehci_alloc_sqtd(sc);
if (next == NULL)
goto nomem;
@@ -2332,14 +2331,16 @@ ehci_alloc_sqtd_chain(struct ehci_pipe *epipe, ehci_softc_t *sc, int alen,
cur->len = curlen;
DPRINTFN(10,("ehci_alloc_sqtd_chain: cbp=0x%08x end=0x%08x\n",
dataphys, dataphys + curlen));
- /* adjust the toggle based on the number of packets in this
- qtd */
- if (((curlen + mps - 1) / mps) & 1) {
+ /* adjust the toggle based on the number of packets
+ * in this qtd */
+ if ((((curlen + mps - 1) / mps) & 1) || curlen == 0)
tog ^= 1;
- qtdstatus ^= EHCI_QTD_TOGGLE_MASK;
+ if (len == 0) {
+ if (! forceshort) {
+ break;
+ }
+ forceshort = 0;
}
- if (next == NULL)
- break;
DPRINTFN(10,("ehci_alloc_sqtd_chain: extend chain\n"));
dataphys += curlen;
cur = next;