diff options
Diffstat (limited to 'net/rfkill/rfkill.c')
| -rw-r--r-- | net/rfkill/rfkill.c | 62 |
1 files changed, 39 insertions, 23 deletions
diff --git a/net/rfkill/rfkill.c b/net/rfkill/rfkill.c index 7a560b785097..c6f2f388cb72 100644 --- a/net/rfkill/rfkill.c +++ b/net/rfkill/rfkill.c | |||
| @@ -130,7 +130,6 @@ static void update_rfkill_state(struct rfkill *rfkill) | |||
| 130 | 130 | ||
| 131 | /** | 131 | /** |
| 132 | * rfkill_toggle_radio - wrapper for toggle_radio hook | 132 | * rfkill_toggle_radio - wrapper for toggle_radio hook |
| 133 | * | ||
| 134 | * @rfkill: the rfkill struct to use | 133 | * @rfkill: the rfkill struct to use |
| 135 | * @force: calls toggle_radio even if cache says it is not needed, | 134 | * @force: calls toggle_radio even if cache says it is not needed, |
| 136 | * and also makes sure notifications of the state will be | 135 | * and also makes sure notifications of the state will be |
| @@ -141,8 +140,8 @@ static void update_rfkill_state(struct rfkill *rfkill) | |||
| 141 | * calls and handling all the red tape such as issuing notifications | 140 | * calls and handling all the red tape such as issuing notifications |
| 142 | * if the call is successful. | 141 | * if the call is successful. |
| 143 | * | 142 | * |
| 144 | * Note that @force cannot override a (possibly cached) state of | 143 | * Note that the @force parameter cannot override a (possibly cached) |
| 145 | * RFKILL_STATE_HARD_BLOCKED. Any device making use of | 144 | * state of RFKILL_STATE_HARD_BLOCKED. Any device making use of |
| 146 | * RFKILL_STATE_HARD_BLOCKED implements either get_state() or | 145 | * RFKILL_STATE_HARD_BLOCKED implements either get_state() or |
| 147 | * rfkill_force_state(), so the cache either is bypassed or valid. | 146 | * rfkill_force_state(), so the cache either is bypassed or valid. |
| 148 | * | 147 | * |
| @@ -150,7 +149,7 @@ static void update_rfkill_state(struct rfkill *rfkill) | |||
| 150 | * even if the radio is in RFKILL_STATE_HARD_BLOCKED state, so as to | 149 | * even if the radio is in RFKILL_STATE_HARD_BLOCKED state, so as to |
| 151 | * give the driver a hint that it should double-BLOCK the transmitter. | 150 | * give the driver a hint that it should double-BLOCK the transmitter. |
| 152 | * | 151 | * |
| 153 | * Caller must have aquired rfkill_mutex. | 152 | * Caller must have acquired rfkill->mutex. |
| 154 | */ | 153 | */ |
| 155 | static int rfkill_toggle_radio(struct rfkill *rfkill, | 154 | static int rfkill_toggle_radio(struct rfkill *rfkill, |
| 156 | enum rfkill_state state, | 155 | enum rfkill_state state, |
| @@ -200,12 +199,12 @@ static int rfkill_toggle_radio(struct rfkill *rfkill, | |||
| 200 | 199 | ||
| 201 | /** | 200 | /** |
| 202 | * rfkill_switch_all - Toggle state of all switches of given type | 201 | * rfkill_switch_all - Toggle state of all switches of given type |
| 203 | * @type: type of interfaces to be affeceted | 202 | * @type: type of interfaces to be affected |
| 204 | * @state: the new state | 203 | * @state: the new state |
| 205 | * | 204 | * |
| 206 | * This function toggles state of all switches of given type unless | 205 | * This function toggles the state of all switches of given type, |
| 207 | * a specific switch is claimed by userspace in which case it is | 206 | * unless a specific switch is claimed by userspace (in which case, |
| 208 | * left alone. | 207 | * that switch is left alone). |
| 209 | */ | 208 | */ |
| 210 | void rfkill_switch_all(enum rfkill_type type, enum rfkill_state state) | 209 | void rfkill_switch_all(enum rfkill_type type, enum rfkill_state state) |
| 211 | { | 210 | { |
| @@ -216,8 +215,11 @@ void rfkill_switch_all(enum rfkill_type type, enum rfkill_state state) | |||
| 216 | rfkill_states[type] = state; | 215 | rfkill_states[type] = state; |
| 217 | 216 | ||
| 218 | list_for_each_entry(rfkill, &rfkill_list, node) { | 217 | list_for_each_entry(rfkill, &rfkill_list, node) { |
| 219 | if ((!rfkill->user_claim) && (rfkill->type == type)) | 218 | if ((!rfkill->user_claim) && (rfkill->type == type)) { |
| 219 | mutex_lock(&rfkill->mutex); | ||
| 220 | rfkill_toggle_radio(rfkill, state, 0); | 220 | rfkill_toggle_radio(rfkill, state, 0); |
| 221 | mutex_unlock(&rfkill->mutex); | ||
| 222 | } | ||
| 221 | } | 223 | } |
| 222 | 224 | ||
| 223 | mutex_unlock(&rfkill_mutex); | 225 | mutex_unlock(&rfkill_mutex); |
| @@ -228,7 +230,7 @@ EXPORT_SYMBOL(rfkill_switch_all); | |||
| 228 | * rfkill_epo - emergency power off all transmitters | 230 | * rfkill_epo - emergency power off all transmitters |
| 229 | * | 231 | * |
| 230 | * This kicks all rfkill devices to RFKILL_STATE_SOFT_BLOCKED, ignoring | 232 | * This kicks all rfkill devices to RFKILL_STATE_SOFT_BLOCKED, ignoring |
| 231 | * everything in its path but rfkill_mutex. | 233 | * everything in its path but rfkill_mutex and rfkill->mutex. |
| 232 | */ | 234 | */ |
| 233 | void rfkill_epo(void) | 235 | void rfkill_epo(void) |
| 234 | { | 236 | { |
| @@ -236,7 +238,9 @@ void rfkill_epo(void) | |||
| 236 | 238 | ||
| 237 | mutex_lock(&rfkill_mutex); | 239 | mutex_lock(&rfkill_mutex); |
| 238 | list_for_each_entry(rfkill, &rfkill_list, node) { | 240 | list_for_each_entry(rfkill, &rfkill_list, node) { |
| 241 | mutex_lock(&rfkill->mutex); | ||
| 239 | rfkill_toggle_radio(rfkill, RFKILL_STATE_SOFT_BLOCKED, 1); | 242 | rfkill_toggle_radio(rfkill, RFKILL_STATE_SOFT_BLOCKED, 1); |
| 243 | mutex_unlock(&rfkill->mutex); | ||
| 240 | } | 244 | } |
| 241 | mutex_unlock(&rfkill_mutex); | 245 | mutex_unlock(&rfkill_mutex); |
| 242 | } | 246 | } |
| @@ -252,7 +256,12 @@ EXPORT_SYMBOL_GPL(rfkill_epo); | |||
| 252 | * a notification by the firmware/hardware of the current *real* | 256 | * a notification by the firmware/hardware of the current *real* |
| 253 | * state of the radio rfkill switch. | 257 | * state of the radio rfkill switch. |
| 254 | * | 258 | * |
| 255 | * It may not be called from an atomic context. | 259 | * Devices which are subject to external changes on their rfkill |
| 260 | * state (such as those caused by a hardware rfkill line) MUST | ||
| 261 | * have their driver arrange to call rfkill_force_state() as soon | ||
| 262 | * as possible after such a change. | ||
| 263 | * | ||
| 264 | * This function may not be called from an atomic context. | ||
| 256 | */ | 265 | */ |
| 257 | int rfkill_force_state(struct rfkill *rfkill, enum rfkill_state state) | 266 | int rfkill_force_state(struct rfkill *rfkill, enum rfkill_state state) |
| 258 | { | 267 | { |
| @@ -367,6 +376,9 @@ static ssize_t rfkill_claim_store(struct device *dev, | |||
| 367 | if (!capable(CAP_NET_ADMIN)) | 376 | if (!capable(CAP_NET_ADMIN)) |
| 368 | return -EPERM; | 377 | return -EPERM; |
| 369 | 378 | ||
| 379 | if (rfkill->user_claim_unsupported) | ||
| 380 | return -EOPNOTSUPP; | ||
| 381 | |||
| 370 | /* | 382 | /* |
| 371 | * Take the global lock to make sure the kernel is not in | 383 | * Take the global lock to make sure the kernel is not in |
| 372 | * the middle of rfkill_switch_all | 384 | * the middle of rfkill_switch_all |
| @@ -375,19 +387,17 @@ static ssize_t rfkill_claim_store(struct device *dev, | |||
| 375 | if (error) | 387 | if (error) |
| 376 | return error; | 388 | return error; |
| 377 | 389 | ||
| 378 | if (rfkill->user_claim_unsupported) { | ||
| 379 | error = -EOPNOTSUPP; | ||
| 380 | goto out_unlock; | ||
| 381 | } | ||
| 382 | if (rfkill->user_claim != claim) { | 390 | if (rfkill->user_claim != claim) { |
| 383 | if (!claim) | 391 | if (!claim) { |
| 392 | mutex_lock(&rfkill->mutex); | ||
| 384 | rfkill_toggle_radio(rfkill, | 393 | rfkill_toggle_radio(rfkill, |
| 385 | rfkill_states[rfkill->type], | 394 | rfkill_states[rfkill->type], |
| 386 | 0); | 395 | 0); |
| 396 | mutex_unlock(&rfkill->mutex); | ||
| 397 | } | ||
| 387 | rfkill->user_claim = claim; | 398 | rfkill->user_claim = claim; |
| 388 | } | 399 | } |
| 389 | 400 | ||
| 390 | out_unlock: | ||
| 391 | mutex_unlock(&rfkill_mutex); | 401 | mutex_unlock(&rfkill_mutex); |
| 392 | 402 | ||
| 393 | return error ? error : count; | 403 | return error ? error : count; |
| @@ -516,8 +526,11 @@ static void rfkill_remove_switch(struct rfkill *rfkill) | |||
| 516 | { | 526 | { |
| 517 | mutex_lock(&rfkill_mutex); | 527 | mutex_lock(&rfkill_mutex); |
| 518 | list_del_init(&rfkill->node); | 528 | list_del_init(&rfkill->node); |
| 519 | rfkill_toggle_radio(rfkill, RFKILL_STATE_SOFT_BLOCKED, 1); | ||
| 520 | mutex_unlock(&rfkill_mutex); | 529 | mutex_unlock(&rfkill_mutex); |
| 530 | |||
| 531 | mutex_lock(&rfkill->mutex); | ||
| 532 | rfkill_toggle_radio(rfkill, RFKILL_STATE_SOFT_BLOCKED, 1); | ||
| 533 | mutex_unlock(&rfkill->mutex); | ||
| 521 | } | 534 | } |
| 522 | 535 | ||
| 523 | /** | 536 | /** |
| @@ -526,9 +539,10 @@ static void rfkill_remove_switch(struct rfkill *rfkill) | |||
| 526 | * @type: type of the switch (RFKILL_TYPE_*) | 539 | * @type: type of the switch (RFKILL_TYPE_*) |
| 527 | * | 540 | * |
| 528 | * This function should be called by the network driver when it needs | 541 | * This function should be called by the network driver when it needs |
| 529 | * rfkill structure. Once the structure is allocated the driver shoud | 542 | * rfkill structure. Once the structure is allocated the driver should |
| 530 | * finish its initialization by setting name, private data, enable_radio | 543 | * finish its initialization by setting the name, private data, enable_radio |
| 531 | * and disable_radio methods and then register it with rfkill_register(). | 544 | * and disable_radio methods and then register it with rfkill_register(). |
| 545 | * | ||
| 532 | * NOTE: If registration fails the structure shoudl be freed by calling | 546 | * NOTE: If registration fails the structure shoudl be freed by calling |
| 533 | * rfkill_free() otherwise rfkill_unregister() should be used. | 547 | * rfkill_free() otherwise rfkill_unregister() should be used. |
| 534 | */ | 548 | */ |
| @@ -560,7 +574,7 @@ EXPORT_SYMBOL(rfkill_allocate); | |||
| 560 | * rfkill_free - Mark rfkill structure for deletion | 574 | * rfkill_free - Mark rfkill structure for deletion |
| 561 | * @rfkill: rfkill structure to be destroyed | 575 | * @rfkill: rfkill structure to be destroyed |
| 562 | * | 576 | * |
| 563 | * Decrements reference count of rfkill structure so it is destroyed. | 577 | * Decrements reference count of the rfkill structure so it is destroyed. |
| 564 | * Note that rfkill_free() should _not_ be called after rfkill_unregister(). | 578 | * Note that rfkill_free() should _not_ be called after rfkill_unregister(). |
| 565 | */ | 579 | */ |
| 566 | void rfkill_free(struct rfkill *rfkill) | 580 | void rfkill_free(struct rfkill *rfkill) |
| @@ -585,8 +599,10 @@ static void rfkill_led_trigger_register(struct rfkill *rfkill) | |||
| 585 | static void rfkill_led_trigger_unregister(struct rfkill *rfkill) | 599 | static void rfkill_led_trigger_unregister(struct rfkill *rfkill) |
| 586 | { | ||
