aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/rtwn
diff options
context:
space:
mode:
authorAndriy Voskoboinyk <avos@FreeBSD.org>2017-01-10 01:09:39 +0000
committerAndriy Voskoboinyk <avos@FreeBSD.org>2017-01-10 01:09:39 +0000
commitae60d856a31f28c45f814421765e716ec1bd4278 (patch)
treec461e19d2819b354c2b575b063182b34eaa32353 /sys/dev/rtwn
parent5ca4ae8bb7f474cd6d3b1346393ebfb03cf7dd8a (diff)
downloadsrc-ae60d856a31f28c45f814421765e716ec1bd4278.tar.gz
src-ae60d856a31f28c45f814421765e716ec1bd4278.zip
rtwn_pci(4): fix possible race while accessing 'matched_chip' variable.
Notes
Notes: svn path=/head/; revision=311845
Diffstat (limited to 'sys/dev/rtwn')
-rw-r--r--sys/dev/rtwn/pci/rtwn_pci_attach.c34
1 files changed, 23 insertions, 11 deletions
diff --git a/sys/dev/rtwn/pci/rtwn_pci_attach.c b/sys/dev/rtwn/pci/rtwn_pci_attach.c
index e021c401ad3c..3af8d176f790 100644
--- a/sys/dev/rtwn/pci/rtwn_pci_attach.c
+++ b/sys/dev/rtwn/pci/rtwn_pci_attach.c
@@ -94,20 +94,31 @@ static void rtwn_pci_beacon_update_end(struct rtwn_softc *,
static void rtwn_pci_attach_methods(struct rtwn_softc *);
-static int matched_chip = RTWN_CHIP_MAX_PCI;
+static const struct rtwn_pci_ident *
+rtwn_pci_probe_sub(device_t dev)
+{
+ const struct rtwn_pci_ident *ident;
+ int vendor_id, device_id;
+
+ vendor_id = pci_get_vendor(dev);
+ device_id = pci_get_device(dev);
+
+ for (ident = rtwn_pci_ident_table; ident->name != NULL; ident++)
+ if (vendor_id == ident->vendor && device_id == ident->device)
+ return (ident);
+
+ return (NULL);
+}
static int
rtwn_pci_probe(device_t dev)
{
const struct rtwn_pci_ident *ident;
- for (ident = rtwn_pci_ident_table; ident->name != NULL; ident++) {
- if (pci_get_vendor(dev) == ident->vendor &&
- pci_get_device(dev) == ident->device) {
- matched_chip = ident->chip;
- device_set_desc(dev, ident->name);
- return (BUS_PROBE_DEFAULT);
- }
+ ident = rtwn_pci_probe_sub(dev);
+ if (ident != NULL) {
+ device_set_desc(dev, ident->name);
+ return (BUS_PROBE_DEFAULT);
}
return (ENXIO);
}
@@ -591,13 +602,15 @@ rtwn_pci_attach_methods(struct rtwn_softc *sc)
static int
rtwn_pci_attach(device_t dev)
{
+ const struct rtwn_pci_ident *ident;
struct rtwn_pci_softc *pc = device_get_softc(dev);
struct rtwn_softc *sc = &pc->pc_sc;
struct ieee80211com *ic = &sc->sc_ic;
uint32_t lcsr;
int cap_off, i, error, rid;
- if (matched_chip >= RTWN_CHIP_MAX_PCI)
+ ident = rtwn_pci_probe_sub(dev);
+ if (ident == NULL)
return (ENXIO);
/*
@@ -649,8 +662,7 @@ rtwn_pci_attach(device_t dev)
mtx_init(&sc->sc_mtx, ic->ic_name, MTX_NETWORK_LOCK, MTX_DEF);
rtwn_pci_attach_methods(sc);
- /* XXX something similar to USB_GET_DRIVER_INFO() */
- rtwn_pci_attach_private(pc, matched_chip);
+ rtwn_pci_attach_private(pc, ident->chip);
/* Allocate Tx/Rx buffers. */
error = rtwn_pci_alloc_rx_list(sc);