Bring the suspend/resume code of all the Intel wireless drivers in line with
authorkettenis <kettenis@openbsd.org>
Tue, 3 Aug 2010 18:26:25 +0000 (18:26 +0000)
committerkettenis <kettenis@openbsd.org>
Tue, 3 Aug 2010 18:26:25 +0000 (18:26 +0000)
iwn(4) again.

ok deraadt@

sys/dev/pci/if_ipw.c
sys/dev/pci/if_ipwvar.h
sys/dev/pci/if_iwi.c
sys/dev/pci/if_iwivar.h
sys/dev/pci/if_wpi.c

index d7f90e1..2bd6444 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: if_ipw.c,v 1.87 2010/07/28 21:21:38 deraadt Exp $     */
+/*     $OpenBSD: if_ipw.c,v 1.88 2010/08/03 18:26:25 kettenis Exp $    */
 
 /*-
  * Copyright (c) 2004-2008
@@ -326,6 +326,7 @@ ipw_power(int why, void *arg)
        struct ipw_softc *sc = arg;
        struct ifnet *ifp = &sc->sc_ic.ic_if;
        pcireg_t data;
+       int s;
 
        if (why != PWR_RESUME) {
                ipw_stop(ifp, 0);
@@ -337,8 +338,14 @@ ipw_power(int why, void *arg)
        data &= ~0x0000ff00;
        pci_conf_write(sc->sc_pct, sc->sc_pcitag, 0x40, data);
 
+       s = splnet();
+       sc->sc_flags |= IPW_FLAG_BUSY;
+
        if (ifp->if_flags & IFF_UP)
                ipw_init(ifp);
+
+       sc->sc_flags &= ~IPW_FLAG_BUSY;
+       splx(s);
 }
 
 int
@@ -1388,6 +1395,15 @@ ipw_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
        int s, error = 0;
 
        s = splnet();
+       /*
+        * Prevent processes from entering this function while another
+        * process is tsleep'ing in it.
+        */
+       if (sc->sc_flags & IPW_FLAG_BUSY) {
+               splx(s);
+               return EBUSY;
+       }
+       sc->sc_flags |= IPW_FLAG_BUSY;
 
        switch (cmd) {
        case SIOCSIFADDR:
@@ -1441,6 +1457,7 @@ ipw_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
                error = 0;
        }
 
+       sc->sc_flags &= ~IPW_FLAG_BUSY;
        splx(s);
        return error;
 }
@@ -1504,7 +1521,7 @@ ipw_stop_master(struct ipw_softc *sc)
        tmp = CSR_READ_4(sc, IPW_CSR_RST);
        CSR_WRITE_4(sc, IPW_CSR_RST, tmp | IPW_RST_PRINCETON_RESET);
 
-       sc->flags &= ~IPW_FLAG_FW_INITED;
+       sc->sc_flags &= ~IPW_FLAG_FW_INITED;
 }
 
 int
@@ -2025,7 +2042,7 @@ ipw_init(struct ifnet *ifp)
                printf("%s: could not load firmware\n", sc->sc_dev.dv_xname);
                goto fail2;
        }
-       sc->flags |= IPW_FLAG_FW_INITED;
+       sc->sc_flags |= IPW_FLAG_FW_INITED;
        free(fw.data, M_DEVBUF);
 
        /* retrieve information tables base addresses */
