at v2.6.23-rc2 9.6 kB view raw
1/* 2 * Copyright (C) 2006 Ivo van Doorn 3 * Copyright (C) 2007 Dmitry Torokhov 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the 17 * Free Software Foundation, Inc., 18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 19 */ 20 21#include <linux/kernel.h> 22#include <linux/module.h> 23#include <linux/init.h> 24#include <linux/workqueue.h> 25#include <linux/capability.h> 26#include <linux/list.h> 27#include <linux/mutex.h> 28#include <linux/rfkill.h> 29 30MODULE_AUTHOR("Ivo van Doorn <IvDoorn@gmail.com>"); 31MODULE_VERSION("1.0"); 32MODULE_DESCRIPTION("RF switch support"); 33MODULE_LICENSE("GPL"); 34 35static LIST_HEAD(rfkill_list); /* list of registered rf switches */ 36static DEFINE_MUTEX(rfkill_mutex); 37 38static enum rfkill_state rfkill_states[RFKILL_TYPE_MAX]; 39 40static int rfkill_toggle_radio(struct rfkill *rfkill, 41 enum rfkill_state state) 42{ 43 int retval; 44 45 retval = mutex_lock_interruptible(&rfkill->mutex); 46 if (retval) 47 return retval; 48 49 if (state != rfkill->state) { 50 retval = rfkill->toggle_radio(rfkill->data, state); 51 if (!retval) 52 rfkill->state = state; 53 } 54 55 mutex_unlock(&rfkill->mutex); 56 return retval; 57} 58 59/** 60 * rfkill_switch_all - Toggle state of all switches of given type 61 * @type: type of interfaces to be affeceted 62 * @state: the new state 63 * 64 * This function toggles state of all switches of given type unless 65 * a specific switch is claimed by userspace in which case it is 66 * left alone. 67 */ 68 69void rfkill_switch_all(enum rfkill_type type, enum rfkill_state state) 70{ 71 struct rfkill *rfkill; 72 73 mutex_lock(&rfkill_mutex); 74 75 rfkill_states[type] = state; 76 77 list_for_each_entry(rfkill, &rfkill_list, node) { 78 if (!rfkill->user_claim) 79 rfkill_toggle_radio(rfkill, state); 80 } 81 82 mutex_unlock(&rfkill_mutex); 83} 84EXPORT_SYMBOL(rfkill_switch_all); 85 86static ssize_t rfkill_name_show(struct device *dev, 87 struct device_attribute *attr, 88 char *buf) 89{ 90 struct rfkill *rfkill = to_rfkill(dev); 91 92 return sprintf(buf, "%s\n", rfkill->name); 93} 94 95static ssize_t rfkill_type_show(struct device *dev, 96 struct device_attribute *attr, 97 char *buf) 98{ 99 struct rfkill *rfkill = to_rfkill(dev); 100 const char *type; 101 102 switch (rfkill->type) { 103 case RFKILL_TYPE_WLAN: 104 type = "wlan"; 105 break; 106 case RFKILL_TYPE_BLUETOOTH: 107 type = "bluetooth"; 108 break; 109 case RFKILL_TYPE_IRDA: 110 type = "irda"; 111 break; 112 default: 113 BUG(); 114 } 115 116 return sprintf(buf, "%s\n", type); 117} 118 119static ssize_t rfkill_state_show(struct device *dev, 120 struct device_attribute *attr, 121 char *buf) 122{ 123 struct rfkill *rfkill = to_rfkill(dev); 124 125 return sprintf(buf, "%d\n", rfkill->state); 126} 127 128static ssize_t rfkill_state_store(struct device *dev, 129 struct device_attribute *attr, 130 const char *buf, size_t count) 131{ 132 struct rfkill *rfkill = to_rfkill(dev); 133 unsigned int state = simple_strtoul(buf, NULL, 0); 134 int error; 135 136 if (!capable(CAP_NET_ADMIN)) 137 return -EPERM; 138 139 error = rfkill_toggle_radio(rfkill, 140 state ? RFKILL_STATE_ON : RFKILL_STATE_OFF); 141 if (error) 142 return error; 143 144 return count; 145} 146 147static ssize_t rfkill_claim_show(struct device *dev, 148 struct device_attribute *attr, 149 char *buf) 150{ 151 struct rfkill *rfkill = to_rfkill(dev); 152 153 return sprintf(buf, "%d", rfkill->user_claim); 154} 155 156static ssize_t rfkill_claim_store(struct device *dev, 157 struct device_attribute *attr, 158 const char *buf, size_t count) 159{ 160 struct rfkill *rfkill = to_rfkill(dev); 161 bool claim = !!simple_strtoul(buf, NULL, 0); 162 int error; 163 164 if (!capable(CAP_NET_ADMIN)) 165 return -EPERM; 166 167 /* 168 * Take the global lock to make sure the kernel is not in 169 * the middle of rfkill_switch_all 170 */ 171 error = mutex_lock_interruptible(&rfkill_mutex); 172 if (error) 173 return error; 174 175 if (rfkill->user_claim != claim) { 176 if (!claim) 177 rfkill_toggle_radio(rfkill, 178 rfkill_states[rfkill->type]); 179 rfkill->user_claim = claim; 180 } 181 182 mutex_unlock(&rfkill_mutex); 183 184 return count; 185} 186 187static struct device_attribute rfkill_dev_attrs[] = { 188 __ATTR(name, S_IRUGO, rfkill_name_show, NULL), 189 __ATTR(type, S_IRUGO, rfkill_type_show, NULL), 190 __ATTR(state, S_IRUGO|S_IWUSR, rfkill_state_show, rfkill_state_store), 191 __ATTR(claim, S_IRUGO|S_IWUSR, rfkill_claim_show, rfkill_claim_store), 192 __ATTR_NULL 193}; 194 195static void rfkill_release(struct device *dev) 196{ 197 struct rfkill *rfkill = to_rfkill(dev); 198 199 kfree(rfkill); 200 module_put(THIS_MODULE); 201} 202 203#ifdef CONFIG_PM 204static int rfkill_suspend(struct device *dev, pm_message_t state) 205{ 206 struct rfkill *rfkill = to_rfkill(dev); 207 208 if (dev->power.power_state.event != state.event) { 209 if (state.event == PM_EVENT_SUSPEND) { 210 mutex_lock(&rfkill->mutex); 211 212 if (rfkill->state == RFKILL_STATE_ON) 213 rfkill->toggle_radio(rfkill->data, 214 RFKILL_STATE_OFF); 215 216 mutex_unlock(&rfkill->mutex); 217 } 218 219 dev->power.power_state = state; 220 } 221 222 return 0; 223} 224 225static int rfkill_resume(struct device *dev) 226{ 227 struct rfkill *rfkill = to_rfkill(dev); 228 229 if (dev->power.power_state.event != PM_EVENT_ON) { 230 mutex_lock(&rfkill->mutex); 231 232 if (rfkill->state == RFKILL_STATE_ON) 233 rfkill->toggle_radio(rfkill->data, RFKILL_STATE_ON); 234 235 mutex_unlock(&rfkill->mutex); 236 } 237 238 dev->power.power_state = PMSG_ON; 239 return 0; 240} 241#else 242#define rfkill_suspend NULL 243#define rfkill_resume NULL 244#endif 245 246static struct class rfkill_class = { 247 .name = "rfkill", 248 .dev_release = rfkill_release, 249 .dev_attrs = rfkill_dev_attrs, 250 .suspend = rfkill_suspend, 251 .resume = rfkill_resume, 252}; 253 254static int rfkill_add_switch(struct rfkill *rfkill) 255{ 256 int retval; 257 258 retval = mutex_lock_interruptible(&rfkill_mutex); 259 if (retval) 260 return retval; 261 262 retval = rfkill_toggle_radio(rfkill, rfkill_states[rfkill->type]); 263 if (retval) 264 goto out; 265 266 list_add_tail(&rfkill->node, &rfkill_list); 267 268 out: 269 mutex_unlock(&rfkill_mutex); 270 return retval; 271} 272 273static void rfkill_remove_switch(struct rfkill *rfkill) 274{ 275 mutex_lock(&rfkill_mutex); 276 list_del_init(&rfkill->node); 277 rfkill_toggle_radio(rfkill, RFKILL_STATE_OFF); 278 mutex_unlock(&rfkill_mutex); 279} 280 281/** 282 * rfkill_allocate - allocate memory for rfkill structure. 283 * @parent: device that has rf switch on it 284 * @type: type of the switch (wlan, bluetooth, irda) 285 * 286 * This function should be called by the network driver when it needs 287 * rfkill structure. Once the structure is allocated the driver shoud 288 * finish its initialization by setting name, private data, enable_radio 289 * and disable_radio methods and then register it with rfkill_register(). 290 * NOTE: If registration fails the structure shoudl be freed by calling 291 * rfkill_free() otherwise rfkill_unregister() should be used. 292 */ 293struct rfkill *rfkill_allocate(struct device *parent, enum rfkill_type type) 294{ 295 struct rfkill *rfkill; 296 struct device *dev; 297 298 rfkill = kzalloc(sizeof(struct rfkill), GFP_KERNEL); 299 if (!rfkill) 300 return NULL; 301 302 mutex_init(&rfkill->mutex); 303 INIT_LIST_HEAD(&rfkill->node); 304 rfkill->type = type; 305 306 dev = &rfkill->dev; 307 dev->class = &rfkill_class; 308 dev->parent = parent; 309 device_initialize(dev); 310 311 __module_get(THIS_MODULE); 312 313 return rfkill; 314} 315EXPORT_SYMBOL(rfkill_allocate); 316 317/** 318 * rfkill_free - Mark rfkill structure for deletion 319 * @rfkill: rfkill structure to be destroyed 320 * 321 * Decrements reference count of rfkill structure so it is destoryed. 322 * Note that rfkill_free() should _not_ be called after rfkill_unregister(). 323 */ 324void rfkill_free(struct rfkill *rfkill) 325{ 326 if (rfkill) 327 put_device(&rfkill->dev); 328} 329EXPORT_SYMBOL(rfkill_free); 330 331/** 332 * rfkill_register - Register a rfkill structure. 333 * @rfkill: rfkill structure to be registered 334 * 335 * This function should be called by the network driver when the rfkill 336 * structure needs to be registered. Immediately from registration the 337 * switch driver should be able to service calls to toggle_radio. 338 */ 339int rfkill_register(struct rfkill *rfkill) 340{ 341 static atomic_t rfkill_no = ATOMIC_INIT(0); 342 struct device *dev = &rfkill->dev; 343 int error; 344 345 if (!rfkill->toggle_radio) 346 return -EINVAL; 347 348 error = rfkill_add_switch(rfkill); 349 if (error) 350 return error; 351 352 snprintf(dev->bus_id, sizeof(dev->bus_id), 353 "rfkill%ld", (long)atomic_inc_return(&rfkill_no) - 1); 354 355 error = device_add(dev); 356 if (error) { 357 rfkill_remove_switch(rfkill); 358 return error; 359 } 360 361 return 0; 362} 363EXPORT_SYMBOL(rfkill_register); 364 365/** 366 * rfkill_unregister - Uegister a rfkill structure. 367 * @rfkill: rfkill structure to be unregistered 368 * 369 * This function should be called by the network driver during device 370 * teardown to destroy rfkill structure. Note that rfkill_free() should 371 * _not_ be called after rfkill_unregister(). 372 */ 373void rfkill_unregister(struct rfkill *rfkill) 374{ 375 device_del(&rfkill->dev); 376 rfkill_remove_switch(rfkill); 377 put_device(&rfkill->dev); 378} 379EXPORT_SYMBOL(rfkill_unregister); 380 381/* 382 * Rfkill module initialization/deinitialization. 383 */ 384static int __init rfkill_init(void) 385{ 386 int error; 387 int i; 388 389 for (i = 0; i < ARRAY_SIZE(rfkill_states); i++) 390 rfkill_states[i] = RFKILL_STATE_ON; 391 392 error = class_register(&rfkill_class); 393 if (error) { 394 printk(KERN_ERR "rfkill: unable to register rfkill class\n"); 395 return error; 396 } 397 398 return 0; 399} 400 401static void __exit rfkill_exit(void) 402{ 403 class_unregister(&rfkill_class); 404} 405 406module_init(rfkill_init); 407module_exit(rfkill_exit);