diff options
Diffstat (limited to 'net/rfkill/core.c')
-rw-r--r-- | net/rfkill/core.c | 53 |
1 files changed, 46 insertions, 7 deletions
diff --git a/net/rfkill/core.c b/net/rfkill/core.c index c218e07e5caf..7ae58b5b5a08 100644 --- a/net/rfkill/core.c +++ b/net/rfkill/core.c | |||
@@ -628,6 +628,49 @@ static ssize_t rfkill_persistent_show(struct device *dev, | |||
628 | return sprintf(buf, "%d\n", rfkill->persistent); | 628 | return sprintf(buf, "%d\n", rfkill->persistent); |
629 | } | 629 | } |
630 | 630 | ||
631 | static ssize_t rfkill_hard_show(struct device *dev, | ||
632 | struct device_attribute *attr, | ||
633 | char *buf) | ||
634 | { | ||
635 | struct rfkill *rfkill = to_rfkill(dev); | ||
636 | |||
637 | return sprintf(buf, "%d\n", (rfkill->state & RFKILL_BLOCK_HW) ? 1 : 0 ); | ||
638 | } | ||
639 | |||
640 | static ssize_t rfkill_soft_show(struct device *dev, | ||
641 | struct device_attribute *attr, | ||
642 | char *buf) | ||
643 | { | ||
644 | struct rfkill *rfkill = to_rfkill(dev); | ||
645 | |||
646 | return sprintf(buf, "%d\n", (rfkill->state & RFKILL_BLOCK_SW) ? 1 : 0 ); | ||
647 | } | ||
648 | |||
649 | static ssize_t rfkill_soft_store(struct device *dev, | ||
650 | struct device_attribute *attr, | ||
651 | const char *buf, size_t count) | ||
652 | { | ||
653 | struct rfkill *rfkill = to_rfkill(dev); | ||
654 | unsigned long state; | ||
655 | int err; | ||
656 | |||
657 | if (!capable(CAP_NET_ADMIN)) | ||
658 | return -EPERM; | ||
659 | |||
660 | err = strict_strtoul(buf, 0, &state); | ||
661 | if (err) | ||
662 | return err; | ||
663 | |||
664 | if (state > 1 ) | ||
665 | return -EINVAL; | ||
666 | |||
667 | mutex_lock(&rfkill_global_mutex); | ||
668 | rfkill_set_block(rfkill, state); | ||
669 | mutex_unlock(&rfkill_global_mutex); | ||
670 | |||
671 | return err ?: count; | ||
672 | } | ||
673 | |||
631 | static u8 user_state_from_blocked(unsigned long state) | 674 | static u8 user_state_from_blocked(unsigned long state) |
632 | { | 675 | { |
633 | if (state & RFKILL_BLOCK_HW) | 676 | if (state & RFKILL_BLOCK_HW) |
@@ -643,14 +686,8 @@ static ssize_t rfkill_state_show(struct device *dev, | |||
643 | char *buf) | 686 | char *buf) |
644 | { | 687 | { |
645 | struct rfkill *rfkill = to_rfkill(dev); | 688 | struct rfkill *rfkill = to_rfkill(dev); |
646 | unsigned long flags; | ||
647 | u32 state; | ||
648 | |||
649 | spin_lock_irqsave(&rfkill->lock, flags); | ||
650 | state = rfkill->state; | ||
651 | spin_unlock_irqrestore(&rfkill->lock, flags); | ||
652 | 689 | ||
653 | return sprintf(buf, "%d\n", user_state_from_blocked(state)); | 690 | return sprintf(buf, "%d\n", user_state_from_blocked(rfkill->state)); |
654 | } | 691 | } |
655 | 692 | ||
656 | static ssize_t rfkill_state_store(struct device *dev, | 693 | static ssize_t rfkill_state_store(struct device *dev, |
@@ -700,6 +737,8 @@ static struct device_attribute rfkill_dev_attrs[] = { | |||
700 | __ATTR(persistent, S_IRUGO, rfkill_persistent_show, NULL), | 737 | __ATTR(persistent, S_IRUGO, rfkill_persistent_show, NULL), |
701 | __ATTR(state, S_IRUGO|S_IWUSR, rfkill_state_show, rfkill_state_store), | 738 | __ATTR(state, S_IRUGO|S_IWUSR, rfkill_state_show, rfkill_state_store), |
702 | __ATTR(claim, S_IRUGO|S_IWUSR, rfkill_claim_show, rfkill_claim_store), | 739 | __ATTR(claim, S_IRUGO|S_IWUSR, rfkill_claim_show, rfkill_claim_store), |
740 | __ATTR(soft, S_IRUGO|S_IWUSR, rfkill_soft_show, rfkill_soft_store), | ||
741 | __ATTR(hard, S_IRUGO, rfkill_hard_show, NULL), | ||
703 | __ATTR_NULL | 742 | __ATTR_NULL |
704 | }; | 743 | }; |
705 | 744 | ||