Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/usb more (and less) locking fixes



details:   https://anonhg.NetBSD.org/src/rev/721b569d80a1
branches:  trunk
changeset: 784170:721b569d80a1
user:      christos <christos%NetBSD.org@localhost>
date:      Sun Jan 20 20:21:57 2013 +0000

description:
more (and less) locking fixes

diffstat:

 sys/dev/usb/if_urtwn.c    |  226 ++++++++++++++++++++++++++++++++++-----------
 sys/dev/usb/if_urtwnreg.h |    3 +-
 sys/dev/usb/if_urtwnvar.h |    9 +-
 3 files changed, 178 insertions(+), 60 deletions(-)

diffs (truncated from 777 to 300 lines):

diff -r a8597f79881d -r 721b569d80a1 sys/dev/usb/if_urtwn.c
--- a/sys/dev/usb/if_urtwn.c    Sun Jan 20 18:45:56 2013 +0000
+++ b/sys/dev/usb/if_urtwn.c    Sun Jan 20 20:21:57 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_urtwn.c,v 1.11 2013/01/18 13:45:51 jmcneill Exp $   */
+/*     $NetBSD: if_urtwn.c,v 1.12 2013/01/20 20:21:57 christos Exp $   */
 /*     $OpenBSD: if_urtwn.c,v 1.20 2011/11/26 06:39:33 ckuethe Exp $   */
 
 /*-
@@ -22,7 +22,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_urtwn.c,v 1.11 2013/01/18 13:45:51 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_urtwn.c,v 1.12 2013/01/20 20:21:57 christos Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -74,6 +74,12 @@
 #include <dev/usb/if_urtwnvar.h>
 #include <dev/usb/if_urtwn_data.h>
 
+/*
+ * The sc_write_mtx locking is to prevent sequences of writes from
+ * being intermingled with each other.  I don't know if this is really
+ * needed.  I have added it just to be on the safe side.
+ */
+
 #ifdef URTWN_DEBUG
 #define        DBG_INIT        __BIT(0)
 #define        DBG_FN          __BIT(1)
@@ -168,17 +174,31 @@
 static void    urtwn_wait_async(struct urtwn_softc *);
 static int     urtwn_write_region_1(struct urtwn_softc *, uint16_t, uint8_t *,
                    int);
+static void    urtwn_write_1(struct urtwn_softc *, uint16_t, uint8_t);
+static void    urtwn_write_2(struct urtwn_softc *, uint16_t, uint16_t);
+static void    urtwn_write_4(struct urtwn_softc *, uint16_t, uint32_t);
+static int     urtwn_write_region(struct urtwn_softc *, uint16_t, uint8_t *,
+                   int);
 static int     urtwn_read_region_1(struct urtwn_softc *, uint16_t, uint8_t *,
                    int);
+static uint8_t urtwn_read_1(struct urtwn_softc *, uint16_t);
+static uint16_t        urtwn_read_2(struct urtwn_softc *, uint16_t);
+static uint32_t        urtwn_read_4(struct urtwn_softc *, uint16_t);
 static int     urtwn_fw_cmd(struct urtwn_softc *, uint8_t, const void *, int);
+static void    urtwn_rf_write(struct urtwn_softc *, int, uint8_t, uint32_t);
 static uint32_t        urtwn_rf_read(struct urtwn_softc *, int, uint8_t);
 static int     urtwn_llt_write(struct urtwn_softc *, uint32_t, uint32_t);
 static uint8_t urtwn_efuse_read_1(struct urtwn_softc *, uint16_t);
 static void    urtwn_efuse_read(struct urtwn_softc *);
 static int     urtwn_read_chipid(struct urtwn_softc *);
+#ifdef URTWN_DEBUG
+static void    urtwn_dump_rom(struct urtwn_softc *, struct r92c_rom *);
+#endif
 static void    urtwn_read_rom(struct urtwn_softc *);
 static int     urtwn_media_change(struct ifnet *);
 static int     urtwn_ra_init(struct urtwn_softc *);
+static int     urtwn_get_nettype(struct urtwn_softc *);
+static void    urtwn_set_nettype0_msr(struct urtwn_softc *, uint8_t);
 static void    urtwn_tsf_sync_enable(struct urtwn_softc *);
 static void    urtwn_set_led(struct urtwn_softc *, int, int);
 static void    urtwn_calib_to(void *);
@@ -195,7 +215,7 @@
 static void    urtwn_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
 static void    urtwn_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
 static int     urtwn_tx(struct urtwn_softc *, struct mbuf *,
-                   struct ieee80211_node *);
+                   struct ieee80211_node *, struct urtwn_tx_data *);
 static void    urtwn_start(struct ifnet *);
 static void    urtwn_watchdog(struct ifnet *);
 static int     urtwn_ioctl(struct ifnet *, u_long, void *);
