diff options
author | Andriy Voskoboinyk <avos@FreeBSD.org> | 2017-01-10 01:09:39 +0000 |
---|---|---|
committer | Andriy Voskoboinyk <avos@FreeBSD.org> | 2017-01-10 01:09:39 +0000 |
commit | ae60d856a31f28c45f814421765e716ec1bd4278 (patch) | |
tree | c461e19d2819b354c2b575b063182b34eaa32353 /sys/dev/rtwn | |
parent | 5ca4ae8bb7f474cd6d3b1346393ebfb03cf7dd8a (diff) | |
download | src-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.c | 34 |
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); |