Module Name: src Committed By: skrll Date: Wed Dec 28 07:44:26 UTC 2016
Modified Files: src/sys/dev/usb [nick-nhusb]: if_smsc.c Log Message: More MPification To generate a diff of this commit: cvs rdiff -u -r1.22.2.16 -r1.22.2.17 src/sys/dev/usb/if_smsc.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/usb/if_smsc.c diff -u src/sys/dev/usb/if_smsc.c:1.22.2.16 src/sys/dev/usb/if_smsc.c:1.22.2.17 --- src/sys/dev/usb/if_smsc.c:1.22.2.16 Sun Oct 16 11:18:30 2016 +++ src/sys/dev/usb/if_smsc.c Wed Dec 28 07:44:26 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: if_smsc.c,v 1.22.2.16 2016/10/16 11:18:30 skrll Exp $ */ +/* $NetBSD: if_smsc.c,v 1.22.2.17 2016/12/28 07:44:26 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 $ */ @@ -557,7 +557,6 @@ smsc_init(struct ifnet *ifp) return ret; } - int smsc_init_locked(struct ifnet *ifp) { @@ -581,7 +580,7 @@ smsc_init_locked(struct ifnet *ifp) /* Open RX and TX pipes. */ err = usbd_open_pipe(sc->sc_iface, sc->sc_ed[SMSC_ENDPT_RX], - USBD_EXCLUSIVE_USE, &sc->sc_ep[SMSC_ENDPT_RX]); + USBD_EXCLUSIVE_USE | USBD_MPSAFE, &sc->sc_ep[SMSC_ENDPT_RX]); if (err) { printf("%s: open rx pipe failed: %s\n", device_xname(sc->sc_dev), usbd_errstr(err)); @@ -589,7 +588,7 @@ smsc_init_locked(struct ifnet *ifp) } err = usbd_open_pipe(sc->sc_iface, sc->sc_ed[SMSC_ENDPT_TX], - USBD_EXCLUSIVE_USE, &sc->sc_ep[SMSC_ENDPT_TX]); + USBD_EXCLUSIVE_USE | USBD_MPSAFE, &sc->sc_ep[SMSC_ENDPT_TX]); if (err) { printf("%s: open tx pipe failed: %s\n", device_xname(sc->sc_dev), usbd_errstr(err)); @@ -616,6 +615,8 @@ smsc_init_locked(struct ifnet *ifp) usbd_transfer(c->sc_xfer); } + sc->sc_stopping = false; + /* Indicate we are up and running. */ ifp->if_flags |= IFF_RUNNING; ifp->if_flags &= ~IFF_OACTIVE; @@ -641,7 +642,8 @@ smsc_start(struct ifnet *ifp) KASSERT(ifp->if_extflags & IFEF_START_MPSAFE); mutex_enter(&sc->sc_txlock); - smsc_start_locked(ifp); + if (!sc->sc_stopping) + smsc_start_locked(ifp); mutex_exit(&sc->sc_txlock); } @@ -651,6 +653,8 @@ smsc_start_locked(struct ifnet *ifp) struct smsc_softc * const sc = ifp->if_softc; struct mbuf *m_head = NULL; + KASSERT(mutex_owned(&sc->sc_txlock)); + /* Don't send anything if there is no link or controller is busy. */ if ((sc->sc_flags & SMSC_FLAG_LINK) == 0) { return; @@ -710,6 +714,13 @@ smsc_stop_locked(struct ifnet *ifp, int // smsc_reset(sc); + KASSERT(mutex_owned(&sc->sc_lock)); + mutex_enter(&sc->sc_rxlock); + mutex_enter(&sc->sc_txlock); + sc->sc_stopping = true; + mutex_exit(&sc->sc_txlock); + mutex_exit(&sc->sc_rxlock); + callout_stop(&sc->sc_stat_ch); /* Stop transfers. */ @@ -1012,6 +1023,7 @@ smsc_attach(device_t parent, device_t se sc->sc_dev = self; sc->sc_udev = dev; + sc->sc_stopping = false; aprint_naive("\n"); aprint_normal("\n"); @@ -1285,17 +1297,24 @@ smsc_rxeof(struct usbd_xfer *xfer, void uint32_t rxhdr; uint16_t pktlen; struct mbuf *m; - int s; - if (sc->sc_dying) + mutex_enter(&sc->sc_rxlock); + + if (sc->sc_dying) { + mutex_exit(&sc->sc_rxlock); return; + } - if (!(ifp->if_flags & IFF_RUNNING)) + if (!(ifp->if_flags & IFF_RUNNING)) { + mutex_exit(&sc->sc_rxlock); return; + } if (status != USBD_NORMAL_COMPLETION) { - if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) + if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) { + mutex_exit(&sc->sc_rxlock); return; + } if (usbd_ratecheck(&sc->sc_rx_notice)) { printf("%s: usb errors on rx: %s\n", device_xname(sc->sc_dev), usbd_errstr(status)); @@ -1434,14 +1453,18 @@ smsc_rxeof(struct usbd_xfer *xfer, void buf += pktlen; total_len -= pktlen; + mutex_exit(&sc->sc_rxlock); + /* push the packet up */ - s = splnet(); bpf_mtap(ifp, m); if_percpuq_enqueue(sc->sc_ipq, m); - splx(s); + + mutex_enter(&sc->sc_rxlock); } done: + mutex_exit(&sc->sc_rxlock); + /* Setup new transfer. */ usbd_setup_xfer(xfer, c, c->sc_buf, sc->sc_bufsz, USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, smsc_rxeof); @@ -1457,17 +1480,24 @@ smsc_txeof(struct usbd_xfer *xfer, void struct smsc_softc *sc = c->sc_sc; struct ifnet *ifp = &sc->sc_ec.ec_if; - if (sc->sc_dying) + mutex_enter(&sc->sc_txlock); + + if (sc->sc_dying) { + mutex_exit(&sc->sc_txlock); return; + } - int s = splnet(); + if (sc->sc_stopping) { + mutex_exit(&sc->sc_txlock); + return; + } ifp->if_timer = 0; ifp->if_flags &= ~IFF_OACTIVE; if (status != USBD_NORMAL_COMPLETION) { if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) { - splx(s); + mutex_exit(&sc->sc_txlock); return; } ifp->if_oerrors++; @@ -1475,7 +1505,7 @@ smsc_txeof(struct usbd_xfer *xfer, void usbd_errstr(status)); if (status == USBD_STALLED) usbd_clear_endpoint_stall_async(sc->sc_ep[SMSC_ENDPT_TX]); - splx(s); + mutex_exit(&sc->sc_txlock); return; } ifp->if_opackets++; @@ -1484,9 +1514,9 @@ smsc_txeof(struct usbd_xfer *xfer, void c->sc_mbuf = NULL; if (IFQ_IS_EMPTY(&ifp->if_snd) == 0) - smsc_start(ifp); + smsc_start_locked(ifp); - splx(s); + mutex_exit(&sc->sc_txlock); } int