cregit-Linux how code gets into the kernel

Release 4.8 net/rfkill/core.c

Directory: net/rfkill
/*
 * Copyright (C) 2006 - 2007 Ivo van Doorn
 * Copyright (C) 2007 Dmitry Torokhov
 * Copyright 2009 Johannes Berg <johannes@sipsolutions.net>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/workqueue.h>
#include <linux/capability.h>
#include <linux/list.h>
#include <linux/mutex.h>
#include <linux/rfkill.h>
#include <linux/sched.h>
#include <linux/spinlock.h>
#include <linux/device.h>
#include <linux/miscdevice.h>
#include <linux/wait.h>
#include <linux/poll.h>
#include <linux/fs.h>
#include <linux/slab.h>

#include "rfkill.h"


#define POLL_INTERVAL		(5 * HZ)


#define RFKILL_BLOCK_HW		BIT(0)

#define RFKILL_BLOCK_SW		BIT(1)

#define RFKILL_BLOCK_SW_PREV	BIT(2)

#define RFKILL_BLOCK_ANY	(RFKILL_BLOCK_HW |\
                                 RFKILL_BLOCK_SW |\
                                 RFKILL_BLOCK_SW_PREV)

#define RFKILL_BLOCK_SW_SETCALL	BIT(31)


struct rfkill {
	
spinlock_t		lock;

	
enum rfkill_type	type;

	
unsigned long		state;

	
u32			idx;

	
bool			registered;
	
bool			persistent;
	
bool			polling_paused;
	
bool			suspended;

	
const struct rfkill_ops	*ops;
	
void			*data;

#ifdef CONFIG_RFKILL_LEDS
	
struct led_trigger	led_trigger;
	
const char		*ledtrigname;
#endif

	
struct device		dev;
	
struct list_head	node;

	
struct delayed_work	poll_work;
	
struct work_struct	uevent_work;
	
struct work_struct	sync_work;
	
char			name[];
};

#define to_rfkill(d)	container_of(d, struct rfkill, dev)


struct rfkill_int_event {
	
struct list_head	list;
	
struct rfkill_event	ev;
};


struct rfkill_data {
	
struct list_head	list;
	
struct list_head	events;
	
struct mutex		mtx;
	
wait_queue_head_t	read_wait;
	
bool			input_handler;
};


MODULE_AUTHOR("Ivo van Doorn <IvDoorn@gmail.com>");
MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
MODULE_DESCRIPTION("RF switch support");
MODULE_LICENSE("GPL");


/*
 * The locking here should be made much smarter, we currently have
 * a bit of a stupid situation because drivers might want to register
 * the rfkill struct under their own lock, and take this lock during
 * rfkill method calls -- which will cause an AB-BA deadlock situation.
 *
 * To fix that, we need to rework this code here to be mostly lock-free
 * and only use the mutex for list manipulations, not to protect the
 * various other global variables. Then we can avoid holding the mutex
 * around driver operations, and all is happy.
 */
static LIST_HEAD(rfkill_list);	/* list of registered rf switches */
static DEFINE_MUTEX(rfkill_global_mutex);
static LIST_HEAD(rfkill_fds);	/* list of open fds of /dev/rfkill */


static unsigned int rfkill_default_state = 1;
module_param_named(default_state, rfkill_default_state, uint, 0444);
MODULE_PARM_DESC(default_state,
		 "Default initial state for all radio types, 0 = radio off");

static struct {
	

bool cur, sav;
} 
rfkill_global_states[NUM_RFKILL_TYPES];


static bool rfkill_epo_lock_active;


#ifdef CONFIG_RFKILL_LEDS

static void rfkill_led_trigger_event(struct rfkill *rfkill) { struct led_trigger *trigger; if (!rfkill->registered) return; trigger = &rfkill->led_trigger; if (rfkill->state & RFKILL_BLOCK_ANY) led_trigger_event(trigger, LED_OFF); else led_trigger_event(trigger, LED_FULL); }

