diff options
Diffstat (limited to 'net/rfkill/rfkill.c')
-rw-r--r-- | net/rfkill/rfkill.c | 77 |
1 files changed, 53 insertions, 24 deletions
diff --git a/net/rfkill/rfkill.c b/net/rfkill/rfkill.c index 7a560b785097..d2d45655cd1a 100644 --- a/net/rfkill/rfkill.c +++ b/net/rfkill/rfkill.c | |||
@@ -105,6 +105,16 @@ static void rfkill_led_trigger(struct rfkill *rfkill, | |||
105 | #endif /* CONFIG_RFKILL_LEDS */ | 105 | #endif /* CONFIG_RFKILL_LEDS */ |
106 | } | 106 | } |
107 | 107 | ||
108 | #ifdef CONFIG_RFKILL_LEDS | ||
109 | static void rfkill_led_trigger_activate(struct led_classdev *led) | ||
110 | { | ||
111 | struct rfkill *rfkill = container_of(led->trigger, | ||
112 | struct rfkill, led_trigger); | ||
113 | |||
114 | rfkill_led_trigger(rfkill, rfkill->state); | ||
115 | } | ||
116 | #endif /* CONFIG_RFKILL_LEDS */ | ||
117 | |||
108 | static void notify_rfkill_state_change(struct rfkill *rfkill) | 118 | static void notify_rfkill_state_change(struct rfkill *rfkill) |
109 | { | 119 | { |
110 | blocking_notifier_call_chain(&rfkill_notifier_list, | 120 | blocking_notifier_call_chain(&rfkill_notifier_list, |
@@ -130,7 +140,6 @@ static void update_rfkill_state(struct rfkill *rfkill) | |||
130 | 140 | ||
131 | /** | 141 | /** |
132 | * rfkill_toggle_radio - wrapper for toggle_radio hook | 142 | * rfkill_toggle_radio - wrapper for toggle_radio hook |
133 | * | ||
134 | * @rfkill: the rfkill struct to use | 143 | * @rfkill: the rfkill struct to use |
135 | * @force: calls toggle_radio even if cache says it is not needed, | 144 | * @force: calls toggle_radio even if cache says it is not needed, |
136 | * and also makes sure notifications of the state will be | 145 | * and also makes sure notifications of the state will be |
@@ -141,8 +150,8 @@ static void update_rfkill_state(struct rfkill *rfkill) | |||
141 | * calls and handling all the red tape such as issuing notifications | 150 | * calls and handling all the red tape such as issuing notifications |
142 | * if the call is successful. | 151 | * if the call is successful. |
143 | * | 152 | * |
144 | * Note that @force cannot override a (possibly cached) state of | 153 | * Note that the @force parameter cannot override a (possibly cached) |
145 | * RFKILL_STATE_HARD_BLOCKED. Any device making use of | 154 | * state of RFKILL_STATE_HARD_BLOCKED. Any device making use of |
146 | * RFKILL_STATE_HARD_BLOCKED implements either get_state() or | 155 | * RFKILL_STATE_HARD_BLOCKED implements either get_state() or |
147 | * rfkill_force_state(), so the cache either is bypassed or valid. | 156 | * rfkill_force_state(), so the cache either is bypassed or valid. |
148 | * | 157 | * |
@@ -150,7 +159,7 @@ static void update_rfkill_state(struct rfkill *rfkill) | |||
150 | * even if the radio is in RFKILL_STATE_HARD_BLOCKED state, so as to | 159 | * 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. | 160 | * give the driver a hint that it should double-BLOCK the transmitter. |
152 | * | 161 | * |
153 | * Caller must have aquired rfkill_mutex. | 162 | * Caller must have acquired rfkill->mutex. |
154 | */ | 163 | */ |
155 | static int rfkill_toggle_radio(struct rfkill *rfkill, | 164 | static int rfkill_toggle_radio(struct rfkill *rfkill, |
156 | enum rfkill_state state, | 165 | enum rfkill_state state, |
@@ -200,12 +209,12 @@ static int rfkill_toggle_radio(struct rfkill *rfkill, | |||
200 | 209 | ||
201 | /** | 210 | /** |
202 | * rfkill_switch_all - Toggle state of all switches of given type | 211 | * rfkill_switch_all - Toggle state of all switches of given type |
203 | * @type: type of interfaces to be affeceted | 212 | * @type: type of interfaces to be affected |
204 | * @state: the new state | 213 | * @state: the new state |
205 | * | 214 | * |
206 | * This function toggles state of all switches of given type unless | 215 | * This function toggles the state of all switches of given type, |
207 | * a specific switch is claimed by userspace in which case it is | 216 | * unless a specific switch is claimed by userspace (in which case, |
208 | * left alone. | 217 | * that switch is left alone). |
209 | */ | 218 | */ |
210 | void rfkill_switch_all(enum rfkill_type type, enum rfkill_state state) | 219 | void rfkill_switch_all(enum rfkill_type type, enum rfkill_state state) |
211 | { | 220 | { |
@@ -216,8 +225,11 @@ void rfkill_switch_all(enum rfkill_type type, enum rfkill_state state) | |||
216 | rfkill_states[type] = state; | 225 | rfkill_states[type] = state; |
217 | 226 | ||
218 | list_for_each_entry(rfkill, &rfkill_list, node) { | 227 | list_for_each_entry(rfkill, &rfkill_list, node) { |
219 | if ((!rfkill->user_claim) && (rfkill->type == type)) | 228 | if ((!rfkill->user_claim) && (rfkill->type == type)) { |
229 | mutex_lock(&rfkill->mutex); | ||
220 | rfkill_toggle_radio(rfkill, state, 0); | 230 | rfkill_toggle_radio(rfkill, state, 0); |
231 | mutex_unlock(&rfkill->mutex); | ||
232 | } | ||
221 | } | 233 | } |
222 | 234 | ||
223 | mutex_unlock(&rfkill_mutex); | 235 | mutex_unlock(&rfkill_mutex); |
@@ -228,7 +240,7 @@ EXPORT_SYMBOL(rfkill_switch_all); | |||
228 | * rfkill_epo - emergency power off all transmitters | 240 | * rfkill_epo - emergency power off all transmitters |
229 | * | 241 | * |
230 | * This kicks all rfkill devices to RFKILL_STATE_SOFT_BLOCKED, ignoring | 242 | * This kicks all rfkill devices to RFKILL_STATE_SOFT_BLOCKED, ignoring |
231 | * everything in its path but rfkill_mutex. | 243 | * everything in its path but rfkill_mutex and rfkill->mutex. |
232 | */ | 244 | */ |
233 | void rfkill_epo(void) | 245 | void rfkill_epo(void) |
234 | { | 246 | { |
@@ -236,7 +248,9 @@ void rfkill_epo(void) | |||
236 | 248 | ||
237 | mutex_lock(&rfkill_mutex); | 249 | mutex_lock(&rfkill_mutex); |
238 | list_for_each_entry(rfkill, &rfkill_list, node) { | 250 | list_for_each_entry(rfkill, &rfkill_list, node) { |
251 | mutex_lock(&rfkill->mutex); | ||
239 | rfkill_toggle_radio(rfkill, RFKILL_STATE_SOFT_BLOCKED, 1); | 252 | rfkill_toggle_radio(rfkill, RFKILL_STATE_SOFT_BLOCKED, 1); |
253 | mutex_unlock(&rfkill->mutex); | ||
240 | } | 254 | } |
241 | mutex_unlock(&rfkill_mutex); | 255 | mutex_unlock(&rfkill_mutex); |
242 | } | 256 | } |
@@ -252,7 +266,12 @@ EXPORT_SYMBOL_GPL(rfkill_epo); | |||
252 | * a notification by the firmware/hardware of the current *real* | 266 | * a notification by the firmware/hardware of the current *real* |
253 | * state of the radio rfkill switch. | 267 | * state of the radio rfkill switch. |
254 | * | 268 | * |
255 | * It may not be called from an atomic context. | 269 | * Devices which are subject to external changes on their rfkill |
270 | * state (such as those caused by a hardware rfkill line) MUST | ||
271 | * have their driver arrange to call rfkill_force_state() as soon | ||
272 | * as possible after such a change. | ||
273 | * | ||
274 | * This function may not be called from an atomic context. | ||
256 | */ | 275 | */ |
257 | int rfkill_force_state(struct rfkill *rfkill, enum rfkill_state state) | 276 | int rfkill_force_state(struct rfkill *rfkill, enum rfkill_state state) |
258 | { | 277 | { |
@@ -367,6 +386,9 @@ static ssize_t rfkill_claim_store(struct device *dev, | |||
367 | if (!capable(CAP_NET_ADMIN)) | 386 | if (!capable(CAP_NET_ADMIN)) |
368 | return -EPERM; | 387 | return -EPERM; |
369 | 388 | ||
389 | if (rfkill->user_claim_unsupported) | ||
390 | return -EOPNOTSUPP; | ||
391 | |||
370 | /* | 392 | /* |
371 | * Take the global lock to make sure the kernel is not in | 393 | * Take the global lock to make sure the kernel is not in |
372 | * the middle of rfkill_switch_all | 394 | * the middle of rfkill_switch_all |
@@ -375,19 +397,17 @@ static ssize_t rfkill_claim_store(struct device *dev, | |||
375 | if (error) | 397 | if (error) |
376 | return error; | 398 | return error; |
377 | 399 | ||
378 | if (rfkill->user_claim_unsupported) { | ||
379 | error = -EOPNOTSUPP; | ||
380 | goto out_unlock; | ||
381 | } | ||
382 | if (rfkill->user_claim != claim) { | 400 | if (rfkill->user_claim != claim) { |
383 | if (!claim) | 401 | if (!claim) { |
402 | mutex_lock(&rfkill->mutex); | ||
384 | rfkill_toggle_radio(rfkill, | 403 | rfkill_toggle_radio(rfkill, |
385 | rfkill_states[rfkill->type], | 404 | rfkill_states[rfkill->type], |
386 | 0); | 405 | 0); |
406 | mutex_unlock(&rfkill->mutex); | ||
407 | } | ||
387 | rfkill->user_claim = claim; | 408 | rfkill->user_claim = claim; |
388 | } | 409 | } |
389 | 410 | ||
390 | out_unlock: | ||
391 | mutex_unlock(&rfkill_mutex); | 411 | mutex_unlock(&rfkill_mutex); |
392 | 412 | ||
393 | return error ? error : count; | 413 | return error ? error : count; |
@@ -516,8 +536,11 @@ static void rfkill_remove_switch(struct rfkill *rfkill) | |||
516 | { | 536 | { |
517 | mutex_lock(&rfkill_mutex); | 537 | mutex_lock(&rfkill_mutex); |
518 | list_del_init(&rfkill->node); | 538 | list_del_init(&rfkill->node); |
519 | rfkill_toggle_radio(rfkill, RFKILL_STATE_SOFT_BLOCKED, 1); | ||
520 | mutex_unlock(&rfkill_mutex); | 539 | mutex_unlock(&rfkill_mutex); |
540 | |||
541 | mutex_lock(&rfkill->mutex); | ||
542 | rfkill_toggle_radio(rfkill, RFKILL_STATE_SOFT_BLOCKED, 1); | ||
543 | mutex_unlock(&rfkill->mutex); | ||
521 | } | 544 | } |
522 | 545 | ||
523 | /** | 546 | /** |
@@ -526,9 +549,10 @@ static void rfkill_remove_switch(struct rfkill *rfkill) | |||
526 | * @type: type of the switch (RFKILL_TYPE_*) | 549 | * @type: type of the switch (RFKILL_TYPE_*) |
527 | * | 550 | * |
528 | * This function should be called by the network driver when it needs | 551 | * This function should be called by the network driver when it needs |
529 | * rfkill structure. Once the structure is allocated the driver shoud | 552 | * rfkill structure. Once the structure is allocated the driver should |
530 | * finish its initialization by setting name, private data, enable_radio | 553 | * finish its initialization by setting the name, private data, enable_radio |
531 | * and disable_radio methods and then register it with rfkill_register(). | 554 | * and disable_radio methods and then register it with rfkill_register(). |
555 | * | ||
532 | * NOTE: If registration fails the structure shoudl be freed by calling | 556 | * NOTE: If registration fails the structure shoudl be freed by calling |
533 | * rfkill_free() otherwise rfkill_unregister() should be used. | 557 | * rfkill_free() otherwise rfkill_unregister() should be used. |
534 | */ | 558 | */ |
@@ -560,7 +584,7 @@ EXPORT_SYMBOL(rfkill_allocate); | |||
560 | * rfkill_free - Mark rfkill structure for deletion | 584 | * rfkill_free - Mark rfkill structure for deletion |
561 | * @rfkill: rfkill structure to be destroyed | 585 | * @rfkill: rfkill structure to be destroyed |
562 | * | 586 | * |
563 | * Decrements reference count of rfkill structure so it is destroyed. | 587 | * Decrements reference count of the rfkill structure so it is destroyed. |
564 | * Note that rfkill_free() should _not_ be called after rfkill_unregister(). | 588 | * Note that rfkill_free() should _not_ be called after rfkill_unregister(). |
565 | */ | 589 | */ |
566 | void rfkill_free(struct rfkill *rfkill) | 590 | void rfkill_free(struct rfkill *rfkill) |
@@ -575,7 +599,10 @@ static void rfkill_led_trigger_register(struct rfkill *rfkill) | |||
575 | #ifdef CONFIG_RFKILL_LEDS | 599 | #ifdef CONFIG_RFKILL_LEDS |
576 | int error; | 600 | int error; |
577 | 601 | ||
578 | rfkill->led_trigger.name = rfkill->dev.bus_id; | 602 | if (!rfkill->led_trigger.name) |
603 | rfkill->led_trigger.name = rfkill->dev.bus_id; | ||
604 | if (!rfkill->led_trigger.activate) | ||
605 | rfkill->led_trigger.activate = rfkill_led_trigger_activate; | ||
579 | error = led_trigger_register(&rfkill->led_trigger); | 606 | error = led_trigger_register(&rfkill->led_trigger); |
580 | if (error) | 607 | if (error) |
581 | rfkill->led_trigger.name = NULL; | 608 | rfkill->led_trigger.name = NULL; |
@@ -585,8 +612,10 @@ static void rfkill_led_trigger_register(struct rfkill *rfkill) | |||
585 | static void rfkill_led_trigger_unregister(struct rfkill *rfkill) | 612 | static void rfkill_led_trigger_unregister(struct rfkill *rfkill) |
586 | { | 613 | { |
587 | #ifdef CONFIG_RFKILL_LEDS | 614 | #ifdef CONFIG_RFKILL_LEDS |
588 | if (rfkill->led_trigger.name) | 615 | if (rfkill->led_trigger.name) { |
589 | led_trigger_unregister(&rfkill->led_trigger); | 616 | led_trigger_unregister(&rfkill->led_trigger); |
617 | rfkill->led_trigger.name = NULL; | ||
618 | } | ||
590 | #endif | 619 | #endif |
591 | } | 620 | } |
592 | 621 | ||
@@ -622,8 +651,8 @@ int rfkill_register(struct rfkill *rfkill) | |||
622 | 651 | ||
623 | error = device_add(dev); | 652 | error = device_add(dev); |
624 | if (error) { | 653 | if (error) { |
625 | rfkill_led_trigger_unregister(rfkill); | ||
626 | rfkill_remove_switch(rfkill); | 654 | rfkill_remove_switch(rfkill); |
655 | rfkill_led_trigger_unregister(rfkill); | ||
627 | return error; | 656 | return error; |
628 | } | 657 | } |
629 | 658 | ||