Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/usb Only clear the endpoint information in ugen_set_...



details:   https://anonhg.NetBSD.org/src/rev/2dd1eb5b841b
branches:  trunk
changeset: 343704:2dd1eb5b841b
user:      skrll <skrll%NetBSD.org@localhost>
date:      Mon Feb 22 07:46:00 2016 +0000

description:
Only clear the endpoint information in ugen_set_interface only if setting
the new altno suceeds.

Avoids the null de-ref in PR/50597 and PR/50810

diffstat:

 sys/dev/usb/ugen.c |  40 ++++++++++++++++++++--------------------
 1 files changed, 20 insertions(+), 20 deletions(-)

diffs (89 lines):

diff -r d64bbb444ac9 -r 2dd1eb5b841b sys/dev/usb/ugen.c
--- a/sys/dev/usb/ugen.c        Sun Feb 21 22:51:29 2016 +0000
+++ b/sys/dev/usb/ugen.c        Mon Feb 22 07:46:00 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ugen.c,v 1.129 2016/02/21 09:50:10 skrll Exp $ */
+/*     $NetBSD: ugen.c,v 1.130 2016/02/22 07:46:00 skrll Exp $ */
 
 /*
  * Copyright (c) 1998, 2004 The NetBSD Foundation, Inc.
@@ -37,7 +37,7 @@
 
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ugen.c,v 1.129 2016/02/21 09:50:10 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ugen.c,v 1.130 2016/02/22 07:46:00 skrll Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_compat_netbsd.h"
@@ -270,6 +270,19 @@
        return;
 }
 
+Static void
+ugen_clear_endpoints(struct ugen_softc *sc)
+{
+
+       /* Clear out the old info, but leave the selinfo and cv initialised. */
+       for (int i = 0; i < USB_MAX_ENDPOINTS; i++) {
+               for (int dir = OUT; dir <= IN; dir++) {
+                       struct ugen_endpoint *sce = &sc->sc_endpoints[i][dir];
+                       memset(sce, 0, UGEN_ENDPOINT_NONZERO_CRUFT);
+               }
+       }
+}
+
 Static int
 ugen_set_config(struct ugen_softc *sc, int configno)
 {
@@ -281,7 +294,7 @@
        u_int8_t niface, nendpt;
        int ifaceno, endptno, endpt;
        usbd_status err;
-       int dir, i;
+       int dir;
 
        DPRINTFN(1,("ugen_set_config: %s to configno %d, sc=%p\n",
                    device_xname(sc->sc_dev), configno, sc));
@@ -310,13 +323,7 @@
        if (err)
                return (err);
 
-       /* Clear out the old info, but leave the selinfo and cv initialised. */
-       for (i = 0; i < USB_MAX_ENDPOINTS; i++) {
-               for (dir = OUT; dir <= IN; dir++) {
-                       sce = &sc->sc_endpoints[i][dir];
-                       memset(sce, 0, UGEN_ENDPOINT_NONZERO_CRUFT);
-               }
-       }
+       ugen_clear_endpoints(sc);
 
        for (ifaceno = 0; ifaceno < niface; ifaceno++) {
                DPRINTFN(1,("ugen_set_config: ifaceno %d\n", ifaceno));
@@ -1336,16 +1343,6 @@
        err = usbd_endpoint_count(iface, &nendpt);
        if (err)
                return (err);
-       /* XXX should only do this after setting new altno has succeeded */
-       for (endptno = 0; endptno < nendpt; endptno++) {
-               ed = usbd_interface2endpoint_descriptor(iface,endptno);
-               endpt = ed->bEndpointAddress;
-               dir = UE_GET_DIR(endpt) == UE_DIR_IN ? IN : OUT;
-               sce = &sc->sc_endpoints[UE_GET_ADDR(endpt)][dir];
-               sce->sc = NULL;
-               sce->edesc = NULL;
-               sce->iface = NULL;
-       }
 
        /* change setting */
        err = usbd_set_interface(iface, altno);
@@ -1355,6 +1352,9 @@
        err = usbd_endpoint_count(iface, &nendpt);
        if (err)
                return (err);
+
+       ugen_clear_endpoints(sc);
+
        for (endptno = 0; endptno < nendpt; endptno++) {
                ed = usbd_interface2endpoint_descriptor(iface,endptno);
                KASSERT(ed != NULL);



Home | Main Index | Thread Index | Old Index