diff mbox

[RFC] cfg80211: Make NL80211_CMD_SET_REG synchronous

Message ID 1291715126-7652-1-git-send-email-helmut.schaa@googlemail.com (mailing list archive)
State Not Applicable, archived
Headers show

Commit Message

Helmut Schaa Dec. 7, 2010, 9:45 a.m. UTC
None
diff mbox

Patch

diff --git a/include/net/regulatory.h b/include/net/regulatory.h
index 356d6e3..e58a744 100644
--- a/include/net/regulatory.h
+++ b/include/net/regulatory.h
@@ -62,6 +62,7 @@  struct regulatory_request {
 	bool intersect;
 	bool processed;
 	enum environment_cap country_ie_env;
+	struct completion *completion;
 	struct list_head list;
 };
 
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 56508d4..8e76a63 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -2535,6 +2535,7 @@  static int parse_reg_rule(struct nlattr *tb[],
 
 static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info)
 {
+	DECLARE_COMPLETION_ONSTACK(completion);
 	int r;
 	char *data = NULL;
 
@@ -2556,7 +2557,9 @@  static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info)
 
 	data = nla_data(info->attrs[NL80211_ATTR_REG_ALPHA2]);
 
-	r = regulatory_hint_user(data);
+	r = regulatory_hint_user(data, &completion);
+
+	wait_for_completion_interruptible(&completion);
 
 	return r;
 }
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 5ed615f..84787e3 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -1428,6 +1428,7 @@  static void reg_process_hint(struct regulatory_request *reg_request)
 	int r = 0;
 	struct wiphy *wiphy = NULL;
 	enum nl80211_reg_initiator initiator = reg_request->initiator;
+	struct completion *completion = reg_request->completion;
 
 	BUG_ON(!reg_request->alpha2);
 
@@ -1437,7 +1438,7 @@  static void reg_process_hint(struct regulatory_request *reg_request)
 	if (reg_request->initiator == NL80211_REGDOM_SET_BY_DRIVER &&
 	    !wiphy) {
 		kfree(reg_request);
-		return;
+		goto out;
 	}
 
 	r = __regulatory_hint(wiphy, reg_request);
@@ -1445,6 +1446,11 @@  static void reg_process_hint(struct regulatory_request *reg_request)
 	if (r == -EALREADY && wiphy &&
 	    wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY)
 		wiphy_update_regulatory(wiphy, initiator);
+
+out:
+	/* Mark this reg request done */
+	if (completion)
+		complete_all(completion);
 }
 
 /*
@@ -1571,7 +1577,7 @@  static int regulatory_hint_core(const char *alpha2)
 }
 
 /* User hints */
-int regulatory_hint_user(const char *alpha2)
+int regulatory_hint_user(const char *alpha2, struct completion *completion)
 {
 	struct regulatory_request *request;
 
@@ -1585,6 +1591,7 @@  int regulatory_hint_user(const char *alpha2)
 	request->alpha2[0] = alpha2[0];
 	request->alpha2[1] = alpha2[1];
 	request->initiator = NL80211_REGDOM_SET_BY_USER;
+	request->completion = completion;
 
 	queue_regulatory_request(request);
 
@@ -1787,7 +1794,7 @@  static void restore_regulatory_settings(bool reset_user)
 	 * settings, user regulatory settings takes precedence.
 	 */
 	if (is_an_alpha2(alpha2))
-		regulatory_hint_user(user_alpha2);
+		regulatory_hint_user(user_alpha2, NULL);
 }
 
 
@@ -2149,7 +2156,7 @@  int __init regulatory_init(void)
 	 * as a user hint.
 	 */
 	if (!is_world_regdom(ieee80211_regdom))
-		regulatory_hint_user(ieee80211_regdom);
+		regulatory_hint_user(ieee80211_regdom, NULL);
 
 	return 0;
 }
diff --git a/net/wireless/reg.h b/net/wireless/reg.h
index c4695d0..8be4d42 100644
--- a/net/wireless/reg.h
+++ b/net/wireless/reg.h
@@ -6,7 +6,7 @@  extern const struct ieee80211_regdomain *cfg80211_regdomain;
 bool is_world_regdom(const char *alpha2);
 bool reg_is_valid_request(const char *alpha2);
 
-int regulatory_hint_user(const char *alpha2);
+int regulatory_hint_user(const char *alpha2, struct completion *completion);
 
 void reg_device_remove(struct wiphy *wiphy);