Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.39 474 lines 11 kB view raw
1/* 2 * Ultra Wide Band 3 * Life cycle of radio controllers 4 * 5 * Copyright (C) 2005-2006 Intel Corporation 6 * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com> 7 * 8 * This program is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU General Public License version 10 * 2 as published by the Free Software Foundation. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 20 * 02110-1301, USA. 21 * 22 * 23 * FIXME: docs 24 * 25 * A UWB radio controller is also a UWB device, so it embeds one... 26 * 27 * List of RCs comes from the 'struct class uwb_rc_class'. 28 */ 29 30#include <linux/kernel.h> 31#include <linux/string.h> 32#include <linux/device.h> 33#include <linux/err.h> 34#include <linux/random.h> 35#include <linux/kdev_t.h> 36#include <linux/etherdevice.h> 37#include <linux/usb.h> 38#include <linux/slab.h> 39 40#include "uwb-internal.h" 41 42static int uwb_rc_index_match(struct device *dev, void *data) 43{ 44 int *index = data; 45 struct uwb_rc *rc = dev_get_drvdata(dev); 46 47 if (rc->index == *index) 48 return 1; 49 return 0; 50} 51 52static struct uwb_rc *uwb_rc_find_by_index(int index) 53{ 54 struct device *dev; 55 struct uwb_rc *rc = NULL; 56 57 dev = class_find_device(&uwb_rc_class, NULL, &index, uwb_rc_index_match); 58 if (dev) 59 rc = dev_get_drvdata(dev); 60 return rc; 61} 62 63static int uwb_rc_new_index(void) 64{ 65 int index = 0; 66 67 for (;;) { 68 if (!uwb_rc_find_by_index(index)) 69 return index; 70 if (++index < 0) 71 index = 0; 72 } 73} 74 75/** 76 * Release the backing device of a uwb_rc that has been dynamically allocated. 77 */ 78static void uwb_rc_sys_release(struct device *dev) 79{ 80 struct uwb_dev *uwb_dev = container_of(dev, struct uwb_dev, dev); 81 struct uwb_rc *rc = container_of(uwb_dev, struct uwb_rc, uwb_dev); 82 83 uwb_rc_ie_release(rc); 84 kfree(rc); 85} 86 87 88void uwb_rc_init(struct uwb_rc *rc) 89{ 90 struct uwb_dev *uwb_dev = &rc->uwb_dev; 91 92 uwb_dev_init(uwb_dev); 93 rc->uwb_dev.dev.class = &uwb_rc_class; 94 rc->uwb_dev.dev.release = uwb_rc_sys_release; 95 uwb_rc_neh_create(rc); 96 rc->beaconing = -1; 97 rc->scan_type = UWB_SCAN_DISABLED; 98 INIT_LIST_HEAD(&rc->notifs_chain.list); 99 mutex_init(&rc->notifs_chain.mutex); 100 INIT_LIST_HEAD(&rc->uwb_beca.list); 101 mutex_init(&rc->uwb_beca.mutex); 102 uwb_drp_avail_init(rc); 103 uwb_rc_ie_init(rc); 104 uwb_rsv_init(rc); 105 uwb_rc_pal_init(rc); 106} 107EXPORT_SYMBOL_GPL(uwb_rc_init); 108 109 110struct uwb_rc *uwb_rc_alloc(void) 111{ 112 struct uwb_rc *rc; 113 rc = kzalloc(sizeof(*rc), GFP_KERNEL); 114 if (rc == NULL) 115 return NULL; 116 uwb_rc_init(rc); 117 return rc; 118} 119EXPORT_SYMBOL_GPL(uwb_rc_alloc); 120 121static struct attribute *rc_attrs[] = { 122 &dev_attr_mac_address.attr, 123 &dev_attr_scan.attr, 124 &dev_attr_beacon.attr, 125 NULL, 126}; 127 128static struct attribute_group rc_attr_group = { 129 .attrs = rc_attrs, 130}; 131 132/* 133 * Registration of sysfs specific stuff 134 */ 135static int uwb_rc_sys_add(struct uwb_rc *rc) 136{ 137 return sysfs_create_group(&rc->uwb_dev.dev.kobj, &rc_attr_group); 138} 139 140 141static void __uwb_rc_sys_rm(struct uwb_rc *rc) 142{ 143 sysfs_remove_group(&rc->uwb_dev.dev.kobj, &rc_attr_group); 144} 145 146/** 147 * uwb_rc_mac_addr_setup - get an RC's EUI-48 address or set it 148 * @rc: the radio controller. 149 * 150 * If the EUI-48 address is 00:00:00:00:00:00 or FF:FF:FF:FF:FF:FF 151 * then a random locally administered EUI-48 is generated and set on 152 * the device. The probability of address collisions is sufficiently 153 * unlikely (1/2^40 = 9.1e-13) that they're not checked for. 154 */ 155static 156int uwb_rc_mac_addr_setup(struct uwb_rc *rc) 157{ 158 int result; 159 struct device *dev = &rc->uwb_dev.dev; 160 struct uwb_dev *uwb_dev = &rc->uwb_dev; 161 char devname[UWB_ADDR_STRSIZE]; 162 struct uwb_mac_addr addr; 163 164 result = uwb_rc_mac_addr_get(rc, &addr); 165 if (result < 0) { 166 dev_err(dev, "cannot retrieve UWB EUI-48 address: %d\n", result); 167 return result; 168 } 169 170 if (uwb_mac_addr_unset(&addr) || uwb_mac_addr_bcast(&addr)) { 171 addr.data[0] = 0x02; /* locally administered and unicast */ 172 get_random_bytes(&addr.data[1], sizeof(addr.data)-1); 173 174 result = uwb_rc_mac_addr_set(rc, &addr); 175 if (result < 0) { 176 uwb_mac_addr_print(devname, sizeof(devname), &addr); 177 dev_err(dev, "cannot set EUI-48 address %s: %d\n", 178 devname, result); 179 return result; 180 } 181 } 182 uwb_dev->mac_addr = addr; 183 return 0; 184} 185 186 187 188static int uwb_rc_setup(struct uwb_rc *rc) 189{ 190 int result; 191 struct device *dev = &rc->uwb_dev.dev; 192 193 result = uwb_radio_setup(rc); 194 if (result < 0) { 195 dev_err(dev, "cannot setup UWB radio: %d\n", result); 196 goto error; 197 } 198 result = uwb_rc_mac_addr_setup(rc); 199 if (result < 0) { 200 dev_err(dev, "cannot setup UWB MAC address: %d\n", result); 201 goto error; 202 } 203 result = uwb_rc_dev_addr_assign(rc); 204 if (result < 0) { 205 dev_err(dev, "cannot assign UWB DevAddr: %d\n", result); 206 goto error; 207 } 208 result = uwb_rc_ie_setup(rc); 209 if (result < 0) { 210 dev_err(dev, "cannot setup IE subsystem: %d\n", result); 211 goto error_ie_setup; 212 } 213 result = uwb_rsv_setup(rc); 214 if (result < 0) { 215 dev_err(dev, "cannot setup reservation subsystem: %d\n", result); 216 goto error_rsv_setup; 217 } 218 uwb_dbg_add_rc(rc); 219 return 0; 220 221error_rsv_setup: 222 uwb_rc_ie_release(rc); 223error_ie_setup: 224error: 225 return result; 226} 227 228 229/** 230 * Register a new UWB radio controller 231 * 232 * Did you call uwb_rc_init() on your rc? 233 * 234 * We assume that this is being called with a > 0 refcount on 235 * it [through ops->{get|put}_device(). We'll take our own, though. 236 * 237 * @parent_dev is our real device, the one that provides the actual UWB device 238 */ 239int uwb_rc_add(struct uwb_rc *rc, struct device *parent_dev, void *priv) 240{ 241 int result; 242 struct device *dev; 243 char macbuf[UWB_ADDR_STRSIZE], devbuf[UWB_ADDR_STRSIZE]; 244 245 rc->index = uwb_rc_new_index(); 246 247 dev = &rc->uwb_dev.dev; 248 dev_set_name(dev, "uwb%d", rc->index); 249 250 rc->priv = priv; 251 252 init_waitqueue_head(&rc->uwbd.wq); 253 INIT_LIST_HEAD(&rc->uwbd.event_list); 254 spin_lock_init(&rc->uwbd.event_list_lock); 255 256 uwbd_start(rc); 257 258 result = rc->start(rc); 259 if (result < 0) 260 goto error_rc_start; 261 262 result = uwb_rc_setup(rc); 263 if (result < 0) { 264 dev_err(dev, "cannot setup UWB radio controller: %d\n", result); 265 goto error_rc_setup; 266 } 267 268 result = uwb_dev_add(&rc->uwb_dev, parent_dev, rc); 269 if (result < 0 && result != -EADDRNOTAVAIL) 270 goto error_dev_add; 271 272 result = uwb_rc_sys_add(rc); 273 if (result < 0) { 274 dev_err(parent_dev, "cannot register UWB radio controller " 275 "dev attributes: %d\n", result); 276 goto error_sys_add; 277 } 278 279 uwb_mac_addr_print(macbuf, sizeof(macbuf), &rc->uwb_dev.mac_addr); 280 uwb_dev_addr_print(devbuf, sizeof(devbuf), &rc->uwb_dev.dev_addr); 281 dev_info(dev, 282 "new uwb radio controller (mac %s dev %s) on %s %s\n", 283 macbuf, devbuf, parent_dev->bus->name, dev_name(parent_dev)); 284 rc->ready = 1; 285 return 0; 286 287error_sys_add: 288 uwb_dev_rm(&rc->uwb_dev); 289error_dev_add: 290error_rc_setup: 291 rc->stop(rc); 292error_rc_start: 293 uwbd_stop(rc); 294 return result; 295} 296EXPORT_SYMBOL_GPL(uwb_rc_add); 297 298 299static int uwb_dev_offair_helper(struct device *dev, void *priv) 300{ 301 struct uwb_dev *uwb_dev = to_uwb_dev(dev); 302 303 return __uwb_dev_offair(uwb_dev, uwb_dev->rc); 304} 305 306/* 307 * Remove a Radio Controller; stop beaconing/scanning, disconnect all children 308 */ 309void uwb_rc_rm(struct uwb_rc *rc) 310{ 311 rc->ready = 0; 312 313 uwb_dbg_del_rc(rc); 314 uwb_rsv_remove_all(rc); 315 uwb_radio_shutdown(rc); 316 317 rc->stop(rc); 318 319 uwbd_stop(rc); 320 uwb_rc_neh_destroy(rc); 321 322 uwb_dev_lock(&rc->uwb_dev); 323 rc->priv = NULL; 324 rc->cmd = NULL; 325 uwb_dev_unlock(&rc->uwb_dev); 326 mutex_lock(&rc->uwb_beca.mutex); 327 uwb_dev_for_each(rc, uwb_dev_offair_helper, NULL); 328 __uwb_rc_sys_rm(rc); 329 mutex_unlock(&rc->uwb_beca.mutex); 330 uwb_rsv_cleanup(rc); 331 uwb_beca_release(rc); 332 uwb_dev_rm(&rc->uwb_dev); 333} 334EXPORT_SYMBOL_GPL(uwb_rc_rm); 335 336static int find_rc_try_get(struct device *dev, void *data) 337{ 338 struct uwb_rc *target_rc = data; 339 struct uwb_rc *rc = dev_get_drvdata(dev); 340 341 if (rc == NULL) { 342 WARN_ON(1); 343 return 0; 344 } 345 if (rc == target_rc) { 346 if (rc->ready == 0) 347 return 0; 348 else 349 return 1; 350 } 351 return 0; 352} 353 354/** 355 * Given a radio controller descriptor, validate and refcount it 356 * 357 * @returns NULL if the rc does not exist or is quiescing; the ptr to 358 * it otherwise. 359 */ 360struct uwb_rc *__uwb_rc_try_get(struct uwb_rc *target_rc) 361{ 362 struct device *dev; 363 struct uwb_rc *rc = NULL; 364 365 dev = class_find_device(&uwb_rc_class, NULL, target_rc, 366 find_rc_try_get); 367 if (dev) { 368 rc = dev_get_drvdata(dev); 369 __uwb_rc_get(rc); 370 } 371 return rc; 372} 373EXPORT_SYMBOL_GPL(__uwb_rc_try_get); 374 375/* 376 * RC get for external refcount acquirers... 377 * 378 * Increments the refcount of the device and it's backend modules 379 */ 380static inline struct uwb_rc *uwb_rc_get(struct uwb_rc *rc) 381{ 382 if (rc->ready == 0) 383 return NULL; 384 uwb_dev_get(&rc->uwb_dev); 385 return rc; 386} 387 388static int find_rc_grandpa(struct device *dev, void *data) 389{ 390 struct device *grandpa_dev = data; 391 struct uwb_rc *rc = dev_get_drvdata(dev); 392 393 if (rc->uwb_dev.dev.parent->parent == grandpa_dev) { 394 rc = uwb_rc_get(rc); 395 return 1; 396 } 397 return 0; 398} 399 400/** 401 * Locate and refcount a radio controller given a common grand-parent 402 * 403 * @grandpa_dev Pointer to the 'grandparent' device structure. 404 * @returns NULL If the rc does not exist or is quiescing; the ptr to 405 * it otherwise, properly referenced. 406 * 407 * The Radio Control interface (or the UWB Radio Controller) is always 408 * an interface of a device. The parent is the interface, the 409 * grandparent is the device that encapsulates the interface. 410 * 411 * There is no need to lock around as the "grandpa" would be 412 * refcounted by the target, and to remove the referemes, the 413 * uwb_rc_class->sem would have to be taken--we hold it, ergo we 414 * should be safe. 415 */ 416struct uwb_rc *uwb_rc_get_by_grandpa(const struct device *grandpa_dev) 417{ 418 struct device *dev; 419 struct uwb_rc *rc = NULL; 420 421 dev = class_find_device(&uwb_rc_class, NULL, (void *)grandpa_dev, 422 find_rc_grandpa); 423 if (dev) 424 rc = dev_get_drvdata(dev); 425 return rc; 426} 427EXPORT_SYMBOL_GPL(uwb_rc_get_by_grandpa); 428 429/** 430 * Find a radio controller by device address 431 * 432 * @returns the pointer to the radio controller, properly referenced 433 */ 434static int find_rc_dev(struct device *dev, void *data) 435{ 436 struct uwb_dev_addr *addr = data; 437 struct uwb_rc *rc = dev_get_drvdata(dev); 438 439 if (rc == NULL) { 440 WARN_ON(1); 441 return 0; 442 } 443 if (!uwb_dev_addr_cmp(&rc->uwb_dev.dev_addr, addr)) { 444 rc = uwb_rc_get(rc); 445 return 1; 446 } 447 return 0; 448} 449 450struct uwb_rc *uwb_rc_get_by_dev(const struct uwb_dev_addr *addr) 451{ 452 struct device *dev; 453 struct uwb_rc *rc = NULL; 454 455 dev = class_find_device(&uwb_rc_class, NULL, (void *)addr, 456 find_rc_dev); 457 if (dev) 458 rc = dev_get_drvdata(dev); 459 460 return rc; 461} 462EXPORT_SYMBOL_GPL(uwb_rc_get_by_dev); 463 464/** 465 * Drop a reference on a radio controller 466 * 467 * This is the version that should be done by entities external to the 468 * UWB Radio Control stack (ie: clients of the API). 469 */ 470void uwb_rc_put(struct uwb_rc *rc) 471{ 472 __uwb_rc_put(rc); 473} 474EXPORT_SYMBOL_GPL(uwb_rc_put);