diff options
author | Dan Williams <dcbw@redhat.com> | 2007-05-25 22:18:47 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2007-06-11 14:28:43 -0400 |
commit | 80e78ef74dffb2195e2a1164c18579180a76fd5b (patch) | |
tree | 362cae9f290534bb810f263477c977c6d082cebe /drivers/net/wireless | |
parent | 94b23855c034ffa50e1f94f43ef4500520e4c36e (diff) | |
download | kernel_samsung_smdk4412-80e78ef74dffb2195e2a1164c18579180a76fd5b.zip kernel_samsung_smdk4412-80e78ef74dffb2195e2a1164c18579180a76fd5b.tar.gz kernel_samsung_smdk4412-80e78ef74dffb2195e2a1164c18579180a76fd5b.tar.bz2 |
[PATCH] libertas: fix deadlock SIOCGIWSCAN handler
Update signal quality before the locked scan result translation loop,
because calling libertas_prepare_and_send_command() with the
'waitforrsp' option grabs adapter->lock in the command return processing,
leading to the deadlock.
Signed-off-by: Dan Williams <dcbw@redhat.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r-- | drivers/net/wireless/libertas/scan.c | 35 |
1 files changed, 18 insertions, 17 deletions
diff --git a/drivers/net/wireless/libertas/scan.c b/drivers/net/wireless/libertas/scan.c index abc9d56..8aaac5f 100644 --- a/drivers/net/wireless/libertas/scan.c +++ b/drivers/net/wireless/libertas/scan.c @@ -1506,7 +1506,6 @@ static inline char *libertas_translate_scan(wlan_private *priv, char *current_val; /* For rates */ struct iw_event iwe; /* Temporary buffer */ int j; - int ret; #define PERFECT_RSSI ((u8)50) #define WORST_RSSI ((u8)0) #define RSSI_DIFF ((u8)(PERFECT_RSSI - WORST_RSSI)) @@ -1560,22 +1559,18 @@ static inline char *libertas_translate_scan(wlan_private *priv, iwe.u.qual.noise = CAL_NF(adapter->NF[TYPE_BEACON][TYPE_NOAVG]); } - if ((adapter->mode == IW_MODE_AUTO) && - !libertas_SSID_cmp(&adapter->curbssparams.ssid, &bss->ssid) - && adapter->adhoccreate) { - ret = libertas_prepare_and_send_command(priv, - cmd_802_11_rssi, - 0, - cmd_option_waitforrsp, - 0, NULL); - - if (!ret) { - iwe.u.qual.level = - CAL_RSSI(adapter->SNR[TYPE_RXPD][TYPE_AVG] / - AVG_SCALE, - adapter->NF[TYPE_RXPD][TYPE_AVG] / - AVG_SCALE); - } + + /* Locally created ad-hoc BSSs won't have beacons if this is the + * only station in the adhoc network; so get signal strength + * from receive statistics. + */ + if ((adapter->mode == IW_MODE_ADHOC) + && adapter->adhoccreate + && !libertas_SSID_cmp(&adapter->curbssparams.ssid, &bss->ssid)) { + int snr, nf; + snr = adapter->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE; + nf = adapter->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE; + iwe.u.qual.level = CAL_RSSI(snr, nf); } start = iwe_stream_add_event(start, stop, &iwe, IW_EV_QUAL_LEN); @@ -1665,6 +1660,12 @@ int libertas_get_scan(struct net_device *dev, struct iw_request_info *info, if (!adapter->nr_cmd_pending && adapter->last_scanned_channel) wlan_scan_networks(priv, NULL, 0); + /* Update RSSI if current BSS is a locally created ad-hoc BSS */ + if ((adapter->inframode == wlan802_11ibss) && adapter->adhoccreate) { + libertas_prepare_and_send_command(priv, cmd_802_11_rssi, 0, + cmd_option_waitforrsp, 0, NULL); + } + mutex_lock(&adapter->lock); list_for_each_entry_safe (iter_bss, safe, &adapter->network_list, list) { char * next_ev; |