diff options
author | florian@mickler.org <florian@mickler.org> | 2010-02-26 06:01:34 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-03-10 17:09:34 -0500 |
commit | 6c26361e4be3cf0dad7083e38ca52001a987e3e6 (patch) | |
tree | 4638fff76e14e4a8ab6de035a8e3ee47cb7bfae1 | |
parent | 69c86373c6ea1149aa559e6088362d58d8ec8835 (diff) |
enhance sysfs rfkill interface
This commit introduces two new sysfs knobs.
/sys/class/rfkill/rfkill[0-9]+/blocked_hw: (ro)
hardblock kill state
/sys/class/rfkill/rfkill[0-9]+/blocked_sw: (rw)
softblock kill state
Signed-off-by: Florian Mickler <florian@mickler.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | Documentation/ABI/stable/sysfs-class-rfkill | 25 | ||||
-rw-r--r-- | net/rfkill/core.c | 58 |
2 files changed, 83 insertions, 0 deletions
diff --git a/Documentation/ABI/stable/sysfs-class-rfkill b/Documentation/ABI/stable/sysfs-class-rfkill index 97d5064f4f84..b91c3f37453a 100644 --- a/Documentation/ABI/stable/sysfs-class-rfkill +++ b/Documentation/ABI/stable/sysfs-class-rfkill | |||
@@ -40,3 +40,28 @@ Description: Whether the soft blocked state is initialised from non-volatile | |||
40 | Values: A numeric value. | 40 | Values: A numeric value. |
41 | 0: false | 41 | 0: false |
42 | 1: true | 42 | 1: true |
43 | |||
44 | |||
45 | What: /sys/class/rfkill/rfkill[0-9]+/blocked_hw | ||
46 | Date: 23-Feb-2010 | ||
47 | KernelVersion v2.6.34 | ||
48 | Contact: linux-wireless@vger.kernel.org | ||
49 | Description: Current hardblock state. This file is read only. | ||
50 | Values: A numeric value. | ||
51 | 0: inactive | ||
52 | The transmitter is (potentially) active. | ||
53 | 1: active | ||
54 | The transmitter is forced off by something outside of | ||
55 | the driver's control. | ||
56 | |||
57 | |||
58 | What: /sys/class/rfkill/rfkill[0-9]+/blocked_sw | ||
59 | Date: 23-Feb-2010 | ||
60 | KernelVersion v2.6.34 | ||
61 | Contact: linux-wireless@vger.kernel.org | ||
62 | Description: Current softblock state. This file is read and write. | ||
63 | Values: A numeric value. | ||
64 | 0: inactive | ||
65 | The transmitter is (potentially) active. | ||
66 | 1: active | ||
67 | The transmitter is turned off by software. | ||
diff --git a/net/rfkill/core.c b/net/rfkill/core.c index c218e07e5caf..5f33151d70ae 100644 --- a/net/rfkill/core.c +++ b/net/rfkill/core.c | |||
@@ -628,6 +628,61 @@ 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_blocked_hw_show(struct device *dev, | ||
632 | struct device_attribute *attr, | ||
633 | char *buf) | ||
634 | { | ||
635 | struct rfkill *rfkill = to_rfkill(dev); | ||
636 | unsigned long flags; | ||
637 | u32 state; | ||
638 | |||
639 | spin_lock_irqsave(&rfkill->lock, flags); | ||
640 | state = rfkill->state; | ||
641 | spin_unlock_irqrestore(&rfkill->lock, flags); | ||
642 | |||
643 | return sprintf(buf, "%d\n", (state & RFKILL_BLOCK_HW) ? 1 : 0 ); | ||
644 | } | ||
645 | |||
646 | static ssize_t rfkill_blocked_sw_show(struct device *dev, | ||
647 | struct device_attribute *attr, | ||
648 | char *buf) | ||
649 | { | ||
650 | struct rfkill *rfkill = to_rfkill(dev); | ||
651 | unsigned long flags; | ||
652 | u32 state; | ||
653 | |||
654 | spin_lock_irqsave(&rfkill->lock, flags); | ||
655 | state = rfkill->state; | ||
656 | spin_unlock_irqrestore(&rfkill->lock, flags); | ||
657 | |||
658 | return sprintf(buf, "%d\n", (state & RFKILL_BLOCK_SW) ? 1 : 0 ); | ||
659 | } | ||
660 | |||
661 | static ssize_t rfkill_blocked_sw_store(struct device *dev, | ||
662 | struct device_attribute *attr, | ||
663 | const char *buf, size_t count) | ||
664 | { | ||
665 | struct rfkill *rfkill = to_rfkill(dev); | ||
666 | unsigned long state; | ||
667 | int err; | ||
668 | |||
669 | if (!capable(CAP_NET_ADMIN)) | ||
670 | return -EPERM; | ||
671 | |||
672 | err = strict_strtoul(buf, 0, &state); | ||
673 | if (err) | ||
674 | return err; | ||
675 | |||
676 | if (state > 1 ) | ||
677 | return -EINVAL; | ||
678 | |||
679 | mutex_lock(&rfkill_global_mutex); | ||
680 | rfkill_set_block(rfkill, state); | ||
681 | mutex_unlock(&rfkill_global_mutex); | ||
682 | |||
683 | return err ?: count; | ||
684 | } | ||
685 | |||
631 | static u8 user_state_from_blocked(unsigned long state) | 686 | static u8 user_state_from_blocked(unsigned long state) |
632 | { | 687 | { |
633 | if (state & RFKILL_BLOCK_HW) | 688 | if (state & RFKILL_BLOCK_HW) |
@@ -700,6 +755,9 @@ static struct device_attribute rfkill_dev_attrs[] = { | |||
700 | __ATTR(persistent, S_IRUGO, rfkill_persistent_show, NULL), | 755 | __ATTR(persistent, S_IRUGO, rfkill_persistent_show, NULL), |
701 | __ATTR(state, S_IRUGO|S_IWUSR, rfkill_state_show, rfkill_state_store), | 756 | __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), | 757 | __ATTR(claim, S_IRUGO|S_IWUSR, rfkill_claim_show, rfkill_claim_store), |
758 | __ATTR(sw, S_IRUGO|S_IWUSR, rfkill_blocked_sw_show, | ||
759 | rfkill_blocked_sw_store), | ||
760 | __ATTR(hw, S_IRUGO, rfkill_blocked_hw_show, NULL), | ||
703 | __ATTR_NULL | 761 | __ATTR_NULL |
704 | }; | 762 | }; |
705 | 763 | ||