The urtwn(4) driver uses usbd_is_dying() calls in its timeouts.

usbd_is_dying() can't be part of the common rtwn(4) driver code once we
merge code from urtwn(4). So timeouts must move back to the bus-specific
part of the driver.

The common driver code now indicates when timeouts must be scheduled
or cancelled, and provides funtions to be called from timeouts.
The bus-specific parts are now responsible for managing timouts and
calling the common code when a timout fires.

This way, the future USB code will be able to use usbd_is_dying() in
its timeouts, like this:

urtwn_calib_to()
{
        if (usbd_is_dying())
                return;

        rtwn_calib();
}

While the PCI code is quite boring in comparison:

rtwn_calib_to()
{
        rtwn_calib();
}

Tested on
MAC/BB RTL8188CE, RF 6052 1T1R (PCI)

Index: ic/rtwn.c
===================================================================
RCS file: /cvs/src/sys/dev/ic/rtwn.c,v
retrieving revision 1.4
diff -u -p -r1.4 rtwn.c
--- ic/rtwn.c   11 Mar 2016 14:06:37 -0000      1.4
+++ ic/rtwn.c   12 Mar 2016 15:06:32 -0000
@@ -90,8 +90,6 @@ int           rtwn_media_change(struct ifnet *);
 int            rtwn_ra_init(struct rtwn_softc *);
 void           rtwn_tsf_sync_enable(struct rtwn_softc *);
 void           rtwn_set_led(struct rtwn_softc *, int, int);
