summaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorStephen Rothwell <sfr@canb.auug.org.au>2009-06-02 11:03:14 +1000
committerStephen Rothwell <sfr@canb.auug.org.au>2009-06-02 11:03:14 +1000
commit9b9e69a28db2c520c7c5982e246676bc83081081 (patch)
treef8f1253e0ced4f761360503b10a238d5ec04e406 /net
parent4512d1dc438fd648acaec97d8bac1602d732face (diff)
Revert "rfkill: remove user_claim stuff"
This reverts commit 621cac85297de5ba655e3430b007dd2e0da91da6.
Diffstat (limited to 'net')
-rw-r--r--net/rfkill/rfkill.c45
-rw-r--r--net/wimax/op-rfkill.c1
2 files changed, 43 insertions, 3 deletions
diff --git a/net/rfkill/rfkill.c b/net/rfkill/rfkill.c
index 4f5a83183c95..b770401b5bd0 100644
--- a/net/rfkill/rfkill.c
+++ b/net/rfkill/rfkill.c
@@ -208,7 +208,7 @@ static void __rfkill_switch_all(const enum rfkill_type type,
rfkill_global_states[type].current_state = state;
list_for_each_entry(rfkill, &rfkill_list, node) {
- if (rfkill->type == type) {
+ if ((!rfkill->user_claim) && (rfkill->type == type)) {
mutex_lock(&rfkill->mutex);
rfkill_toggle_radio(rfkill, state, 0);
mutex_unlock(&rfkill->mutex);
@@ -458,14 +458,53 @@ static ssize_t rfkill_claim_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
- return sprintf(buf, "%d\n", 0);
+ struct rfkill *rfkill = to_rfkill(dev);
+
+ return sprintf(buf, "%d\n", rfkill->user_claim);
}
static ssize_t rfkill_claim_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
- return -EOPNOTSUPP;
+ struct rfkill *rfkill = to_rfkill(dev);
+ unsigned long claim_tmp;
+ bool claim;
+ int error;
+
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
+
+ if (rfkill->user_claim_unsupported)
+ return -EOPNOTSUPP;
+
+ error = strict_strtoul(buf, 0, &claim_tmp);
+ if (error)
+ return error;
+ claim = !!claim_tmp;
+
+ /*
+ * Take the global lock to make sure the kernel is not in
+ * the middle of rfkill_switch_all
+ */
+ error = mutex_lock_killable(&rfkill_global_mutex);
+ if (error)
+ return error;
+
+ if (rfkill->user_claim != claim) {
+ if (!claim && !rfkill_epo_lock_active) {
+ mutex_lock(&rfkill->mutex);
+ rfkill_toggle_radio(rfkill,
+ rfkill_global_states[rfkill->type].current_state,
+ 0);
+ mutex_unlock(&rfkill->mutex);
+ }
+ rfkill->user_claim = claim;
+ }
+
+ mutex_unlock(&rfkill_global_mutex);
+
+ return error ? error : count;
}
static struct device_attribute rfkill_dev_attrs[] = {
diff --git a/net/wimax/op-rfkill.c b/net/wimax/op-rfkill.c
index a3616e2ccb8a..870032faece2 100644
--- a/net/wimax/op-rfkill.c
+++ b/net/wimax/op-rfkill.c
@@ -364,6 +364,7 @@ int wimax_rfkill_add(struct wimax_dev *wimax_dev)
rfkill->state = RFKILL_STATE_UNBLOCKED;
rfkill->data = wimax_dev;
rfkill->toggle_radio = wimax_rfkill_toggle_radio;
+ rfkill->user_claim_unsupported = 1;
/* Initialize the input device for the hw key */
input_dev = input_allocate_device();