Contributors

PersonTokensPropCommitsCommitProp
michael bueschmichael buesch3768.52%150.00%
johannes bergjohannes berg1731.48%150.00%
Total54100.00%2100.00%


static void rfkill_led_trigger_activate(struct led_classdev *led) { struct rfkill *rfkill; rfkill = container_of(led->trigger, struct rfkill, led_trigger); rfkill_led_trigger_event(rfkill); }

Contributors

PersonTokensPropCommitsCommitProp
dmitry eremin-baryshkovdmitry eremin-baryshkov3085.71%150.00%
johannes bergjohannes berg514.29%150.00%
Total35100.00%2100.00%


const char *rfkill_get_led_trigger_name(struct rfkill *rfkill) { return rfkill->led_trigger.name; }

Contributors

PersonTokensPropCommitsCommitProp
acelan kaoacelan kao19100.00%1100.00%
Total19100.00%1100.00%

EXPORT_SYMBOL(rfkill_get_led_trigger_name);
void rfkill_set_led_trigger_name(struct rfkill *rfkill, const char *name) { BUG_ON(!rfkill); rfkill->ledtrigname = name; }

Contributors

PersonTokensPropCommitsCommitProp
acelan kaoacelan kao27100.00%1100.00%
Total27100.00%1100.00%

EXPORT_SYMBOL(rfkill_set_led_trigger_name);
static int rfkill_led_trigger_register(struct rfkill *rfkill) { rfkill->led_trigger.name = rfkill->ledtrigname ? : dev_name(&rfkill->dev); rfkill->led_trigger.activate = rfkill_led_trigger_activate; return led_trigger_register(&rfkill->led_trigger); }

Contributors

PersonTokensPropCommitsCommitProp
johannes bergjohannes berg2553.19%150.00%
henrique de moraes holschuhhenrique de moraes holschuh2246.81%150.00%
Total47100.00%2100.00%


static void rfkill_led_trigger_unregister(struct rfkill *rfkill) { led_trigger_unregister(&rfkill->led_trigger); }

Contributors

PersonTokensPropCommitsCommitProp
johannes bergjohannes berg1578.95%150.00%
henrique de moraes holschuhhenrique de moraes holschuh421.05%150.00%
Total19100.00%2100.00%

#else
static void rfkill_led_trigger_event(struct rfkill *rfkill) { }

Contributors

PersonTokensPropCommitsCommitProp
johannes bergjohannes berg990.00%150.00%
henrique de moraes holschuhhenrique de moraes holschuh110.00%150.00%
Total10100.00%2100.00%


static inline int rfkill_led_trigger_register(struct rfkill *rfkill) { return 0; }

Contributors

PersonTokensPropCommitsCommitProp
johannes bergjohannes berg15100.00%1100.00%
Total15100.00%1100.00%


static inline void rfkill_led_trigger_unregister(struct rfkill *rfkill) { }

Contributors

PersonTokensPropCommitsCommitProp
johannes bergjohannes berg11100.00%1100.00%
Total11100.00%1100.00%

#endif /* CONFIG_RFKILL_LEDS */
static void rfkill_fill_event(struct rfkill_event *ev, struct rfkill *rfkill, enum rfkill_operation op) { unsigned long flags; ev->idx = rfkill->idx; ev->type = rfkill->type; ev->op = op; spin_lock_irqsave(&rfkill->lock, flags); ev->hard = !!(rfkill->state & RFKILL_BLOCK_HW); ev->soft = !!(rfkill->state & (RFKILL_BLOCK_SW | RFKILL_BLOCK_SW_PREV)); spin_unlock_irqrestore(&rfkill->lock, flags); }

Contributors

PersonTokensPropCommitsCommitProp
johannes bergjohannes berg98100.00%1100.00%
Total98100.00%1100.00%


