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