diff options
author | Sage Weil <sage@inktank.com> | 2012-06-15 12:32:04 -0700 |
---|---|---|
committer | Sage Weil <sage@inktank.com> | 2012-06-15 12:32:04 -0700 |
commit | 9a64e8e0ace51b309fdcff4b4754b3649250382a (patch) | |
tree | 1f0d75c196c5ab0408c55ed6cf3a152f1f921e15 /net/nfc/netlink.c | |
parent | f3dea7edd3d449fe7a6d402c1ce56a294b985261 (diff) | |
parent | f8f5701bdaf9134b1f90e5044a82c66324d2073f (diff) | |
download | linux-9a64e8e0ace51b309fdcff4b4754b3649250382a.tar.gz linux-9a64e8e0ace51b309fdcff4b4754b3649250382a.tar.bz2 linux-9a64e8e0ace51b309fdcff4b4754b3649250382a.zip |
Merge tag 'v3.5-rc1'
Linux 3.5-rc1
Conflicts:
net/ceph/messenger.c
Diffstat (limited to 'net/nfc/netlink.c')
-rw-r--r-- | net/nfc/netlink.c | 160 |
1 files changed, 102 insertions, 58 deletions
diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c index 6989dfa28ee2..581d419083aa 100644 --- a/net/nfc/netlink.c +++ b/net/nfc/netlink.c @@ -33,7 +33,7 @@ static struct genl_multicast_group nfc_genl_event_mcgrp = { .name = NFC_GENL_MCAST_EVENT_NAME, }; -struct genl_family nfc_genl_family = { +static struct genl_family nfc_genl_family = { .id = GENL_ID_GENERATE, .hdrsize = 0, .name = NFC_GENL_NAME, @@ -48,28 +48,38 @@ static const struct nla_policy nfc_genl_policy[NFC_ATTR_MAX + 1] = { [NFC_ATTR_PROTOCOLS] = { .type = NLA_U32 }, [NFC_ATTR_COMM_MODE] = { .type = NLA_U8 }, [NFC_ATTR_RF_MODE] = { .type = NLA_U8 }, + [NFC_ATTR_DEVICE_POWERED] = { .type = NLA_U8 }, }; static int nfc_genl_send_target(struct sk_buff *msg, struct nfc_target *target, - struct netlink_callback *cb, int flags) + struct netlink_callback *cb, int flags) { void *hdr; hdr = genlmsg_put(msg, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq, - &nfc_genl_family, flags, NFC_CMD_GET_TARGET); + &nfc_genl_family, flags, NFC_CMD_GET_TARGET); if (!hdr) return -EMSGSIZE; genl_dump_check_consistent(cb, hdr, &nfc_genl_family); - NLA_PUT_U32(msg, NFC_ATTR_TARGET_INDEX, target->idx); - NLA_PUT_U32(msg, NFC_ATTR_PROTOCOLS, - target->supported_protocols); - NLA_PUT_U16(msg, NFC_ATTR_TARGET_SENS_RES, target->sens_res); - NLA_PUT_U8(msg, NFC_ATTR_TARGET_SEL_RES, target->sel_res); - if (target->nfcid1_len > 0) - NLA_PUT(msg, NFC_ATTR_TARGET_NFCID1, target->nfcid1_len, - target->nfcid1); + if (nla_put_u32(msg, NFC_ATTR_TARGET_INDEX, target->idx) || + nla_put_u32(msg, NFC_ATTR_PROTOCOLS, target->supported_protocols) || + nla_put_u16(msg, NFC_ATTR_TARGET_SENS_RES, target->sens_res) || + nla_put_u8(msg, NFC_ATTR_TARGET_SEL_RES, target->sel_res)) + goto nla_put_failure; + if (target->nfcid1_len > 0 && + nla_put(msg, NFC_ATTR_TARGET_NFCID1, target->nfcid1_len, + target->nfcid1)) + goto nla_put_failure; + if (target->sensb_res_len > 0 && + nla_put(msg, NFC_ATTR_TARGET_SENSB_RES, target->sensb_res_len, + target->sensb_res)) + goto nla_put_failure; + if (target->sensf_res_len > 0 && + nla_put(msg, NFC_ATTR_TARGET_SENSF_RES, target->sensf_res_len, + target->sensf_res)) + goto nla_put_failure; return genlmsg_end(msg, hdr); @@ -85,9 +95,9 @@ static struct nfc_dev *__get_device_from_cb(struct netlink_callback *cb) u32 idx; rc = nlmsg_parse(cb->nlh, GENL_HDRLEN + nfc_genl_family.hdrsize, - nfc_genl_family.attrbuf, - nfc_genl_family.maxattr, - nfc_genl_policy); + nfc_genl_family.attrbuf, + nfc_genl_family.maxattr, + nfc_genl_policy); if (rc < 0) return ERR_PTR(rc); @@ -104,7 +114,7 @@ static struct nfc_dev *__get_device_from_cb(struct netlink_callback *cb) } static int nfc_genl_dump_targets(struct sk_buff *skb, - struct netlink_callback *cb) + struct netlink_callback *cb) { int i = cb->args[0]; struct nfc_dev *dev = (struct nfc_dev *) cb->args[1]; @@ -118,20 +128,20 @@ static int nfc_genl_dump_targets(struct sk_buff *skb, cb->args[1] = (long) dev; } - spin_lock_bh(&dev->targets_lock); + device_lock(&dev->dev); cb->seq = dev->targets_generation; while (i < dev->n_targets) { rc = nfc_genl_send_target(skb, &dev->targets[i], cb, - NLM_F_MULTI); + NLM_F_MULTI); if (rc < 0) break; i++; } - spin_unlock_bh(&dev->targets_lock); + device_unlock(&dev->dev); cb->args[0] = i; @@ -160,11 +170,12 @@ int nfc_genl_targets_found(struct nfc_dev *dev) return -ENOMEM; hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0, - NFC_EVENT_TARGETS_FOUND); + NFC_EVENT_TARGETS_FOUND); if (!hdr) goto free_msg; - NLA_PUT_U32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx); + if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx)) + goto nla_put_failure; genlmsg_end(msg, hdr); @@ -177,6 +188,37 @@ free_msg: return -EMSGSIZE; } +int nfc_genl_target_lost(struct nfc_dev *dev, u32 target_idx) +{ + struct sk_buff *msg; + void *hdr; + + msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); + if (!msg) + return -ENOMEM; + + hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0, + NFC_EVENT_TARGET_LOST); + if (!hdr) + goto free_msg; + + if (nla_put_string(msg, NFC_ATTR_DEVICE_NAME, nfc_device_name(dev)) || + nla_put_u32(msg, NFC_ATTR_TARGET_INDEX, target_idx)) + goto nla_put_failure; + + genlmsg_end(msg, hdr); + + genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_KERNEL); + + return 0; + +nla_put_failure: + genlmsg_cancel(msg, hdr); +free_msg: + nlmsg_free(msg); + return -EMSGSIZE; +} + int nfc_genl_device_added(struct nfc_dev *dev) { struct sk_buff *msg; @@ -187,13 +229,15 @@ int nfc_genl_device_added(struct nfc_dev *dev) return -ENOMEM; hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0, - NFC_EVENT_DEVICE_ADDED); + NFC_EVENT_DEVICE_ADDED); if (!hdr) goto free_msg; - NLA_PUT_STRING(msg, NFC_ATTR_DEVICE_NAME, nfc_device_name(dev)); - NLA_PUT_U32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx); - NLA_PUT_U32(msg, NFC_ATTR_PROTOCOLS, dev->supported_protocols); + if (nla_put_string(msg, NFC_ATTR_DEVICE_NAME, nfc_device_name(dev)) || + nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx) || + nla_put_u32(msg, NFC_ATTR_PROTOCOLS, dev->supported_protocols) || + nla_put_u8(msg, NFC_ATTR_DEVICE_POWERED, dev->dev_up)) + goto nla_put_failure; genlmsg_end(msg, hdr); @@ -218,11 +262,12 @@ int nfc_genl_device_removed(struct nfc_dev *dev) return -ENOMEM; hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0, - NFC_EVENT_DEVICE_REMOVED); + NFC_EVENT_DEVICE_REMOVED); if (!hdr) goto free_msg; - NLA_PUT_U32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx); + if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx)) + goto nla_put_failure; genlmsg_end(msg, hdr); @@ -238,23 +283,25 @@ free_msg: } static int nfc_genl_send_device(struct sk_buff *msg, struct nfc_dev *dev, - u32 pid, u32 seq, - struct netlink_callback *cb, - int flags) + u32 pid, u32 seq, + struct netlink_callback *cb, + int flags) { void *hdr; hdr = genlmsg_put(msg, pid, seq, &nfc_genl_family, flags, - NFC_CMD_GET_DEVICE); + NFC_CMD_GET_DEVICE); if (!hdr) return -EMSGSIZE; if (cb) genl_dump_check_consistent(cb, hdr, &nfc_genl_family); - NLA_PUT_STRING(msg, NFC_ATTR_DEVICE_NAME, nfc_device_name(dev)); - NLA_PUT_U32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx); - NLA_PUT_U32(msg, NFC_ATTR_PROTOCOLS, dev->supported_protocols); + if (nla_put_string(msg, NFC_ATTR_DEVICE_NAME, nfc_device_name(dev)) || + nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx) || + nla_put_u32(msg, NFC_ATTR_PROTOCOLS, dev->supported_protocols) || + nla_put_u8(msg, NFC_ATTR_DEVICE_POWERED, dev->dev_up)) + goto nla_put_failure; return genlmsg_end(msg, hdr); @@ -264,7 +311,7 @@ nla_put_failure: } static int nfc_genl_dump_devices(struct sk_buff *skb, - struct netlink_callback *cb) + struct netlink_callback *cb) { struct class_dev_iter *iter = (struct class_dev_iter *) cb->args[0]; struct nfc_dev *dev = (struct nfc_dev *) cb->args[1]; @@ -291,8 +338,7 @@ static int nfc_genl_dump_devices(struct sk_buff *skb, int rc; rc = nfc_genl_send_device(skb, dev, NETLINK_CB(cb->skb).pid, - cb->nlh->nlmsg_seq, - cb, NLM_F_MULTI); + cb->nlh->nlmsg_seq, cb, NLM_F_MULTI); if (rc < 0) break; @@ -317,7 +363,7 @@ static int nfc_genl_dump_devices_done(struct netlink_callback *cb) } int nfc_genl_dep_link_up_event(struct nfc_dev *dev, u32 target_idx, - u8 comm_mode, u8 rf_mode) + u8 comm_mode, u8 rf_mode) { struct sk_buff *msg; void *hdr; @@ -328,16 +374,18 @@ int nfc_genl_dep_link_up_event(struct nfc_dev *dev, u32 target_idx, if (!msg) return -ENOMEM; - hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0, - NFC_CMD_DEP_LINK_UP); + hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0, NFC_CMD_DEP_LINK_UP); if (!hdr) goto free_msg; - NLA_PUT_U32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx); - if (rf_mode == NFC_RF_INITIATOR) - NLA_PUT_U32(msg, NFC_ATTR_TARGET_INDEX, target_idx); - NLA_PUT_U8(msg, NFC_ATTR_COMM_MODE, comm_mode); - NLA_PUT_U8(msg, NFC_ATTR_RF_MODE, rf_mode); + if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx)) + goto nla_put_failure; + if (rf_mode == NFC_RF_INITIATOR && + nla_put_u32(msg, NFC_ATTR_TARGET_INDEX, target_idx)) + goto nla_put_failure; + if (nla_put_u8(msg, NFC_ATTR_COMM_MODE, comm_mode) || + nla_put_u8(msg, NFC_ATTR_RF_MODE, rf_mode)) + goto nla_put_failure; genlmsg_end(msg, hdr); @@ -366,11 +414,12 @@ int nfc_genl_dep_link_down_event(struct nfc_dev *dev) return -ENOMEM; hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0, - NFC_CMD_DEP_LINK_DOWN); + NFC_CMD_DEP_LINK_DOWN); if (!hdr) goto free_msg; - NLA_PUT_U32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx); + if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx)) + goto nla_put_failure; genlmsg_end(msg, hdr); @@ -408,7 +457,7 @@ static int nfc_genl_get_device(struct sk_buff *skb, struct genl_info *info) } rc = nfc_genl_send_device(msg, dev, info->snd_pid, info->snd_seq, - NULL, 0); + NULL, 0); if (rc < 0) goto out_free; @@ -475,7 +524,7 @@ static int nfc_genl_start_poll(struct sk_buff *skb, struct genl_info *info) pr_debug("Poll start\n"); if (!info->attrs[NFC_ATTR_DEVICE_INDEX] || - !info->attrs[NFC_ATTR_PROTOCOLS]) + !info->attrs[NFC_ATTR_PROTOCOLS]) return -EINVAL; idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]); @@ -533,13 +582,12 @@ static int nfc_genl_dep_link_up(struct sk_buff *skb, struct genl_info *info) struct nfc_dev *dev; int rc, tgt_idx; u32 idx; - u8 comm, rf; + u8 comm; pr_debug("DEP link up\n"); if (!info->attrs[NFC_ATTR_DEVICE_INDEX] || - !info->attrs[NFC_ATTR_COMM_MODE] || - !info->attrs[NFC_ATTR_RF_MODE]) + !info->attrs[NFC_ATTR_COMM_MODE]) return -EINVAL; idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]); @@ -549,19 +597,15 @@ static int nfc_genl_dep_link_up(struct sk_buff *skb, struct genl_info *info) tgt_idx = nla_get_u32(info->attrs[NFC_ATTR_TARGET_INDEX]); comm = nla_get_u8(info->attrs[NFC_ATTR_COMM_MODE]); - rf = nla_get_u8(info->attrs[NFC_ATTR_RF_MODE]); if (comm != NFC_COMM_ACTIVE && comm != NFC_COMM_PASSIVE) return -EINVAL; - if (rf != NFC_RF_INITIATOR && comm != NFC_RF_TARGET) - return -EINVAL; - dev = nfc_get_device(idx); if (!dev) return -ENODEV; - rc = nfc_dep_link_up(dev, tgt_idx, comm, rf); + rc = nfc_dep_link_up(dev, tgt_idx, comm); nfc_put_device(dev); @@ -636,7 +680,7 @@ static struct genl_ops nfc_genl_ops[] = { }; static int nfc_genl_rcv_nl_event(struct notifier_block *this, - unsigned long event, void *ptr) + unsigned long event, void *ptr) { struct netlink_notify *n = ptr; struct class_dev_iter iter; @@ -689,7 +733,7 @@ int __init nfc_genl_init(void) int rc; rc = genl_register_family_with_ops(&nfc_genl_family, nfc_genl_ops, - ARRAY_SIZE(nfc_genl_ops)); + ARRAY_SIZE(nfc_genl_ops)); if (rc) return rc; |