@@ -254,13 +274,16 @@
        aprint_naive("\n");
        aprint_normal("\n");
 
+       DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__));
+
        devinfop = usbd_devinfo_alloc(sc->sc_udev, 0);
        aprint_normal_dev(self, "%s\n", devinfop);
        usbd_devinfo_free(devinfop);
 
        mutex_init(&sc->sc_task_mtx, MUTEX_DEFAULT, IPL_NET);
-       mutex_init(&sc->sc_tx_mtx, MUTEX_DEFAULT, IPL_NET);
+       mutex_init(&sc->sc_tx_mtx, MUTEX_DEFAULT, IPL_NONE);
        mutex_init(&sc->sc_fwcmd_mtx, MUTEX_DEFAULT, IPL_NONE);
+       mutex_init(&sc->sc_write_mtx, MUTEX_DEFAULT, IPL_NONE);
 
        usb_init_task(&sc->sc_task, urtwn_task, sc);
 
@@ -412,10 +435,6 @@
                ieee80211_ifdetach(&sc->sc_ic);
                if_detach(ifp);
 
-               /* Free Tx/Rx buffers. */
-               urtwn_free_tx_list(sc);
-               urtwn_free_rx_list(sc);
-       
                /* Abort and close Tx/Rx pipes. */
                urtwn_close_pipes(sc);
        }
@@ -426,6 +445,8 @@
 
        callout_destroy(&sc->sc_scan_to);
        callout_destroy(&sc->sc_calib_to);
+
+       mutex_destroy(&sc->sc_write_mtx);
        mutex_destroy(&sc->sc_fwcmd_mtx);
        mutex_destroy(&sc->sc_tx_mtx);
        mutex_destroy(&sc->sc_task_mtx);
@@ -483,7 +504,8 @@
        error = usbd_open_pipe(sc->sc_iface, 0x81, USBD_EXCLUSIVE_USE,
            &sc->rx_pipe);
        if (error != 0) {
-               aprint_error_dev(sc->sc_dev, "could not open Rx bulk pipe\n");
+               aprint_error_dev(sc->sc_dev, "could not open Rx bulk pipe"
+                   ": %d\n", error);
                goto fail;
        }
 
@@ -493,7 +515,8 @@
                    USBD_EXCLUSIVE_USE, &sc->tx_pipe[i]);
                if (error != 0) {
                        aprint_error_dev(sc->sc_dev,
-                           "could not open Tx bulk pipe 0x%02x\n", epaddr[i]);
+                           "could not open Tx bulk pipe 0x%02x: %d\n",
+                           epaddr[i], error);
                        goto fail;
                }
        }
@@ -591,6 +614,7 @@
 
        DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__));
 
+       mutex_enter(&sc->sc_tx_mtx);
        TAILQ_INIT(&sc->tx_free_list);
        for (i = 0; i < URTWN_TX_LIST_COUNT; i++) {
                data = &sc->tx_data[i];
@@ -616,10 +640,12 @@
                /* Append this Tx buffer to our free list. */
                TAILQ_INSERT_TAIL(&sc->tx_free_list, data, next);
        }
+       mutex_exit(&sc->sc_tx_mtx);
        return (0);
 
  fail:
        urtwn_free_tx_list(sc);
+       mutex_exit(&sc->sc_tx_mtx);
        return (error);
 }
 
@@ -717,6 +743,8 @@
        usb_device_request_t req;
        usbd_status error;
 
+       KASSERT(mutex_owned(&sc->sc_write_mtx));
+
        req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
        req.bRequest = R92C_REQ_REGS;
        USETW(req.wValue, addr);
@@ -852,6 +880,8 @@
        DPRINTFN(DBG_REG, ("%s: %s: id=%d, buf=%p, len=%d\n",
            device_xname(sc->sc_dev), __func__, id, buf, len));
 
+       KASSERT(mutex_owned(&sc->sc_write_mtx));
+
        mutex_enter(&sc->sc_fwcmd_mtx);
        fwcur = sc->fwcur;
        sc->fwcur = (sc->fwcur + 1) % R92C_H2C_NBOX;
@@ -932,6 +962,8 @@
 {
        int ntries;
 
+       KASSERT(mutex_owned(&sc->sc_write_mtx));
+
        urtwn_write_4(sc, R92C_LLT_INIT,
            SM(R92C_LLT_INIT_OP, R92C_LLT_INIT_OP_WRITE) |
            SM(R92C_LLT_INIT_ADDR, addr) |
@@ -954,6 +986,8 @@
        uint32_t reg;
        int ntries;
 
+       KASSERT(mutex_owned(&sc->sc_write_mtx));
+
        reg = urtwn_read_4(sc, R92C_EFUSE_CTRL);
        reg = RW(reg, R92C_EFUSE_CTRL_ADDR, addr);
        reg &= ~R92C_EFUSE_CTRL_VALID;
@@ -984,6 +1018,8 @@
 
        DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__));
 
