summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authoraugustss <augustss@NetBSD.org>2005-05-05 20:40:20 +0000
committeraugustss <augustss@NetBSD.org>2005-05-05 20:40:20 +0000
commit9a2e60d4f639622ced9c2800e60cdd73bfd13c20 (patch)
tree69e8338d19c1bfd30a515a95de91b4ecd0e63f72 /sys/dev
parentd7dd731e0292a8d89df8e95f7e832f4db46c06bf (diff)
Make sure to honor the USBD_FORCE_SHORT_XFER flag and generate an empty
transfer when necessary.
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/usb/ehci.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/sys/dev/usb/ehci.c b/sys/dev/usb/ehci.c
index c10bcb252ed..6a11bf9675b 100644
--- a/sys/dev/usb/ehci.c
+++ b/sys/dev/usb/ehci.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ehci.c,v 1.101 2005/05/01 21:47:11 wiz Exp $ */
+/* $NetBSD: ehci.c,v 1.102 2005/05/05 20:40:20 augustss Exp $ */
/*
* Copyright (c) 2004,2005 The NetBSD Foundation, Inc.
@@ -61,7 +61,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.101 2005/05/01 21:47:11 wiz Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.102 2005/05/05 20:40:20 augustss Exp $");
#include "ohci.h"
#include "uhci.h"
@@ -2266,6 +2266,7 @@ ehci_alloc_sqtd_chain(struct ehci_pipe *epipe, ehci_softc_t *sc,
int len, curlen, mps;
int i, tog;
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));
@@ -2327,7 +2328,14 @@ printf("status=%08x toggle=%d\n", epipe->sqh->qh.qh_qtd.qtd_status,
len, curlen));
len -= curlen;
- if (len != 0) {
+ /*
+ * Allocate another transfer if there's more data left,
+ * 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))) {
next = ehci_alloc_sqtd(sc);
if (next == NULL)
goto nomem;
@@ -2364,7 +2372,7 @@ printf("status=%08x toggle=%d\n", epipe->sqh->qh.qh_qtd.qtd_status,
tog ^= 1;
qtdstatus ^= EHCI_QTD_TOGGLE_MASK;
}
- if (len == 0)
+ if (next == NULL)
break;
DPRINTFN(10,("ehci_alloc_sqtd_chain: extend chain\n"));
dataphys += curlen;