aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Williams <dcbw@redhat.com>2007-05-25 22:18:47 -0400
committerJohn W. Linville <linville@tuxdriver.com>2007-06-11 14:28:43 -0400
commit80e78ef74dffb2195e2a1164c18579180a76fd5b (patch)
tree362cae9f290534bb810f263477c977c6d082cebe
parent94b23855c034ffa50e1f94f43ef4500520e4c36e (diff)
[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>
-rw-r--r--drivers/net/wireless/libertas/scan.c35
1 files changed, 18 insertions, 17 deletions
diff --git a/drivers/net/wireless/libertas/scan.c b/drivers/net/wireless/libertas/scan.c
index abc9d563ce46..8aaac5f6c9de 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,
1506 char *current_val; /* For rates */ 1506 char *current_val; /* For rates */
1507 struct iw_event iwe; /* Temporary buffer */ 1507 struct iw_event iwe; /* Temporary buffer */
1508 int j; 1508 int j;
1509 int ret;
1510#define PERFECT_RSSI ((u8)50) 1509#define PERFECT_RSSI ((u8)50)
1511#define WORST_RSSI ((u8)0) 1510#define WORST_RSSI ((u8)0)
1512#define RSSI_DIFF ((u8)(PERFECT_RSSI - WORST_RSSI)) 1511#define RSSI_DIFF ((u8)(PERFECT_RSSI - WORST_RSSI))
@@ -1560,22 +1559,18 @@ static inline char *libertas_translate_scan(wlan_private *priv,
1560 iwe.u.qual.noise = 1559 iwe.u.qual.noise =
1561 CAL_NF(adapter->NF[TYPE_BEACON][TYPE_NOAVG]); 1560 CAL_NF(adapter->NF[TYPE_BEACON][TYPE_NOAVG]);
1562 } 1561 }
1563 if ((adapter->mode == IW_MODE_AUTO) && 1562
1564 !libertas_SSID_cmp(&adapter->curbssparams.ssid, &bss->ssid) 1563 /* Locally created ad-hoc BSSs won't have beacons if this is the
1565 && adapter->adhoccreate) { 1564 * only station in the adhoc network; so get signal strength
1566 ret = libertas_prepare_and_send_command(priv, 1565 * from receive statistics.
1567 cmd_802_11_rssi, 1566 */
1568 0, 1567 if ((adapter->mode == IW_MODE_ADHOC)
1569 cmd_option_waitforrsp, 1568 && adapter->adhoccreate
1570 0, NULL); 1569 && !libertas_SSID_cmp(&adapter->curbssparams.ssid, &bss->ssid)) {
1571 1570 int snr, nf;
1572 if (!ret) { 1571 snr = adapter->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE;
1573 iwe.u.qual.level = 1572 nf = adapter->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE;
1574 CAL_RSSI(adapter->SNR[TYPE_RXPD][TYPE_AVG] / 1573 iwe.u.qual.level = CAL_RSSI(snr, nf);
1575 AVG_SCALE,
1576 adapter->NF[TYPE_RXPD][TYPE_AVG] /
1577 AVG_SCALE);
1578 }
1579 } 1574 }
1580 start = iwe_stream_add_event(start, stop, &iwe, IW_EV_QUAL_LEN); 1575 start = iwe_stream_add_event(start, stop, &iwe, IW_EV_QUAL_LEN);
1581 1576
@@ -1665,6 +1660,12 @@ int libertas_get_scan(struct net_device *dev, struct iw_request_info *info,
1665 if (!adapter->nr_cmd_pending && adapter->last_scanned_channel) 1660 if (!adapter->nr_cmd_pending && adapter->last_scanned_channel)
1666 wlan_scan_networks(priv, NULL, 0); 1661 wlan_scan_networks(priv, NULL, 0);
1667 1662
1663 /* Update RSSI if current BSS is a locally created ad-hoc BSS */
1664 if ((adapter->inframode == wlan802_11ibss) && adapter->adhoccreate) {
1665 libertas_prepare_and_send_command(priv, cmd_802_11_rssi, 0,
1666 cmd_option_waitforrsp, 0, NULL);
1667 }
1668
1668 mutex_lock(&adapter->lock); 1669 mutex_lock(&adapter->lock);
1669 list_for_each_entry_safe (iter_bss, safe, &adapter->network_list, list) { 1670 list_for_each_entry_safe (iter_bss, safe, &adapter->network_list, list) {
1670 char * next_ev; 1671 char * next_ev;