+       KASSERT(mutex_owned(&sc->sc_write_mtx));
+
        reg = urtwn_read_2(sc, R92C_SYS_ISO_CTRL);
        if (!(reg & R92C_SYS_ISO_CTRL_PWC_EV12V)) {
                urtwn_write_2(sc, R92C_SYS_ISO_CTRL,
@@ -1152,6 +1188,8 @@
 
        DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__));
 
+       mutex_enter(&sc->sc_write_mtx);
+
        /* Read full ROM image. */
        urtwn_efuse_read(sc);
 #ifdef URTWN_DEBUG
@@ -1170,6 +1208,8 @@
            sc->board_type, sc->regulatory));
 
        IEEE80211_ADDR_COPY(ic->ic_myaddr, rom->macaddr);
+
+       mutex_exit(&sc->sc_write_mtx);
 }
 
 static int
@@ -1212,6 +1252,8 @@
 
        DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__));
 
+       KASSERT(mutex_owned(&sc->sc_write_mtx));
+
        /* Get normal and basic rates mask. */
        rates = basicrates = 0;
        maxrate = maxbasicrate = 0;
@@ -1326,6 +1368,8 @@
        DPRINTFN(DBG_FN, ("%s: %s: type=%d\n", device_xname(sc->sc_dev),
            __func__, type));
 
+       KASSERT(mutex_owned(&sc->sc_write_mtx));
+
        reg = urtwn_read_1(sc, R92C_CR + 2) & 0x0c;
        urtwn_write_1(sc, R92C_CR + 2, reg | type);
 }
@@ -1338,6 +1382,8 @@
 
        DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__));
 
+       KASSERT(mutex_owned(&sc->sc_write_mtx));
+
        /* Enable TSF synchronization. */
        urtwn_write_1(sc, R92C_BCN_CTRL,
            urtwn_read_1(sc, R92C_BCN_CTRL) & ~R92C_BCN_CTRL_DIS_TSF_UDT0);
@@ -1366,6 +1412,8 @@
        DPRINTFN(DBG_FN, ("%s: %s: led=%d, on=%d\n", device_xname(sc->sc_dev),
            __func__, led, on));
 
+       KASSERT(mutex_owned(&sc->sc_write_mtx));
+
        if (led == URTWN_LED_LINK) {
                reg = urtwn_read_1(sc, R92C_LEDCFG0) & 0x70;
                if (!on) {
@@ -1401,6 +1449,7 @@
        if (sc->sc_ic.ic_state != IEEE80211_S_RUN)
                goto restart_timer;
 
+       mutex_enter(&sc->sc_write_mtx);
        if (sc->avg_pwdb != -1) {
                /* Indicate Rx signal strength to FW for rate adaptation. */
                memset(&cmd, 0, sizeof(cmd));
@@ -1413,6 +1462,7 @@
 
        /* Do temperature compensation. */
        urtwn_temp_calib(sc);
+       mutex_exit(&sc->sc_write_mtx);
 
  restart_timer:
        if (!sc->sc_dying) {
@@ -1473,6 +1523,10 @@
            ieee80211_state_name[nstate], nstate));
 
        s = splnet();
+       mutex_enter(&sc->sc_write_mtx);
+
+       callout_stop(&sc->sc_scan_to);
+       callout_stop(&sc->sc_calib_to);
 
        switch (ostate) {
        case IEEE80211_S_INIT:
@@ -1594,11 +1648,19 @@
        case IEEE80211_S_AUTH:
                /* Set initial gain under link. */
                reg = urtwn_bb_read(sc, R92C_OFDM0_AGCCORE1(0));
+#ifdef doaslinux
                reg = RW(reg, R92C_OFDM0_AGCCORE1_GAIN, 0x32);
+#else
+               reg = RW(reg, R92C_OFDM0_AGCCORE1_GAIN, 0x20);
+#endif
                urtwn_bb_write(sc, R92C_OFDM0_AGCCORE1(0), reg);
 
                reg = urtwn_bb_read(sc, R92C_OFDM0_AGCCORE1(1));
+#ifdef doaslinux
                reg = RW(reg, R92C_OFDM0_AGCCORE1_GAIN, 0x32);
+#else
+               reg = RW(reg, R92C_OFDM0_AGCCORE1_GAIN, 0x20);
+#endif
                urtwn_bb_write(sc, R92C_OFDM0_AGCCORE1(1), reg);
 
                /* Set media status to 'No Link'. */
@@ -1695,6 +1757,7 @@
 
        (*sc->sc_newstate)(ic, nstate, cmd->arg);



Home | Main Index | Thread Index | Old Index