Module Name: src
Committed By: mrg
Date: Sat Jun 2 08:07:25 UTC 2012
Modified Files:
src/sys/dev/usb [jmcneill-usbmp]: TODO.usbmp usbdi.c usbdi.h
usbdi_util.c
Log Message:
convert usbd_{intr,bulk}_transfer() in the USBMP world:
- add a new USBD_SYNCHRONOUS_SIG flag for transfers
- in usbd_transfer(), if USBD_SYNCHRONOUS_SIG is set use cv_wait_sig()
(or tlseep(xfer, PZERO|PATCH, ...) for the unconverted controllers)
- add a usbd_sync_transfer_sig() front-end to usbd_transfer()
- greatly simplify both usbd_{intr,bulk}_transfer() to just
usbd_sync_transfer_sig() and usbd_get_xfer_status().
this fixes lockdebug issues where usbd_{intr,bulk}_transfer() where it
taking the pipe lock, when usbd_transfer() would call functions that
expect the pipe lock not to be taken (and try to taken it.)
To generate a diff of this commit:
cvs rdiff -u -r1.1.2.13 -r1.1.2.14 src/sys/dev/usb/TODO.usbmp
cvs rdiff -u -r1.134.2.15 -r1.134.2.16 src/sys/dev/usb/usbdi.c
cvs rdiff -u -r1.80.2.2 -r1.80.2.3 src/sys/dev/usb/usbdi.h
cvs rdiff -u -r1.55.12.7 -r1.55.12.8 src/sys/dev/usb/usbdi_util.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/dev/usb/TODO.usbmp
diff -u src/sys/dev/usb/TODO.usbmp:1.1.2.13 src/sys/dev/usb/TODO.usbmp:1.1.2.14
--- src/sys/dev/usb/TODO.usbmp:1.1.2.13 Sat May 12 21:30:07 2012
+++ src/sys/dev/usb/TODO.usbmp Sat Jun 2 08:07:25 2012
@@ -1,4 +1,4 @@
-$NetBSD: TODO.usbmp,v 1.1.2.13 2012/05/12 21:30:07 mrg Exp $
+$NetBSD: TODO.usbmp,v 1.1.2.14 2012/06/02 08:07:25 mrg Exp $
the majority of the USB MP device interface is documented in usbdivar.h.
@@ -155,7 +155,7 @@ driver testing: STATUS
- uyap
- udsbr
- ugen mostly done, testing is a MERGE ISSUE
- - pseye
+ - pseye working
- uvideo
- auvitek ? (must take kernel lock for scsipi)
- emdtv ? (must take kernel lock for scsipi)
Index: src/sys/dev/usb/usbdi.c
diff -u src/sys/dev/usb/usbdi.c:1.134.2.15 src/sys/dev/usb/usbdi.c:1.134.2.16
--- src/sys/dev/usb/usbdi.c:1.134.2.15 Tue Mar 6 18:26:48 2012
+++ src/sys/dev/usb/usbdi.c Sat Jun 2 08:07:25 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: usbdi.c,v 1.134.2.15 2012/03/06 18:26:48 mrg Exp $ */
+/* $NetBSD: usbdi.c,v 1.134.2.16 2012/06/02 08:07:25 mrg Exp $ */
/*
* Copyright (c) 1998, 2012 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: usbdi.c,v 1.134.2.15 2012/03/06 18:26:48 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: usbdi.c,v 1.134.2.16 2012/06/02 08:07:25 mrg Exp $");
#include "opt_compat_netbsd.h"
#include "opt_usb.h"
@@ -322,10 +322,17 @@ usbd_transfer(usbd_xfer_handle xfer)
if (pipe->device->bus->use_polling)
panic("usbd_transfer: not done");
- if (pipe->device->bus->lock)
- cv_wait(&xfer->cv, pipe->device->bus->lock);
- else
- tsleep(xfer, PRIBIO, "usbsyn", 0);
+ if ((flags & USBD_SYNCHRONOUS_SIG) != 0) {
+ if (pipe->device->bus->lock)
+ cv_wait_sig(&xfer->cv, pipe->device->bus->lock);
+ else
+ tsleep(xfer, PZERO|PCATCH, "usbsyn", 0);
+ } else {
+ if (pipe->device->bus->lock)
+ cv_wait(&xfer->cv, pipe->device->bus->lock);
+ else
+ tsleep(xfer, PRIBIO, "usbsyn", 0);
+ }
}
usbd_unlock_pipe(pipe);
return (xfer->status);
@@ -339,6 +346,14 @@ usbd_sync_transfer(usbd_xfer_handle xfer
return (usbd_transfer(xfer));
}
+/* Like usbd_transfer(), but waits for completion and listens for signals. */
+usbd_status
+usbd_sync_transfer_sig(usbd_xfer_handle xfer)
+{
+ xfer->flags |= USBD_SYNCHRONOUS | USBD_SYNCHRONOUS_SIG;
+ return (usbd_transfer(xfer));
+}
+
void *
usbd_alloc_buffer(usbd_xfer_handle xfer, u_int32_t size)
{
@@ -780,7 +795,7 @@ usb_transfer_complete(usbd_xfer_handle x
#ifdef DIAGNOSTIC
if (pipe == NULL) {
- printf("usbd_transfer_cb: pipe==0, xfer=%p\n", xfer);
+ printf("usb_transfer_complete: pipe==0, xfer=%p\n", xfer);
return;
}
#endif
@@ -831,7 +846,7 @@ usb_transfer_complete(usbd_xfer_handle x
xfer->done = 1;
if (!xfer->status && xfer->actlen < xfer->length &&
!(xfer->flags & USBD_SHORT_XFER_OK)) {
- DPRINTFN(-1,("usbd_transfer_cb: short transfer %d<%d\n",
+ DPRINTFN(-1,("usb_transfer_complete: short transfer %d<%d\n",
xfer->actlen, xfer->length));
xfer->status = USBD_SHORT_XFER;
}
Index: src/sys/dev/usb/usbdi.h
diff -u src/sys/dev/usb/usbdi.h:1.80.2.2 src/sys/dev/usb/usbdi.h:1.80.2.3
--- src/sys/dev/usb/usbdi.h:1.80.2.2 Sun Apr 29 23:05:02 2012
+++ src/sys/dev/usb/usbdi.h Sat Jun 2 08:07:25 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: usbdi.h,v 1.80.2.2 2012/04/29 23:05:02 mrg Exp $ */
+/* $NetBSD: usbdi.h,v 1.80.2.3 2012/06/02 08:07:25 mrg Exp $ */
/* $FreeBSD: src/sys/dev/usb/usbdi.h,v 1.18 1999/11/17 22:33:49 n_hibma Exp $ */
/*
@@ -80,6 +80,8 @@ typedef void (*usbd_callback)(usbd_xfer_
#define USBD_SYNCHRONOUS 0x02 /* wait for completion */
/* in usb.h #define USBD_SHORT_XFER_OK 0x04*/ /* allow short reads */
#define USBD_FORCE_SHORT_XFER 0x08 /* force last short packet on write */
+#define USBD_SYNCHRONOUS_SIG 0x10 /* if waiting for completion,
+ * also take signals */
#define USBD_NO_TIMEOUT 0
#define USBD_DEFAULT_TIMEOUT 5000 /* ms = 5 s */
@@ -125,6 +127,7 @@ void *usbd_alloc_buffer(usbd_xfer_handle
void usbd_free_buffer(usbd_xfer_handle);
void *usbd_get_buffer(usbd_xfer_handle);
usbd_status usbd_sync_transfer(usbd_xfer_handle);
+usbd_status usbd_sync_transfer_sig(usbd_xfer_handle);
usbd_status usbd_open_pipe_intr(usbd_interface_handle, u_int8_t,
u_int8_t, usbd_pipe_handle *,
usbd_private_handle, void *,
Index: src/sys/dev/usb/usbdi_util.c
diff -u src/sys/dev/usb/usbdi_util.c:1.55.12.7 src/sys/dev/usb/usbdi_util.c:1.55.12.8
--- src/sys/dev/usb/usbdi_util.c:1.55.12.7 Tue Mar 6 18:26:48 2012
+++ src/sys/dev/usb/usbdi_util.c Sat Jun 2 08:07:25 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: usbdi_util.c,v 1.55.12.7 2012/03/06 18:26:48 mrg Exp $ */
+/* $NetBSD: usbdi_util.c,v 1.55.12.8 2012/06/02 08:07:25 mrg Exp $ */
/*
* Copyright (c) 1998, 2012 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: usbdi_util.c,v 1.55.12.7 2012/03/06 18:26:48 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: usbdi_util.c,v 1.55.12.8 2012/06/02 08:07:25 mrg Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -434,28 +434,13 @@ usbd_bulk_transfer(usbd_xfer_handle xfer
u_int32_t *size, const char *lbl)
{
usbd_status err;
- int s, error;
usbd_setup_xfer(xfer, pipe, 0, buf, *size,
flags, timeout, usbd_bulk_transfer_cb);
DPRINTFN(1, ("usbd_bulk_transfer: start transfer %d bytes\n", *size));
- usbd_lock_pipe(pipe); /* don't want callback until block */
- err = usbd_transfer(xfer);
- if (err != USBD_IN_PROGRESS) {
- usbd_unlock_pipe(pipe);
- return (err);
- }
- if (pipe->device->bus->lock)
- error = cv_wait_sig(&xfer->cv, pipe->device->bus->lock);
- else
- error = tsleep(xfer, PZERO | PCATCH, lbl, 0); /* XXXSMP ok */
- usbd_unlock_pipe(pipe);
- if (error) {
- DPRINTF(("usbd_bulk_transfer: wait=%d\n", error));
- usbd_abort_pipe(pipe);
- return (USBD_INTERRUPTED);
- }
- usbd_get_xfer_status(xfer, NULL, NULL, size, &err);
+
+ err = usbd_sync_transfer_sig(xfer);
+ usbd_get_xfer_status(xfer, NULL, NULL, size, NULL);
DPRINTFN(1,("usbd_bulk_transfer: transferred %d\n", *size));
if (err) {
DPRINTF(("usbd_bulk_transfer: error=%d\n", err));
@@ -483,28 +468,12 @@ usbd_intr_transfer(usbd_xfer_handle xfer
u_int32_t *size, const char *lbl)
{
usbd_status err;
- int s, error;
usbd_setup_xfer(xfer, pipe, 0, buf, *size,
flags, timeout, usbd_intr_transfer_cb);
DPRINTFN(1, ("usbd_intr_transfer: start transfer %d bytes\n", *size));
- usbd_lock_pipe(pipe); /* don't want callback until block */
- err = usbd_transfer(xfer);
- if (err != USBD_IN_PROGRESS) {
- usbd_unlock_pipe(pipe);
- return (err);
- }
- if (pipe->device->bus->lock)
- error = cv_wait_sig(&xfer->cv, pipe->device->bus->lock);
- else
- error = tsleep(xfer, PZERO | PCATCH, lbl, 0); /* XXXSMP ok */
- usbd_unlock_pipe(pipe);
- if (error) {
- DPRINTF(("usbd_intr_transfer: wait=%d\n", error));
- usbd_abort_pipe(pipe);
- return (USBD_INTERRUPTED);
- }
- usbd_get_xfer_status(xfer, NULL, NULL, size, &err);
+ err = usbd_sync_transfer_sig(xfer);
+ usbd_get_xfer_status(xfer, NULL, NULL, size, NULL);
DPRINTFN(1,("usbd_intr_transfer: transferred %d\n", *size));
if (err) {
DPRINTF(("usbd_intr_transfer: error=%d\n", err));