From e0841944412c2d6ba1f99b17e5b577f7c7d7d199 Mon Sep 17 00:00:00 2001 From: mpi Date: Mon, 15 Jun 2015 15:45:28 +0000 Subject: [PATCH] Set the length of isochronous transfers as the sum of the frames lengths. This reduces differences between non-isoch and isoch transfers submissions, makes the generic DMA buffer overrun check work with isoch transfers and will allow some code simplifications in HC drivers. Since short-transfers were never checked for isoch transfers, we now need to pass the USBD_SHORT_XFER_OK flag to not change this behavior. This might be revisited later. ok ratchov@ --- sys/dev/usb/uaudio.c | 18 +++++++----------- sys/dev/usb/ugen.c | 13 ++++++------- sys/dev/usb/usbdi.c | 19 ++++++++++--------- 3 files changed, 23 insertions(+), 27 deletions(-) diff --git a/sys/dev/usb/uaudio.c b/sys/dev/usb/uaudio.c index e23915a4157..7bdce7a8336 100644 --- a/sys/dev/usb/uaudio.c +++ b/sys/dev/usb/uaudio.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uaudio.c,v 1.111 2015/05/11 06:46:22 ratchov Exp $ */ +/* $OpenBSD: uaudio.c,v 1.112 2015/06/15 15:45:28 mpi Exp $ */ /* $NetBSD: uaudio.c,v 1.90 2004/10/29 17:12:53 kent Exp $ */ /* @@ -2938,10 +2938,8 @@ uaudio_chan_ptransfer(struct chan *ch) #endif DPRINTFN(5,("uaudio_chan_ptransfer: transfer xfer=%p\n", cb->xfer)); - /* Fill the request */ - usbd_setup_isoc_xfer(cb->xfer, ch->pipe, cb, cb->sizes, - ch->nframes, USBD_NO_COPY, - uaudio_chan_pintr); + usbd_setup_isoc_xfer(cb->xfer, ch->pipe, cb, cb->sizes, ch->nframes, + USBD_NO_COPY | USBD_SHORT_XFER_OK, uaudio_chan_pintr); (void)usbd_transfer(cb->xfer); } @@ -2996,9 +2994,9 @@ uaudio_chan_psync_transfer(struct chan *ch) sb->size = total; DPRINTFN(5,("%s: transfer xfer=%p\n", __func__, sb->xfer)); - /* Fill the request */ usbd_setup_isoc_xfer(sb->xfer, ch->sync_pipe, sb, sb->sizes, - ch->nsync_frames, USBD_NO_COPY, uaudio_chan_psync_intr); + ch->nsync_frames, USBD_NO_COPY | USBD_SHORT_XFER_OK, + uaudio_chan_psync_intr); (void)usbd_transfer(sb->xfer); } @@ -3095,10 +3093,8 @@ uaudio_chan_rtransfer(struct chan *ch) #endif DPRINTFN(5,("uaudio_chan_rtransfer: transfer xfer=%p\n", cb->xfer)); - /* Fill the request */ - usbd_setup_isoc_xfer(cb->xfer, ch->pipe, cb, cb->sizes, - ch->nframes, USBD_NO_COPY, - uaudio_chan_rintr); + usbd_setup_isoc_xfer(cb->xfer, ch->pipe, cb, cb->sizes, ch->nframes, + USBD_NO_COPY | USBD_SHORT_XFER_OK, uaudio_chan_rintr); (void)usbd_transfer(cb->xfer); } diff --git a/sys/dev/usb/ugen.c b/sys/dev/usb/ugen.c index 22a62200c3e..df31ad749df 100644 --- a/sys/dev/usb/ugen.c +++ b/sys/dev/usb/ugen.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ugen.c,v 1.83 2015/05/25 11:52:15 mpi Exp $ */ +/* $OpenBSD: ugen.c,v 1.84 2015/06/15 15:45:28 mpi Exp $ */ /* $NetBSD: ugen.c,v 1.63 2002/11/26 18:49:48 christos Exp $ */ /* $FreeBSD: src/sys/dev/usb/ugen.c,v 1.26 1999/11/17 22:33:41 n_hibma Exp $ */ @@ -374,11 +374,10 @@ ugenopen(dev_t dev, int flag, int mode, struct proc *p) sce->isoreqs[i].dmabuf = buf; for(j = 0; j < UGEN_NISORFRMS; ++j) sce->isoreqs[i].sizes[j] = isize; - usbd_setup_isoc_xfer - (xfer, sce->pipeh, &sce->isoreqs[i], - sce->isoreqs[i].sizes, - UGEN_NISORFRMS, USBD_NO_COPY, - ugen_isoc_rintr); + usbd_setup_isoc_xfer(xfer, sce->pipeh, + &sce->isoreqs[i], sce->isoreqs[i].sizes, + UGEN_NISORFRMS, USBD_NO_COPY | + USBD_SHORT_XFER_OK, ugen_isoc_rintr); (void)usbd_transfer(xfer); } DPRINTFN(5, ("ugenopen: isoc open done\n")); @@ -874,7 +873,7 @@ ugen_isoc_rintr(struct usbd_xfer *xfer, void *addr, usbd_status status) } usbd_setup_isoc_xfer(xfer, sce->pipeh, req, req->sizes, UGEN_NISORFRMS, - USBD_NO_COPY, ugen_isoc_rintr); + USBD_NO_COPY | USBD_SHORT_XFER_OK, ugen_isoc_rintr); (void)usbd_transfer(xfer); if (sce->state & UGEN_ASLP) { diff --git a/sys/dev/usb/usbdi.c b/sys/dev/usb/usbdi.c index 833ed45adf6..428d3839751 100644 --- a/sys/dev/usb/usbdi.c +++ b/sys/dev/usb/usbdi.c @@ -1,4 +1,4 @@ -/* $OpenBSD: usbdi.c,v 1.81 2015/03/14 03:38:50 jsg Exp $ */ +/* $OpenBSD: usbdi.c,v 1.82 2015/06/15 15:45:28 mpi Exp $ */ /* $NetBSD: usbdi.c,v 1.103 2002/09/27 15:37:38 provos Exp $ */ /* $FreeBSD: src/sys/dev/usb/usbdi.c,v 1.28 1999/11/17 22:33:49 n_hibma Exp $ */ @@ -280,7 +280,6 @@ usbd_transfer(struct usbd_xfer *xfer) { struct usbd_pipe *pipe = xfer->pipe; usbd_status err; - u_int size; int flags, s; if (usbd_is_dying(pipe->device)) @@ -297,25 +296,23 @@ usbd_transfer(struct usbd_xfer *xfer) if (pipe->aborting) return (USBD_CANCELLED); - size = xfer->length; /* If there is no buffer, allocate one. */ - if (!(xfer->rqflags & URQ_DEV_DMABUF) && size != 0) { + if ((xfer->rqflags & URQ_DEV_DMABUF) == 0) { struct usbd_bus *bus = pipe->device->bus; #ifdef DIAGNOSTIC if (xfer->rqflags & URQ_AUTO_DMABUF) printf("usbd_transfer: has old buffer!\n"); #endif - err = usb_allocmem(bus, size, 0, &xfer->dmabuf); + err = usb_allocmem(bus, xfer->length, 0, &xfer->dmabuf); if (err) return (err); xfer->rqflags |= URQ_AUTO_DMABUF; } /* Copy data if going out. */ - if (!(xfer->flags & USBD_NO_COPY) && size != 0 && - !usbd_xfer_isread(xfer)) - memcpy(KERNADDR(&xfer->dmabuf, 0), xfer->buffer, size); + if (((xfer->flags & USBD_NO_COPY) == 0) && !usbd_xfer_isread(xfer)) + memcpy(KERNADDR(&xfer->dmabuf, 0), xfer->buffer, xfer->length); err = pipe->methods->transfer(xfer); @@ -458,10 +455,14 @@ usbd_setup_isoc_xfer(struct usbd_xfer *xfer, struct usbd_pipe *pipe, void *priv, u_int16_t *frlengths, u_int32_t nframes, u_int16_t flags, usbd_callback callback) { + int i; + xfer->pipe = pipe; xfer->priv = priv; xfer->buffer = 0; xfer->length = 0; + for (i = 0; i < nframes; i++) + xfer->length += frlengths[i]; xfer->actlen = 0; xfer->flags = flags; xfer->timeout = USBD_NO_TIMEOUT; @@ -736,7 +737,7 @@ usb_transfer_complete(struct usbd_xfer *xfer) pipe->running = 0; #ifdef DIAGNOSTIC - if (xfer->actlen > xfer->length && xfer->length != 0) { + if (xfer->actlen > xfer->length) { printf("%s: actlen > len %u > %u\n", __func__, xfer->actlen, xfer->length); xfer->actlen = xfer->length; -- 2.20.1