Source-Changes-HG archive

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

[src/nick-nhusb]: src/sys/dev/usb WIP MPification



details:   https://anonhg.NetBSD.org/src/rev/afb646516ed5
branches:  nick-nhusb
changeset: 334577:afb646516ed5
user:      skrll <skrll%NetBSD.org@localhost>
date:      Tue Dec 27 11:37:36 2016 +0000

description:
WIP MPification

diffstat:

 sys/dev/usb/if_urndis.c |  162 +++++++++++++++++++++++++++++------------------
 1 files changed, 98 insertions(+), 64 deletions(-)

diffs (truncated from 343 to 300 lines):

diff -r 39e810a69862 -r afb646516ed5 sys/dev/usb/if_urndis.c
--- a/sys/dev/usb/if_urndis.c   Tue Dec 27 10:37:52 2016 +0000
+++ b/sys/dev/usb/if_urndis.c   Tue Dec 27 11:37:36 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_urndis.c,v 1.9.4.11 2016/12/05 10:55:18 skrll Exp $ */
+/*     $NetBSD: if_urndis.c,v 1.9.4.12 2016/12/27 11:37:36 skrll Exp $ */
 /*     $OpenBSD: if_urndis.c,v 1.31 2011/07/03 15:47:17 matthew Exp $ */
 
 /*
@@ -21,7 +21,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_urndis.c,v 1.9.4.11 2016/12/05 10:55:18 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_urndis.c,v 1.9.4.12 2016/12/27 11:37:36 skrll Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -75,13 +75,18 @@
 #endif
 
 static void urndis_start(struct ifnet *);
+static void urndis_start_locked(struct ifnet *);
 static void urndis_rxeof(struct usbd_xfer *, void *, usbd_status);
 static void urndis_txeof(struct usbd_xfer *, void *, usbd_status);
 static int urndis_rx_list_init(struct urndis_softc *);
+static void urndis_rx_list_free(struct urndis_softc *);
 static int urndis_tx_list_init(struct urndis_softc *);
+static void urndis_tx_list_free(struct urndis_softc *);
 
 static int urndis_init(struct ifnet *);
+static int urndis_init_locked(struct ifnet *);
 static void urndis_stop(struct ifnet *);
+static void urndis_stop_locked(struct ifnet *);
 
 static usbd_status urndis_ctrl_msg(struct urndis_softc *, uint8_t, uint8_t,
     uint16_t, uint16_t, void *, size_t);
@@ -879,7 +884,7 @@
 
                        bpf_mtap(ifp, m);
 
-                       if_percpuq_enqueue(ifp->if_percpuq, m);
+                       if_percpuq_enqueue(sc->urndis_ipq, m);
                }
                splx(s);
 
@@ -941,6 +946,21 @@
        return 0;
 }
 
+static void
+urndis_rx_list_free(struct urndis_softc *sc)
+{
+       for (int i = 0; i < RNDIS_RX_LIST_CNT; i++) {
+               if (sc->sc_data.sc_rx_chain[i].sc_mbuf != NULL) {
+                       m_freem(sc->sc_data.sc_rx_chain[i].sc_mbuf);
+                       sc->sc_data.sc_rx_chain[i].sc_mbuf = NULL;
+               }
+               if (sc->sc_data.sc_rx_chain[i].sc_xfer != NULL) {
+                       usbd_destroy_xfer(sc->sc_data.sc_rx_chain[i].sc_xfer);
+                       sc->sc_data.sc_rx_chain[i].sc_xfer = NULL;
+               }
+       }
+}
+
 static int
 urndis_tx_list_init(struct urndis_softc *sc)
 {
@@ -965,6 +985,21 @@
        return 0;
 }
 
+static void
+urndis_tx_list_free(struct urndis_softc *sc)
+{
+       for (int i = 0; i < RNDIS_TX_LIST_CNT; i++) {
+               if (sc->sc_data.sc_tx_chain[i].sc_mbuf != NULL) {
+                       m_freem(sc->sc_data.sc_tx_chain[i].sc_mbuf);
+                       sc->sc_data.sc_tx_chain[i].sc_mbuf = NULL;
+               }
+               if (sc->sc_data.sc_tx_chain[i].sc_xfer != NULL) {
+                       usbd_destroy_xfer(sc->sc_data.sc_tx_chain[i].sc_xfer);
+                       sc->sc_data.sc_tx_chain[i].sc_xfer = NULL;
+               }
+       }
+}
+
 static int
 urndis_ioctl(struct ifnet *ifp, unsigned long command, void *data)
 {
@@ -979,24 +1014,7 @@
 
        s = splnet();
 
-       switch(command) {
-       case SIOCSIFFLAGS:
-               if ((error = ifioctl_common(ifp, command, data)) != 0)
-                       break;
-               if (ifp->if_flags & IFF_UP) {
-                       if (!(ifp->if_flags & IFF_RUNNING))
-                               urndis_init(ifp);
-               } else {
-                       if (ifp->if_flags & IFF_RUNNING)
-                               urndis_stop(ifp);
-               }
-               error = 0;
-               break;
-
-       default:
-               error = ether_ioctl(ifp, command, data);
-               break;
-       }
+       error = ether_ioctl(ifp, command, data);
 
        if (error == ENETRESET)
                error = 0;
@@ -1026,8 +1044,20 @@
 static int
 urndis_init(struct ifnet *ifp)
 {
+       struct urndis_softc *sc = ifp->if_softc;
+
+       mutex_enter(&sc->urndis_lock);
+       int ret = urndis_init_locked(ifp);
+       mutex_exit(&sc->urndis_lock);
+
+       return ret;
+}
+
+static int
+urndis_init_locked(struct ifnet *ifp)
+{
        struct urndis_softc     *sc;
-       int                      i, s;
+       int                      i;
        int                      err;
        usbd_status              usberr;
 
@@ -1040,15 +1070,12 @@
        if (err != RNDIS_STATUS_SUCCESS)
                return EIO;
 
-       s = splnet();
-
        usberr = usbd_open_pipe(sc->sc_iface_data, sc->sc_bulkin_no,
            USBD_EXCLUSIVE_USE, &sc->sc_bulkin_pipe);
        if (usberr) {
                printf("%s: open rx pipe failed: %s\n", DEVNAME(sc),
                    usbd_errstr(err));
-               splx(s);
-               return EIO;
+               goto fail;
        }
 
        usberr = usbd_open_pipe(sc->sc_iface_data, sc->sc_bulkout_no,
@@ -1056,24 +1083,21 @@
        if (usberr) {
                printf("%s: open tx pipe failed: %s\n", DEVNAME(sc),
                    usbd_errstr(err));
-               splx(s);
-               return EIO;
+               goto fail2;
        }
 
        err = urndis_tx_list_init(sc);
        if (err) {
                printf("%s: tx list init failed\n",
                    DEVNAME(sc));
-               splx(s);
-               return err;
+               goto fail3;
        }
 
        err = urndis_rx_list_init(sc);
        if (err) {
                printf("%s: rx list init failed\n",
                    DEVNAME(sc));
-               splx(s);
-               return err;
+               goto fail4;
        }
 
        for (i = 0; i < RNDIS_RX_LIST_CNT; i++) {
@@ -1089,16 +1113,33 @@
        ifp->if_flags |= IFF_RUNNING;
        ifp->if_flags &= ~IFF_OACTIVE;
 
-       splx(s);
        return 0;
+
+fail4:
+       urndis_tx_list_free(sc);
+fail3:
+       usbd_close_pipe(sc->sc_bulkout_pipe);
+fail2:
+       usbd_close_pipe(sc->sc_bulkin_pipe);
+fail:
+       return EIO;
 }
 
 static void
 urndis_stop(struct ifnet *ifp)
 {
+       struct urndis_softc *sc = ifp->if_softc;
+
+       mutex_enter(&sc->urndis_lock);
+       urndis_stop_locked(ifp);
+       mutex_exit(&sc->urndis_lock);
+}
+
+static void
+urndis_stop_locked(struct ifnet *ifp)
+{
        struct urndis_softc     *sc;
        usbd_status      err;
-       int              i;
 
        sc = ifp->if_softc;
 
@@ -1119,27 +1160,9 @@
                            DEVNAME(sc), usbd_errstr(err));
        }
 
-       for (i = 0; i < RNDIS_RX_LIST_CNT; i++) {
-               if (sc->sc_data.sc_rx_chain[i].sc_mbuf != NULL) {
-                       m_freem(sc->sc_data.sc_rx_chain[i].sc_mbuf);
-                       sc->sc_data.sc_rx_chain[i].sc_mbuf = NULL;
-               }
-               if (sc->sc_data.sc_rx_chain[i].sc_xfer != NULL) {
-                       usbd_destroy_xfer(sc->sc_data.sc_rx_chain[i].sc_xfer);
-                       sc->sc_data.sc_rx_chain[i].sc_xfer = NULL;
-               }
-       }
+       urndis_tx_list_free(sc);
 
-       for (i = 0; i < RNDIS_TX_LIST_CNT; i++) {
-               if (sc->sc_data.sc_tx_chain[i].sc_mbuf != NULL) {
-                       m_freem(sc->sc_data.sc_tx_chain[i].sc_mbuf);
-                       sc->sc_data.sc_tx_chain[i].sc_mbuf = NULL;
-               }
-               if (sc->sc_data.sc_tx_chain[i].sc_xfer != NULL) {
-                       usbd_destroy_xfer(sc->sc_data.sc_tx_chain[i].sc_xfer);
-                       sc->sc_data.sc_tx_chain[i].sc_xfer = NULL;
-               }
-       }
+       urndis_rx_list_free(sc);
 
        /* Close pipes. */
        if (sc->sc_bulkin_pipe != NULL) {
@@ -1162,6 +1185,17 @@
 static void
 urndis_start(struct ifnet *ifp)
 {
+       struct urndis_softc *sc = ifp->if_softc;
+       KASSERT(ifp->if_extflags & IFEF_START_MPSAFE);
+
+       mutex_enter(&sc->urndis_txlock);
+       urndis_start_locked(ifp);
+       mutex_exit(&sc->urndis_txlock);
+}
+
+static void
+urndis_start_locked(struct ifnet *ifp)
+{
        struct urndis_softc     *sc;
        struct mbuf             *m_head = NULL;
 
@@ -1330,7 +1364,6 @@
        usbd_desc_iter_t                 iter;
        int                              if_ctl, if_data;
        int                              i, j, altcnt;
-       int                              s;
        u_char                           eaddr[ETHER_ADDR_LEN];
        void                            *buf;
        size_t                           bufsz;
@@ -1355,6 +1388,10 @@
        sc->sc_ifaceno_ctl = if_ctl;
        if_data = -1;
 
+       mutex_init(&sc->urndis_lock, MUTEX_DEFAULT, IPL_NONE);
+       mutex_init(&sc->urndis_txlock, MUTEX_DEFAULT, IPL_SOFTUSB);
+       mutex_init(&sc->urndis_rxlock, MUTEX_DEFAULT, IPL_SOFTUSB);
+
        usb_desc_iter_init(sc->sc_udev, &iter);
        while ((desc = (const void *)usb_desc_iter_next(&iter)) != NULL) {
 
@@ -1442,11 +1479,12 @@
                aprint_error("%s: could not find data bulk out\n",DEVNAME(sc));
        return;
 
-       found:
+found:
 
        ifp = GET_IFP(sc);
        ifp->if_softc = sc;
        ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
+       ifp->if_extflags = IFEF_START_MPSAFE;
        ifp->if_start = urndis_start;
        ifp->if_ioctl = urndis_ioctl;
        ifp->if_init = urndis_init;



Home | Main Index | Thread Index | Old Index