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/6fdf921c1eff
branches:  nick-nhusb
changeset: 804704:6fdf921c1eff
user:      skrll <skrll%NetBSD.org@localhost>
date:      Mon Dec 12 13:15:39 2016 +0000

description:
WIP MPification

diffstat:

 sys/dev/usb/if_aue.c     |  345 +++++++++++++++++++++-------------------------
 sys/dev/usb/if_auereg.h  |    8 +-
 sys/dev/usb/if_axe.c     |  214 ++++++++++++++++++----------
 sys/dev/usb/if_axen.c    |  198 ++++++++++++++++----------
 sys/dev/usb/if_axenreg.h |    7 +-
 sys/dev/usb/if_axereg.h  |    7 +-
 sys/dev/usb/if_cdce.c    |  237 +++++++++++++++----------------
 sys/dev/usb/if_cdcereg.h |   10 +-
 sys/dev/usb/if_cue.c     |  308 ++++++++++++++++++++++-------------------
 sys/dev/usb/if_cuereg.h  |    8 +-
 sys/dev/usb/if_udav.c    |  148 ++++++++++++-------
 sys/dev/usb/if_udavreg.h |    7 +-
 12 files changed, 827 insertions(+), 670 deletions(-)

diffs (truncated from 2874 to 300 lines):

diff -r a27b14aeb65a -r 6fdf921c1eff sys/dev/usb/if_aue.c
--- a/sys/dev/usb/if_aue.c      Sun Dec 11 17:31:09 2016 +0000
+++ b/sys/dev/usb/if_aue.c      Mon Dec 12 13:15:39 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_aue.c,v 1.132.4.13 2016/12/05 10:55:18 skrll Exp $  */
+/*     $NetBSD: if_aue.c,v 1.132.4.14 2016/12/12 13:15:39 skrll Exp $  */
 
 /*
  * Copyright (c) 1997, 1998, 1999, 2000
@@ -71,14 +71,13 @@
  * TODO:
  * better error messages from rxstat
  * split out if_auevar.h
- * add thread to avoid register reads from interrupt context
  * more error checks
  * investigate short rx problem
  * proper cleanup on errors
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_aue.c,v 1.132.4.13 2016/12/05 10:55:18 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_aue.c,v 1.132.4.14 2016/12/12 13:15:39 skrll Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -217,11 +216,11 @@
 CFATTACH_DECL_NEW(aue, sizeof(struct aue_softc), aue_match, aue_attach,
     aue_detach, aue_activate);
 
-Static void aue_multithread(void *);
-
 Static void aue_reset_pegasus_II(struct aue_softc *);
 Static int aue_tx_list_init(struct aue_softc *);
+Static void aue_tx_list_free(struct aue_softc *);
 Static int aue_rx_list_init(struct aue_softc *);
+Static void aue_rx_list_free(struct aue_softc *);
 Static int aue_newbuf(struct aue_softc *, struct aue_chain *, struct mbuf *);
 Static int aue_send(struct aue_softc *, struct mbuf *, int);
 Static void aue_intr(struct usbd_xfer *, void *, usbd_status);
@@ -230,11 +229,14 @@
 Static void aue_tick(void *);
 Static void aue_tick_task(void *);
 Static void aue_start(struct ifnet *);
+Static void aue_start_locked(struct ifnet *);
 Static int aue_ioctl(struct ifnet *, u_long, void *);
-Static void aue_init(void *);
-Static void aue_stop(struct aue_softc *);
+Static int aue_ifflags_cb(struct ethercom *);
+Static int aue_init(struct ifnet *);
+Static int aue_init_locked(struct ifnet *);
+Static void aue_stop(struct ifnet *, int);
+Static void aue_stop_locked(struct ifnet *, int);
 Static void aue_watchdog(struct ifnet *);
-Static int aue_openpipes(struct aue_softc *);
 Static int aue_ifmedia_upd(struct ifnet *);
 
 Static int aue_eeprom_getword(struct aue_softc *, int);
@@ -723,7 +725,6 @@
        struct aue_softc *sc = device_private(self);
        struct usb_attach_arg *uaa = aux;
        char                    *devinfop;
-       int                     s;
        u_char                  eaddr[ETHER_ADDR_LEN];
        struct ifnet            *ifp;
        struct mii_data         *mii;
@@ -755,6 +756,9 @@
        usb_init_task(&sc->aue_tick_task, aue_tick_task, sc, 0);
        usb_init_task(&sc->aue_stop_task, (void (*)(void *))aue_stop, sc, 0);
        mutex_init(&sc->aue_mii_lock, MUTEX_DEFAULT, IPL_NONE);
+       mutex_init(&sc->aue_lock, MUTEX_DEFAULT, IPL_NONE);
+       mutex_init(&sc->aue_txlock, MUTEX_DEFAULT, IPL_SOFTUSB);
+       mutex_init(&sc->aue_rxlock, MUTEX_DEFAULT, IPL_SOFTUSB);
 
        err = usbd_device2interface_handle(dev, AUE_IFACE_IDX, &iface);
        if (err) {
@@ -764,13 +768,8 @@
        sc->aue_closing = 0;
 
        mutex_init(&sc->aue_mcmtx, MUTEX_DRIVER, IPL_NET);
-       cv_init(&sc->aue_domc, "auemc");
        cv_init(&sc->aue_closemc, "auemccl");
 
-       err = kthread_create(PRI_NONE, 0, NULL,
-               aue_multithread, sc, &sc->aue_thread,
-               "%s-mc", device_xname(sc->aue_dev));
-
        if (err) {
                aprint_error_dev(self,
                    "creating multicast configuration thread\n");
@@ -813,7 +812,6 @@
        }
 
 
-       s = splnet();
 
        /* Reset the adapter. */
        aue_reset(sc);