static void rfkill_send_events(struct rfkill *rfkill, enum rfkill_operation op) { struct rfkill_data *data; struct rfkill_int_event *ev; list_for_each_entry(data, &rfkill_fds, list) { ev = kzalloc(sizeof(*ev), GFP_KERNEL); if (!ev) continue; rfkill_fill_event(&ev->ev, rfkill, op); mutex_lock(&data->mtx); list_add_tail(&ev->list, &data->events); mutex_unlock(&data->mtx); wake_up_interruptible(&data->read_wait); } }

Contributors

PersonTokensPropCommitsCommitProp
johannes bergjohannes berg103100.00%1100.00%
Total103100.00%1100.00%


static void rfkill_event(struct rfkill *rfkill) { if (!rfkill->registered) return; kobject_uevent(&rfkill->dev.kobj, KOBJ_CHANGE); /* also send event to /dev/rfkill */ rfkill_send_events(rfkill, RFKILL_OP_CHANGE); }

Contributors

PersonTokensPropCommitsCommitProp
johannes bergjohannes berg3179.49%266.67%
henrique de moraes holschuhhenrique de moraes holschuh820.51%133.33%
Total39100.00%3100.00%

/** * rfkill_set_block - wrapper for set_block method * * @rfkill: the rfkill struct to use * @blocked: the new software state * * Calls the set_block method (when applicable) and handles notifications * etc. as well. */
static void rfkill_set_block(struct rfkill *rfkill, bool blocked) { unsigned long flags; bool prev, curr; int err; if (unlikely(rfkill->dev.power.power_state.event & PM_EVENT_SLEEP)) return; /* * Some platforms (...!) generate input events which affect the * _hard_ kill state -- whenever something tries to change the * current software state query the hardware state too. */ if (rfkill->ops->query) rfkill->ops->query(rfkill, rfkill->data); spin_lock_irqsave(&rfkill->lock, flags); prev = rfkill->state & RFKILL_BLOCK_SW; if (prev) rfkill->state |= RFKILL_BLOCK_SW_PREV; else rfkill->state &= ~RFKILL_BLOCK_SW_PREV; if (blocked) rfkill->state |= RFKILL_BLOCK_SW; else rfkill->state &= ~RFKILL_BLOCK_SW; rfkill->state |= RFKILL_BLOCK_SW_SETCALL; spin_unlock_irqrestore(&rfkill->lock, flags); err = rfkill->ops->set_block(rfkill->data, blocked); spin_lock_irqsave(&rfkill->lock, flags); if (err) { /* * Failed -- reset status to _PREV, which may be different * from what we have set _PREV to earlier in this function * if rfkill_set_sw_state was invoked. */ if (rfkill->state & RFKILL_BLOCK_SW_PREV) rfkill->state |= RFKILL_BLOCK_SW; else rfkill->state &= ~RFKILL_BLOCK_SW; } rfkill->state &= ~RFKILL_BLOCK_SW_SETCALL; rfkill->state &= ~RFKILL_BLOCK_SW_PREV; curr = rfkill->state & RFKILL_BLOCK_SW; spin_unlock_irqrestore(&rfkill->lock, flags); rfkill_led_trigger_event(rfkill); if (prev != curr) rfkill_event(rfkill); }

Contributors

PersonTokensPropCommitsCommitProp
johannes bergjohannes berg11447.90%215.38%
henrique de moraes holschuhhenrique de moraes holschuh4318.07%538.46%
ivo van doornivo van doorn2912.18%17.69%
vitaly woolvitaly wool2711.34%17.69%
alan jenkinsalan jenkins187.56%17.69%
larry fingerlarry finger52.10%17.69%
joao paulo rechi vitajoao paulo rechi vita20.84%215.38%
Total238100.00%13100.00%


static void rfkill_update_global_state(enum rfkill_type type, bool blocked) { int i; if (type != RFKILL_TYPE_ALL) { rfkill_global_states[type].cur = blocked; return; } for (i = 0; i < NUM_RFKILL_TYPES; i++) rfkill_global_states[i].cur = blocked; }

