From patchwork Mon May 2 14:39:07 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Jo=C3=A3o_Paulo_Rechi_Vita?= X-Patchwork-Id: 8993031 X-Patchwork-Delegate: johannes@sipsolutions.net Return-Path: X-Original-To: patchwork-linux-wireless@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 9ED929F39D for ; Mon, 2 May 2016 14:42:50 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 9C446201B4 for ; Mon, 2 May 2016 14:42:49 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 8964E20173 for ; Mon, 2 May 2016 14:42:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754049AbcEBOji (ORCPT ); Mon, 2 May 2016 10:39:38 -0400 Received: from mail-qk0-f194.google.com ([209.85.220.194]:33913 "EHLO mail-qk0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754027AbcEBOj2 (ORCPT ); Mon, 2 May 2016 10:39:28 -0400 Received: by mail-qk0-f194.google.com with SMTP id i7so8697026qkd.1; Mon, 02 May 2016 07:39:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=eomxSXYYzFL8O7S2Es8fXiislmV9qGg9y1j40SqAbCI=; b=LRtH4IjbQrRZlXiw1LexrTZovYxS06yGpT0kl5h0u8pNosxsfFxPVtfMGU5j6XhnA0 NSswEs2HbZfeM6tx6mwHsx9AWxpHtplNZydjwJ3E58PRSqh4gBK7nYn51gJDFhHq4yre 4UUyTsH0NYaccmwrzXt6NndXA/YbMn1om3jKVJ3fnem5DS3wNXb/9AWhG62p05U2sHcc cMCnVrkeqPITU2SHdXRVXoZB3nWGihjg/2TSo/DjWv6yR49ipXLk6fiEkX9p55dk2uym +hbILawSl7JfY2gpliePs0Q7MCaISWcTznG/ZVtlOxeEEBftlvHKoT58HLHESoYF96G3 qqzw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=eomxSXYYzFL8O7S2Es8fXiislmV9qGg9y1j40SqAbCI=; b=Z0giYmI2n2hfHcPEuzoqTknMGY6IJejVoFUf7Lnl5jJOYSwkr0kLjwubwEHfeyvCfy g4c6zf6RJd15X6nr2AO9TRhh1D3cHMk/4+tIf9JQ1pM0NI0zdw27QRW7FI1a0dOiZ2Ks 5zSZ67042dIVMST0+vOxxZY8j8a3eit0aYEJdAXBoDDm5HWsNc4qHhEDsnTK+117BhlD vrBc/jhsRWYnOMfPViHmFG6A4CGQTjLXj1g19CORnXGEDO2Yh1IKHULVFwjSCPQmC9V3 yGi6j8uMqjBmW/YXFo3D6NKOmKkUETkB9Whwa6+tE9X5M8ypJF6W0J3TWQF9mEBPQe1Y 5XVg== X-Gm-Message-State: AOPr4FVqIQki+LyHf2OcBAT/EEVbaEoAqbthT7/UeLVJfy2irHwF8R1gehUw/emdNmo/nw== X-Received: by 10.55.151.199 with SMTP id z190mr32804444qkd.172.1462199966832; Mon, 02 May 2016 07:39:26 -0700 (PDT) Received: from kiddo.endlessm-sf.com (c-98-239-150-235.hsd1.wv.comcast.net. [98.239.150.235]) by smtp.gmail.com with ESMTPSA id 23sm9313213qkd.8.2016.05.02.07.39.25 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 02 May 2016 07:39:26 -0700 (PDT) From: "=?UTF-8?q?Jo=C3=A3o=20Paulo=20Rechi=20Vita?=" X-Google-Original-From: =?UTF-8?q?Jo=C3=A3o=20Paulo=20Rechi=20Vita?= To: Johannes Berg Cc: "David S. Miller" , Darren Hart , linux-wireless@vger.kernel.org, netdev@vger.kernel.org, platform-driver-x86@vger.kernel.org, linux-api@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux@endlessm.com, =?UTF-8?q?Jo=C3=A3o=20Paulo=20Rechi=20Vita?= , =?UTF-8?q?Jo=C3=A3o=20Paulo=20Rechi=20Vita?= Subject: [RESEND PATCH 2/3] rfkill: Userspace control for airplane mode Date: Mon, 2 May 2016 10:39:07 -0400 Message-Id: <1462199948-6424-3-git-send-email-jprvita@endlessm.com> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1462199948-6424-1-git-send-email-jprvita@endlessm.com> References: <1462199948-6424-1-git-send-email-jprvita@endlessm.com> MIME-Version: 1.0 Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Spam-Status: No, score=-7.8 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: João Paulo Rechi Vita Provide an interface for the airplane-mode indicator be controlled from userspace. User has to first acquire the control through RFKILL_OP_AIRPLANE_MODE_INDICATOR_ACQUIRE and keep the fd open for the whole time it wants to be in control of the indicator. Closing the fd restores the default policy. To change state of the indicator, the RFKILL_OP_AIRPLANE_MODE_INDICATOR_CHANGE operation is used, passing the value on "struct rfkill_event.soft". If the caller has not acquired the airplane-mode control beforehand, the operation fails. Signed-off-by: João Paulo Rechi Vita --- Documentation/rfkill.txt | 10 ++++++++++ include/uapi/linux/rfkill.h | 6 ++++++ net/rfkill/core.c | 40 ++++++++++++++++++++++++++++++++++++++-- 3 files changed, 54 insertions(+), 2 deletions(-) diff --git a/Documentation/rfkill.txt b/Documentation/rfkill.txt index b13025a..9dbe3fc 100644 --- a/Documentation/rfkill.txt +++ b/Documentation/rfkill.txt @@ -87,6 +87,7 @@ RFKill provides per-switch LED triggers, which can be used to drive LEDs according to the switch state (LED_FULL when blocked, LED_OFF otherwise). An airplane-mode indicator LED trigger is also available, which triggers LED_FULL when all radios known by RFKill are blocked, and LED_OFF otherwise. +The airplane-mode indicator LED trigger policy can be overridden by userspace. 5. Userspace support @@ -123,5 +124,14 @@ RFKILL_TYPE The contents of these variables corresponds to the "name", "state" and "type" sysfs files explained above. +Userspace can also override the default airplane-mode indicator policy through +/dev/rfkill. Control of the airplane mode indicator has to be acquired first, +using RFKILL_OP_AIRPLANE_MODE_INDICATOR_ACQUIRE, and is only available for one +userspace application at a time. Closing the fd reverts the airplane-mode +indicator back to the default kernel policy and makes it available for other +applications to take control. Changes to the airplane-mode indicator state can +be made using RFKILL_OP_AIRPLANE_MODE_INDICATOR_CHANGE, passing the new value +in the 'soft' field of 'struct rfkill_event'. + For further details consult Documentation/ABI/stable/sysfs-class-rfkill. diff --git a/include/uapi/linux/rfkill.h b/include/uapi/linux/rfkill.h index 2e00dce..36e0770 100644 --- a/include/uapi/linux/rfkill.h +++ b/include/uapi/linux/rfkill.h @@ -61,12 +61,18 @@ enum rfkill_type { * @RFKILL_OP_CHANGE_ALL: userspace changes all devices (of a type, or all) * into a state, also updating the default state used for devices that * are hot-plugged later. + * @RFKILL_OP_AIRPLANE_MODE_INDICATOR_ACQUIRE: userspace acquires control of + * the airplane-mode indicator. + * @RFKILL_OP_AIRPLANE_MODE_INDICATOR_CHANGE: userspace changes the + * airplane-mode indicator state. */ enum rfkill_operation { RFKILL_OP_ADD = 0, RFKILL_OP_DEL, RFKILL_OP_CHANGE, RFKILL_OP_CHANGE_ALL, + RFKILL_OP_AIRPLANE_MODE_INDICATOR_ACQUIRE, + RFKILL_OP_AIRPLANE_MODE_INDICATOR_CHANGE, }; /** diff --git a/net/rfkill/core.c b/net/rfkill/core.c index 9adf95e..95824b3 100644 --- a/net/rfkill/core.c +++ b/net/rfkill/core.c @@ -89,6 +89,7 @@ struct rfkill_data { struct mutex mtx; wait_queue_head_t read_wait; bool input_handler; + bool is_apm_owner; }; @@ -123,7 +124,7 @@ static struct { } rfkill_global_states[NUM_RFKILL_TYPES]; static bool rfkill_epo_lock_active; - +static bool rfkill_apm_owned; #ifdef CONFIG_RFKILL_LEDS static struct led_trigger rfkill_apm_led_trigger; @@ -350,7 +351,8 @@ static void rfkill_update_global_state(enum rfkill_type type, bool blocked) for (i = 0; i < NUM_RFKILL_TYPES; i++) rfkill_global_states[i].cur = blocked; - rfkill_apm_led_trigger_event(blocked); + if (!rfkill_apm_owned) + rfkill_apm_led_trigger_event(blocked); } #ifdef CONFIG_RFKILL_INPUT @@ -1174,9 +1176,23 @@ static ssize_t rfkill_fop_read(struct file *file, char __user *buf, return ret; } +static int rfkill_airplane_mode_release(struct rfkill_data *data) +{ + bool state = rfkill_global_states[RFKILL_TYPE_ALL].cur; + + if (rfkill_apm_owned && data->is_apm_owner) { + rfkill_apm_owned = false; + data->is_apm_owner = false; + rfkill_apm_led_trigger_event(state); + return 0; + } + return -EACCES; +} + static ssize_t rfkill_fop_write(struct file *file, const char __user *buf, size_t count, loff_t *pos) { + struct rfkill_data *data = file->private_data; struct rfkill *rfkill; struct rfkill_event ev; int ret; @@ -1216,6 +1232,25 @@ static ssize_t rfkill_fop_write(struct file *file, const char __user *buf, rfkill_set_block(rfkill, ev.soft); ret = 0; break; + case RFKILL_OP_AIRPLANE_MODE_INDICATOR_ACQUIRE: + if (rfkill_apm_owned && !data->is_apm_owner) { + ret = -EACCES; + break; + } + + rfkill_apm_owned = true; + data->is_apm_owner = true; + ret = 0; + break; + case RFKILL_OP_AIRPLANE_MODE_INDICATOR_CHANGE: + if (!rfkill_apm_owned || !data->is_apm_owner) { + ret = -EACCES; + break; + } + + rfkill_apm_led_trigger_event(ev.soft); + ret = 0; + break; default: ret = -EINVAL; break; @@ -1232,6 +1267,7 @@ static int rfkill_fop_release(struct inode *inode, struct file *file) struct rfkill_int_event *ev, *tmp; mutex_lock(&rfkill_global_mutex); + rfkill_airplane_mode_release(data); list_del(&data->list); mutex_unlock(&rfkill_global_mutex);