linux/net/nfc/netlink.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2011 Instituto Nokia de Tecnologia
   3 *
   4 * Authors:
   5 *    Lauro Ramos Venancio <lauro.venancio@openbossa.org>
   6 *    Aloisio Almeida Jr <aloisio.almeida@openbossa.org>
   7 *
   8 * This program is free software; you can redistribute it and/or modify
   9 * it under the terms of the GNU General Public License as published by
  10 * the Free Software Foundation; either version 2 of the License, or
  11 * (at your option) any later version.
  12 *
  13 * This program is distributed in the hope that it will be useful,
  14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16 * GNU General Public License for more details.
  17 *
  18 * You should have received a copy of the GNU General Public License
  19 * along with this program; if not, write to the
  20 * Free Software Foundation, Inc.,
  21 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  22 */
  23
  24#define pr_fmt(fmt) KBUILD_MODNAME ": %s: " fmt, __func__
  25
  26#include <net/genetlink.h>
  27#include <linux/nfc.h>
  28#include <linux/slab.h>
  29
  30#include "nfc.h"
  31
  32static struct genl_multicast_group nfc_genl_event_mcgrp = {
  33        .name = NFC_GENL_MCAST_EVENT_NAME,
  34};
  35
  36static struct genl_family nfc_genl_family = {
  37        .id = GENL_ID_GENERATE,
  38        .hdrsize = 0,
  39        .name = NFC_GENL_NAME,
  40        .version = NFC_GENL_VERSION,
  41        .maxattr = NFC_ATTR_MAX,
  42};
  43
  44static const struct nla_policy nfc_genl_policy[NFC_ATTR_MAX + 1] = {
  45        [NFC_ATTR_DEVICE_INDEX] = { .type = NLA_U32 },
  46        [NFC_ATTR_DEVICE_NAME] = { .type = NLA_STRING,
  47                                .len = NFC_DEVICE_NAME_MAXSIZE },
  48        [NFC_ATTR_PROTOCOLS] = { .type = NLA_U32 },
  49        [NFC_ATTR_COMM_MODE] = { .type = NLA_U8 },
  50        [NFC_ATTR_RF_MODE] = { .type = NLA_U8 },
  51        [NFC_ATTR_DEVICE_POWERED] = { .type = NLA_U8 },
  52        [NFC_ATTR_IM_PROTOCOLS] = { .type = NLA_U32 },
  53        [NFC_ATTR_TM_PROTOCOLS] = { .type = NLA_U32 },
  54};
  55
  56static int nfc_genl_send_target(struct sk_buff *msg, struct nfc_target *target,
  57                                struct netlink_callback *cb, int flags)
  58{
  59        void *hdr;
  60
  61        hdr = genlmsg_put(msg, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq,
  62                          &nfc_genl_family, flags, NFC_CMD_GET_TARGET);
  63        if (!hdr)
  64                return -EMSGSIZE;
  65
  66        genl_dump_check_consistent(cb, hdr, &nfc_genl_family);
  67
  68        if (nla_put_u32(msg, NFC_ATTR_TARGET_INDEX, target->idx) ||
  69            nla_put_u32(msg, NFC_ATTR_PROTOCOLS, target->supported_protocols) ||
  70            nla_put_u16(msg, NFC_ATTR_TARGET_SENS_RES, target->sens_res) ||
  71            nla_put_u8(msg, NFC_ATTR_TARGET_SEL_RES, target->sel_res))
  72                goto nla_put_failure;
  73        if (target->nfcid1_len > 0 &&
  74            nla_put(msg, NFC_ATTR_TARGET_NFCID1, target->nfcid1_len,
  75                    target->nfcid1))
  76                goto nla_put_failure;
  77        if (target->sensb_res_len > 0 &&
  78            nla_put(msg, NFC_ATTR_TARGET_SENSB_RES, target->sensb_res_len,
  79                    target->sensb_res))
  80                goto nla_put_failure;
  81        if (target->sensf_res_len > 0 &&
  82            nla_put(msg, NFC_ATTR_TARGET_SENSF_RES, target->sensf_res_len,
  83                    target->sensf_res))
  84                goto nla_put_failure;
  85
  86        return genlmsg_end(msg, hdr);
  87
  88nla_put_failure:
  89        genlmsg_cancel(msg, hdr);
  90        return -EMSGSIZE;
  91}
  92
  93static struct nfc_dev *__get_device_from_cb(struct netlink_callback *cb)
  94{
  95        struct nfc_dev *dev;
  96        int rc;
  97        u32 idx;
  98
  99        rc = nlmsg_parse(cb->nlh, GENL_HDRLEN + nfc_genl_family.hdrsize,
 100                         nfc_genl_family.attrbuf,
 101                         nfc_genl_family.maxattr,
 102                         nfc_genl_policy);
 103        if (rc < 0)
 104                return ERR_PTR(rc);
 105
 106        if (!nfc_genl_family.attrbuf[NFC_ATTR_DEVICE_INDEX])
 107                return ERR_PTR(-EINVAL);
 108
 109        idx = nla_get_u32(nfc_genl_family.attrbuf[NFC_ATTR_DEVICE_INDEX]);
 110
 111        dev = nfc_get_device(idx);
 112        if (!dev)
 113                return ERR_PTR(-ENODEV);
 114
 115        return dev;
 116}
 117
 118static int nfc_genl_dump_targets(struct sk_buff *skb,
 119                                 struct netlink_callback *cb)
 120{
 121        int i = cb->args[0];
 122        struct nfc_dev *dev = (struct nfc_dev *) cb->args[1];
 123        int rc;
 124
 125        if (!dev) {
 126                dev = __get_device_from_cb(cb);
 127                if (IS_ERR(dev))
 128                        return PTR_ERR(dev);
 129
 130                cb->args[1] = (long) dev;
 131        }
 132
 133        device_lock(&dev->dev);
 134
 135        cb->seq = dev->targets_generation;
 136
 137        while (i < dev->n_targets) {
 138                rc = nfc_genl_send_target(skb, &dev->targets[i], cb,
 139                                          NLM_F_MULTI);
 140                if (rc < 0)
 141                        break;
 142
 143                i++;
 144        }
 145
 146        device_unlock(&dev->dev);
 147
 148        cb->args[0] = i;
 149
 150        return skb->len;
 151}
 152
 153static int nfc_genl_dump_targets_done(struct netlink_callback *cb)
 154{
 155        struct nfc_dev *dev = (struct nfc_dev *) cb->args[1];
 156
 157        if (dev)
 158                nfc_put_device(dev);
 159
 160        return 0;
 161}
 162
 163int nfc_genl_targets_found(struct nfc_dev *dev)
 164{
 165        struct sk_buff *msg;
 166        void *hdr;
 167
 168        dev->genl_data.poll_req_pid = 0;
 169
 170        msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
 171        if (!msg)
 172                return -ENOMEM;
 173
 174        hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
 175                          NFC_EVENT_TARGETS_FOUND);
 176        if (!hdr)
 177                goto free_msg;
 178
 179        if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx))
 180                goto nla_put_failure;
 181
 182        genlmsg_end(msg, hdr);
 183
 184        return genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_ATOMIC);
 185
 186nla_put_failure:
 187        genlmsg_cancel(msg, hdr);
 188free_msg:
 189        nlmsg_free(msg);
 190        return -EMSGSIZE;
 191}
 192
 193int nfc_genl_target_lost(struct nfc_dev *dev, u32 target_idx)
 194{
 195        struct sk_buff *msg;
 196        void *hdr;
 197
 198        msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 199        if (!msg)
 200                return -ENOMEM;
 201
 202        hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
 203                          NFC_EVENT_TARGET_LOST);
 204        if (!hdr)
 205                goto free_msg;
 206
 207        if (nla_put_string(msg, NFC_ATTR_DEVICE_NAME, nfc_device_name(dev)) ||
 208            nla_put_u32(msg, NFC_ATTR_TARGET_INDEX, target_idx))
 209                goto nla_put_failure;
 210
 211        genlmsg_end(msg, hdr);
 212
 213        genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_KERNEL);
 214
 215        return 0;
 216
 217nla_put_failure:
 218        genlmsg_cancel(msg, hdr);
 219free_msg:
 220        nlmsg_free(msg);
 221        return -EMSGSIZE;
 222}
 223
 224int nfc_genl_tm_activated(struct nfc_dev *dev, u32 protocol)
 225{
 226        struct sk_buff *msg;
 227        void *hdr;
 228
 229        msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 230        if (!msg)
 231                return -ENOMEM;
 232
 233        hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
 234                          NFC_EVENT_TM_ACTIVATED);
 235        if (!hdr)
 236                goto free_msg;
 237
 238        if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx))
 239                goto nla_put_failure;
 240        if (nla_put_u32(msg, NFC_ATTR_TM_PROTOCOLS, protocol))
 241                goto nla_put_failure;
 242
 243        genlmsg_end(msg, hdr);
 244
 245        genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_KERNEL);
 246
 247        return 0;
 248
 249nla_put_failure:
 250        genlmsg_cancel(msg, hdr);
 251free_msg:
 252        nlmsg_free(msg);
 253        return -EMSGSIZE;
 254}
 255
 256int nfc_genl_tm_deactivated(struct nfc_dev *dev)
 257{
 258        struct sk_buff *msg;
 259        void *hdr;
 260
 261        msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 262        if (!msg)
 263                return -ENOMEM;
 264
 265        hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
 266                          NFC_EVENT_TM_DEACTIVATED);
 267        if (!hdr)
 268                goto free_msg;
 269
 270        if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx))
 271                goto nla_put_failure;
 272
 273        genlmsg_end(msg, hdr);
 274
 275        genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_KERNEL);
 276
 277        return 0;
 278
 279nla_put_failure:
 280        genlmsg_cancel(msg, hdr);
 281free_msg:
 282        nlmsg_free(msg);
 283        return -EMSGSIZE;
 284}
 285
 286int nfc_genl_device_added(struct nfc_dev *dev)
 287{
 288        struct sk_buff *msg;
 289        void *hdr;
 290
 291        msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 292        if (!msg)
 293                return -ENOMEM;
 294
 295        hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
 296                          NFC_EVENT_DEVICE_ADDED);
 297        if (!hdr)
 298                goto free_msg;
 299
 300        if (nla_put_string(msg, NFC_ATTR_DEVICE_NAME, nfc_device_name(dev)) ||
 301            nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx) ||
 302            nla_put_u32(msg, NFC_ATTR_PROTOCOLS, dev->supported_protocols) ||
 303            nla_put_u8(msg, NFC_ATTR_DEVICE_POWERED, dev->dev_up))
 304                goto nla_put_failure;
 305
 306        genlmsg_end(msg, hdr);
 307
 308        genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_KERNEL);
 309
 310        return 0;
 311
 312nla_put_failure:
 313        genlmsg_cancel(msg, hdr);
 314free_msg:
 315        nlmsg_free(msg);
 316        return -EMSGSIZE;
 317}
 318
 319int nfc_genl_device_removed(struct nfc_dev *dev)
 320{
 321        struct sk_buff *msg;
 322        void *hdr;
 323
 324        msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 325        if (!msg)
 326                return -ENOMEM;
 327
 328        hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
 329                          NFC_EVENT_DEVICE_REMOVED);
 330        if (!hdr)
 331                goto free_msg;
 332
 333        if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx))
 334                goto nla_put_failure;
 335
 336        genlmsg_end(msg, hdr);
 337
 338        genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_KERNEL);
 339
 340        return 0;
 341
 342nla_put_failure:
 343        genlmsg_cancel(msg, hdr);
 344free_msg:
 345        nlmsg_free(msg);
 346        return -EMSGSIZE;
 347}
 348
 349static int nfc_genl_send_device(struct sk_buff *msg, struct nfc_dev *dev,
 350                                u32 pid, u32 seq,
 351                                struct netlink_callback *cb,
 352                                int flags)
 353{
 354        void *hdr;
 355
 356        hdr = genlmsg_put(msg, pid, seq, &nfc_genl_family, flags,
 357                          NFC_CMD_GET_DEVICE);
 358        if (!hdr)
 359                return -EMSGSIZE;
 360
 361        if (cb)
 362                genl_dump_check_consistent(cb, hdr, &nfc_genl_family);
 363
 364        if (nla_put_string(msg, NFC_ATTR_DEVICE_NAME, nfc_device_name(dev)) ||
 365            nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx) ||
 366            nla_put_u32(msg, NFC_ATTR_PROTOCOLS, dev->supported_protocols) ||
 367            nla_put_u8(msg, NFC_ATTR_DEVICE_POWERED, dev->dev_up))
 368                goto nla_put_failure;
 369
 370        return genlmsg_end(msg, hdr);
 371
 372nla_put_failure:
 373        genlmsg_cancel(msg, hdr);
 374        return -EMSGSIZE;
 375}
 376
 377static int nfc_genl_dump_devices(struct sk_buff *skb,
 378                                 struct netlink_callback *cb)
 379{
 380        struct class_dev_iter *iter = (struct class_dev_iter *) cb->args[0];
 381        struct nfc_dev *dev = (struct nfc_dev *) cb->args[1];
 382        bool first_call = false;
 383
 384        if (!iter) {
 385                first_call = true;
 386                iter = kmalloc(sizeof(struct class_dev_iter), GFP_KERNEL);
 387                if (!iter)
 388                        return -ENOMEM;
 389                cb->args[0] = (long) iter;
 390        }
 391
 392        mutex_lock(&nfc_devlist_mutex);
 393
 394        cb->seq = nfc_devlist_generation;
 395
 396        if (first_call) {
 397                nfc_device_iter_init(iter);
 398                dev = nfc_device_iter_next(iter);
 399        }
 400
 401        while (dev) {
 402                int rc;
 403
 404                rc = nfc_genl_send_device(skb, dev, NETLINK_CB(cb->skb).pid,
 405                                          cb->nlh->nlmsg_seq, cb, NLM_F_MULTI);
 406                if (rc < 0)
 407                        break;
 408
 409                dev = nfc_device_iter_next(iter);
 410        }
 411
 412        mutex_unlock(&nfc_devlist_mutex);
 413
 414        cb->args[1] = (long) dev;
 415
 416        return skb->len;
 417}
 418
 419static int nfc_genl_dump_devices_done(struct netlink_callback *cb)
 420{
 421        struct class_dev_iter *iter = (struct class_dev_iter *) cb->args[0];
 422
 423        nfc_device_iter_exit(iter);
 424        kfree(iter);
 425
 426        return 0;
 427}
 428
 429int nfc_genl_dep_link_up_event(struct nfc_dev *dev, u32 target_idx,
 430                               u8 comm_mode, u8 rf_mode)
 431{
 432        struct sk_buff *msg;
 433        void *hdr;
 434
 435        pr_debug("DEP link is up\n");
 436
 437        msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
 438        if (!msg)
 439                return -ENOMEM;
 440
 441        hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0, NFC_CMD_DEP_LINK_UP);
 442        if (!hdr)
 443                goto free_msg;
 444
 445        if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx))
 446                goto nla_put_failure;
 447        if (rf_mode == NFC_RF_INITIATOR &&
 448            nla_put_u32(msg, NFC_ATTR_TARGET_INDEX, target_idx))
 449                goto nla_put_failure;
 450        if (nla_put_u8(msg, NFC_ATTR_COMM_MODE, comm_mode) ||
 451            nla_put_u8(msg, NFC_ATTR_RF_MODE, rf_mode))
 452                goto nla_put_failure;
 453
 454        genlmsg_end(msg, hdr);
 455
 456        dev->dep_link_up = true;
 457
 458        genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_ATOMIC);
 459
 460        return 0;
 461
 462nla_put_failure:
 463        genlmsg_cancel(msg, hdr);
 464free_msg:
 465        nlmsg_free(msg);
 466        return -EMSGSIZE;
 467}
 468
 469int nfc_genl_dep_link_down_event(struct nfc_dev *dev)
 470{
 471        struct sk_buff *msg;
 472        void *hdr;
 473
 474        pr_debug("DEP link is down\n");
 475
 476        msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
 477        if (!msg)
 478                return -ENOMEM;
 479
 480        hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
 481                          NFC_CMD_DEP_LINK_DOWN);
 482        if (!hdr)
 483                goto free_msg;
 484
 485        if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx))
 486                goto nla_put_failure;
 487
 488        genlmsg_end(msg, hdr);
 489
 490        genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_ATOMIC);
 491
 492        return 0;
 493
 494nla_put_failure:
 495        genlmsg_cancel(msg, hdr);
 496free_msg:
 497        nlmsg_free(msg);
 498        return -EMSGSIZE;
 499}
 500
 501static int nfc_genl_get_device(struct sk_buff *skb, struct genl_info *info)
 502{
 503        struct sk_buff *msg;
 504        struct nfc_dev *dev;
 505        u32 idx;
 506        int rc = -ENOBUFS;
 507
 508        if (!info->attrs[NFC_ATTR_DEVICE_INDEX])
 509                return -EINVAL;
 510
 511        idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
 512
 513        dev = nfc_get_device(idx);
 514        if (!dev)
 515                return -ENODEV;
 516
 517        msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 518        if (!msg) {
 519                rc = -ENOMEM;
 520                goto out_putdev;
 521        }
 522
 523        rc = nfc_genl_send_device(msg, dev, info->snd_pid, info->snd_seq,
 524                                  NULL, 0);
 525        if (rc < 0)
 526                goto out_free;
 527
 528        nfc_put_device(dev);
 529
 530        return genlmsg_reply(msg, info);
 531
 532out_free:
 533        nlmsg_free(msg);
 534out_putdev:
 535        nfc_put_device(dev);
 536        return rc;
 537}
 538
 539static int nfc_genl_dev_up(struct sk_buff *skb, struct genl_info *info)
 540{
 541        struct nfc_dev *dev;
 542        int rc;
 543        u32 idx;
 544
 545        if (!info->attrs[NFC_ATTR_DEVICE_INDEX])
 546                return -EINVAL;
 547
 548        idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
 549
 550        dev = nfc_get_device(idx);
 551        if (!dev)
 552                return -ENODEV;
 553
 554        rc = nfc_dev_up(dev);
 555
 556        nfc_put_device(dev);
 557        return rc;
 558}
 559
 560static int nfc_genl_dev_down(struct sk_buff *skb, struct genl_info *info)
 561{
 562        struct nfc_dev *dev;
 563        int rc;
 564        u32 idx;
 565
 566        if (!info->attrs[NFC_ATTR_DEVICE_INDEX])
 567                return -EINVAL;
 568
 569        idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
 570
 571        dev = nfc_get_device(idx);
 572        if (!dev)
 573                return -ENODEV;
 574
 575        rc = nfc_dev_down(dev);
 576
 577        nfc_put_device(dev);
 578        return rc;
 579}
 580
 581static int nfc_genl_start_poll(struct sk_buff *skb, struct genl_info *info)
 582{
 583        struct nfc_dev *dev;
 584        int rc;
 585        u32 idx;
 586        u32 im_protocols = 0, tm_protocols = 0;
 587
 588        pr_debug("Poll start\n");
 589
 590        if (!info->attrs[NFC_ATTR_DEVICE_INDEX] ||
 591            ((!info->attrs[NFC_ATTR_IM_PROTOCOLS] &&
 592              !info->attrs[NFC_ATTR_PROTOCOLS]) &&
 593             !info->attrs[NFC_ATTR_TM_PROTOCOLS]))
 594                return -EINVAL;
 595
 596        idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
 597
 598        if (info->attrs[NFC_ATTR_TM_PROTOCOLS])
 599                tm_protocols = nla_get_u32(info->attrs[NFC_ATTR_TM_PROTOCOLS]);
 600
 601        if (info->attrs[NFC_ATTR_IM_PROTOCOLS])
 602                im_protocols = nla_get_u32(info->attrs[NFC_ATTR_IM_PROTOCOLS]);
 603        else if (info->attrs[NFC_ATTR_PROTOCOLS])
 604                im_protocols = nla_get_u32(info->attrs[NFC_ATTR_PROTOCOLS]);
 605
 606        dev = nfc_get_device(idx);
 607        if (!dev)
 608                return -ENODEV;
 609
 610        mutex_lock(&dev->genl_data.genl_data_mutex);
 611
 612        rc = nfc_start_poll(dev, im_protocols, tm_protocols);
 613        if (!rc)
 614                dev->genl_data.poll_req_pid = info->snd_pid;
 615
 616        mutex_unlock(&dev->genl_data.genl_data_mutex);
 617
 618        nfc_put_device(dev);
 619        return rc;
 620}
 621
 622static int nfc_genl_stop_poll(struct sk_buff *skb, struct genl_info *info)
 623{
 624        struct nfc_dev *dev;
 625        int rc;
 626        u32 idx;
 627
 628        if (!info->attrs[NFC_ATTR_DEVICE_INDEX])
 629                return -EINVAL;
 630
 631        idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
 632
 633        dev = nfc_get_device(idx);
 634        if (!dev)
 635                return -ENODEV;
 636
 637        device_lock(&dev->dev);
 638
 639        if (!dev->polling) {
 640                device_unlock(&dev->dev);
 641                return -EINVAL;
 642        }
 643
 644        device_unlock(&dev->dev);
 645
 646        mutex_lock(&dev->genl_data.genl_data_mutex);
 647
 648        if (dev->genl_data.poll_req_pid != info->snd_pid) {
 649                rc = -EBUSY;
 650                goto out;
 651        }
 652
 653        rc = nfc_stop_poll(dev);
 654        dev->genl_data.poll_req_pid = 0;
 655
 656out:
 657        mutex_unlock(&dev->genl_data.genl_data_mutex);
 658        nfc_put_device(dev);
 659        return rc;
 660}
 661
 662static int nfc_genl_dep_link_up(struct sk_buff *skb, struct genl_info *info)
 663{
 664        struct nfc_dev *dev;
 665        int rc, tgt_idx;
 666        u32 idx;
 667        u8 comm;
 668
 669        pr_debug("DEP link up\n");
 670
 671        if (!info->attrs[NFC_ATTR_DEVICE_INDEX] ||
 672            !info->attrs[NFC_ATTR_COMM_MODE])
 673                return -EINVAL;
 674
 675        idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
 676        if (!info->attrs[NFC_ATTR_TARGET_INDEX])
 677                tgt_idx = NFC_TARGET_IDX_ANY;
 678        else
 679                tgt_idx = nla_get_u32(info->attrs[NFC_ATTR_TARGET_INDEX]);
 680
 681        comm = nla_get_u8(info->attrs[NFC_ATTR_COMM_MODE]);
 682
 683        if (comm != NFC_COMM_ACTIVE && comm != NFC_COMM_PASSIVE)
 684                return -EINVAL;
 685
 686        dev = nfc_get_device(idx);
 687        if (!dev)
 688                return -ENODEV;
 689
 690        rc = nfc_dep_link_up(dev, tgt_idx, comm);
 691
 692        nfc_put_device(dev);
 693
 694        return rc;
 695}
 696
 697static int nfc_genl_dep_link_down(struct sk_buff *skb, struct genl_info *info)
 698{
 699        struct nfc_dev *dev;
 700        int rc;
 701        u32 idx;
 702
 703        if (!info->attrs[NFC_ATTR_DEVICE_INDEX])
 704                return -EINVAL;
 705
 706        idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
 707
 708        dev = nfc_get_device(idx);
 709        if (!dev)
 710                return -ENODEV;
 711
 712        rc = nfc_dep_link_down(dev);
 713
 714        nfc_put_device(dev);
 715        return rc;
 716}
 717
 718static struct genl_ops nfc_genl_ops[] = {
 719        {
 720                .cmd = NFC_CMD_GET_DEVICE,
 721                .doit = nfc_genl_get_device,
 722                .dumpit = nfc_genl_dump_devices,
 723                .done = nfc_genl_dump_devices_done,
 724                .policy = nfc_genl_policy,
 725        },
 726        {
 727                .cmd = NFC_CMD_DEV_UP,
 728                .doit = nfc_genl_dev_up,
 729                .policy = nfc_genl_policy,
 730        },
 731        {
 732                .cmd = NFC_CMD_DEV_DOWN,
 733                .doit = nfc_genl_dev_down,
 734                .policy = nfc_genl_policy,
 735        },
 736        {
 737                .cmd = NFC_CMD_START_POLL,
 738                .doit = nfc_genl_start_poll,
 739                .policy = nfc_genl_policy,
 740        },
 741        {
 742                .cmd = NFC_CMD_STOP_POLL,
 743                .doit = nfc_genl_stop_poll,
 744                .policy = nfc_genl_policy,
 745        },
 746        {
 747                .cmd = NFC_CMD_DEP_LINK_UP,
 748                .doit = nfc_genl_dep_link_up,
 749                .policy = nfc_genl_policy,
 750        },
 751        {
 752                .cmd = NFC_CMD_DEP_LINK_DOWN,
 753                .doit = nfc_genl_dep_link_down,
 754                .policy = nfc_genl_policy,
 755        },
 756        {
 757                .cmd = NFC_CMD_GET_TARGET,
 758                .dumpit = nfc_genl_dump_targets,
 759                .done = nfc_genl_dump_targets_done,
 760                .policy = nfc_genl_policy,
 761        },
 762};
 763
 764static int nfc_genl_rcv_nl_event(struct notifier_block *this,
 765                                 unsigned long event, void *ptr)
 766{
 767        struct netlink_notify *n = ptr;
 768        struct class_dev_iter iter;
 769        struct nfc_dev *dev;
 770
 771        if (event != NETLINK_URELEASE || n->protocol != NETLINK_GENERIC)
 772                goto out;
 773
 774        pr_debug("NETLINK_URELEASE event from id %d\n", n->pid);
 775
 776        nfc_device_iter_init(&iter);
 777        dev = nfc_device_iter_next(&iter);
 778
 779        while (dev) {
 780                if (dev->genl_data.poll_req_pid == n->pid) {
 781                        nfc_stop_poll(dev);
 782                        dev->genl_data.poll_req_pid = 0;
 783                }
 784                dev = nfc_device_iter_next(&iter);
 785        }
 786
 787        nfc_device_iter_exit(&iter);
 788
 789out:
 790        return NOTIFY_DONE;
 791}
 792
 793void nfc_genl_data_init(struct nfc_genl_data *genl_data)
 794{
 795        genl_data->poll_req_pid = 0;
 796        mutex_init(&genl_data->genl_data_mutex);
 797}
 798
 799void nfc_genl_data_exit(struct nfc_genl_data *genl_data)
 800{
 801        mutex_destroy(&genl_data->genl_data_mutex);
 802}
 803
 804static struct notifier_block nl_notifier = {
 805        .notifier_call  = nfc_genl_rcv_nl_event,
 806};
 807
 808/**
 809 * nfc_genl_init() - Initialize netlink interface
 810 *
 811 * This initialization function registers the nfc netlink family.
 812 */
 813int __init nfc_genl_init(void)
 814{
 815        int rc;
 816
 817        rc = genl_register_family_with_ops(&nfc_genl_family, nfc_genl_ops,
 818                                           ARRAY_SIZE(nfc_genl_ops));
 819        if (rc)
 820                return rc;
 821
 822        rc = genl_register_mc_group(&nfc_genl_family, &nfc_genl_event_mcgrp);
 823
 824        netlink_register_notifier(&nl_notifier);
 825
 826        return rc;
 827}
 828
 829/**
 830 * nfc_genl_exit() - Deinitialize netlink interface
 831 *
 832 * This exit function unregisters the nfc netlink family.
 833 */
 834void nfc_genl_exit(void)
 835{
 836        netlink_unregister_notifier(&nl_notifier);
 837        genl_unregister_family(&nfc_genl_family);
 838}
 839
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.