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/1fa57a4902c9
branches:  nick-nhusb
changeset: 334534:1fa57a4902c9
user:      skrll <skrll%NetBSD.org@localhost>
date:      Fri Jul 15 08:50:59 2016 +0000

description:
WIP MPification

diffstat:

 sys/dev/usb/if_smsc.c    |  287 +++++++++++++++++++++++++++-------------------
 sys/dev/usb/if_smscvar.h |    8 +-
 2 files changed, 176 insertions(+), 119 deletions(-)

diffs (truncated from 519 to 300 lines):

diff -r 343c46d73527 -r 1fa57a4902c9 sys/dev/usb/if_smsc.c
--- a/sys/dev/usb/if_smsc.c     Fri Jul 15 06:36:21 2016 +0000
+++ b/sys/dev/usb/if_smsc.c     Fri Jul 15 08:50:59 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_smsc.c,v 1.22.2.12 2016/07/09 20:25:15 skrll Exp $  */
+/*     $NetBSD: if_smsc.c,v 1.22.2.13 2016/07/15 08:50:59 skrll Exp $  */
 
 /*     $OpenBSD: if_smsc.c,v 1.4 2012/09/27 12:38:11 jsg Exp $ */
 /* $FreeBSD: src/sys/dev/usb/net/if_smsc.c,v 1.1 2012/08/15 04:03:55 gonzo Exp $ */
@@ -161,9 +161,12 @@
 int             smsc_activate(device_t, enum devact);
 
 int             smsc_init(struct ifnet *);
+int             smsc_init_locked(struct ifnet *);
 void            smsc_start(struct ifnet *);
+void            smsc_start_locked(struct ifnet *);
 int             smsc_ioctl(struct ifnet *, u_long, void *);
 void            smsc_stop(struct ifnet *, int);
+void            smsc_stop_locked(struct ifnet *, int);
 
 void            smsc_reset(struct smsc_softc *);
 struct mbuf    *smsc_newbuf(void);
@@ -179,7 +182,9 @@
 void            smsc_unlock_mii(struct smsc_softc *);
 
 int             smsc_tx_list_init(struct smsc_softc *);
+void            smsc_tx_list_free(struct smsc_softc *);
 int             smsc_rx_list_init(struct smsc_softc *);
+void            smsc_rx_list_free(struct smsc_softc *);
 int             smsc_encap(struct smsc_softc *, struct mbuf *, int);
 void            smsc_rxeof(struct usbd_xfer *, void *, usbd_status);
 void            smsc_txeof(struct usbd_xfer *, void *, usbd_status);
