From bff05058eeb94caf9acd31e32f69e71ac7206618 Mon Sep 17 00:00:00 2001 From: kettenis Date: Tue, 3 Aug 2010 18:26:25 +0000 Subject: [PATCH] Bring the suspend/resume code of all the Intel wireless drivers in line with iwn(4) again. ok deraadt@ --- sys/dev/pci/if_ipw.c | 23 ++++++++++++++++++++--- sys/dev/pci/if_ipwvar.h | 5 +++-- sys/dev/pci/if_iwi.c | 20 +++++++++++++++++--- sys/dev/pci/if_iwivar.h | 5 +++-- sys/dev/pci/if_wpi.c | 9 +++------ 5 files changed, 46 insertions(+), 16 deletions(-) diff --git a/sys/dev/pci/if_ipw.c b/sys/dev/pci/if_ipw.c index d7f90e163bc..2bd64440f5d 100644 --- a/sys/dev/pci/if_ipw.c +++ b/sys/dev/pci/if_ipw.c @@ -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 */ diff --git a/sys/dev/pci/if_ipwvar.h b/sys/dev/pci/if_ipwvar.h index 77029a5c904..5c5d83b9abf 100644 --- a/sys/dev/pci/if_ipwvar.h +++ b/sys/dev/pci/if_ipwvar.h @@ -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; diff --git a/sys/dev/pci/if_iwi.c b/sys/dev/pci/if_iwi.c index 8c307a6dff4..febc0c50180 100644 --- a/sys/dev/pci/if_iwi.c +++ b/sys/dev/pci/if_iwi.c @@ -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", diff --git a/sys/dev/pci/if_iwivar.h b/sys/dev/pci/if_iwivar.h index b0c51fae01d..ecd7791dfb5 100644 --- a/sys/dev/pci/if_iwivar.h +++ b/sys/dev/pci/if_iwivar.h @@ -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; diff --git a/sys/dev/pci/if_wpi.c b/sys/dev/pci/if_wpi.c index 46cb8514d1c..ee754fda4cf 100644 --- a/sys/dev/pci/if_wpi.c +++ b/sys/dev/pci/if_wpi.c @@ -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); -- 2.20.1