diff options
Diffstat (limited to 'net/nfc/netlink.c')
-rw-r--r-- | net/nfc/netlink.c | 95 |
1 files changed, 94 insertions, 1 deletions
diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c index f16fd59d4160..68063b2025da 100644 --- a/net/nfc/netlink.c +++ b/net/nfc/netlink.c | |||
@@ -1114,7 +1114,8 @@ static int nfc_genl_fw_download(struct sk_buff *skb, struct genl_info *info) | |||
1114 | return rc; | 1114 | return rc; |
1115 | } | 1115 | } |
1116 | 1116 | ||
1117 | int nfc_genl_fw_download_done(struct nfc_dev *dev, const char *firmware_name) | 1117 | int nfc_genl_fw_download_done(struct nfc_dev *dev, const char *firmware_name, |
1118 | u32 result) | ||
1118 | { | 1119 | { |
1119 | struct sk_buff *msg; | 1120 | struct sk_buff *msg; |
1120 | void *hdr; | 1121 | void *hdr; |
@@ -1129,6 +1130,7 @@ int nfc_genl_fw_download_done(struct nfc_dev *dev, const char *firmware_name) | |||
1129 | goto free_msg; | 1130 | goto free_msg; |
1130 | 1131 | ||
1131 | if (nla_put_string(msg, NFC_ATTR_FIRMWARE_NAME, firmware_name) || | 1132 | if (nla_put_string(msg, NFC_ATTR_FIRMWARE_NAME, firmware_name) || |
1133 | nla_put_u32(msg, NFC_ATTR_FIRMWARE_DOWNLOAD_STATUS, result) || | ||
1132 | nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx)) | 1134 | nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx)) |
1133 | goto nla_put_failure; | 1135 | goto nla_put_failure; |
1134 | 1136 | ||
@@ -1191,6 +1193,91 @@ static int nfc_genl_disable_se(struct sk_buff *skb, struct genl_info *info) | |||
1191 | return rc; | 1193 | return rc; |
1192 | } | 1194 | } |
1193 | 1195 | ||
1196 | static int nfc_genl_send_se(struct sk_buff *msg, struct nfc_dev *dev, | ||
1197 | u32 portid, u32 seq, | ||
1198 | struct netlink_callback *cb, | ||
1199 | int flags) | ||
1200 | { | ||
1201 | void *hdr; | ||
1202 | struct nfc_se *se, *n; | ||
1203 | |||
1204 | list_for_each_entry_safe(se, n, &dev->secure_elements, list) { | ||
1205 | hdr = genlmsg_put(msg, portid, seq, &nfc_genl_family, flags, | ||
1206 | NFC_CMD_GET_SE); | ||
1207 | if (!hdr) | ||
1208 | goto nla_put_failure; | ||
1209 | |||
1210 | if (cb) | ||
1211 | genl_dump_check_consistent(cb, hdr, &nfc_genl_family); | ||
1212 | |||
1213 | if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx) || | ||
1214 | nla_put_u32(msg, NFC_ATTR_SE_INDEX, se->idx) || | ||
1215 | nla_put_u8(msg, NFC_ATTR_SE_TYPE, se->type)) | ||
1216 | goto nla_put_failure; | ||
1217 | |||
1218 | if (genlmsg_end(msg, hdr) < 0) | ||
1219 | goto nla_put_failure; | ||
1220 | } | ||
1221 | |||
1222 | return 0; | ||
1223 | |||
1224 | nla_put_failure: | ||
1225 | genlmsg_cancel(msg, hdr); | ||
1226 | return -EMSGSIZE; | ||
1227 | } | ||
1228 | |||
1229 | static int nfc_genl_dump_ses(struct sk_buff *skb, | ||
1230 | struct netlink_callback *cb) | ||
1231 | { | ||
1232 | struct class_dev_iter *iter = (struct class_dev_iter *) cb->args[0]; | ||
1233 | struct nfc_dev *dev = (struct nfc_dev *) cb->args[1]; | ||
1234 | bool first_call = false; | ||
1235 | |||
1236 | if (!iter) { | ||
1237 | first_call = true; | ||
1238 | iter = kmalloc(sizeof(struct class_dev_iter), GFP_KERNEL); | ||
1239 | if (!iter) | ||
1240 | return -ENOMEM; | ||
1241 | cb->args[0] = (long) iter; | ||
1242 | } | ||
1243 | |||
1244 | mutex_lock(&nfc_devlist_mutex); | ||
1245 | |||
1246 | cb->seq = nfc_devlist_generation; | ||
1247 | |||
1248 | if (first_call) { | ||
1249 | nfc_device_iter_init(iter); | ||
1250 | dev = nfc_device_iter_next(iter); | ||
1251 | } | ||
1252 | |||
1253 | while (dev) { | ||
1254 | int rc; | ||
1255 | |||
1256 | rc = nfc_genl_send_se(skb, dev, NETLINK_CB(cb->skb).portid, | ||
1257 | cb->nlh->nlmsg_seq, cb, NLM_F_MULTI); | ||
1258 | if (rc < 0) | ||
1259 | break; | ||
1260 | |||
1261 | dev = nfc_device_iter_next(iter); | ||
1262 | } | ||
1263 | |||
1264 | mutex_unlock(&nfc_devlist_mutex); | ||
1265 | |||
1266 | cb->args[1] = (long) dev; | ||
1267 | |||
1268 | return skb->len; | ||
1269 | } | ||
1270 | |||
1271 | static int nfc_genl_dump_ses_done(struct netlink_callback *cb) | ||
1272 | { | ||
1273 | struct class_dev_iter *iter = (struct class_dev_iter *) cb->args[0]; | ||
1274 | |||
1275 | nfc_device_iter_exit(iter); | ||
1276 | kfree(iter); | ||
1277 | |||
1278 | return 0; | ||
1279 | } | ||
1280 | |||
1194 | static struct genl_ops nfc_genl_ops[] = { | 1281 | static struct genl_ops nfc_genl_ops[] = { |
1195 | { | 1282 | { |
1196 | .cmd = NFC_CMD_GET_DEVICE, | 1283 | .cmd = NFC_CMD_GET_DEVICE, |
@@ -1265,6 +1352,12 @@ static struct genl_ops nfc_genl_ops[] = { | |||
1265 | .doit = nfc_genl_disable_se, | 1352 | .doit = nfc_genl_disable_se, |
1266 | .policy = nfc_genl_policy, | 1353 | .policy = nfc_genl_policy, |
1267 | }, | 1354 | }, |
1355 | { | ||
1356 | .cmd = NFC_CMD_GET_SE, | ||
1357 | .dumpit = nfc_genl_dump_ses, | ||
1358 | .done = nfc_genl_dump_ses_done, | ||
1359 | .policy = nfc_genl_policy, | ||
1360 | }, | ||
1268 | }; | 1361 | }; |
1269 | 1362 | ||
1270 | 1363 | ||