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