summaryrefslogtreecommitdiffstats
path: root/net/nfc/netlink.c
diff options
context:
space:
mode:
authorSage Weil <sage@inktank.com>2012-06-15 12:32:04 -0700
committerSage Weil <sage@inktank.com>2012-06-15 12:32:04 -0700
commit9a64e8e0ace51b309fdcff4b4754b3649250382a (patch)
tree1f0d75c196c5ab0408c55ed6cf3a152f1f921e15 /net/nfc/netlink.c
parentf3dea7edd3d449fe7a6d402c1ce56a294b985261 (diff)
parentf8f5701bdaf9134b1f90e5044a82c66324d2073f (diff)
downloadlinux-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.c160
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;