index 77029a5..5c5d83b 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: if_ipwvar.h,v 1.19 2010/07/28 21:21:38 deraadt Exp $  */
+/*     $OpenBSD: if_ipwvar.h,v 1.20 2010/08/03 18:26:25 kettenis Exp $ */
 
 /*-
  * Copyright (c) 2004-2006
@@ -81,8 +81,9 @@ struct ipw_softc {
        int                             (*sc_newstate)(struct ieee80211com *,
                                            enum ieee80211_state, int);
 
-       uint32_t                        flags;
+       uint32_t                        sc_flags;
 #define IPW_FLAG_FW_INITED     (1 << 0)
+#define IPW_FLAG_BUSY          (1 << 1)
 
        bus_space_tag_t                 sc_st;
        bus_space_handle_t              sc_sh;
index 8c307a6..febc0c5 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: if_iwi.c,v 1.104 2010/07/28 21:21:38 deraadt Exp $    */
+/*     $OpenBSD: if_iwi.c,v 1.105 2010/08/03 18:26:25 kettenis Exp $   */
 
 /*-
  * Copyright (c) 2004-2008
@@ -381,8 +381,12 @@ iwi_power(int why, void *arg)
        pci_conf_write(sc->sc_pct, sc->sc_pcitag, 0x40, data);
 
        s = splnet();
+       sc->sc_flags |= IWI_FLAG_BUSY;
+
        if (ifp->if_flags & IFF_UP)
                iwi_init(ifp);
+
+       sc->sc_flags &= ~IWI_FLAG_BUSY;
        splx(s);
 }
 
@@ -1478,6 +1482,15 @@ iwi_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
        int s, error = 0;
 
        s = splnet();
+       /*
+        * Prevent processes from entering this function while another
+        * process is tsleep'ing in it.
+        */
+       if (sc->sc_flags & IWI_FLAG_BUSY) {
+               splx(s);
+               return EBUSY;
+       }
+       sc->sc_flags |= IWI_FLAG_BUSY;
 
        switch (cmd) {
        case SIOCSIFADDR:
@@ -1531,6 +1544,7 @@ iwi_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
                error = 0;
        }
 
+       sc->sc_flags &= ~IWI_FLAG_BUSY;
        splx(s);
        return error;
 }
@@ -1558,7 +1572,7 @@ iwi_stop_master(struct iwi_softc *sc)
        tmp = CSR_READ_4(sc, IWI_CSR_RST);
        CSR_WRITE_4(sc, IWI_CSR_RST, tmp | IWI_RST_PRINCETON_RESET);
 
-       sc->flags &= ~IWI_FLAG_FW_INITED;
+       sc->sc_flags &= ~IWI_FLAG_FW_INITED;
 }
 
 int
@@ -2300,7 +2314,7 @@ iwi_init(struct ifnet *ifp)
        }
 
        free(data, M_DEVBUF);
-       sc->flags |= IWI_FLAG_FW_INITED;
+       sc->sc_flags |= IWI_FLAG_FW_INITED;
 
        if ((error = iwi_config(sc)) != 0) {
                printf("%s: device configuration failed\n",
index b0c51fa..ecd7791 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: if_iwivar.h,v 1.21 2010/07/28 21:21:38 deraadt Exp $  */
+/*     $OpenBSD: if_iwivar.h,v 1.22 2010/08/03 18:26:25 kettenis Exp $ */
 
 /*-
  * Copyright (c) 2004-2006
@@ -91,8 +91,9 @@ struct iwi_softc {
        int                     (*sc_newstate)(struct ieee80211com *,
                                    enum ieee80211_state, int);
 
-       uint32_t                flags;
+       uint32_t                sc_flags;
 #define IWI_FLAG_FW_INITED     (1 << 0)
+#define IWI_FLAG_BUSY          (1 << 1)
 
        bus_dma_tag_t           sc_dmat;
 
index 46cb851..ee754fd 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: if_wpi.c,v 1.103 2010/07/28 21:21:38 deraadt Exp $    */
+/*     $OpenBSD: if_wpi.c,v 1.104 2010/08/03 18:26:25 kettenis Exp $   */
 
 /*-
  * Copyright (c) 2006-2008
@@ -438,11 +438,8 @@ wpi_power(int why, void *arg)
        s = splnet();
        sc->sc_flags |= WPI_FLAG_BUSY;
 
-       if (ifp->if_flags & IFF_UP) {
-               ifp->if_init(ifp);
-               if (ifp->if_flags & IFF_RUNNING)
-                       ifp->if_start(ifp);
-       }
+       if (ifp->if_flags & IFF_UP)
+               wpi_init(ifp);
 
        sc->sc_flags &= ~WPI_FLAG_BUSY;
        splx(s);