Contributors

PersonTokensPropCommitsCommitProp
joao paulo rechi vitajoao paulo rechi vita4478.57%240.00%
ivo van doornivo van doorn916.07%120.00%
johannes bergjohannes berg23.57%120.00%
henrique de moraes holschuhhenrique de moraes holschuh11.79%120.00%
Total56100.00%5100.00%

#ifdef CONFIG_RFKILL_INPUT static atomic_t rfkill_input_disabled = ATOMIC_INIT(0); /** * __rfkill_switch_all - Toggle state of all switches of given type * @type: type of interfaces to be affected * @blocked: the new state * * This function sets the state of all switches of given type, * unless a specific switch is suspended. * * Caller must have acquired rfkill_global_mutex. */
static void __rfkill_switch_all(const enum rfkill_type type, bool blocked) { struct rfkill *rfkill; rfkill_update_global_state(type, blocked); list_for_each_entry(rfkill, &rfkill_list, node) { if (rfkill->type != type && type != RFKILL_TYPE_ALL) continue; rfkill_set_block(rfkill, blocked); } }

Contributors

PersonTokensPropCommitsCommitProp
joao paulo rechi vitajoao paulo rechi vita2239.29%233.33%
ivo van doornivo van doorn1425.00%116.67%
johannes bergjohannes berg1221.43%116.67%
alex hungalex hung47.14%116.67%
carlos corbachocarlos corbacho47.14%116.67%
Total56100.00%6100.00%

/** * rfkill_switch_all - Toggle state of all switches of given type * @type: type of interfaces to be affected * @blocked: the new state * * Acquires rfkill_global_mutex and calls __rfkill_switch_all(@type, @state). * Please refer to __rfkill_switch_all() for details. * * Does nothing if the EPO lock is active. */
void rfkill_switch_all(enum rfkill_type type, bool blocked) { if (atomic_read(&rfkill_input_disabled)) return; mutex_lock(&rfkill_global_mutex); if (!rfkill_epo_lock_active) __rfkill_switch_all(type, blocked); mutex_unlock(&rfkill_global_mutex); }

Contributors

PersonTokensPropCommitsCommitProp
johannes bergjohannes berg3271.11%240.00%
henrique de moraes holschuhhenrique de moraes holschuh1022.22%240.00%
ivo van doornivo van doorn36.67%120.00%
Total45100.00%5100.00%

/** * rfkill_epo - emergency power off all transmitters * * This kicks all non-suspended rfkill devices to RFKILL_STATE_SOFT_BLOCKED, * ignoring everything in its path but rfkill_global_mutex and rfkill->mutex. * * The global state before the EPO is saved and can be restored later * using rfkill_restore_states(). */
void rfkill_epo(void) { struct rfkill *rfkill; int i; if (atomic_read(&rfkill_input_disabled)) return; mutex_lock(&rfkill_global_mutex); rfkill_epo_lock_active = true; list_for_each_entry(rfkill, &rfkill_list, node) rfkill_set_block(rfkill, true); for (i = 0; i < NUM_RFKILL_TYPES; i++) { rfkill_global_states[i].sav = rfkill_global_states[i].cur; rfkill_global_states[i].cur = true; } mutex_unlock(&rfkill_global_mutex); }

Contributors

PersonTokensPropCommitsCommitProp
johannes bergjohannes berg8288.17%233.33%
larry fingerlarry finger55.38%116.67%
henrique de moraes holschuhhenrique de moraes holschuh55.38%233.33%
alan jenkinsalan jenkins11.08%116.67%
Total93100.00%6100.00%

/** * rfkill_restore_states - restore global states * * Restore (and sync switches to) the global state from the * states in rfkill_default_states. This can undo the effects of * a call to rfkill_epo(). */
void rfkill_restore_states(void) { int i; if (atomic_read(&rfkill_input_disabled)) return; mutex_lock(&rfkill_global_mutex); rfkill_epo_lock_active = false; for (i = 0; i < NUM_RFKILL_TYPES; i++) __rfkill_switch_all(i, rfkill_global_states[i].sav); mutex_unlock(&rfkill_global_mutex); }

