Source-Changes-HG archive

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

[src/netbsd-6]: src/sys/dev/usb Pull up the following revisions(s) (requested...



details:   https://anonhg.NetBSD.org/src/rev/365723019d99
branches:  netbsd-6
changeset: 776578:365723019d99
user:      sborrill <sborrill%NetBSD.org@localhost>
date:      Fri Feb 21 10:41:06 2014 +0000

description:
Pull up the following revisions(s) (requested by mlelstv in ticket #1032):
        sys/dev/usb/umass.c:    revision 1.148
        sys/dev/usb/umassvar.h: revision 1.35
        sys/dev/usb/usb_mem.c:  revision 1.64

Fix problem where umass might allocate buffers in interrupt context which
causes it to fail or a DIAGNOSTIC kernel to panic.

diffstat:

 sys/dev/usb/umass.c    |  59 +++++++++++++++++++++++++++++++++++--------------
 sys/dev/usb/umassvar.h |   5 +++-
 sys/dev/usb/usb_mem.c  |  10 ++++----
 3 files changed, 51 insertions(+), 23 deletions(-)

diffs (160 lines):

diff -r de810cc6d457 -r 365723019d99 sys/dev/usb/umass.c
--- a/sys/dev/usb/umass.c       Thu Feb 20 13:55:53 2014 +0000
+++ b/sys/dev/usb/umass.c       Fri Feb 21 10:41:06 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: umass.c,v 1.141 2011/08/24 11:28:50 mbalmer Exp $      */
+/*     $NetBSD: umass.c,v 1.141.10.1 2014/02/21 10:41:06 sborrill Exp $        */
 
 /*
  * Copyright (c) 2003 The NetBSD Foundation, Inc.
@@ -124,7 +124,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: umass.c,v 1.141 2011/08/24 11:28:50 mbalmer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: umass.c,v 1.141.10.1 2014/02/21 10:41:06 sborrill Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_umass.h"
@@ -310,7 +310,7 @@
        const char *sWire, *sCommand;
        char *devinfop;
        usbd_status err;
-       int i, bno, error;
+       int i, error;
 
        sc->sc_dev = self;
 
@@ -563,29 +563,54 @@
                        return;
                }
        }
-       /* Allocate buffer for data transfer (it's huge). */
+       /* Allocate buffer for data transfer (it's huge), command and
+          status data here as auto allocation cannot happen in interrupt
+          context */
        switch (sc->sc_wire) {
        case UMASS_WPROTO_BBB:
-               bno = XFER_BBB_DATA;
-               goto dalloc;
+               sc->data_buffer = usbd_alloc_buffer(
+                       sc->transfer_xfer[XFER_BBB_DATA],
+                       UMASS_MAX_TRANSFER_SIZE);
+               sc->cmd_buffer = usbd_alloc_buffer(
+                       sc->transfer_xfer[XFER_BBB_CBW],
+                       UMASS_BBB_CBW_SIZE);
+               sc->s1_buffer = usbd_alloc_buffer(
+                       sc->transfer_xfer[XFER_BBB_CSW1],
+                       UMASS_BBB_CSW_SIZE);
+               sc->s2_buffer = usbd_alloc_buffer(
+                       sc->transfer_xfer[XFER_BBB_CSW2],
+                       UMASS_BBB_CSW_SIZE);
+               break;
        case UMASS_WPROTO_CBI:
-               bno = XFER_CBI_DATA;
-               goto dalloc;
        case UMASS_WPROTO_CBI_I:
-               bno = XFER_CBI_DATA;
-       dalloc:
-               sc->data_buffer = usbd_alloc_buffer(sc->transfer_xfer[bno],
-                                                   UMASS_MAX_TRANSFER_SIZE);
-               if (sc->data_buffer == NULL) {
-                       aprint_error_dev(self, "no buffer memory\n");
-                       umass_disco(sc);
-                       return;
-               }
+               sc->data_buffer = usbd_alloc_buffer(
+                       sc->transfer_xfer[XFER_CBI_DATA],
+                       UMASS_MAX_TRANSFER_SIZE);
+               sc->cmd_buffer = usbd_alloc_buffer(
+                       sc->transfer_xfer[XFER_CBI_CB],
+                       sizeof(sc->cbl));
+               sc->s1_buffer = usbd_alloc_buffer(
+                       sc->transfer_xfer[XFER_CBI_STATUS],
+                       sizeof(sc->sbl));
+               sc->s2_buffer = usbd_alloc_buffer(
+                       sc->transfer_xfer[XFER_CBI_RESET1],
+                       sizeof(sc->cbl));
                break;
        default:
                break;
        }
 
+       if (sc->data_buffer == NULL || sc->cmd_buffer == NULL
+           || sc->s1_buffer == NULL || sc->s2_buffer == NULL) {
+               /*
+                * partially preallocated buffers are freed with
+                * the xfer structures
+                */
+               aprint_error_dev(self, "no buffer memory\n");
+               umass_disco(sc);
+               return;
+       }
+
        /* Initialise the wire protocol specific methods */
        switch (sc->sc_wire) {
        case UMASS_WPROTO_BBB:
diff -r de810cc6d457 -r 365723019d99 sys/dev/usb/umassvar.h
--- a/sys/dev/usb/umassvar.h    Thu Feb 20 13:55:53 2014 +0000
+++ b/sys/dev/usb/umassvar.h    Fri Feb 21 10:41:06 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: umassvar.h,v 1.31 2011/07/31 16:32:02 jakllsch Exp $   */
+/*     $NetBSD: umassvar.h,v 1.31.10.1 2014/02/21 10:41:06 sborrill Exp $      */
 /*-
  * Copyright (c) 1999 MAEKAWA Masahide <bishop%rr.iij4u.or.jp@localhost>,
  *                   Nick Hibma <n_hibma%freebsd.org@localhost>
@@ -223,6 +223,9 @@
        usbd_xfer_handle        transfer_xfer[XFER_NR]; /* for ctrl xfers */
 
        void                    *data_buffer;
+       void                    *cmd_buffer;
+       void                    *s1_buffer;
+       void                    *s2_buffer;
 
        int                     transfer_dir;           /* data direction */
        void                    *transfer_data;         /* data buffer */
diff -r de810cc6d457 -r 365723019d99 sys/dev/usb/usb_mem.c
--- a/sys/dev/usb/usb_mem.c     Thu Feb 20 13:55:53 2014 +0000
+++ b/sys/dev/usb/usb_mem.c     Fri Feb 21 10:41:06 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: usb_mem.c,v 1.51 2012/01/27 18:53:09 para Exp $        */
+/*     $NetBSD: usb_mem.c,v 1.51.2.1 2014/02/21 10:41:06 sborrill Exp $        */
 
 /*
  * Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -38,7 +38,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: usb_mem.c,v 1.51 2012/01/27 18:53:09 para Exp $");
+__KERNEL_RCSID(0, "$NetBSD: usb_mem.c,v 1.51.2.1 2014/02/21 10:41:06 sborrill Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -115,7 +115,7 @@
        DPRINTFN(5, ("usb_block_allocmem: size=%zu align=%zu\n", size, align));
 
 #ifdef DIAGNOSTIC
-       if (cpu_intr_p()) {
+       if (cpu_softintr_p() || cpu_intr_p()) {
                printf("usb_block_allocmem: in interrupt context, size=%lu\n",
                    (unsigned long) size);
        }
@@ -137,7 +137,7 @@
        splx(s);
 
 #ifdef DIAGNOSTIC
-       if (cpu_intr_p()) {
+       if (cpu_softintr_p() || cpu_intr_p()) {
                printf("usb_block_allocmem: in interrupt context, failed\n");
                return (USBD_NOMEM);
        }
@@ -194,7 +194,7 @@
 usb_block_real_freemem(usb_dma_block_t *b)
 {
 #ifdef DIAGNOSTIC
-       if (cpu_intr_p()) {
+       if (cpu_softintr_p() || cpu_intr_p()) {
                printf("usb_block_real_freemem: in interrupt context\n");
                return;
        }



Home | Main Index | Thread Index | Old Index