diff options
author | Henrique de Moraes Holschuh <hmh@hmh.eng.br> | 2008-08-02 14:10:57 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-08-22 16:29:56 -0400 |
commit | 02589f60510030a3c1496e7a8c511e4f674ef5ff (patch) | |
tree | 24650fdd0e2a0ad8145693164fa27e847379aacc /net/rfkill | |
parent | c94c93da90a9e46a73a5733ff8454fb4b14733fb (diff) |
rfkill: detect bogus double-registering (v2)
Detect and abort with -EEXIST if rfkill_register is called twice on the
same rfkill struct. And WARN_ON(it) for good measure.
While at it, flag when we are adding the first switch of a type, we will
need that information later.
Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Acked-by: Ivo van Doorn <IvDoorn@gmail.com>
Cc: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/rfkill')
-rw-r--r-- | net/rfkill/rfkill.c | 29 |
1 files changed, 28 insertions, 1 deletions
diff --git a/net/rfkill/rfkill.c b/net/rfkill/rfkill.c index 35a9994e2339..1f23de20a85e 100644 --- a/net/rfkill/rfkill.c +++ b/net/rfkill/rfkill.c | |||
@@ -525,17 +525,44 @@ static struct class rfkill_class = { | |||
525 | .dev_uevent = rfkill_dev_uevent, | 525 | .dev_uevent = rfkill_dev_uevent, |
526 | }; | 526 | }; |
527 | 527 | ||
528 | static int rfkill_check_duplicity(const struct rfkill *rfkill) | ||
529 | { | ||
530 | struct rfkill *p; | ||
531 | unsigned long seen[BITS_TO_LONGS(RFKILL_TYPE_MAX)]; | ||
532 | |||
533 | memset(seen, 0, sizeof(seen)); | ||
534 | |||
535 | list_for_each_entry(p, &rfkill_list, node) { | ||
536 | if (p == rfkill) { | ||
537 | WARN_ON(1); | ||
538 | return -EEXIST; | ||
539 | } | ||
540 | set_bit(p->type, seen); | ||
541 | } | ||
542 | |||
543 | /* 0: first switch of its kind */ | ||
544 | return test_bit(rfkill->type, seen); | ||
545 | } | ||
546 | |||
528 | static int rfkill_add_switch(struct rfkill *rfkill) | 547 | static int rfkill_add_switch(struct rfkill *rfkill) |
529 | { | 548 | { |
549 | int error; | ||
550 | |||
530 | mutex_lock(&rfkill_mutex); | 551 | mutex_lock(&rfkill_mutex); |
531 | 552 | ||
553 | error = rfkill_check_duplicity(rfkill); | ||
554 | if (error < 0) | ||
555 | goto unlock_out; | ||
556 | |||
532 | rfkill_toggle_radio(rfkill, rfkill_states[rfkill->type], 0); | 557 | rfkill_toggle_radio(rfkill, rfkill_states[rfkill->type], 0); |
533 | 558 | ||
534 | list_add_tail(&rfkill->node, &rfkill_list); | 559 | list_add_tail(&rfkill->node, &rfkill_list); |
535 | 560 | ||
561 | error = 0; | ||
562 | unlock_out: | ||
536 | mutex_unlock(&rfkill_mutex); | 563 | mutex_unlock(&rfkill_mutex); |
537 | 564 | ||
538 | return 0; | 565 | return error; |
539 | } | 566 | } |
540 | 567 | ||
541 | static void rfkill_remove_switch(struct rfkill *rfkill) | 568 | static void rfkill_remove_switch(struct rfkill *rfkill) |