@@ -833,6 +831,8 @@
        ifp->if_softc = sc;
        ifp->if_mtu = ETHERMTU;
        ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
+       ifp->if_extflags = IFEF_START_MPSAFE;
+       ifp->if_init = aue_init;
        ifp->if_ioctl = aue_ioctl;
        ifp->if_start = aue_start;
        ifp->if_watchdog = aue_watchdog;
@@ -857,15 +857,17 @@
                ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_AUTO);
 
        /* Attach the interface. */
-       if_attach(ifp);
+       if_initialize(ifp);
+       sc->aue_ipq = if_percpuq_create(&sc->aue_ec.ec_if);
        ether_ifattach(ifp, eaddr);
+       if_register(ifp);
+       ether_set_ifflags_cb(&sc->aue_ec, aue_ifflags_cb);
        rnd_attach_source(&sc->rnd_source, device_xname(sc->aue_dev),
            RND_TYPE_NET, RND_FLAG_DEFAULT);
 
        callout_init(&(sc->aue_stat_ch), 0);
 
        sc->aue_attached = 1;
-       splx(s);
 
        usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->aue_udev, sc->aue_dev);
 
@@ -895,20 +897,18 @@
        usb_rem_task(sc->aue_udev, &sc->aue_stop_task);
 
        sc->aue_closing = 1;
-       cv_signal(&sc->aue_domc);
 
        mutex_enter(&sc->aue_mcmtx);
        cv_wait(&sc->aue_closemc,&sc->aue_mcmtx);
        mutex_exit(&sc->aue_mcmtx);
 
        mutex_destroy(&sc->aue_mcmtx);
-       cv_destroy(&sc->aue_domc);
        cv_destroy(&sc->aue_closemc);
 
        s = splusb();
 
        if (ifp->if_flags & IFF_RUNNING)
-               aue_stop(sc);
+               aue_stop(ifp, 1);
 
        rnd_detach_source(&sc->rnd_source);
        mii_detach(&sc->aue_mii, MII_PHY_ANY, MII_OFFSET_ANY);
@@ -1025,6 +1025,22 @@
        return 0;
 }
 
+Static void
+aue_rx_list_free(struct aue_softc *sc)
+{
+       /* Free RX resources. */
+       for (int i = 0; i < AUE_RX_LIST_CNT; i++) {
+               if (sc->aue_cdata.aue_rx_chain[i].aue_mbuf != NULL) {
+                       m_freem(sc->aue_cdata.aue_rx_chain[i].aue_mbuf);
+                       sc->aue_cdata.aue_rx_chain[i].aue_mbuf = NULL;
+               }
+               if (sc->aue_cdata.aue_rx_chain[i].aue_xfer != NULL) {
+                       usbd_destroy_xfer(sc->aue_cdata.aue_rx_chain[i].aue_xfer);
+                       sc->aue_cdata.aue_rx_chain[i].aue_xfer = NULL;
+               }
+       }
+}
+
 Static int
 aue_tx_list_init(struct aue_softc *sc)
 {
@@ -1054,6 +1070,22 @@
 }
 
 Static void
