diff options
author | Christopher Pascoe <pascoe@cvs.openbsd.org> | 2006-05-28 23:52:28 +0000 |
---|---|---|
committer | Christopher Pascoe <pascoe@cvs.openbsd.org> | 2006-05-28 23:52:28 +0000 |
commit | 404ee465a85d4279109b767b5a1f39cc390012a4 (patch) | |
tree | d41c47a6feb825ad98b948a0080c67211a91a319 /sys/dev/usb | |
parent | 539abeda35c1281656f73efa5990f655b0521794 (diff) |
Make sure to honor the USBD_FORCE_SHORT_XFER flag and generate an empty
transfer when necessary.
From Dan Ellis via NetBSD rev 1.102
Diffstat (limited to 'sys/dev/usb')
-rw-r--r-- | sys/dev/usb/ehci.c | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/sys/dev/usb/ehci.c b/sys/dev/usb/ehci.c index 7e459c04ed0..e3f88a607b5 100644 --- a/sys/dev/usb/ehci.c +++ b/sys/dev/usb/ehci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ehci.c,v 1.53 2005/12/03 03:40:52 brad Exp $ */ +/* $OpenBSD: ehci.c,v 1.54 2006/05/28 23:52:27 pascoe Exp $ */ /* $NetBSD: ehci.c,v 1.66 2004/06/30 03:11:56 mycroft Exp $ */ /* @@ -2240,6 +2240,7 @@ ehci_alloc_sqtd_chain(struct ehci_pipe *epipe, ehci_softc_t *sc, int alen, 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)); @@ -2292,7 +2293,14 @@ ehci_alloc_sqtd_chain(struct ehci_pipe *epipe, ehci_softc_t *sc, int alen, dataphys, dataphyslastpage, 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; @@ -2329,7 +2337,7 @@ ehci_alloc_sqtd_chain(struct ehci_pipe *epipe, ehci_softc_t *sc, int alen, 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; |