Contributors

PersonTokensPropCommitsCommitProp
johannes bergjohannes berg3761.67%228.57%
henrique de moraes holschuhhenrique de moraes holschuh1626.67%342.86%
ivo van doornivo van doorn610.00%114.29%
alan jenkinsalan jenkins11.67%114.29%
Total60100.00%7100.00%

/** * rfkill_remove_epo_lock - unlock state changes * * Used by rfkill-input manually unlock state changes, when * the EPO switch is deactivated. */
void rfkill_remove_epo_lock(void) { if (atomic_read(&rfkill_input_disabled)) return; mutex_lock(&rfkill_global_mutex); rfkill_epo_lock_active = false; mutex_unlock(&rfkill_global_mutex); }

Contributors

PersonTokensPropCommitsCommitProp
johannes bergjohannes berg2990.62%266.67%
ivo van doornivo van doorn39.38%133.33%
Total32100.00%3100.00%

/** * rfkill_is_epo_lock_active - returns true EPO is active * * Returns 0 (false) if there is NOT an active EPO contidion, * and 1 (true) if there is an active EPO contition, which * locks all radios in one of the BLOCKED states. * * Can be called in atomic context. */
bool rfkill_is_epo_lock_active(void) { return rfkill_epo_lock_active; }

Contributors

PersonTokensPropCommitsCommitProp
johannes bergjohannes berg990.00%150.00%
henrique de moraes holschuhhenrique de moraes holschuh110.00%150.00%
Total10100.00%2100.00%

/** * rfkill_get_global_sw_state - returns global state for a type * @type: the type to get the global state of * * Returns the current global state for a given wireless * device type. */
bool rfkill_get_global_sw_state(const enum rfkill_type type) { return rfkill_global_states[type].cur; }

Contributors

PersonTokensPropCommitsCommitProp
johannes bergjohannes berg1794.44%150.00%
henrique de moraes holschuhhenrique de moraes holschuh15.56%150.00%
Total18100.00%2100.00%