+aue_tx_list_free(struct aue_softc *sc)
+{
+       /* Free TX resources. */
+       for (int i = 0; i < AUE_TX_LIST_CNT; i++) {
+               if (sc->aue_cdata.aue_tx_chain[i].aue_mbuf != NULL) {
+                       m_freem(sc->aue_cdata.aue_tx_chain[i].aue_mbuf);
+                       sc->aue_cdata.aue_tx_chain[i].aue_mbuf = NULL;
+               }
+               if (sc->aue_cdata.aue_tx_chain[i].aue_xfer != NULL) {
+                       usbd_destroy_xfer(sc->aue_cdata.aue_tx_chain[i].aue_xfer);
+                       sc->aue_cdata.aue_tx_chain[i].aue_xfer = NULL;
+               }
+       }
+}
+
+Static void
 aue_intr(struct usbd_xfer *xfer, void *priv,
     usbd_status status)
 {
@@ -1346,6 +1378,17 @@
 Static void
 aue_start(struct ifnet *ifp)
 {
+       struct aue_softc *sc = ifp->if_softc;
+       KASSERT(ifp->if_extflags & IFEF_START_MPSAFE);
+
+       mutex_enter(&sc->aue_txlock);
+       aue_start_locked(ifp);
+       mutex_exit(&sc->aue_txlock);
+}
+
+Static void
+aue_start_locked(struct ifnet *ifp)
+{
        struct aue_softc        *sc = ifp->if_softc;
        struct mbuf             *m_head = NULL;
 
@@ -1366,7 +1409,6 @@
                return;
 
        if (aue_send(sc, m_head, 0)) {
-               ifp->if_flags |= IFF_OACTIVE;
                return;
        }
 
@@ -1386,24 +1428,33 @@
        ifp->if_timer = 5;
 }
 
-Static void
-aue_init(void *xsc)
+Static int
+aue_init(struct ifnet *ifp)
 {
-       struct aue_softc        *sc = xsc;
-       struct ifnet            *ifp = GET_IFP(sc);
+       struct aue_softc        *sc = ifp->if_softc;
+
+       mutex_enter(&sc->aue_lock);
+       int ret = aue_init_locked(ifp);
+       mutex_exit(&sc->aue_lock);
+
+       return ret;
+}
+
+Static int
+aue_init_locked(struct ifnet *ifp)
+{
+       struct aue_softc        *sc = ifp->if_softc;
        struct mii_data         *mii = GET_MII(sc);
-       int                     i, s;
+       int                     i;
        const u_char            *eaddr;
+       usbd_status             err;
 
        DPRINTFN(5,("%s: %s: enter\n", device_xname(sc->aue_dev), __func__));
 
        if (sc->aue_dying)
-               return;
+               return EIO;
 
-       if (ifp->if_flags & IFF_RUNNING)
-               return;
-
-       s = splnet();
+       aue_stop_locked(ifp, 1);
 
        /*
         * Cancel pending I/O and free all RX/TX buffers.
@@ -1421,23 +1472,41 @@
                AUE_CLRBIT(sc, AUE_CTL2, AUE_CTL2_RX_PROMISC);
 
        if (sc->aue_ep[AUE_ENDPT_RX] == NULL) {
-               if (aue_openpipes(sc)) {
-                       splx(s);
-                       return;
+               /* Open RX and TX pipes. */
+               err = usbd_open_pipe(sc->aue_iface, sc->aue_ed[AUE_ENDPT_RX],
+               USBD_EXCLUSIVE_USE, &sc->aue_ep[AUE_ENDPT_RX]);
+               if (err) {
+                       aprint_error_dev(sc->aue_dev, "open rx pipe failed: %s\n",
+                       usbd_errstr(err));
+                       goto fail;
+               }
+               err = usbd_open_pipe(sc->aue_iface, sc->aue_ed[AUE_ENDPT_TX],
+               USBD_EXCLUSIVE_USE, &sc->aue_ep[AUE_ENDPT_TX]);
+               if (err) {
+                       aprint_error_dev(sc->aue_dev, "open tx pipe failed: %s\n",
+                       usbd_errstr(err));
+                       goto fail1;
+               }
+               err = usbd_open_pipe_intr(sc->aue_iface, sc->aue_ed[AUE_ENDPT_INTR],
+                       USBD_EXCLUSIVE_USE, &sc->aue_ep[AUE_ENDPT_INTR], sc,
+                       &sc->aue_cdata.aue_ibuf, AUE_INTR_PKTLEN, aue_intr,
+                       AUE_INTR_INTERVAL);
+               if (err) {
+                       aprint_error_dev(sc->aue_dev, "open intr pipe failed: %s\n",
+                       usbd_errstr(err));
+                       goto fail2;
                }
        }
        /* Init TX ring. */
        if (aue_tx_list_init(sc)) {
                aprint_error_dev(sc->aue_dev, "tx list init failed\n");
-               splx(s);



Home | Main Index | Thread Index | Old Index