Blame view
net/nfc/core.c
24.9 KB
3e256b8f8 NFC: add nfc subs... |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
/* * Copyright (C) 2011 Instituto Nokia de Tecnologia * * Authors: * Lauro Ramos Venancio <lauro.venancio@openbossa.org> * Aloisio Almeida Jr <aloisio.almeida@openbossa.org> * * 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 |
98b32decc nfc: Fix FSF addr... |
19 |
* along with this program; if not, see <http://www.gnu.org/licenses/>. |
3e256b8f8 NFC: add nfc subs... |
20 |
*/ |
52858b51b NFC: Add function... |
21 |
#define pr_fmt(fmt) KBUILD_MODNAME ": %s: " fmt, __func__ |
ed1e0ad88 nfc: Use standard... |
22 |
|
3e256b8f8 NFC: add nfc subs... |
23 24 25 26 |
#include <linux/init.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/slab.h> |
be055b2f8 NFC: RFKILL support |
27 |
#include <linux/rfkill.h> |
7c7cd3bfe NFC: Add tx skb a... |
28 |
#include <linux/nfc.h> |
3e256b8f8 NFC: add nfc subs... |
29 |
|
5df16cad4 NFC: Add netlink ... |
30 |
#include <net/genetlink.h> |
3e256b8f8 NFC: add nfc subs... |
31 32 33 |
#include "nfc.h" #define VERSION "0.1" |
c8d56ae78 NFC: Add Core sup... |
34 |
#define NFC_CHECK_PRES_FREQ_MS 2000 |
3e256b8f8 NFC: add nfc subs... |
35 36 |
int nfc_devlist_generation; DEFINE_MUTEX(nfc_devlist_mutex); |
7eda8b8e9 NFC: Use IDR libr... |
37 38 |
/* NFC device ID bitmap */ static DEFINE_IDA(nfc_index_ida); |
9ea7187c5 NFC: netlink: Ren... |
39 |
int nfc_fw_download(struct nfc_dev *dev, const char *firmware_name) |
9674da875 NFC: Add firmware... |
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
{ int rc = 0; pr_debug("%s do firmware %s ", dev_name(&dev->dev), firmware_name); device_lock(&dev->dev); if (!device_is_registered(&dev->dev)) { rc = -ENODEV; goto error; } if (dev->dev_up) { rc = -EBUSY; goto error; } |
9ea7187c5 NFC: netlink: Ren... |
57 |
if (!dev->ops->fw_download) { |
9674da875 NFC: Add firmware... |
58 59 60 |
rc = -EOPNOTSUPP; goto error; } |
9ea7187c5 NFC: netlink: Ren... |
61 62 |
dev->fw_download_in_progress = true; rc = dev->ops->fw_download(dev, firmware_name); |
9674da875 NFC: Add firmware... |
63 |
if (rc) |
9ea7187c5 NFC: netlink: Ren... |
64 |
dev->fw_download_in_progress = false; |
9674da875 NFC: Add firmware... |
65 66 67 68 69 |
error: device_unlock(&dev->dev); return rc; } |
352a5f5fb NFC: netlink: Add... |
70 71 72 73 74 75 76 77 78 |
/** * nfc_fw_download_done - inform that a firmware download was completed * * @dev: The nfc device to which firmware was downloaded * @firmware_name: The firmware filename * @result: The positive value of a standard errno value */ int nfc_fw_download_done(struct nfc_dev *dev, const char *firmware_name, u32 result) |
9674da875 NFC: Add firmware... |
79 |
{ |
9ea7187c5 NFC: netlink: Ren... |
80 |
dev->fw_download_in_progress = false; |
9674da875 NFC: Add firmware... |
81 |
|
352a5f5fb NFC: netlink: Add... |
82 |
return nfc_genl_fw_download_done(dev, firmware_name, result); |
9674da875 NFC: Add firmware... |
83 |
} |
9ea7187c5 NFC: netlink: Ren... |
84 |
EXPORT_SYMBOL(nfc_fw_download_done); |
9674da875 NFC: Add firmware... |
85 |
|
3e256b8f8 NFC: add nfc subs... |
86 |
/** |
8b3fe7b59 NFC: Add dev_up a... |
87 88 89 90 91 92 93 94 95 |
* nfc_dev_up - turn on the NFC device * * @dev: The nfc device to be turned on * * The device remains up until the nfc_dev_down function is called. */ int nfc_dev_up(struct nfc_dev *dev) { int rc = 0; |
20c239c13 nfc: Convert nfc_... |
96 97 |
pr_debug("dev_name=%s ", dev_name(&dev->dev)); |
8b3fe7b59 NFC: Add dev_up a... |
98 99 |
device_lock(&dev->dev); |
be055b2f8 NFC: RFKILL support |
100 101 102 103 |
if (dev->rfkill && rfkill_blocked(dev->rfkill)) { rc = -ERFKILL; goto error; } |
8b3fe7b59 NFC: Add dev_up a... |
104 105 106 107 |
if (!device_is_registered(&dev->dev)) { rc = -ENODEV; goto error; } |
9ea7187c5 NFC: netlink: Ren... |
108 |
if (dev->fw_download_in_progress) { |
9674da875 NFC: Add firmware... |
109 110 111 |
rc = -EBUSY; goto error; } |
8b3fe7b59 NFC: Add dev_up a... |
112 113 114 115 116 117 118 119 120 121 |
if (dev->dev_up) { rc = -EALREADY; goto error; } if (dev->ops->dev_up) rc = dev->ops->dev_up(dev); if (!rc) dev->dev_up = true; |
0a946301c NFC: Extend and f... |
122 |
/* We have to enable the device before discovering SEs */ |
a434c2407 NFC: Only warn on... |
123 124 125 |
if (dev->ops->discover_se && dev->ops->discover_se(dev)) pr_err("SE discovery failed "); |
0a946301c NFC: Extend and f... |
126 |
|
8b3fe7b59 NFC: Add dev_up a... |
127 128 129 130 131 132 133 134 135 136 137 138 139 |
error: device_unlock(&dev->dev); return rc; } /** * nfc_dev_down - turn off the NFC device * * @dev: The nfc device to be turned off */ int nfc_dev_down(struct nfc_dev *dev) { int rc = 0; |
20c239c13 nfc: Convert nfc_... |
140 141 |
pr_debug("dev_name=%s ", dev_name(&dev->dev)); |
8b3fe7b59 NFC: Add dev_up a... |
142 143 144 145 146 147 148 149 150 151 152 153 |
device_lock(&dev->dev); if (!device_is_registered(&dev->dev)) { rc = -ENODEV; goto error; } if (!dev->dev_up) { rc = -EALREADY; goto error; } |
900994332 NFC: Cache the co... |
154 |
if (dev->polling || dev->active_target) { |
8b3fe7b59 NFC: Add dev_up a... |
155 156 157 158 159 160 161 162 163 164 165 166 167 |
rc = -EBUSY; goto error; } if (dev->ops->dev_down) dev->ops->dev_down(dev); dev->dev_up = false; error: device_unlock(&dev->dev); return rc; } |
be055b2f8 NFC: RFKILL support |
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 |
static int nfc_rfkill_set_block(void *data, bool blocked) { struct nfc_dev *dev = data; pr_debug("%s blocked %d", dev_name(&dev->dev), blocked); if (!blocked) return 0; nfc_dev_down(dev); return 0; } static const struct rfkill_ops nfc_rfkill_ops = { .set_block = nfc_rfkill_set_block, }; |
8b3fe7b59 NFC: Add dev_up a... |
185 |
/** |
3e256b8f8 NFC: add nfc subs... |
186 187 188 189 190 191 192 193 |
* nfc_start_poll - start polling for nfc targets * * @dev: The nfc device that must start polling * @protocols: bitset of nfc protocols that must be used for polling * * The device remains polling for targets until a target is found or * the nfc_stop_poll function is called. */ |
fe7c58007 NFC: Add target m... |
194 |
int nfc_start_poll(struct nfc_dev *dev, u32 im_protocols, u32 tm_protocols) |
3e256b8f8 NFC: add nfc subs... |
195 196 |
{ int rc; |
fe7c58007 NFC: Add target m... |
197 198 199 |
pr_debug("dev_name %s initiator protocols 0x%x target protocols 0x%x ", dev_name(&dev->dev), im_protocols, tm_protocols); |
3e256b8f8 NFC: add nfc subs... |
200 |
|
fe7c58007 NFC: Add target m... |
201 |
if (!im_protocols && !tm_protocols) |
3e256b8f8 NFC: add nfc subs... |
202 203 204 205 206 207 208 209 |
return -EINVAL; device_lock(&dev->dev); if (!device_is_registered(&dev->dev)) { rc = -ENODEV; goto error; } |
7757dc8a3 NFC: Prevent poll... |
210 211 212 213 |
if (!dev->dev_up) { rc = -ENODEV; goto error; } |
3e256b8f8 NFC: add nfc subs... |
214 215 216 217 |
if (dev->polling) { rc = -EBUSY; goto error; } |
fe7c58007 NFC: Add target m... |
218 |
rc = dev->ops->start_poll(dev, im_protocols, tm_protocols); |
f212ad5e9 NFC: Set the NFC ... |
219 |
if (!rc) { |
3e256b8f8 NFC: add nfc subs... |
220 |
dev->polling = true; |
f212ad5e9 NFC: Set the NFC ... |
221 222 |
dev->rf_mode = NFC_RF_NONE; } |
3e256b8f8 NFC: add nfc subs... |
223 224 225 226 227 228 229 230 231 232 233 234 235 236 |
error: device_unlock(&dev->dev); return rc; } /** * nfc_stop_poll - stop polling for nfc targets * * @dev: The nfc device that must stop polling */ int nfc_stop_poll(struct nfc_dev *dev) { int rc = 0; |
20c239c13 nfc: Convert nfc_... |
237 238 |
pr_debug("dev_name=%s ", dev_name(&dev->dev)); |
3e256b8f8 NFC: add nfc subs... |
239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 |
device_lock(&dev->dev); if (!device_is_registered(&dev->dev)) { rc = -ENODEV; goto error; } if (!dev->polling) { rc = -EINVAL; goto error; } dev->ops->stop_poll(dev); dev->polling = false; |
5bcf099c1 NFC: Set rf_mode ... |
254 |
dev->rf_mode = NFC_RF_NONE; |
3e256b8f8 NFC: add nfc subs... |
255 256 257 258 259 |
error: device_unlock(&dev->dev); return rc; } |
900994332 NFC: Cache the co... |
260 261 262 |
static struct nfc_target *nfc_find_target(struct nfc_dev *dev, u32 target_idx) { int i; |
0f4507722 NFC: Fix some cod... |
263 |
for (i = 0; i < dev->n_targets; i++) { |
900994332 NFC: Cache the co... |
264 265 266 267 268 269 |
if (dev->targets[i].idx == target_idx) return &dev->targets[i]; } return NULL; } |
47807d3db NFC: Remove the r... |
270 |
int nfc_dep_link_up(struct nfc_dev *dev, int target_index, u8 comm_mode) |
1ed28f610 NFC: Add a DEP li... |
271 272 |
{ int rc = 0; |
47807d3db NFC: Remove the r... |
273 274 |
u8 *gb; size_t gb_len; |
900994332 NFC: Cache the co... |
275 |
struct nfc_target *target; |
1ed28f610 NFC: Add a DEP li... |
276 |
|
47807d3db NFC: Remove the r... |
277 278 |
pr_debug("dev_name=%s comm %d ", dev_name(&dev->dev), comm_mode); |
1ed28f610 NFC: Add a DEP li... |
279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 |
if (!dev->ops->dep_link_up) return -EOPNOTSUPP; device_lock(&dev->dev); if (!device_is_registered(&dev->dev)) { rc = -ENODEV; goto error; } if (dev->dep_link_up == true) { rc = -EALREADY; goto error; } |
47807d3db NFC: Remove the r... |
294 295 296 297 298 |
gb = nfc_llcp_general_bytes(dev, &gb_len); if (gb_len > NFC_MAX_GT_LEN) { rc = -EINVAL; goto error; } |
900994332 NFC: Cache the co... |
299 300 301 302 303 304 305 |
target = nfc_find_target(dev, target_index); if (target == NULL) { rc = -ENOTCONN; goto error; } rc = dev->ops->dep_link_up(dev, target, comm_mode, gb, gb_len); |
f212ad5e9 NFC: Set the NFC ... |
306 |
if (!rc) { |
900994332 NFC: Cache the co... |
307 |
dev->active_target = target; |
f212ad5e9 NFC: Set the NFC ... |
308 309 |
dev->rf_mode = NFC_RF_INITIATOR; } |
1ed28f610 NFC: Add a DEP li... |
310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 |
error: device_unlock(&dev->dev); return rc; } int nfc_dep_link_down(struct nfc_dev *dev) { int rc = 0; pr_debug("dev_name=%s ", dev_name(&dev->dev)); if (!dev->ops->dep_link_down) return -EOPNOTSUPP; device_lock(&dev->dev); if (!device_is_registered(&dev->dev)) { rc = -ENODEV; goto error; } if (dev->dep_link_up == false) { rc = -EALREADY; goto error; } |
1ed28f610 NFC: Add a DEP li... |
337 338 339 |
rc = dev->ops->dep_link_down(dev); if (!rc) { dev->dep_link_up = false; |
900994332 NFC: Cache the co... |
340 |
dev->active_target = NULL; |
5bcf099c1 NFC: Set rf_mode ... |
341 |
dev->rf_mode = NFC_RF_NONE; |
d646960f7 NFC: Initial LLCP... |
342 |
nfc_llcp_mac_is_down(dev); |
1ed28f610 NFC: Add a DEP li... |
343 344 345 346 347 |
nfc_genl_dep_link_down_event(dev); } error: device_unlock(&dev->dev); |
5bcf099c1 NFC: Set rf_mode ... |
348 |
|
1ed28f610 NFC: Add a DEP li... |
349 350 351 352 |
return rc; } int nfc_dep_link_is_up(struct nfc_dev *dev, u32 target_idx, |
0a40acb24 NFC: Core code id... |
353 |
u8 comm_mode, u8 rf_mode) |
1ed28f610 NFC: Add a DEP li... |
354 355 |
{ dev->dep_link_up = true; |
1ed28f610 NFC: Add a DEP li... |
356 |
|
d31652a26 NFC: Fix target m... |
357 |
if (!dev->active_target && rf_mode == NFC_RF_INITIATOR) { |
e29a9e2ae NFC: Set active t... |
358 359 360 361 362 363 364 365 366 367 368 |
struct nfc_target *target; target = nfc_find_target(dev, target_idx); if (target == NULL) return -ENOTCONN; dev->active_target = target; } dev->polling = false; dev->rf_mode = rf_mode; |
d646960f7 NFC: Initial LLCP... |
369 |
nfc_llcp_mac_is_up(dev, target_idx, comm_mode, rf_mode); |
1ed28f610 NFC: Add a DEP li... |
370 371 372 |
return nfc_genl_dep_link_up_event(dev, target_idx, comm_mode, rf_mode); } EXPORT_SYMBOL(nfc_dep_link_is_up); |
3e256b8f8 NFC: add nfc subs... |
373 374 375 376 377 378 379 380 381 382 |
/** * nfc_activate_target - prepare the target for data exchange * * @dev: The nfc device that found the target * @target_idx: index of the target that must be activated * @protocol: nfc protocol that will be used for data exchange */ int nfc_activate_target(struct nfc_dev *dev, u32 target_idx, u32 protocol) { int rc; |
900994332 NFC: Cache the co... |
383 |
struct nfc_target *target; |
3e256b8f8 NFC: add nfc subs... |
384 |
|
20c239c13 nfc: Convert nfc_... |
385 386 387 |
pr_debug("dev_name=%s target_idx=%u protocol=%u ", dev_name(&dev->dev), target_idx, protocol); |
3e256b8f8 NFC: add nfc subs... |
388 389 390 391 392 393 394 |
device_lock(&dev->dev); if (!device_is_registered(&dev->dev)) { rc = -ENODEV; goto error; } |
900994332 NFC: Cache the co... |
395 396 397 398 399 400 401 402 403 404 405 406 |
if (dev->active_target) { rc = -EBUSY; goto error; } target = nfc_find_target(dev, target_idx); if (target == NULL) { rc = -ENOTCONN; goto error; } rc = dev->ops->activate_target(dev, target, protocol); |
c8d56ae78 NFC: Add Core sup... |
407 |
if (!rc) { |
900994332 NFC: Cache the co... |
408 |
dev->active_target = target; |
f212ad5e9 NFC: Set the NFC ... |
409 |
dev->rf_mode = NFC_RF_INITIATOR; |
3e256b8f8 NFC: add nfc subs... |
410 |
|
f0c910381 NFC: Fixed nfc co... |
411 |
if (dev->ops->check_presence && !dev->shutting_down) |
c8d56ae78 NFC: Add Core sup... |
412 413 414 |
mod_timer(&dev->check_pres_timer, jiffies + msecs_to_jiffies(NFC_CHECK_PRES_FREQ_MS)); } |
3e256b8f8 NFC: add nfc subs... |
415 416 417 418 419 420 421 422 423 424 425 426 |
error: device_unlock(&dev->dev); return rc; } /** * nfc_deactivate_target - deactivate a nfc target * * @dev: The nfc device that found the target * @target_idx: index of the target that must be deactivated */ |
96d4581f0 NFC: netlink: Add... |
427 |
int nfc_deactivate_target(struct nfc_dev *dev, u32 target_idx, u8 mode) |
3e256b8f8 NFC: add nfc subs... |
428 429 |
{ int rc = 0; |
20c239c13 nfc: Convert nfc_... |
430 431 432 |
pr_debug("dev_name=%s target_idx=%u ", dev_name(&dev->dev), target_idx); |
3e256b8f8 NFC: add nfc subs... |
433 434 435 436 437 438 439 |
device_lock(&dev->dev); if (!device_is_registered(&dev->dev)) { rc = -ENODEV; goto error; } |
900994332 NFC: Cache the co... |
440 441 442 443 444 445 446 447 448 |
if (dev->active_target == NULL) { rc = -ENOTCONN; goto error; } if (dev->active_target->idx != target_idx) { rc = -ENOTCONN; goto error; } |
c8d56ae78 NFC: Add Core sup... |
449 450 |
if (dev->ops->check_presence) del_timer_sync(&dev->check_pres_timer); |
96d4581f0 NFC: netlink: Add... |
451 |
dev->ops->deactivate_target(dev, dev->active_target, mode); |
900994332 NFC: Cache the co... |
452 |
dev->active_target = NULL; |
3e256b8f8 NFC: add nfc subs... |
453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 |
error: device_unlock(&dev->dev); return rc; } /** * nfc_data_exchange - transceive data * * @dev: The nfc device that found the target * @target_idx: index of the target * @skb: data to be sent * @cb: callback called when the response is received * @cb_context: parameter for the callback function * * The user must wait for the callback before calling this function again. */ |
0a40acb24 NFC: Core code id... |
470 471 |
int nfc_data_exchange(struct nfc_dev *dev, u32 target_idx, struct sk_buff *skb, data_exchange_cb_t cb, void *cb_context) |
3e256b8f8 NFC: add nfc subs... |
472 473 |
{ int rc; |
20c239c13 nfc: Convert nfc_... |
474 475 476 |
pr_debug("dev_name=%s target_idx=%u skb->len=%u ", dev_name(&dev->dev), target_idx, skb->len); |
3e256b8f8 NFC: add nfc subs... |
477 478 479 480 481 482 483 484 |
device_lock(&dev->dev); if (!device_is_registered(&dev->dev)) { rc = -ENODEV; kfree_skb(skb); goto error; } |
be9ae4ce4 NFC: Introduce ta... |
485 486 487 488 489 490 |
if (dev->rf_mode == NFC_RF_INITIATOR && dev->active_target != NULL) { if (dev->active_target->idx != target_idx) { rc = -EADDRNOTAVAIL; kfree_skb(skb); goto error; } |
144612cac NFC: Changed targ... |
491 |
|
be9ae4ce4 NFC: Introduce ta... |
492 493 494 495 496 |
if (dev->ops->check_presence) del_timer_sync(&dev->check_pres_timer); rc = dev->ops->im_transceive(dev, dev->active_target, skb, cb, cb_context); |
f0c910381 NFC: Fixed nfc co... |
497 |
if (!rc && dev->ops->check_presence && !dev->shutting_down) |
be9ae4ce4 NFC: Introduce ta... |
498 499 500 501 502 503 |
mod_timer(&dev->check_pres_timer, jiffies + msecs_to_jiffies(NFC_CHECK_PRES_FREQ_MS)); } else if (dev->rf_mode == NFC_RF_TARGET && dev->ops->tm_send != NULL) { rc = dev->ops->tm_send(dev, skb); } else { rc = -ENOTCONN; |
144612cac NFC: Changed targ... |
504 505 506 |
kfree_skb(skb); goto error; } |
c8d56ae78 NFC: Add Core sup... |
507 |
|
3e256b8f8 NFC: add nfc subs... |
508 509 510 511 |
error: device_unlock(&dev->dev); return rc; } |
d8eb18eec NFC: Export nfc_f... |
512 |
struct nfc_se *nfc_find_se(struct nfc_dev *dev, u32 se_idx) |
c531c9ec2 NFC: Add secure e... |
513 |
{ |
156cef80f NFC: Use list_for... |
514 |
struct nfc_se *se; |
c531c9ec2 NFC: Add secure e... |
515 |
|
156cef80f NFC: Use list_for... |
516 |
list_for_each_entry(se, &dev->secure_elements, list) |
c531c9ec2 NFC: Add secure e... |
517 518 519 520 521 |
if (se->idx == se_idx) return se; return NULL; } |
d8eb18eec NFC: Export nfc_f... |
522 |
EXPORT_SYMBOL(nfc_find_se); |
c531c9ec2 NFC: Add secure e... |
523 524 525 |
int nfc_enable_se(struct nfc_dev *dev, u32 se_idx) { |
c531c9ec2 NFC: Add secure e... |
526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 |
struct nfc_se *se; int rc; pr_debug("%s se index %d ", dev_name(&dev->dev), se_idx); device_lock(&dev->dev); if (!device_is_registered(&dev->dev)) { rc = -ENODEV; goto error; } if (!dev->dev_up) { rc = -ENODEV; goto error; } if (dev->polling) { rc = -EBUSY; goto error; } if (!dev->ops->enable_se || !dev->ops->disable_se) { rc = -EOPNOTSUPP; goto error; } |
d8eb18eec NFC: Export nfc_f... |
553 |
se = nfc_find_se(dev, se_idx); |
c531c9ec2 NFC: Add secure e... |
554 555 556 557 |
if (!se) { rc = -EINVAL; goto error; } |
2c3832834 NFC: Fix secure e... |
558 |
if (se->state == NFC_SE_ENABLED) { |
c531c9ec2 NFC: Add secure e... |
559 560 561 562 563 |
rc = -EALREADY; goto error; } rc = dev->ops->enable_se(dev, se_idx); |
39525ee1d NFC: Update secur... |
564 565 |
if (rc >= 0) se->state = NFC_SE_ENABLED; |
c531c9ec2 NFC: Add secure e... |
566 567 568 569 570 571 572 573 |
error: device_unlock(&dev->dev); return rc; } int nfc_disable_se(struct nfc_dev *dev, u32 se_idx) { |
c531c9ec2 NFC: Add secure e... |
574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 |
struct nfc_se *se; int rc; pr_debug("%s se index %d ", dev_name(&dev->dev), se_idx); device_lock(&dev->dev); if (!device_is_registered(&dev->dev)) { rc = -ENODEV; goto error; } if (!dev->dev_up) { rc = -ENODEV; goto error; } if (!dev->ops->enable_se || !dev->ops->disable_se) { rc = -EOPNOTSUPP; goto error; } |
d8eb18eec NFC: Export nfc_f... |
596 |
se = nfc_find_se(dev, se_idx); |
c531c9ec2 NFC: Add secure e... |
597 598 599 600 |
if (!se) { rc = -EINVAL; goto error; } |
2c3832834 NFC: Fix secure e... |
601 |
if (se->state == NFC_SE_DISABLED) { |
c531c9ec2 NFC: Add secure e... |
602 603 604 605 606 |
rc = -EALREADY; goto error; } rc = dev->ops->disable_se(dev, se_idx); |
39525ee1d NFC: Update secur... |
607 608 |
if (rc >= 0) se->state = NFC_SE_DISABLED; |
c531c9ec2 NFC: Add secure e... |
609 610 611 612 613 |
error: device_unlock(&dev->dev); return rc; } |
541d920b0 NFC: Set and get ... |
614 615 |
int nfc_set_remote_general_bytes(struct nfc_dev *dev, u8 *gb, u8 gb_len) { |
0a40acb24 NFC: Core code id... |
616 617 |
pr_debug("dev_name=%s gb_len=%d ", dev_name(&dev->dev), gb_len); |
541d920b0 NFC: Set and get ... |
618 |
|
d646960f7 NFC: Initial LLCP... |
619 |
return nfc_llcp_set_remote_gb(dev, gb, gb_len); |
541d920b0 NFC: Set and get ... |
620 621 |
} EXPORT_SYMBOL(nfc_set_remote_general_bytes); |
ab73b7513 NFC: Export LLCP ... |
622 623 624 625 626 627 628 629 |
u8 *nfc_get_local_general_bytes(struct nfc_dev *dev, size_t *gb_len) { pr_debug("dev_name=%s ", dev_name(&dev->dev)); return nfc_llcp_general_bytes(dev, gb_len); } EXPORT_SYMBOL(nfc_get_local_general_bytes); |
73167ced3 NFC: Introduce ta... |
630 631 632 633 634 635 636 637 638 639 640 |
int nfc_tm_data_received(struct nfc_dev *dev, struct sk_buff *skb) { /* Only LLCP target mode for now */ if (dev->dep_link_up == false) { kfree_skb(skb); return -ENOLINK; } return nfc_llcp_data_received(dev, skb); } EXPORT_SYMBOL(nfc_tm_data_received); |
fc40a8c1a NFC: Add target m... |
641 642 643 644 645 646 647 648 649 650 651 652 653 654 |
int nfc_tm_activated(struct nfc_dev *dev, u32 protocol, u8 comm_mode, u8 *gb, size_t gb_len) { int rc; device_lock(&dev->dev); dev->polling = false; if (gb != NULL) { rc = nfc_set_remote_general_bytes(dev, gb, gb_len); if (rc < 0) goto out; } |
f212ad5e9 NFC: Set the NFC ... |
655 |
dev->rf_mode = NFC_RF_TARGET; |
fc40a8c1a NFC: Add target m... |
656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 |
if (protocol == NFC_PROTO_NFC_DEP_MASK) nfc_dep_link_is_up(dev, 0, comm_mode, NFC_RF_TARGET); rc = nfc_genl_tm_activated(dev, protocol); out: device_unlock(&dev->dev); return rc; } EXPORT_SYMBOL(nfc_tm_activated); int nfc_tm_deactivated(struct nfc_dev *dev) { dev->dep_link_up = false; |
5bcf099c1 NFC: Set rf_mode ... |
671 |
dev->rf_mode = NFC_RF_NONE; |
fc40a8c1a NFC: Add target m... |
672 673 674 675 |
return nfc_genl_tm_deactivated(dev); } EXPORT_SYMBOL(nfc_tm_deactivated); |
3e256b8f8 NFC: add nfc subs... |
676 |
/** |
7c7cd3bfe NFC: Add tx skb a... |
677 |
* nfc_alloc_send_skb - allocate a skb for data exchange responses |
3e256b8f8 NFC: add nfc subs... |
678 679 680 681 |
* * @size: size to allocate * @gfp: gfp flags */ |
7c7cd3bfe NFC: Add tx skb a... |
682 |
struct sk_buff *nfc_alloc_send_skb(struct nfc_dev *dev, struct sock *sk, |
0a40acb24 NFC: Core code id... |
683 684 |
unsigned int flags, unsigned int size, unsigned int *err) |
7c7cd3bfe NFC: Add tx skb a... |
685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 |
{ struct sk_buff *skb; unsigned int total_size; total_size = size + dev->tx_headroom + dev->tx_tailroom + NFC_HEADER_SIZE; skb = sock_alloc_send_skb(sk, total_size, flags & MSG_DONTWAIT, err); if (skb) skb_reserve(skb, dev->tx_headroom + NFC_HEADER_SIZE); return skb; } /** * nfc_alloc_recv_skb - allocate a skb for data exchange responses * * @size: size to allocate * @gfp: gfp flags */ struct sk_buff *nfc_alloc_recv_skb(unsigned int size, gfp_t gfp) |
3e256b8f8 NFC: add nfc subs... |
706 707 708 709 710 711 712 713 714 715 716 717 |
{ struct sk_buff *skb; unsigned int total_size; total_size = size + 1; skb = alloc_skb(total_size, gfp); if (skb) skb_reserve(skb, 1); return skb; } |
7c7cd3bfe NFC: Add tx skb a... |
718 |
EXPORT_SYMBOL(nfc_alloc_recv_skb); |
3e256b8f8 NFC: add nfc subs... |
719 |
|
4d12b8b12 NFC: add nfc gene... |
720 721 722 723 724 725 726 727 728 729 |
/** * nfc_targets_found - inform that targets were found * * @dev: The nfc device that found the targets * @targets: array of nfc targets found * @ntargets: targets array size * * The device driver must call this function when one or many nfc targets * are found. After calling this function, the device driver must stop * polling for targets. |
d94f9c55f NFC: nfc_targets_... |
730 731 |
* NOTE: This function can be called with targets=NULL and n_targets=0 to * notify a driver error, meaning that the polling operation cannot complete. |
d4ccb1328 NFC: Specify usag... |
732 733 734 |
* IMPORTANT: this function must not be called from an atomic context. * In addition, it must also not be called from a context that would prevent * the NFC Core to call other nfc ops entry point concurrently. |
4d12b8b12 NFC: add nfc gene... |
735 |
*/ |
0a40acb24 NFC: Core code id... |
736 737 |
int nfc_targets_found(struct nfc_dev *dev, struct nfc_target *targets, int n_targets) |
4d12b8b12 NFC: add nfc gene... |
738 |
{ |
c4fbb6515 NFC: The core par... |
739 |
int i; |
20c239c13 nfc: Convert nfc_... |
740 741 |
pr_debug("dev_name=%s n_targets=%d ", dev_name(&dev->dev), n_targets); |
4d12b8b12 NFC: add nfc gene... |
742 |
|
c4fbb6515 NFC: The core par... |
743 |
for (i = 0; i < n_targets; i++) |
01ae0eea9 NFC: Fix next tar... |
744 |
targets[i].idx = dev->target_next_idx++; |
c4fbb6515 NFC: The core par... |
745 |
|
d4ccb1328 NFC: Specify usag... |
746 |
device_lock(&dev->dev); |
4d12b8b12 NFC: add nfc gene... |
747 |
|
8668fdd6e NFC: Core must te... |
748 749 750 751 752 753 |
if (dev->polling == false) { device_unlock(&dev->dev); return 0; } dev->polling = false; |
4d12b8b12 NFC: add nfc gene... |
754 755 756 |
dev->targets_generation++; kfree(dev->targets); |
d94f9c55f NFC: nfc_targets_... |
757 |
dev->targets = NULL; |
4d12b8b12 NFC: add nfc gene... |
758 |
|
d94f9c55f NFC: nfc_targets_... |
759 760 761 762 763 764 765 766 767 768 |
if (targets) { dev->targets = kmemdup(targets, n_targets * sizeof(struct nfc_target), GFP_ATOMIC); if (!dev->targets) { dev->n_targets = 0; device_unlock(&dev->dev); return -ENOMEM; } |
4d12b8b12 NFC: add nfc gene... |
769 770 771 |
} dev->n_targets = n_targets; |
d4ccb1328 NFC: Specify usag... |
772 |
device_unlock(&dev->dev); |
4d12b8b12 NFC: add nfc gene... |
773 774 775 776 777 778 |
nfc_genl_targets_found(dev); return 0; } EXPORT_SYMBOL(nfc_targets_found); |
d4ccb1328 NFC: Specify usag... |
779 780 781 782 783 784 785 786 787 788 789 790 |
/** * nfc_target_lost - inform that an activated target went out of field * * @dev: The nfc device that had the activated target in field * @target_idx: the nfc index of the target * * The device driver must call this function when the activated target * goes out of the field. * IMPORTANT: this function must not be called from an atomic context. * In addition, it must also not be called from a context that would prevent * the NFC Core to call other nfc ops entry point concurrently. */ |
e1da0efa2 NFC: Export targe... |
791 792 793 794 795 796 797 |
int nfc_target_lost(struct nfc_dev *dev, u32 target_idx) { struct nfc_target *tg; int i; pr_debug("dev_name %s n_target %d ", dev_name(&dev->dev), target_idx); |
d4ccb1328 NFC: Specify usag... |
798 |
device_lock(&dev->dev); |
e1da0efa2 NFC: Export targe... |
799 800 801 802 803 804 805 806 |
for (i = 0; i < dev->n_targets; i++) { tg = &dev->targets[i]; if (tg->idx == target_idx) break; } if (i == dev->n_targets) { |
d4ccb1328 NFC: Specify usag... |
807 |
device_unlock(&dev->dev); |
e1da0efa2 NFC: Export targe... |
808 809 810 811 812 |
return -EINVAL; } dev->targets_generation++; dev->n_targets--; |
900994332 NFC: Cache the co... |
813 |
dev->active_target = NULL; |
e1da0efa2 NFC: Export targe... |
814 815 816 817 818 819 820 821 |
if (dev->n_targets) { memcpy(&dev->targets[i], &dev->targets[i + 1], (dev->n_targets - i) * sizeof(struct nfc_target)); } else { kfree(dev->targets); dev->targets = NULL; } |
d4ccb1328 NFC: Specify usag... |
822 |
device_unlock(&dev->dev); |
e1da0efa2 NFC: Export targe... |
823 824 825 826 827 828 |
nfc_genl_target_lost(dev, target_idx); return 0; } EXPORT_SYMBOL(nfc_target_lost); |
9eb334ac1 NFC: nfc_driver_f... |
829 |
inline void nfc_driver_failure(struct nfc_dev *dev, int err) |
456411ca8 NFC: Driver failu... |
830 |
{ |
9eb334ac1 NFC: nfc_driver_f... |
831 |
nfc_targets_found(dev, NULL, 0); |
456411ca8 NFC: Driver failu... |
832 833 |
} EXPORT_SYMBOL(nfc_driver_failure); |
fed7c25ec NFC: Add secure e... |
834 835 |
int nfc_add_se(struct nfc_dev *dev, u32 se_idx, u16 type) { |
c531c9ec2 NFC: Add secure e... |
836 |
struct nfc_se *se; |
2757c3723 NFC: Send netlink... |
837 |
int rc; |
fed7c25ec NFC: Add secure e... |
838 839 840 |
pr_debug("%s se index %d ", dev_name(&dev->dev), se_idx); |
d8eb18eec NFC: Export nfc_f... |
841 |
se = nfc_find_se(dev, se_idx); |
c531c9ec2 NFC: Add secure e... |
842 843 |
if (se) return -EALREADY; |
fed7c25ec NFC: Add secure e... |
844 845 846 847 848 849 850 851 852 853 854 |
se = kzalloc(sizeof(struct nfc_se), GFP_KERNEL); if (!se) return -ENOMEM; se->idx = se_idx; se->type = type; se->state = NFC_SE_DISABLED; INIT_LIST_HEAD(&se->list); list_add(&se->list, &dev->secure_elements); |
2757c3723 NFC: Send netlink... |
855 856 857 858 859 860 861 |
rc = nfc_genl_se_added(dev, se_idx, type); if (rc < 0) { list_del(&se->list); kfree(se); return rc; } |
fed7c25ec NFC: Add secure e... |
862 863 864 865 866 867 868 |
return 0; } EXPORT_SYMBOL(nfc_add_se); int nfc_remove_se(struct nfc_dev *dev, u32 se_idx) { struct nfc_se *se, *n; |
2757c3723 NFC: Send netlink... |
869 |
int rc; |
fed7c25ec NFC: Add secure e... |
870 871 872 873 874 875 |
pr_debug("%s se index %d ", dev_name(&dev->dev), se_idx); list_for_each_entry_safe(se, n, &dev->secure_elements, list) if (se->idx == se_idx) { |
2757c3723 NFC: Send netlink... |
876 877 878 |
rc = nfc_genl_se_removed(dev, se_idx); if (rc < 0) return rc; |
fed7c25ec NFC: Add secure e... |
879 880 881 882 883 884 885 886 887 |
list_del(&se->list); kfree(se); return 0; } return -EINVAL; } EXPORT_SYMBOL(nfc_remove_se); |
447b27c4f NFC: Forward NFC_... |
888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 |
int nfc_se_transaction(struct nfc_dev *dev, u8 se_idx, struct nfc_evt_transaction *evt_transaction) { int rc; pr_debug("transaction: %x ", se_idx); device_lock(&dev->dev); if (!evt_transaction) { rc = -EPROTO; goto out; } rc = nfc_genl_se_transaction(dev, se_idx, evt_transaction); out: device_unlock(&dev->dev); return rc; } EXPORT_SYMBOL(nfc_se_transaction); |
9afec6d38 nfc: netlink: HCI... |
909 910 911 912 913 914 915 916 917 918 919 920 921 |
int nfc_se_connectivity(struct nfc_dev *dev, u8 se_idx) { int rc; pr_debug("connectivity: %x ", se_idx); device_lock(&dev->dev); rc = nfc_genl_se_connectivity(dev, se_idx); device_unlock(&dev->dev); return rc; } EXPORT_SYMBOL(nfc_se_connectivity); |
3e256b8f8 NFC: add nfc subs... |
922 923 924 |
static void nfc_release(struct device *d) { struct nfc_dev *dev = to_nfc_dev(d); |
ee656e9d0 NFC: Remove and f... |
925 |
struct nfc_se *se, *n; |
3e256b8f8 NFC: add nfc subs... |
926 |
|
20c239c13 nfc: Convert nfc_... |
927 928 |
pr_debug("dev_name=%s ", dev_name(&dev->dev)); |
3e256b8f8 NFC: add nfc subs... |
929 |
|
4d12b8b12 NFC: add nfc gene... |
930 931 |
nfc_genl_data_exit(&dev->genl_data); kfree(dev->targets); |
ee656e9d0 NFC: Remove and f... |
932 933 934 935 936 937 |
list_for_each_entry_safe(se, n, &dev->secure_elements, list) { nfc_genl_se_removed(dev, se->idx); list_del(&se->list); kfree(se); } |
20777bc57 NFC: fix broken d... |
938 |
ida_simple_remove(&nfc_index_ida, dev->idx); |
3e256b8f8 NFC: add nfc subs... |
939 940 |
kfree(dev); } |
c8d56ae78 NFC: Add Core sup... |
941 942 943 944 945 946 947 |
static void nfc_check_pres_work(struct work_struct *work) { struct nfc_dev *dev = container_of(work, struct nfc_dev, check_pres_work); int rc; device_lock(&dev->dev); |
900994332 NFC: Cache the co... |
948 949 |
if (dev->active_target && timer_pending(&dev->check_pres_timer) == 0) { rc = dev->ops->check_presence(dev, dev->active_target); |
632c016ab NFC: HCI check pr... |
950 951 |
if (rc == -EOPNOTSUPP) goto exit; |
f0c910381 NFC: Fixed nfc co... |
952 |
if (rc) { |
d4ccb1328 NFC: Specify usag... |
953 954 955 956 |
u32 active_target_idx = dev->active_target->idx; device_unlock(&dev->dev); nfc_target_lost(dev, active_target_idx); return; |
c8d56ae78 NFC: Add Core sup... |
957 |
} |
f0c910381 NFC: Fixed nfc co... |
958 959 960 961 |
if (!dev->shutting_down) mod_timer(&dev->check_pres_timer, jiffies + msecs_to_jiffies(NFC_CHECK_PRES_FREQ_MS)); |
c8d56ae78 NFC: Add Core sup... |
962 |
} |
632c016ab NFC: HCI check pr... |
963 |
exit: |
c8d56ae78 NFC: Add Core sup... |
964 965 966 967 968 969 |
device_unlock(&dev->dev); } static void nfc_check_pres_timeout(unsigned long data) { struct nfc_dev *dev = (struct nfc_dev *)data; |
916082b07 workqueue: avoid ... |
970 |
schedule_work(&dev->check_pres_work); |
c8d56ae78 NFC: Add Core sup... |
971 |
} |
3e256b8f8 NFC: add nfc subs... |
972 973 974 975 976 |
struct class nfc_class = { .name = "nfc", .dev_release = nfc_release, }; EXPORT_SYMBOL(nfc_class); |
9f3b795a6 driver-core: cons... |
977 |
static int match_idx(struct device *d, const void *data) |
3e256b8f8 NFC: add nfc subs... |
978 979 |
{ struct nfc_dev *dev = to_nfc_dev(d); |
9f3b795a6 driver-core: cons... |
980 |
const unsigned int *idx = data; |
3e256b8f8 NFC: add nfc subs... |
981 982 983 |
return dev->idx == *idx; } |
95c961747 net: cleanup unsi... |
984 |
struct nfc_dev *nfc_get_device(unsigned int idx) |
3e256b8f8 NFC: add nfc subs... |
985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 |
{ struct device *d; d = class_find_device(&nfc_class, NULL, &idx, match_idx); if (!d) return NULL; return to_nfc_dev(d); } /** * nfc_allocate_device - allocate a new nfc device * * @ops: device operations * @supported_protocols: NFC protocols supported by the device */ struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops, |
0a40acb24 NFC: Core code id... |
1002 1003 |
u32 supported_protocols, int tx_headroom, int tx_tailroom) |
3e256b8f8 NFC: add nfc subs... |
1004 |
{ |
3e256b8f8 NFC: add nfc subs... |
1005 |
struct nfc_dev *dev; |
20777bc57 NFC: fix broken d... |
1006 |
int rc; |
3e256b8f8 NFC: add nfc subs... |
1007 1008 |
if (!ops->start_poll || !ops->stop_poll || !ops->activate_target || |
be9ae4ce4 NFC: Introduce ta... |
1009 |
!ops->deactivate_target || !ops->im_transceive) |
3e256b8f8 NFC: add nfc subs... |
1010 1011 1012 1013 1014 1015 1016 1017 |
return NULL; if (!supported_protocols) return NULL; dev = kzalloc(sizeof(struct nfc_dev), GFP_KERNEL); if (!dev) return NULL; |
20777bc57 NFC: fix broken d... |
1018 1019 1020 1021 1022 1023 1024 1025 |
rc = ida_simple_get(&nfc_index_ida, 0, 0, GFP_KERNEL); if (rc < 0) goto err_free_dev; dev->idx = rc; dev->dev.class = &nfc_class; dev_set_name(&dev->dev, "nfc%d", dev->idx); device_initialize(&dev->dev); |
3e256b8f8 NFC: add nfc subs... |
1026 1027 |
dev->ops = ops; dev->supported_protocols = supported_protocols; |
e8753043f NFC: Reserve tx h... |
1028 1029 |
dev->tx_headroom = tx_headroom; dev->tx_tailroom = tx_tailroom; |
fed7c25ec NFC: Add secure e... |
1030 |
INIT_LIST_HEAD(&dev->secure_elements); |
3e256b8f8 NFC: add nfc subs... |
1031 |
|
4d12b8b12 NFC: add nfc gene... |
1032 |
nfc_genl_data_init(&dev->genl_data); |
5bcf099c1 NFC: Set rf_mode ... |
1033 |
dev->rf_mode = NFC_RF_NONE; |
d4ccb1328 NFC: Specify usag... |
1034 |
|
4d12b8b12 NFC: add nfc gene... |
1035 1036 |
/* first generation must not be 0 */ dev->targets_generation = 1; |
c8d56ae78 NFC: Add Core sup... |
1037 |
if (ops->check_presence) { |
c8d56ae78 NFC: Add Core sup... |
1038 1039 1040 1041 1042 |
init_timer(&dev->check_pres_timer); dev->check_pres_timer.data = (unsigned long)dev; dev->check_pres_timer.function = nfc_check_pres_timeout; INIT_WORK(&dev->check_pres_work, nfc_check_pres_work); |
c8d56ae78 NFC: Add Core sup... |
1043 |
} |
3e256b8f8 NFC: add nfc subs... |
1044 |
return dev; |
20777bc57 NFC: fix broken d... |
1045 1046 1047 |
err_free_dev: kfree(dev); |
eb2499b39 NFC: fix device-a... |
1048 |
return NULL; |
3e256b8f8 NFC: add nfc subs... |
1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 |
} EXPORT_SYMBOL(nfc_allocate_device); /** * nfc_register_device - register a nfc device in the nfc subsystem * * @dev: The nfc device to register */ int nfc_register_device(struct nfc_dev *dev) { int rc; |
20c239c13 nfc: Convert nfc_... |
1060 1061 |
pr_debug("dev_name=%s ", dev_name(&dev->dev)); |
3e256b8f8 NFC: add nfc subs... |
1062 1063 1064 1065 1066 |
mutex_lock(&nfc_devlist_mutex); nfc_devlist_generation++; rc = device_add(&dev->dev); mutex_unlock(&nfc_devlist_mutex); |
4d12b8b12 NFC: add nfc gene... |
1067 1068 |
if (rc < 0) return rc; |
d646960f7 NFC: Initial LLCP... |
1069 1070 1071 1072 |
rc = nfc_llcp_register_device(dev); if (rc) pr_err("Could not register llcp device "); |
4d12b8b12 NFC: add nfc gene... |
1073 1074 |
rc = nfc_genl_device_added(dev); if (rc) |
20c239c13 nfc: Convert nfc_... |
1075 1076 1077 |
pr_debug("The userspace won't be notified that the device %s was added ", dev_name(&dev->dev)); |
4d12b8b12 NFC: add nfc gene... |
1078 |
|
be055b2f8 NFC: RFKILL support |
1079 1080 1081 1082 1083 1084 1085 1086 |
dev->rfkill = rfkill_alloc(dev_name(&dev->dev), &dev->dev, RFKILL_TYPE_NFC, &nfc_rfkill_ops, dev); if (dev->rfkill) { if (rfkill_register(dev->rfkill) < 0) { rfkill_destroy(dev->rfkill); dev->rfkill = NULL; } } |
4d12b8b12 NFC: add nfc gene... |
1087 |
return 0; |
3e256b8f8 NFC: add nfc subs... |
1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 |
} EXPORT_SYMBOL(nfc_register_device); /** * nfc_unregister_device - unregister a nfc device in the nfc subsystem * * @dev: The nfc device to unregister */ void nfc_unregister_device(struct nfc_dev *dev) { |
20777bc57 NFC: fix broken d... |
1098 |
int rc; |
4d12b8b12 NFC: add nfc gene... |
1099 |
|
20c239c13 nfc: Convert nfc_... |
1100 1101 |
pr_debug("dev_name=%s ", dev_name(&dev->dev)); |
3e256b8f8 NFC: add nfc subs... |
1102 |
|
be055b2f8 NFC: RFKILL support |
1103 1104 1105 1106 |
if (dev->rfkill) { rfkill_unregister(dev->rfkill); rfkill_destroy(dev->rfkill); } |
f0c910381 NFC: Fixed nfc co... |
1107 1108 1109 1110 1111 1112 1113 |
if (dev->ops->check_presence) { device_lock(&dev->dev); dev->shutting_down = true; device_unlock(&dev->dev); del_timer_sync(&dev->check_pres_timer); cancel_work_sync(&dev->check_pres_work); } |
3e256b8f8 NFC: add nfc subs... |
1114 |
|
f0c910381 NFC: Fixed nfc co... |
1115 1116 1117 1118 1119 |
rc = nfc_genl_device_removed(dev); if (rc) pr_debug("The userspace won't be notified that the device %s " "was removed ", dev_name(&dev->dev)); |
4d12b8b12 NFC: add nfc gene... |
1120 |
|
d646960f7 NFC: Initial LLCP... |
1121 |
nfc_llcp_unregister_device(dev); |
f0c910381 NFC: Fixed nfc co... |
1122 1123 1124 1125 |
mutex_lock(&nfc_devlist_mutex); nfc_devlist_generation++; device_del(&dev->dev); mutex_unlock(&nfc_devlist_mutex); |
3e256b8f8 NFC: add nfc subs... |
1126 1127 1128 1129 1130 |
} EXPORT_SYMBOL(nfc_unregister_device); static int __init nfc_init(void) { |
4d12b8b12 NFC: add nfc gene... |
1131 |
int rc; |
ed1e0ad88 nfc: Use standard... |
1132 1133 |
pr_info("NFC Core ver %s ", VERSION); |
3e256b8f8 NFC: add nfc subs... |
1134 |
|
4d12b8b12 NFC: add nfc gene... |
1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 |
rc = class_register(&nfc_class); if (rc) return rc; rc = nfc_genl_init(); if (rc) goto err_genl; /* the first generation must not be 0 */ nfc_devlist_generation = 1; |
23b7869c0 NFC: add the NFC ... |
1145 1146 1147 |
rc = rawsock_init(); if (rc) goto err_rawsock; |
d646960f7 NFC: Initial LLCP... |
1148 1149 1150 |
rc = nfc_llcp_init(); if (rc) goto err_llcp_sock; |
c7fe3b52c NFC: add NFC sock... |
1151 1152 1153 |
rc = af_nfc_init(); if (rc) goto err_af_nfc; |
4d12b8b12 NFC: add nfc gene... |
1154 |
return 0; |
c7fe3b52c NFC: add NFC sock... |
1155 |
err_af_nfc: |
d646960f7 NFC: Initial LLCP... |
1156 1157 |
nfc_llcp_exit(); err_llcp_sock: |
23b7869c0 NFC: add the NFC ... |
1158 1159 |
rawsock_exit(); err_rawsock: |
c7fe3b52c NFC: add NFC sock... |
1160 |
nfc_genl_exit(); |
4d12b8b12 NFC: add nfc gene... |
1161 1162 1163 |
err_genl: class_unregister(&nfc_class); return rc; |
3e256b8f8 NFC: add nfc subs... |
1164 1165 1166 1167 |
} static void __exit nfc_exit(void) { |
c7fe3b52c NFC: add NFC sock... |
1168 |
af_nfc_exit(); |
d646960f7 NFC: Initial LLCP... |
1169 |
nfc_llcp_exit(); |
23b7869c0 NFC: add the NFC ... |
1170 |
rawsock_exit(); |
4d12b8b12 NFC: add nfc gene... |
1171 |
nfc_genl_exit(); |
3e256b8f8 NFC: add nfc subs... |
1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 |
class_unregister(&nfc_class); } subsys_initcall(nfc_init); module_exit(nfc_exit); MODULE_AUTHOR("Lauro Ramos Venancio <lauro.venancio@openbossa.org>"); MODULE_DESCRIPTION("NFC Core ver " VERSION); MODULE_VERSION(VERSION); MODULE_LICENSE("GPL"); |
1155bb617 NFC: Add modules ... |
1182 |
MODULE_ALIAS_NETPROTO(PF_NFC); |
5df16cad4 NFC: Add netlink ... |
1183 |
MODULE_ALIAS_GENL_FAMILY(NFC_GENL_NAME); |