#endif
bool rfkill_set_hw_state(struct rfkill *rfkill, bool blocked) { unsigned long flags; bool ret, prev; BUG_ON(!rfkill); spin_lock_irqsave(&rfkill->lock, flags); prev = !!(rfkill->state & RFKILL_BLOCK_HW); if (blocked) rfkill->state |= RFKILL_BLOCK_HW; else rfkill->state &= ~RFKILL_BLOCK_HW; ret = !!(rfkill->state & RFKILL_BLOCK_ANY); spin_unlock_irqrestore(&rfkill->lock, flags); rfkill_led_trigger_event(rfkill); if (!rfkill->registered) return ret; if (prev != blocked) schedule_work(&rfkill->uevent_work); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
joao paulo rechi vitajoao paulo rechi vita7259.02%133.33%
johannes bergjohannes berg3629.51%133.33%
henrique de moraes holschuhhenrique de moraes holschuh1411.48%133.33%
Total122100.00%3100.00%

EXPORT_SYMBOL(rfkill_set_hw_state);
static void __rfkill_set_sw_state(struct rfkill *rfkill, bool blocked) { u32 bit = RFKILL_BLOCK_SW; /* if in a ops->set_block right now, use other bit */ if (rfkill->state & RFKILL_BLOCK_SW_SETCALL) bit = RFKILL_BLOCK_SW_PREV; if (blocked) rfkill->state |= bit; else rfkill->state &= ~bit; }

Contributors

PersonTokensPropCommitsCommitProp
johannes bergjohannes berg4692.00%150.00%
henrique de moraes holschuhhenrique de moraes holschuh48.00%150.00%
Total50100.00%2100.00%


bool rfkill_set_sw_state(struct rfkill *rfkill, bool blocked) { unsigned long flags; bool prev, hwblock; BUG_ON(!rfkill); spin_lock_irqsave(&rfkill->lock, flags); prev = !!(rfkill->state & RFKILL_BLOCK_SW); __rfkill_set_sw_state(rfkill, blocked); hwblock = !!(rfkill->state & RFKILL_BLOCK_HW); blocked = blocked || hwblock; spin_unlock_irqrestore(&rfkill->lock, flags); if (!rfkill->registered) return blocked; if (prev != blocked && !hwblock) schedule_work(&rfkill->uevent_work); rfkill_led_trigger_event(rfkill); return blocked; }

Contributors

PersonTokensPropCommitsCommitProp
johannes bergjohannes berg9881.67%125.00%
henrique de moraes holschuhhenrique de moraes holschuh1915.83%250.00%
alan jenkinsalan jenkins32.50%125.00%
Total120100.00%4100.00%

EXPORT_SYMBOL(rfkill_set_sw_state);
void rfkill_init_sw_state(struct rfkill *rfkill, bool blocked) { unsigned long flags; BUG_ON(!rfkill); BUG_ON(rfkill->registered); spin_lock_irqsave(&rfkill->lock, flags); __rfkill_set_sw_state(rfkill, blocked); rfkill->persistent = true; spin_unlock_irqrestore(&rfkill->lock, flags); }

Contributors

PersonTokensPropCommitsCommitProp
alan jenkinsalan jenkins63100.00%1100.00%
Total63100.00%1100.00%

EXPORT_SYMBOL(rfkill_init_sw_state);
void rfkill_set_states(struct rfkill *rfkill, bool sw, bool hw) { unsigned long flags; bool swprev, hwprev; BUG_ON(!rfkill); spin_lock_irqsave(&rfkill->lock, flags); /* * No need to care about prev/setblock ... this is for uevent only * and that will get triggered by rfkill_set_block anyway. */ swprev = !!(rfkill->state & RFKILL_BLOCK_SW); hwprev = !!(rfkill->state & RFKILL_BLOCK_HW); __rfkill_set_sw_state(rfkill, sw); if (hw) rfkill->state |= RFKILL_BLOCK_HW; else rfkill->state &= ~RFKILL_BLOCK_HW; spin_unlock_irqrestore(&rfkill->lock, flags); if (!rfkill->registered) { rfkill->persistent = true; } else { if (swprev != sw || hwprev != hw) schedule_work(&rfkill->uevent_work); rfkill_led_trigger_event(rfkill); } }

Contributors

PersonTokensPropCommitsCommitProp
johannes bergjohannes berg6747.18%114.29%
henrique de moraes holschuhhenrique de moraes holschuh4128.87%342.86%
alan jenkinsalan jenkins2920.42%228.57%
larry fingerlarry finger53.52%114.29%
Total142100.00%7100.00%

EXPORT_SYMBOL(rfkill_set_states); static const char * const rfkill_types[] = { NULL, /* RFKILL_TYPE_ALL */ "wlan", "bluetooth", "ultrawideband", "wimax", "wwan", "gps", "fm", "nfc", };
enum rfkill_type rfkill_find_type(const char *name) { int i; BUILD_BUG_ON(ARRAY_SIZE(rfkill_types) != NUM_RFKILL_TYPES); if (!name) return RFKILL_TYPE_ALL; for (i = 1; i < NUM_RFKILL_TYPES; i++) if (!strcmp(name, rfkill_types[i])) return i; return RFKILL_TYPE_ALL; }

Contributors

PersonTokensPropCommitsCommitProp
heikki krogerusheikki krogerus6296.88%133.33%
larry fingerlarry finger11.56%133.33%
alan jenkinsalan jenkins11.56%133.33%
Total64100.00%3100.00%

EXPORT_SYMBOL(rfkill_find_type);
static ssize_t name_show(struct device *dev, struct device_attribute *attr, char *buf) { struct rfkill *rfkill = to_rfkill(dev); return sprintf(buf, "%s\n", rfkill->name); }

Contributors

PersonTokensPropCommitsCommitProp
ivo van doornivo van doorn4197.62%150.00%
greg kroah-hartmangreg kroah-hartman12.38%150.00%
Total42100.00%2100.00%

static DEVICE_ATTR_RO(name);
static ssize_t type_show(struct device *dev, struct device_attribute *attr, char *buf) { struct rfkill *rfkill = to_rfkill(dev); return sprintf(buf, "%s\n", rfkill_types[rfkill->type]); }

Contributors

PersonTokensPropCommitsCommitProp
henrique de moraes holschuhhenrique de moraes holschuh3168.89%125.00%
ivo van doornivo van doorn1022.22%125.00%
heikki krogerusheikki krogerus36.67%125.00%
greg kroah-hartmangreg kroah-hartman12.22%125.00%
Total45100.00%4100.00%

static DEVICE_ATTR_RO(type);
static ssize_t index_show(struct device *dev, struct device_attribute *attr, char *buf) { struct rfkill *rfkill = to_rfkill(dev); return sprintf(buf, "%d\n", rfkill->idx); }

Contributors

PersonTokensPropCommitsCommitProp
johannes bergjohannes berg4197.62%150.00%
greg kroah-hartmangreg kroah-hartman12.38%150.00%
Total42100.00%2100.00%

static DEVICE_ATTR_RO(index);
static ssize_t persistent_show(struct device *dev, struct device_attribute *attr, char *buf) { struct rfkill *rfkill = to_rfkill(dev); return sprintf(buf, "%d\n", rfkill->persistent); }

Contributors

PersonTokensPropCommitsCommitProp
alan jenkinsalan jenkins4197.62%150.00%
greg kroah-hartmangreg kroah-hartman12.38%150.00%
Total42100.00%2100.00%

static DEVICE_ATTR_RO(persistent);
static ssize_t hard_show(struct device *dev, struct device_attribute *attr, char *buf) { struct rfkill *rfkill = to_rfkill(dev); return sprintf(buf, "%d\n", (rfkill->state & RFKILL_BLOCK_HW) ? 1 : 0 ); }

Contributors

PersonTokensPropCommitsCommitProp
florian micklerflorian mickler4998.00%266.67%
greg kroah-hartmangreg kroah-hartman12.00%133.33%
Total50100.00%3100.00%

static DEVICE_ATTR_RO(hard);
static ssize_t soft_show(struct device *dev, struct device_attribute *attr, char *buf) { struct rfkill *rfkill = to_rfkill(dev); return sprintf(buf, "%d\n", (rfkill->state & RFKILL_BLOCK_SW) ? 1 : 0 ); }

Contributors

PersonTokensPropCommitsCommitProp
florian micklerflorian mickler4998.00%266.67%
greg kroah-hartmangreg kroah-hartman12.00%133.33%
Total50100.00%3100.00%


static ssize_t soft_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct rfkill *rfkill = to_rfkill(dev); unsigned long state; int err; if (!capable(CAP_NET_ADMIN)) return -EPERM; err = kstrtoul(buf, 0, &state); if (err) return err; if (state > 1 ) return -EINVAL; mutex_lock(&rfkill_global_mutex); rfkill_set_block(rfkill, state); mutex_unlock(&rfkill_global_mutex); return count; }

