aboutsummaryrefslogtreecommitdiffstats
path: root/net/rfkill
diff options
context:
space:
mode:
authorHenrique de Moraes Holschuh <hmh@hmh.eng.br>2008-06-23 16:46:42 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-06-26 14:21:22 -0400
commit5005657cbd0fd6f277f807c0612a6b6d4396a02c (patch)
treee6ed81f07a1a85ed2c440ac8631ca19cc77907c1 /net/rfkill
parentdc288520a21879c6540f3249e9532c5e032da4e8 (diff)
rfkill: rename the rfkill_state states and add block-locked state
The current naming of rfkill_state causes a lot of confusion: not only the "kill" in rfkill suggests negative logic, but also the fact that rfkill cannot turn anything on (it can just force something off or stop forcing something off) is often forgotten. Rename RFKILL_STATE_OFF to RFKILL_STATE_SOFT_BLOCKED (transmitter is blocked and will not operate; state can be changed by a toggle_radio request), and RFKILL_STATE_ON to RFKILL_STATE_UNBLOCKED (transmitter is not blocked, and may operate). Also, add a new third state, RFKILL_STATE_HARD_BLOCKED (transmitter is blocked and will not operate; state cannot be changed through a toggle_radio request), which is used by drivers to indicate a wireless transmiter was blocked by a hardware rfkill line that accepts no overrides. Keep the old names as #defines, but document them as deprecated. This way, drivers can be converted to the new names *and* verified to actually use rfkill correctly one by one. Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br> Acked-by: Ivo van Doorn <IvDoorn@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/rfkill')
-rw-r--r--net/rfkill/rfkill-input.c29
-rw-r--r--net/rfkill/rfkill.c75
2 files changed, 76 insertions, 28 deletions
diff --git a/net/rfkill/rfkill-input.c b/net/rfkill/rfkill-input.c
index 5d4c8b2446f7..8aa822730145 100644
--- a/net/rfkill/rfkill-input.c
+++ b/net/rfkill/rfkill-input.c
@@ -84,7 +84,8 @@ static void rfkill_schedule_toggle(struct rfkill_task *task)
84 spin_lock_irqsave(&task->lock, flags); 84 spin_lock_irqsave(&task->lock, flags);
85 85
86 if (time_after(jiffies, task->last + msecs_to_jiffies(200))) { 86 if (time_after(jiffies, task->last + msecs_to_jiffies(200))) {
87 task->desired_state = !task->desired_state; 87 task->desired_state =
88 rfkill_state_complement(task->desired_state);
88 task->last = jiffies; 89 task->last = jiffies;
89 schedule_work(&task->work); 90 schedule_work(&task->work);
90 } 91 }
@@ -92,14 +93,14 @@ static void rfkill_schedule_toggle(struct rfkill_task *task)
92 spin_unlock_irqrestore(&task->lock, flags); 93 spin_unlock_irqrestore(&task->lock, flags);
93} 94}
94 95
95#define DEFINE_RFKILL_TASK(n, t) \ 96#define DEFINE_RFKILL_TASK(n, t) \
96 struct rfkill_task n = { \ 97 struct rfkill_task n = { \
97 .work = __WORK_INITIALIZER(n.work, \ 98 .work = __WORK_INITIALIZER(n.work, \
98 rfkill_task_handler), \ 99 rfkill_task_handler), \
99 .type = t, \ 100 .type = t, \
100 .mutex = __MUTEX_INITIALIZER(n.mutex), \ 101 .mutex = __MUTEX_INITIALIZER(n.mutex), \
101 .lock = __SPIN_LOCK_UNLOCKED(n.lock), \ 102 .lock = __SPIN_LOCK_UNLOCKED(n.lock), \
102 .desired_state = RFKILL_STATE_ON, \ 103 .desired_state = RFKILL_STATE_UNBLOCKED, \
103 } 104 }
104 105
105static DEFINE_RFKILL_TASK(rfkill_wlan, RFKILL_TYPE_WLAN); 106static DEFINE_RFKILL_TASK(rfkill_wlan, RFKILL_TYPE_WLAN);
@@ -135,15 +136,15 @@ static void rfkill_event(struct input_handle *handle, unsigned int type,
135 /* handle EPO (emergency power off) through shortcut */ 136 /* handle EPO (emergency power off) through shortcut */
136 if (data) { 137 if (data) {
137 rfkill_schedule_set(&rfkill_wwan, 138 rfkill_schedule_set(&rfkill_wwan,
138 RFKILL_STATE_ON); 139 RFKILL_STATE_UNBLOCKED);
139 rfkill_schedule_set(&rfkill_wimax, 140 rfkill_schedule_set(&rfkill_wimax,
140 RFKILL_STATE_ON); 141 RFKILL_STATE_UNBLOCKED);
141 rfkill_schedule_set(&rfkill_uwb, 142 rfkill_schedule_set(&rfkill_uwb,
142 RFKILL_STATE_ON); 143 RFKILL_STATE_UNBLOCKED);
143 rfkill_schedule_set(&rfkill_bt, 144 rfkill_schedule_set(&rfkill_bt,
144 RFKILL_STATE_ON); 145 RFKILL_STATE_UNBLOCKED);
145 rfkill_schedule_set(&rfkill_wlan, 146 rfkill_schedule_set(&rfkill_wlan,
146 RFKILL_STATE_ON); 147 RFKILL_STATE_UNBLOCKED);
147 } else 148 } else
148 rfkill_schedule_epo(); 149 rfkill_schedule_epo();
149 break; 150 break;
diff --git a/net/rfkill/rfkill.c b/net/rfkill/rfkill.c
index 7d07175c407f..ce0e23148cdd 100644
--- a/net/rfkill/rfkill.c
+++ b/net/rfkill/rfkill.c
@@ -39,7 +39,7 @@ MODULE_LICENSE("GPL");
39static LIST_HEAD(rfkill_list); /* list of registered rf switches */ 39static LIST_HEAD(rfkill_list); /* list of registered rf switches */
40static DEFINE_MUTEX(rfkill_mutex); 40static DEFINE_MUTEX(rfkill_mutex);
41 41
42static unsigned int rfkill_default_state = RFKILL_STATE_ON; 42static unsigned int rfkill_default_state = RFKILL_STATE_UNBLOCKED;
43module_param_named(default_state, rfkill_default_state, uint, 0444); 43module_param_named(default_state, rfkill_default_state, uint, 0444);
44MODULE_PARM_DESC(default_state, 44MODULE_PARM_DESC(default_state,
45 "Default initial state for all radio types, 0 = radio off"); 45 "Default initial state for all radio types, 0 = radio off");
@@ -98,7 +98,7 @@ static void rfkill_led_trigger(struct rfkill *rfkill,
98 98
99 if (!led->name) 99 if (!led->name)
100 return; 100 return;
101 if (state == RFKILL_STATE_OFF) 101 if (state != RFKILL_STATE_UNBLOCKED)
102 led_trigger_event(led, LED_OFF); 102 led_trigger_event(led, LED_OFF);
103 else 103 else
104 led_trigger_event(led, LED_FULL); 104 led_trigger_event(led, LED_FULL);
@@ -128,6 +128,28 @@ static void update_rfkill_state(struct rfkill *rfkill)
128 } 128 }
129} 129}
130 130
131/**
132 * rfkill_toggle_radio - wrapper for toggle_radio hook
133 * calls toggle_radio taking into account a lot of "small"
134 * details.
135 * @rfkill: the rfkill struct to use
136 * @force: calls toggle_radio even if cache says it is not needed,
137 * and also makes sure notifications of the state will be
138 * sent even if it didn't change
139 * @state: the new state to call toggle_radio() with
140 *
141 * This wrappen protects and enforces the API for toggle_radio
142 * calls. Note that @force cannot override a (possibly cached)
143 * state of RFKILL_STATE_HARD_BLOCKED. Any device making use of
144 * RFKILL_STATE_HARD_BLOCKED implements either get_state() or
145 * rfkill_force_state(), so the cache either is bypassed or valid.
146 *
147 * Note that we do call toggle_radio for RFKILL_STATE_SOFT_BLOCKED
148 * even if the radio is in RFKILL_STATE_HARD_BLOCKED state, so as to
149 * give the driver a hint that it should double-BLOCK the transmitter.
150 *
151 * Caller must have aquired rfkill_mutex.
152 */
131static int rfkill_toggle_radio(struct rfkill *rfkill, 153static int rfkill_toggle_radio(struct rfkill *rfkill,
132 enum rfkill_state state, 154 enum rfkill_state state,
133 int force) 155 int force)
@@ -141,9 +163,28 @@ static int rfkill_toggle_radio(struct rfkill *rfkill,
141 !rfkill->get_state(rfkill->data, &newstate)) 163 !rfkill->get_state(rfkill->data, &newstate))
142 rfkill->state = newstate; 164 rfkill->state = newstate;
143 165
166 switch (state) {
167 case RFKILL_STATE_HARD_BLOCKED:
168 /* typically happens when refreshing hardware state,
169 * such as on resume */
170 state = RFKILL_STATE_SOFT_BLOCKED;
171 break;
172 case RFKILL_STATE_UNBLOCKED:
173 /* force can't override this, only rfkill_force_state() can */
174 if (rfkill->state == RFKILL_STATE_HARD_BLOCKED)
175 return -EPERM;
176 break;
177 case RFKILL_STATE_SOFT_BLOCKED:
178 /* nothing to do, we want to give drivers the hint to double
179 * BLOCK even a transmitter that is already in state
180 * RFKILL_STATE_HARD_BLOCKED */
181 break;
182 }
183
144 if (force || state != rfkill->state) { 184 if (force || state != rfkill->state) {
145 retval = rfkill->toggle_radio(rfkill->data, state); 185 retval = rfkill->toggle_radio(rfkill->data, state);
146 if (!retval) 186 /* never allow a HARD->SOFT downgrade! */
187 if (!retval && rfkill->state != RFKILL_STATE_HARD_BLOCKED)
147 rfkill->state = state; 188 rfkill->state = state;
148 } 189 }
149 190
@@ -184,7 +225,7 @@ EXPORT_SYMBOL(rfkill_switch_all);
184/** 225/**
185 * rfkill_epo - emergency power off all transmitters 226 * rfkill_epo - emergency power off all transmitters
186 * 227 *
187 * This kicks all rfkill devices to RFKILL_STATE_OFF, ignoring 228 * This kicks all rfkill devices to RFKILL_STATE_SOFT_BLOCKED, ignoring
188 * everything in its path but rfkill_mutex. 229 * everything in its path but rfkill_mutex.
189 */ 230 */
190void rfkill_epo(void) 231void rfkill_epo(void)
@@ -193,7 +234,7 @@ void rfkill_epo(void)
193 234
194 mutex_lock(&rfkill_mutex); 235 mutex_lock(&rfkill_mutex);
195 list_for_each_entry(rfkill, &rfkill_list, node) { 236 list_for_each_entry(rfkill, &rfkill_list, node) {
196 rfkill_toggle_radio(rfkill, RFKILL_STATE_OFF, 1); 237 rfkill_toggle_radio(rfkill, RFKILL_STATE_SOFT_BLOCKED, 1);
197 } 238 }
198 mutex_unlock(&rfkill_mutex); 239 mutex_unlock(&rfkill_mutex);
199} 240}
@@ -215,8 +256,9 @@ int rfkill_force_state(struct rfkill *rfkill, enum rfkill_state state)
215{ 256{
216 enum rfkill_state oldstate; 257 enum rfkill_state oldstate;
217 258
218 if (state != RFKILL_STATE_OFF && 259 if (state != RFKILL_STATE_SOFT_BLOCKED &&
219 state != RFKILL_STATE_ON) 260 state != RFKILL_STATE_UNBLOCKED &&
261 state != RFKILL_STATE_HARD_BLOCKED)
220 return -EINVAL; 262 return -EINVAL;
221 263
222 mutex_lock(&rfkill->mutex); 264 mutex_lock(&rfkill->mutex);
@@ -290,11 +332,14 @@ static ssize_t rfkill_state_store(struct device *dev,
290 if (!capable(CAP_NET_ADMIN)) 332 if (!capable(CAP_NET_ADMIN))
291 return -EPERM; 333 return -EPERM;
292 334
335 /* RFKILL_STATE_HARD_BLOCKED is illegal here... */
336 if (state != RFKILL_STATE_UNBLOCKED &&
337 state != RFKILL_STATE_SOFT_BLOCKED)
338 return -EINVAL;
339
293 if (mutex_lock_interruptible(&rfkill->mutex)) 340 if (mutex_lock_interruptible(&rfkill->mutex))
294 return -ERESTARTSYS; 341 return -ERESTARTSYS;
295 error = rfkill_toggle_radio(rfkill, 342 error = rfkill_toggle_radio(rfkill, state, 0);
296 state ? RFKILL_STATE_ON : RFKILL_STATE_OFF,
297 0);
298 mutex_unlock(&rfkill->mutex); 343 mutex_unlock(&rfkill->mutex);
299 344
300 return error ? error : count; 345 return error ? error : count;
@@ -373,7 +418,8 @@ static int rfkill_suspend(struct device *dev, pm_message_t state)
373 update_rfkill_state(rfkill); 418 update_rfkill_state(rfkill);
374 419
375 mutex_lock(&rfkill->mutex); 420 mutex_lock(&rfkill->mutex);
376 rfkill->toggle_radio(rfkill->data, RFKILL_STATE_OFF); 421 rfkill->toggle_radio(rfkill->data,
422 RFKILL_STATE_SOFT_BLOCKED);
377 mutex_unlock(&rfkill->mutex); 423 mutex_unlock(&rfkill->mutex);
378 } 424 }
379 425
@@ -470,7 +516,7 @@ static void rfkill_remove_switch(struct rfkill *rfkill)
470{ 516{
471 mutex_lock(&rfkill_mutex); 517 mutex_lock(&rfkill_mutex);
472 list_del_init(&rfkill->node); 518 list_del_init(&rfkill->node);
473 rfkill_toggle_radio(rfkill, RFKILL_STATE_OFF, 1); 519 rfkill_toggle_radio(rfkill, RFKILL_STATE_SOFT_BLOCKED, 1);
474 mutex_unlock(&rfkill_mutex); 520 mutex_unlock(&rfkill_mutex);
475} 521}
476 522
@@ -610,8 +656,9 @@ static int __init rfkill_init(void)
610 int error; 656 int error;
611 int i; 657 int i;
612 658
613 if (rfkill_default_state != RFKILL_STATE_OFF && 659 /* RFKILL_STATE_HARD_BLOCKED is illegal here... */
614 rfkill_default_state != RFKILL_STATE_ON) 660 if (rfkill_default_state != RFKILL_STATE_SOFT_BLOCKED &&
661 rfkill_default_state != RFKILL_STATE_UNBLOCKED)
615 return -EINVAL; 662 return -EINVAL;
616 663
617 for (i = 0; i < ARRAY_SIZE(rfkill_states); i++) 664 for (i = 0; i < ARRAY_SIZE(rfkill_states); i++)