Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/jmcneill-usbmp]: src/sys/dev/usb convert usbd_{intr, bulk}_transfer() in ...



details:   https://anonhg.NetBSD.org/src/rev/cdbebabc5f78
branches:  jmcneill-usbmp
changeset: 771851:cdbebabc5f78
user:      mrg <mrg%NetBSD.org@localhost>
date:      Sat Jun 02 08:07:25 2012 +0000

description:
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.)

diffstat:

 sys/dev/usb/TODO.usbmp   |   4 ++--
 sys/dev/usb/usbdi.c      |  31 +++++++++++++++++++++++--------
 sys/dev/usb/usbdi.h      |   5 ++++-
 sys/dev/usb/usbdi_util.c |  45 +++++++--------------------------------------
 4 files changed, 36 insertions(+), 49 deletions(-)

diffs (198 lines):

diff -r eff2c76ecfd5 -r cdbebabc5f78 sys/dev/usb/TODO.usbmp
--- a/sys/dev/usb/TODO.usbmp    Sat May 12 21:30:07 2012 +0000
+++ b/sys/dev/usb/TODO.usbmp    Sat Jun 02 08:07:25 2012 +0000
@@ -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 @@
   - 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)
diff -r eff2c76ecfd5 -r cdbebabc5f78 sys/dev/usb/usbdi.c
--- a/sys/dev/usb/usbdi.c       Sat May 12 21:30:07 2012 +0000
+++ b/sys/dev/usb/usbdi.c       Sat Jun 02 08:07:25 2012 +0000
@@ -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 @@
                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 @@
        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 @@
 
 #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 @@
        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;
        }
diff -r eff2c76ecfd5 -r cdbebabc5f78 sys/dev/usb/usbdi.h
--- a/sys/dev/usb/usbdi.h       Sat May 12 21:30:07 2012 +0000
+++ b/sys/dev/usb/usbdi.h       Sat Jun 02 08:07:25 2012 +0000
@@ -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 @@
 #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_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 *,
diff -r eff2c76ecfd5 -r cdbebabc5f78 sys/dev/usb/usbdi_util.c
--- a/sys/dev/usb/usbdi_util.c  Sat May 12 21:30:07 2012 +0000
+++ b/sys/dev/usb/usbdi_util.c  Sat Jun 02 08:07:25 2012 +0000
@@ -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 @@
                   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 @@
                   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));



Home | Main Index | Thread Index | Old Index