-void           rtwn_calib_to(void *);
-void           rtwn_next_scan(void *);
 int            rtwn_newstate(struct ieee80211com *, enum ieee80211_state, int);
 void           rtwn_updateedca(struct ieee80211com *);
 int            rtwn_set_key(struct ieee80211com *, struct ieee80211_node *,
@@ -150,9 +148,6 @@ rtwn_attach(struct device *pdev, struct 
 
        sc->sc_pdev = pdev;
 
-       timeout_set(&sc->calib_to, rtwn_calib_to, sc);
-       timeout_set(&sc->scan_to, rtwn_next_scan, sc);
-
        task_set(&sc->init_task, rtwn_init_task, sc);
 
        error = rtwn_read_chipid(sc);
@@ -251,10 +246,8 @@ rtwn_detach(struct rtwn_softc *sc, int f
 
        s = splnet();
 
-       if (timeout_initialized(&sc->scan_to))
-               timeout_del(&sc->scan_to);
-       if (timeout_initialized(&sc->calib_to))
-               timeout_del(&sc->calib_to);
+       sc->sc_ops.cancel_scan(sc->sc_ops.cookie);
+       sc->sc_ops.cancel_calib(sc->sc_ops.cookie);
 
        task_del(systq, &sc->init_task);
 
@@ -678,9 +671,8 @@ rtwn_set_led(struct rtwn_softc *sc, int 
 }
 
 void
-rtwn_calib_to(void *arg)
+rtwn_calib(struct rtwn_softc *sc)
 {
-       struct rtwn_softc *sc = arg;
        struct r92c_fw_cmd_rssi cmd;
 
        if (sc->avg_pwdb != -1) {
@@ -695,15 +687,19 @@ rtwn_calib_to(void *arg)
        /* Do temperature compensation. */
        rtwn_temp_calib(sc);
 
-       timeout_add_sec(&sc->calib_to, 2);
+       sc->sc_ops.next_calib(sc->sc_ops.cookie);
 }
 
 void
-rtwn_next_scan(void *arg)
+rtwn_next_scan(struct rtwn_softc *sc)
 {
-       struct rtwn_softc *sc = arg;
+       struct ieee80211com *ic = &sc->sc_ic;
+       int s;
 
-       sc->sc_ops.next_scan(sc->sc_ops.cookie);
+       s = splnet();
+       if (ic->ic_state == IEEE80211_S_SCAN)
+               ieee80211_next_scan(&ic->ic_if);
+       splx(s);
 }
 
 int
@@ -725,7 +721,7 @@ rtwn_newstate(struct ieee80211com *ic, e
 
        if (ostate == IEEE80211_S_RUN) {
                /* Stop calibration. */
-               timeout_del(&sc->calib_to);
+               sc->sc_ops.cancel_calib(sc->sc_ops.cookie);
 
                /* Turn link LED off. */
                rtwn_set_led(sc, RTWN_LED_LINK, 0);
@@ -781,7 +777,7 @@ rtwn_newstate(struct ieee80211com *ic, e
                rtwn_write_1(sc, R92C_TXPAUSE,
                    rtwn_read_1(sc, R92C_TXPAUSE) | 0x0f);
                rtwn_set_chan(sc, ic->ic_bss->ni_chan, NULL);
-               timeout_add_msec(&sc->scan_to, 200);
+               sc->sc_ops.next_scan(sc->sc_ops.cookie);
                break;
 
        case IEEE80211_S_AUTH:
@@ -859,7 +855,7 @@ rtwn_newstate(struct ieee80211com *ic, e
                sc->thcal_state = 0;
                sc->thcal_lctemp = 0;
                /* Start periodic calibration. */
-               timeout_add_sec(&sc->calib_to, 2);
+               sc->sc_ops.next_calib(sc->sc_ops.cookie);
                break;
        }
        (void)sc->sc_newstate(ic, nstate, arg);
@@ -2556,8 +2552,8 @@ rtwn_stop(struct ifnet *ifp)
        s = splnet();
        ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
 
-       timeout_del(&sc->scan_to);
-       timeout_del(&sc->calib_to);
+       sc->sc_ops.cancel_scan(sc->sc_ops.cookie);
+       sc->sc_ops.cancel_calib(sc->sc_ops.cookie);
 
        task_del(systq, &sc->init_task);
 
Index: ic/rtwnvar.h
===================================================================
RCS file: /cvs/src/sys/dev/ic/rtwnvar.h,v
retrieving revision 1.3
diff -u -p -r1.3 rtwnvar.h
--- ic/rtwnvar.h        11 Mar 2016 14:06:37 -0000      1.3
+++ ic/rtwnvar.h        12 Mar 2016 15:05:06 -0000
@@ -27,13 +27,16 @@ struct rtwn_ops {
        void            (*write_1)(void *, uint16_t, uint8_t);
        void            (*write_2)(void *, uint16_t, uint16_t);
        void            (*write_4)(void *, uint16_t, uint32_t);
-       void            (*next_scan)(void *);
        int             (*tx)(void *, struct mbuf *, struct ieee80211_node *);
        int             (*dma_init)(void *);
        void            (*enable_intr)(void *);
        void            (*disable_intr)(void *);
        void            (*stop)(void *);
        int             (*is_oactive)(void *);
+       void            (*next_calib)(void *);
+       void            (*cancel_calib)(void *);
+       void            (*next_scan)(void *);
+       void            (*cancel_scan)(void *);
 };
 
 struct rtwn_softc {
@@ -44,8 +47,6 @@ struct rtwn_softc {
        struct ieee80211com             sc_ic;
        int                             (*sc_newstate)(struct ieee80211com *,
                                            enum ieee80211_state, int);
-       struct timeout                  scan_to;
-       struct timeout                  calib_to;
        struct task                     init_task;
        int                             ac2idx[EDCA_NUM_AC];
        u_int                           sc_flags;
@@ -81,3 +82,5 @@ int           rtwn_detach(struct rtwn_softc *, in
 int            rtwn_activate(struct rtwn_softc *, int);
 int8_t         rtwn_get_rssi(struct rtwn_softc *, int, void *);
 void           rtwn_update_avgrssi(struct rtwn_softc *, int, int8_t);
+void           rtwn_calib(struct rtwn_softc *);
+void           rtwn_next_scan(struct rtwn_softc *);
Index: pci/if_rtwn.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_rtwn.c,v
retrieving revision 1.18
diff -u -p -r1.18 if_rtwn.c
--- pci/if_rtwn.c       11 Mar 2016 14:06:37 -0000      1.18
+++ pci/if_rtwn.c       12 Mar 2016 15:24:06 -0000
@@ -148,6 +148,9 @@ struct rtwn_pci_softc {
        struct rtwn_tx_ring     tx_ring[RTWN_NTXQUEUES];
        uint32_t                qfullmsk;
 
+       struct timeout          calib_to;
+       struct timeout          scan_to;
+
        /* PCI specific goo. */
        bus_dma_tag_t           sc_dmat;
        pci_chipset_tag_t       sc_pc;
@@ -219,7 +222,6 @@ void                rtwn_pci_write_4(void *, uint16_t,
 uint8_t                rtwn_pci_read_1(void *, uint16_t);
 uint16_t       rtwn_pci_read_2(void *, uint16_t);
 uint32_t       rtwn_pci_read_4(void *, uint16_t);
-void           rtwn_pci_next_scan(void *);
 void           rtwn_rx_frame(struct rtwn_pci_softc *,
                    struct r92c_rx_desc_pci *, struct rtwn_rx_data *, int);
 int            rtwn_tx(void *, struct mbuf *, struct ieee80211_node *);
@@ -232,6 +234,12 @@ int                rtwn_llt_init(struct rtwn_pci_softc
 int            rtwn_dma_init(void *);
 void           rtwn_enable_intr(void *);
 void           rtwn_disable_intr(void *);
+void           rtwn_calib_to(void *);
+void           rtwn_next_calib(void *);
+void           rtwn_cancel_calib(void *);
+void           rtwn_scan_to(void *);
+void           rtwn_pci_next_scan(void *);
+void           rtwn_cancel_scan(void *);
 
 struct cfdriver rtwn_cd = {
        NULL, "rtwn", DV_IFNET
@@ -267,6 +275,9 @@ rtwn_pci_attach(struct device *parent, s
        sc->sc_pc = pa->pa_pc;
        sc->sc_tag = pa->pa_tag;
 
+       timeout_set(&sc->calib_to, rtwn_calib_to, sc);
+       timeout_set(&sc->scan_to, rtwn_scan_to, sc);
+
        pci_set_powerstate(pa->pa_pc, pa->pa_tag, PCI_PMCSR_STATE_D0);
 
        /* Map control/status registers. */
@@ -329,13 +340,17 @@ rtwn_pci_attach(struct device *parent, s
        sc->sc_sc.sc_ops.read_1 = rtwn_pci_read_1;
        sc->sc_sc.sc_ops.read_2 = rtwn_pci_read_2;
        sc->sc_sc.sc_ops.read_4 = rtwn_pci_read_4;
-       sc->sc_sc.sc_ops.next_scan = rtwn_pci_next_scan;
        sc->sc_sc.sc_ops.tx = rtwn_tx;
        sc->sc_sc.sc_ops.dma_init = rtwn_dma_init;
        sc->sc_sc.sc_ops.enable_intr = rtwn_enable_intr;
        sc->sc_sc.sc_ops.disable_intr = rtwn_disable_intr;
        sc->sc_sc.sc_ops.stop = rtwn_pci_stop;
        sc->sc_sc.sc_ops.is_oactive = rtwn_is_oactive;
+       sc->sc_sc.sc_ops.next_calib = rtwn_next_calib;
+       sc->sc_sc.sc_ops.cancel_calib = rtwn_cancel_calib;
+       sc->sc_sc.sc_ops.next_scan = rtwn_pci_next_scan;
+       sc->sc_sc.sc_ops.cancel_scan = rtwn_cancel_scan;
+
        error = rtwn_attach(&sc->sc_dev, &sc->sc_sc);
        if (error != 0) {
                rtwn_free_rx_list(sc);
@@ -366,9 +381,15 @@ rtwn_pci_detach(struct device *self, int
        struct rtwn_pci_softc *sc = (struct rtwn_pci_softc *)self;
        int s, i;
 
+       s = splnet();
+
+       if (timeout_initialized(&sc->calib_to))
+               timeout_del(&sc->calib_to);
+       if (timeout_initialized(&sc->scan_to))
+               timeout_del(&sc->scan_to);
+
        rtwn_detach(&sc->sc_sc, flags);
 
-       s = splnet();
        /* Free Tx/Rx buffers. */
        for (i = 0; i < RTWN_NTXQUEUES; i++)
                rtwn_free_tx_list(sc, i);
@@ -723,19 +744,6 @@ rtwn_pci_read_4(void *cookie, uint16_t a
 }
 
 void
-rtwn_pci_next_scan(void *arg)
-{
-       struct rtwn_pci_softc *sc = arg;
-       struct ieee80211com *ic = &sc->sc_sc.sc_ic;
-       int s;
-
-       s = splnet();
-       if (ic->ic_state == IEEE80211_S_SCAN)
-               ieee80211_next_scan(&ic->ic_if);
-       splx(s);
-}
-
-void
 rtwn_rx_frame(struct rtwn_pci_softc *sc, struct r92c_rx_desc_pci *rx_desc,
     struct rtwn_rx_data *rx_data, int desc_idx)
 {
@@ -1321,4 +1329,54 @@ rtwn_disable_intr(void *cookie)
        /* Disable interrupts. */
        rtwn_pci_write_4(sc, R92C_HISR, 0x00000000);
        rtwn_pci_write_4(sc, R92C_HIMR, 0x00000000);
+}
+
+void
+rtwn_calib_to(void *arg)
+{
+       struct rtwn_pci_softc *sc = arg;
+
+       rtwn_calib(&sc->sc_sc);
+}
+
+void
+rtwn_next_calib(void *cookie)
+{
+       struct rtwn_pci_softc *sc = cookie;
+
+       timeout_add_sec(&sc->calib_to, 2);
+}
+
+void
+rtwn_cancel_calib(void *cookie)
+{
+       struct rtwn_pci_softc *sc = cookie;
+
+       if (timeout_initialized(&sc->calib_to))
+               timeout_del(&sc->calib_to);
+}
+
+void
+rtwn_scan_to(void *arg)
+{
+       struct rtwn_pci_softc *sc = arg;
+
+       rtwn_next_scan(&sc->sc_sc);
+}
+
+void
+rtwn_pci_next_scan(void *cookie)
+{
+       struct rtwn_pci_softc *sc = cookie;
+
+       timeout_add_msec(&sc->scan_to, 200);
+}
+
+void
+rtwn_cancel_scan(void *cookie)
+{
+       struct rtwn_pci_softc *sc = cookie;
+
+       if (timeout_initialized(&sc->scan_to))
+               timeout_del(&sc->scan_to);
 }

Reply via email to