Contributors

PersonTokensPropCommitsCommitProp
florian micklerflorian mickler10298.08%133.33%
julia lawalljulia lawall10.96%133.33%
greg kroah-hartmangreg kroah-hartman10.96%133.33%
Total104100.00%3100.00%

static DEVICE_ATTR_RW(soft);
static u8 user_state_from_blocked(unsigned long state) { if (state & RFKILL_BLOCK_HW) return RFKILL_USER_STATE_HARD_BLOCKED; if (state & RFKILL_BLOCK_SW) return RFKILL_USER_STATE_SOFT_BLOCKED; return RFKILL_USER_STATE_UNBLOCKED; }

Contributors

PersonTokensPropCommitsCommitProp
johannes bergjohannes berg2374.19%150.00%
ivo van doornivo van doorn825.81%150.00%
Total31100.00%2100.00%


static ssize_t state_show(struct device *dev, struct device_attribute *attr, char *buf) { struct rfkill *rfkill = to_rfkill(dev); return sprintf(buf, "%d\n", user_state_from_blocked(rfkill->state)); }

Contributors

PersonTokensPropCommitsCommitProp
ivo van doornivo van doorn2351.11%125.00%
johannes bergjohannes berg1942.22%125.00%
florian micklerflorian mickler24.44%125.00%
greg kroah-hartmangreg kroah-hartman12.22%125.00%
Total45100.00%4100.00%