@@ -543,19 +548,27 @@
 int
 smsc_init(struct ifnet *ifp)
 {
-       struct smsc_softc       *sc = ifp->if_softc;
-       struct smsc_chain       *c;
-       usbd_status              err;
-       int                      s, i;
+       struct smsc_softc *sc = ifp->if_softc;
+
+       mutex_enter(&sc->sc_lock);
+       int ret = smsc_init_locked(ifp);
+       mutex_exit(&sc->sc_lock);
+
+       return ret;
+}
+
+
+int
+smsc_init_locked(struct ifnet *ifp)
+{
+       struct smsc_softc * const sc = ifp->if_softc;
+       usbd_status err;
 
        if (sc->sc_dying)
                return EIO;
 
-       s = splnet();
-
        /* Cancel pending I/O */
-       if (ifp->if_flags & IFF_RUNNING)
-               smsc_stop(ifp, 1);
+       smsc_stop_locked(ifp, 1);
 
        /* Reset the ethernet interface. */
        smsc_reset(sc);
@@ -572,8 +585,7 @@
        if (err) {
                printf("%s: open rx pipe failed: %s\n",
                    device_xname(sc->sc_dev), usbd_errstr(err));
-               splx(s);
-               return EIO;
+               goto fail;
        }
 
        err = usbd_open_pipe(sc->sc_iface, sc->sc_ed[SMSC_ENDPT_TX],
@@ -581,27 +593,24 @@
        if (err) {
                printf("%s: open tx pipe failed: %s\n",
                    device_xname(sc->sc_dev), usbd_errstr(err));
-               splx(s);
-               return EIO;
+               goto fail1;
        }
 
        /* Init RX ring. */
        if (smsc_rx_list_init(sc)) {
                aprint_error_dev(sc->sc_dev, "rx list init failed\n");
-               splx(s);
-               return EIO;
+               goto fail2;
        }
 
        /* Init TX ring. */
        if (smsc_tx_list_init(sc)) {
                aprint_error_dev(sc->sc_dev, "tx list init failed\n");
-               splx(s);
-               return EIO;
+               goto fail3;
        }
 
        /* Start up the receive pipe. */
-       for (i = 0; i < SMSC_RX_LIST_CNT; i++) {
-               c = &sc->sc_cdata.rx_chain[i];
+       for (size_t i = 0; i < SMSC_RX_LIST_CNT; i++) {
+               struct smsc_chain *c = &sc->sc_cdata.rx_chain[i];
                usbd_setup_xfer(c->sc_xfer, c, c->sc_buf, sc->sc_bufsz,
                    USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, smsc_rxeof);
                usbd_transfer(c->sc_xfer);
@@ -611,18 +620,38 @@
        ifp->if_flags |= IFF_RUNNING;
        ifp->if_flags &= ~IFF_OACTIVE;
 
-       splx(s);
-
        callout_reset(&sc->sc_stat_ch, hz, smsc_tick, sc);
 
        return 0;
+
+fail3:
+       smsc_tx_list_free(sc);
+fail2:
+       smsc_rx_list_free(sc);
+
+       usbd_close_pipe(sc->sc_ep[SMSC_ENDPT_TX]);
+fail1:
+       usbd_close_pipe(sc->sc_ep[SMSC_ENDPT_RX]);
+fail:
+       return EIO;
 }
 
 void
 smsc_start(struct ifnet *ifp)
 {
-       struct smsc_softc       *sc = ifp->if_softc;
-       struct mbuf             *m_head = NULL;
+       struct smsc_softc * const sc = ifp->if_softc;
+       KASSERT(ifp->if_extflags & IFEF_START_MPSAFE);
+
+       mutex_enter(&sc->sc_txlock);
+       smsc_start_locked(ifp);
+       mutex_exit(&sc->sc_txlock);
+}
+
+void
+smsc_start_locked(struct ifnet *ifp)
+{
+       struct smsc_softc * const sc = ifp->if_softc;
+       struct mbuf *m_head = NULL;
 
        /* Don't send anything if there is no link or controller is busy. */
        if ((sc->sc_flags & SMSC_FLAG_LINK) == 0) {
@@ -637,7 +666,6 @@
                return;
 
        if (smsc_encap(sc, m_head, 0)) {
-               ifp->if_flags |= IFF_OACTIVE;
                return;
        }
        IFQ_DEQUEUE(&ifp->if_snd, m_head);
@@ -669,15 +697,20 @@
 void
 smsc_stop(struct ifnet *ifp, int disable)
 {
-       usbd_status             err;
-       struct smsc_softc       *sc = ifp->if_softc;
-       int                     i;
+       struct smsc_softc * const sc = ifp->if_softc;
+
+       mutex_enter(&sc->sc_lock);
+       smsc_stop_locked(ifp, disable);
+       mutex_exit(&sc->sc_lock);
+}
 
-       smsc_reset(sc);
+void
+smsc_stop_locked(struct ifnet *ifp, int disable)
+{
+       struct smsc_softc * const sc = ifp->if_softc;
+       usbd_status err;
 
-       ifp = &sc->sc_ec.ec_if;
-       ifp->if_timer = 0;
-       ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
+//     smsc_reset(sc);
 
        callout_stop(&sc->sc_stat_ch);
 
@@ -706,29 +739,10 @@
                }
        }
 
-       /* Free RX resources. */
-       for (i = 0; i < SMSC_RX_LIST_CNT; i++) {
-               if (sc->sc_cdata.rx_chain[i].sc_mbuf != NULL) {
-                       m_freem(sc->sc_cdata.rx_chain[i].sc_mbuf);
-                       sc->sc_cdata.rx_chain[i].sc_mbuf = NULL;
-               }
-               if (sc->sc_cdata.rx_chain[i].sc_xfer != NULL) {
-                       usbd_destroy_xfer(sc->sc_cdata.rx_chain[i].sc_xfer);
-                       sc->sc_cdata.rx_chain[i].sc_xfer = NULL;
-               }
-       }
+       smsc_rx_list_free(sc);
 
-       /* Free TX resources. */
-       for (i = 0; i < SMSC_TX_LIST_CNT; i++) {
-               if (sc->sc_cdata.tx_chain[i].sc_mbuf != NULL) {
-                       m_freem(sc->sc_cdata.tx_chain[i].sc_mbuf);
-                       sc->sc_cdata.tx_chain[i].sc_mbuf = NULL;
-               }
-               if (sc->sc_cdata.tx_chain[i].sc_xfer != NULL) {
-                       usbd_destroy_xfer(sc->sc_cdata.tx_chain[i].sc_xfer);
-                       sc->sc_cdata.tx_chain[i].sc_xfer = NULL;
-               }
-       }
+       smsc_tx_list_free(sc);
+
        /* Close pipes */
        if (sc->sc_ep[SMSC_ENDPT_RX] != NULL) {
                err = usbd_close_pipe(sc->sc_ep[SMSC_ENDPT_RX]);
@@ -756,6 +770,13 @@
                }
                sc->sc_ep[SMSC_ENDPT_INTR] = NULL;
        }
+
+       ifp->if_timer = 0;
+       ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
+
+       if (disable) {
+               /* drain */
+       }
 }
 
 int
@@ -787,7 +808,7 @@
        usbd_delay_ms(sc->sc_udev, 40);
 
        /* Set the mac address */
-       struct ifnet *ifp = &sc->sc_ec.ec_if;
+       struct ifnet * const ifp = &sc->sc_ec.ec_if;
        const char *eaddr = CLLADDR(ifp->if_sadl);
        if ((err = smsc_setmacaddress(sc, eaddr)) != 0) {
                smsc_warn_printf(sc, "failed to set the MAC address\n");
@@ -906,68 +927,65 @@
        return err;
 }
 
+static int
+smsc_ifflags_cb(struct ethercom *ec)
+{
+       struct ifnet *ifp = &ec->ec_if;
+       struct smsc_softc *sc = ifp->if_softc;
+       int rc = 0;
+
+       mutex_enter(&sc->sc_lock);
+
+       int change = ifp->if_flags ^ sc->sc_if_flags;
+       sc->sc_if_flags = ifp->if_flags;
+
+       if ((change & ~(IFF_CANTCHANGE | IFF_DEBUG)) != 0) {
+               rc = ENETRESET;
+               goto out;
+       }
+
+       if ((change & IFF_PROMISC) != 0) {
+               if (ifp->if_flags & IFF_PROMISC) {
+                       sc->sc_mac_csr |= SMSC_MAC_CSR_PRMS;
+                       smsc_write_reg(sc, SMSC_MAC_CSR, sc->sc_mac_csr);
+               } else if (!(ifp->if_flags & IFF_PROMISC)) {
+                       sc->sc_mac_csr &= ~SMSC_MAC_CSR_PRMS;
+                       smsc_write_reg(sc, SMSC_MAC_CSR, sc->sc_mac_csr);
+               }
+               smsc_setmulti(sc);
+       }
+
+out:
+       mutex_exit(&sc->sc_lock);
+
+       return rc;
+}
+
+
 int
 smsc_ioctl(struct ifnet *ifp, u_long cmd, void *data)
 {
        struct smsc_softc       *sc = ifp->if_softc;
-       struct ifreq /*const*/  *ifr = data;
+//     struct ifreq /*const*/  *ifr = data;
        int                     s, error = 0;
 
        if (sc->sc_dying)
                return EIO;
 
        s = splnet();
-
-       switch(cmd) {
-       case SIOCSIFFLAGS:



Home | Main Index | Thread Index | Old Index