ugen_isoc_rintr() may recycle the xfer immediately. Therefore, we avoid

touching the xfer after calling the callback in usb_transfer_complete().
From PR 25960.
This commit is contained in:
mycroft 2004-07-17 20:16:13 +00:00
parent c206d4cf15
commit ab236698f0
1 changed files with 7 additions and 6 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: usbdi.c,v 1.103 2002/09/27 15:37:38 provos Exp $ */
/* $NetBSD: usbdi.c,v 1.104 2004/07/17 20:16:13 mycroft Exp $ */
/* $FreeBSD: src/sys/dev/usb/usbdi.c,v 1.28 1999/11/17 22:33:49 n_hibma Exp $ */
/*
@ -39,7 +39,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: usbdi.c,v 1.103 2002/09/27 15:37:38 provos Exp $");
__KERNEL_RCSID(0, "$NetBSD: usbdi.c,v 1.104 2004/07/17 20:16:13 mycroft Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -758,6 +758,9 @@ usb_transfer_complete(usbd_xfer_handle xfer)
{
usbd_pipe_handle pipe = xfer->pipe;
usb_dma_t *dmap = &xfer->dmabuf;
int sync = xfer->flags & USBD_SYNCHRONOUS;
int erred = xfer->status == USBD_CANCELLED ||
xfer->status == USBD_TIMEOUT;
int repeat = pipe->repeat;
int polling;
@ -842,14 +845,12 @@ usb_transfer_complete(usbd_xfer_handle xfer)
pipe->methods->done(xfer);
#endif
if ((xfer->flags & USBD_SYNCHRONOUS) && !polling)
if (sync && !polling)
wakeup(xfer);
if (!repeat) {
/* XXX should we stop the queue on all errors? */
if ((xfer->status == USBD_CANCELLED ||
xfer->status == USBD_TIMEOUT) &&
pipe->iface != NULL) /* not control pipe */
if (erred && pipe->iface != NULL) /* not control pipe */
pipe->running = 0;
else
usbd_start_next(pipe);