Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/pci PR/55975: Riccardo Mottola: Don't try to lock a ...



details:   https://anonhg.NetBSD.org/src/rev/68159dfc886a
branches:  trunk
changeset: 959225:68159dfc886a
user:      christos <christos%NetBSD.org@localhost>
date:      Fri Feb 05 16:06:24 2021 +0000

description:
PR/55975: Riccardo Mottola: Don't try to lock a mutex from an interrupt context.

diffstat:

 sys/dev/pci/if_wpi.c |  52 ++++++++++++++++++++++++++++++++++++++--------------
 1 files changed, 38 insertions(+), 14 deletions(-)

diffs (129 lines):

diff -r a91f4ee44c77 -r 68159dfc886a sys/dev/pci/if_wpi.c
--- a/sys/dev/pci/if_wpi.c      Fri Feb 05 08:07:14 2021 +0000
+++ b/sys/dev/pci/if_wpi.c      Fri Feb 05 16:06:24 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_wpi.c,v 1.89 2020/03/20 17:19:25 sevan Exp $        */
+/*     $NetBSD: if_wpi.c,v 1.90 2021/02/05 16:06:24 christos Exp $     */
 
 /*-
  * Copyright (c) 2006, 2007
@@ -18,7 +18,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_wpi.c,v 1.89 2020/03/20 17:19:25 sevan Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_wpi.c,v 1.90 2021/02/05 16:06:24 christos Exp $");
 
 /*
  * Driver for Intel PRO/Wireless 3945ABG 802.11 network adapters.
@@ -158,6 +158,8 @@
 static int     wpi_getrfkill(struct wpi_softc *);
 static void    wpi_sysctlattach(struct wpi_softc *);
 static void    wpi_rsw_thread(void *);
+static void    wpi_rsw_suspend(struct wpi_softc *);
+static void    wpi_stop_intr(struct ifnet *, int);
 
 #ifdef WPI_DEBUG
 #define DPRINTF(x)     do { if (wpi_debug > 0) printf x; } while (0)
@@ -1769,7 +1771,7 @@
                                    "Radio transmitter is off\n");
                                /* turn the interface down */
                                ifp->if_flags &= ~IFF_UP;
-                               wpi_stop(ifp, 1);
+                               wpi_stop_intr(ifp, 1);
                                splx(s);
                                return; /* no further processing */
                        }
@@ -1853,7 +1855,7 @@
                /* SYSTEM FAILURE, SYSTEM FAILURE */
                aprint_error_dev(sc->sc_dev, "fatal firmware error\n");
                ifp->if_flags &= ~IFF_UP;
-               wpi_stop(ifp, 1);
+               wpi_stop_intr(ifp, 1);
                return;
        }
 
@@ -2203,7 +2205,7 @@
                if (--sc->sc_tx_timer == 0) {
                        aprint_error_dev(sc->sc_dev, "device timeout\n");
                        ifp->if_flags &= ~IFF_UP;
-                       wpi_stop(ifp, 1);
+                       wpi_stop_intr(ifp, 1);
                        if_statinc(ifp, if_oerrors);
                        return;
                }
@@ -3200,7 +3202,7 @@
        uint32_t tmp;
        int qid, ntries, error;
 
-       wpi_stop(ifp,1);
+       wpi_stop(ifp, 1);
        (void)wpi_reset(sc);
 
        wpi_mem_lock(sc);
@@ -3311,7 +3313,7 @@
 }
 
 static void
-wpi_stop(struct ifnet *ifp, int disable)
+wpi_stop1(struct ifnet *ifp, int disable, bool fromintr)
 {
        struct wpi_softc *sc = ifp->if_softc;
        struct ieee80211com *ic = &sc->sc_ic;
@@ -3323,13 +3325,11 @@
 
        ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
 
-       /* suspend rfkill test thread */
-       mutex_enter(&sc->sc_rsw_mtx);
-       sc->sc_rsw_suspend = true;
-       cv_broadcast(&sc->sc_rsw_cv);
-       while (!sc->sc_rsw_suspended)
-               cv_wait(&sc->sc_rsw_cv, &sc->sc_rsw_mtx);
-       mutex_exit(&sc->sc_rsw_mtx);
+       if (fromintr) {
+               sc->sc_rsw_suspend = true; // XXX: without mutex or wait
+       } else {
+               wpi_rsw_suspend(sc);
+       }
 
        /* disable interrupts */
        WPI_WRITE(sc, WPI_MASK, 0);
@@ -3361,6 +3361,18 @@
        WPI_WRITE(sc, WPI_RESET, tmp | WPI_SW_RESET);
 }
 
+static void
+wpi_stop(struct ifnet *ifp, int disable)
+{
+       wpi_stop1(ifp, disable, false);
+}
+
+static void
+wpi_stop_intr(struct ifnet *ifp, int disable)
+{
+       wpi_stop1(ifp, disable, true);
+}
+
 static bool
 wpi_resume(device_t dv, const pmf_qual_t *qual)
 {
@@ -3463,6 +3475,18 @@
 }
 
 static void
+wpi_rsw_suspend(struct wpi_softc *sc)
+{
+       /* suspend rfkill test thread */
+       mutex_enter(&sc->sc_rsw_mtx);
+       sc->sc_rsw_suspend = true;
+       cv_broadcast(&sc->sc_rsw_cv);
+       while (!sc->sc_rsw_suspended)
+               cv_wait(&sc->sc_rsw_cv, &sc->sc_rsw_mtx);
+       mutex_exit(&sc->sc_rsw_mtx);
+}
+
+static void
 wpi_rsw_thread(void *arg)
 {
        struct wpi_softc *sc = (struct wpi_softc *)arg;



Home | Main Index | Thread Index | Old Index