static ssize_t state_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct rfkill *rfkill = to_rfkill(dev); unsigned long state; int err; if (!capable(CAP_NET_ADMIN)) return -EPERM; err = kstrtoul(buf, 0, &state); if (err) return err; if (state != RFKILL_USER_STATE_SOFT_BLOCKED && state != RFKILL_USER_STATE_UNBLOCKED) return -EINVAL; mutex_lock(&rfkill_global_mutex); rfkill_set_block(rfkill, state == RFKILL_USER_STATE_SOFT_BLOCKED); mutex_unlock(&rfkill_global_mutex); return count; }

Contributors

PersonTokensPropCommitsCommitProp
johannes bergjohannes berg10595.45%240.00%
ivo van doornivo van doorn32.73%120.00%
greg kroah-hartmangreg kroah-hartman10.91%120.00%
julia lawalljulia lawall10.91%120.00%
Total110100.00%5100.00%

static DEVICE_ATTR_RW(state); static struct attribute *rfkill_dev_attrs[] = { &dev_attr_name.attr, &dev_attr_type.attr, &dev_attr_index.attr, &dev_attr_persistent.attr, &dev_attr_state.attr, &dev_attr_soft.attr, &dev_attr_hard.attr, NULL, }; ATTRIBUTE_GROUPS(rfkill_dev);
static void rfkill_release(struct device *dev) { struct rfkill *rfkill = to_rfkill(dev); kfree(rfkill); }

Contributors

PersonTokensPropCommitsCommitProp
ivo van doornivo van doorn26100.00%1100.00%
Total26100.00%1100.00%


static int rfkill_dev_uevent(struct device *dev, struct kobj_uevent_env *env) { struct rfkill *rfkill = to_rfkill(dev); unsigned long flags; u32 state; int error; error = add_uevent_var(env, "RFKILL_NAME=%s", rfkill->name); if (error) return error; error = add_uevent_var(env, "RFKILL_TYPE=%s", rfkill_types[rfkill->type]); if (error) return error; spin_lock_irqsave(&rfkill->lock, flags); state = rfkill->state; spin_unlock_irqrestore(&rfkill->lock, flags); error = add_uevent_var(env, "RFKILL_STATE=%d", user_state_from_blocked(state)); return error; }

Contributors

PersonTokensPropCommitsCommitProp
henrique de moraes holschuhhenrique de moraes holschuh8368.03%133.33%
johannes bergjohannes berg3629.51%133.33%
heikki krogerusheikki krogerus32.46%133.33%
Total122100.00%3100.00%


void rfkill_pause_polling(struct rfkill *rfkill) { BUG_ON(!rfkill); if (!rfkill->ops->poll) return; rfkill->polling_paused = true; cancel_delayed_work_sync(&rfkill->poll_work); }

Contributors

PersonTokensPropCommitsCommitProp
johannes bergjohannes berg2152.50%250.00%
henrique de moraes holschuhhenrique de moraes holschuh1947.50%250.00%
Total40100.00%4100.00%

EXPORT_SYMBOL(rfkill_pause_polling);
void rfkill_resume_polling(struct rfkill