diff options
| author | Samuel Ortiz <sameo@linux.intel.com> | 2012-05-30 11:20:25 -0400 |
|---|---|---|
| committer | Samuel Ortiz <sameo@linux.intel.com> | 2012-06-04 15:34:33 -0400 |
| commit | 6fbbdc16be3881aabaa4096c3466b9bbd361bd1f (patch) | |
| tree | 15ed55f77042847ce215bbea0deaa49aac52087e /drivers/nfc | |
| parent | 51d9e803b906ea8ef995980d5367ab66ff79305a (diff) | |
NFC: Implement pn533 polling loop
After going through all the modulations, the pn533 driver spends 2
seconds listening for targets.
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers/nfc')
| -rw-r--r-- | drivers/nfc/pn533.c | 287 |
1 files changed, 161 insertions, 126 deletions
diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c index 6e4b228c7e6..c9ba96c320f 100644 --- a/drivers/nfc/pn533.c +++ b/drivers/nfc/pn533.c | |||
| @@ -45,6 +45,9 @@ static const struct usb_device_id pn533_table[] = { | |||
| 45 | }; | 45 | }; |
| 46 | MODULE_DEVICE_TABLE(usb, pn533_table); | 46 | MODULE_DEVICE_TABLE(usb, pn533_table); |
| 47 | 47 | ||
| 48 | /* How much time we spend listening for initiators */ | ||
| 49 | #define PN533_LISTEN_TIME 2 | ||
| 50 | |||
| 48 | /* frame definitions */ | 51 | /* frame definitions */ |
| 49 | #define PN533_FRAME_TAIL_SIZE 2 | 52 | #define PN533_FRAME_TAIL_SIZE 2 |
| 50 | #define PN533_FRAME_SIZE(f) (sizeof(struct pn533_frame) + f->datalen + \ | 53 | #define PN533_FRAME_SIZE(f) (sizeof(struct pn533_frame) + f->datalen + \ |
| @@ -163,6 +166,7 @@ enum { | |||
| 163 | PN533_POLL_MOD_424KBPS_FELICA, | 166 | PN533_POLL_MOD_424KBPS_FELICA, |
| 164 | PN533_POLL_MOD_106KBPS_JEWEL, | 167 | PN533_POLL_MOD_106KBPS_JEWEL, |
| 165 | PN533_POLL_MOD_847KBPS_B, | 168 | PN533_POLL_MOD_847KBPS_B, |
| 169 | PN533_LISTEN_MOD, | ||
| 166 | 170 | ||
| 167 | __PN533_POLL_MOD_AFTER_LAST, | 171 | __PN533_POLL_MOD_AFTER_LAST, |
| 168 | }; | 172 | }; |
| @@ -230,6 +234,9 @@ const struct pn533_poll_modulations poll_mod[] = { | |||
| 230 | }, | 234 | }, |
| 231 | .len = 3, | 235 | .len = 3, |
| 232 | }, | 236 | }, |
| 237 | [PN533_LISTEN_MOD] = { | ||
| 238 | .len = 0, | ||
| 239 | }, | ||
| 233 | }; | 240 | }; |
| 234 | 241 | ||
| 235 | /* PN533_CMD_IN_ATR */ | 242 | /* PN533_CMD_IN_ATR */ |
| @@ -312,10 +319,13 @@ struct pn533 { | |||
| 312 | 319 | ||
| 313 | struct workqueue_struct *wq; | 320 | struct workqueue_struct *wq; |
| 314 | struct work_struct cmd_work; | 321 | struct work_struct cmd_work; |
| 322 | struct work_struct poll_work; | ||
| 315 | struct work_struct mi_work; | 323 | struct work_struct mi_work; |
| 316 | struct work_struct tg_work; | 324 | struct work_struct tg_work; |
| 325 | struct timer_list listen_timer; | ||
| 317 | struct pn533_frame *wq_in_frame; | 326 | struct pn533_frame *wq_in_frame; |
| 318 | int wq_in_error; | 327 | int wq_in_error; |
| 328 | int cancel_listen; | ||
| 319 | 329 | ||
| 320 | pn533_cmd_complete_t cmd_complete; | 330 | pn533_cmd_complete_t cmd_complete; |
| 321 | void *cmd_complete_arg; | 331 | void *cmd_complete_arg; |
| @@ -326,6 +336,10 @@ struct pn533 { | |||
| 326 | u8 poll_mod_count; | 336 | u8 poll_mod_count; |
| 327 | u8 poll_mod_curr; | 337 | u8 poll_mod_curr; |
| 328 | u32 poll_protocols; | 338 | u32 poll_protocols; |
| 339 | u32 listen_protocols; | ||
| 340 | |||
| 341 | u8 *gb; | ||
| 342 | size_t gb_len; | ||
| 329 | 343 | ||
| 330 | u8 tgt_available_prots; | 344 | u8 tgt_available_prots; |
| 331 | u8 tgt_active_prot; | 345 | u8 tgt_active_prot; |
| @@ -1006,6 +1020,11 @@ static int pn533_target_found(struct pn533 *dev, | |||
| 1006 | return 0; | 1020 | return 0; |
| 1007 | } | 1021 | } |
| 1008 | 1022 | ||
| 1023 | static inline void pn533_poll_next_mod(struct pn533 *dev) | ||
| 1024 | { | ||
| 1025 | dev->poll_mod_curr = (dev->poll_mod_curr + 1) % dev->poll_mod_count; | ||
| 1026 | } | ||
| 1027 | |||
| 1009 | static void pn533_poll_reset_mod_list(struct pn533 *dev) | 1028 | static void pn533_poll_reset_mod_list(struct pn533 *dev) |
| 1010 | { | 1029 | { |
| 1011 | dev->poll_mod_count = 0; | 1030 | dev->poll_mod_count = 0; |
| @@ -1018,107 +1037,52 @@ static void pn533_poll_add_mod(struct pn533 *dev, u8 mod_index) | |||
| 1018 | dev->poll_mod_count++; | 1037 | dev->poll_mod_count++; |
| 1019 | } | 1038 | } |
| 1020 | 1039 | ||
| 1021 | static void pn533_poll_create_mod_list(struct pn533 *dev, u32 protocols) | 1040 | static void pn533_poll_create_mod_list(struct pn533 *dev, |
| 1041 | u32 im_protocols, u32 tm_protocols) | ||
| 1022 | { | 1042 | { |
| 1023 | pn533_poll_reset_mod_list(dev); | 1043 | pn533_poll_reset_mod_list(dev); |
| 1024 | 1044 | ||
| 1025 | if (protocols & NFC_PROTO_MIFARE_MASK | 1045 | if (im_protocols & NFC_PROTO_MIFARE_MASK |
| 1026 | || protocols & NFC_PROTO_ISO14443_MASK | 1046 | || im_protocols & NFC_PROTO_ISO14443_MASK |
| 1027 | || protocols & NFC_PROTO_NFC_DEP_MASK) | 1047 | || im_protocols & NFC_PROTO_NFC_DEP_MASK) |
| 1028 | pn533_poll_add_mod(dev, PN533_POLL_MOD_106KBPS_A); | 1048 | pn533_poll_add_mod(dev, PN533_POLL_MOD_106KBPS_A); |
| 1029 | 1049 | ||
| 1030 | if (protocols & NFC_PROTO_FELICA_MASK | 1050 | if (im_protocols & NFC_PROTO_FELICA_MASK |
| 1031 | || protocols & NFC_PROTO_NFC_DEP_MASK) { | 1051 | || im_protocols & NFC_PROTO_NFC_DEP_MASK) { |
| 1032 | pn533_poll_add_mod(dev, PN533_POLL_MOD_212KBPS_FELICA); | 1052 | pn533_poll_add_mod(dev, PN533_POLL_MOD_212KBPS_FELICA); |
| 1033 | pn533_poll_add_mod(dev, PN533_POLL_MOD_424KBPS_FELICA); | 1053 | pn533_poll_add_mod(dev, PN533_POLL_MOD_424KBPS_FELICA); |
| 1034 | } | 1054 | } |
| 1035 | 1055 | ||
| 1036 | if (protocols & NFC_PROTO_JEWEL_MASK) | 1056 | if (im_protocols & NFC_PROTO_JEWEL_MASK) |
| 1037 | pn533_poll_add_mod(dev, PN533_POLL_MOD_106KBPS_JEWEL); | 1057 | pn533_poll_add_mod(dev, PN533_POLL_MOD_106KBPS_JEWEL); |
| 1038 | 1058 | ||
| 1039 | if (protocols & NFC_PROTO_ISO14443_MASK) | 1059 | if (im_protocols & NFC_PROTO_ISO14443_MASK) |
| 1040 | pn533_poll_add_mod(dev, PN533_POLL_MOD_847KBPS_B); | 1060 | pn533_poll_add_mod(dev, PN533_POLL_MOD_847KBPS_B); |
| 1041 | } | ||
| 1042 | |||
| 1043 | static void pn533_start_poll_frame(struct pn533_frame *frame, | ||
| 1044 | struct pn533_poll_modulations *mod) | ||
| 1045 | { | ||
| 1046 | |||
| 1047 | pn533_tx_frame_init(frame, PN533_CMD_IN_LIST_PASSIVE_TARGET); | ||
| 1048 | 1061 | ||
| 1049 | memcpy(PN533_FRAME_CMD_PARAMS_PTR(frame), &mod->data, mod->len); | 1062 | if (tm_protocols) |
| 1050 | frame->datalen += mod->len; | 1063 | pn533_poll_add_mod(dev, PN533_LISTEN_MOD); |
| 1051 | |||
| 1052 | pn533_tx_frame_finish(frame); | ||
| 1053 | } | 1064 | } |
| 1054 | 1065 | ||
| 1055 | static int pn533_start_poll_complete(struct pn533 *dev, void *arg, | 1066 | static int pn533_start_poll_complete(struct pn533 *dev, void *arg, |
| 1056 | u8 *params, int params_len) | 1067 | u8 *params, int params_len) |
| 1057 | { | 1068 | { |
| 1058 | struct pn533_poll_response *resp; | 1069 | struct pn533_poll_response *resp; |
| 1059 | struct pn533_poll_modulations *next_mod; | ||
| 1060 | int rc; | 1070 | int rc; |
| 1061 | 1071 | ||
| 1062 | nfc_dev_dbg(&dev->interface->dev, "%s", __func__); | 1072 | nfc_dev_dbg(&dev->interface->dev, "%s", __func__); |
| 1063 | 1073 | ||
| 1064 | if (params_len == -ENOENT) { | ||
| 1065 | nfc_dev_dbg(&dev->interface->dev, "Polling operation has been" | ||
| 1066 | " stopped"); | ||
| 1067 | goto stop_poll; | ||
| 1068 | } | ||
| 1069 | |||
| 1070 | if (params_len < 0) { | ||
| 1071 | nfc_dev_err(&dev->interface->dev, "Error %d when running poll", | ||
| 1072 | params_len); | ||
| 1073 | goto stop_poll; | ||
| 1074 | } | ||
| 1075 | |||
| 1076 | resp = (struct pn533_poll_response *) params; | 1074 | resp = (struct pn533_poll_response *) params; |
| 1077 | if (resp->nbtg) { | 1075 | if (resp->nbtg) { |
| 1078 | rc = pn533_target_found(dev, resp, params_len); | 1076 | rc = pn533_target_found(dev, resp, params_len); |
| 1079 | 1077 | ||
| 1080 | /* We must stop the poll after a valid target found */ | 1078 | /* We must stop the poll after a valid target found */ |
| 1081 | if (rc == 0) | 1079 | if (rc == 0) { |
| 1082 | goto stop_poll; | 1080 | pn533_poll_reset_mod_list(dev); |
| 1083 | 1081 | return 0; | |
| 1084 | if (rc != -EAGAIN) | 1082 | } |
| 1085 | nfc_dev_err(&dev->interface->dev, "The target found is" | ||
| 1086 | " not valid - continuing to poll"); | ||
| 1087 | } | ||
| 1088 | |||
| 1089 | dev->poll_mod_curr = (dev->poll_mod_curr + 1) % dev->poll_mod_count; | ||
| 1090 | |||
| 1091 | next_mod = dev->poll_mod_active[dev->poll_mod_curr]; | ||
| 1092 | |||
| 1093 | nfc_dev_dbg(&dev->interface->dev, "Polling next modulation (0x%x)", | ||
| 1094 | dev->poll_mod_curr); | ||
| 1095 | |||
| 1096 | pn533_start_poll_frame(dev->out_frame, next_mod); | ||
| 1097 | |||
| 1098 | /* Don't need to down the semaphore again */ | ||
| 1099 | rc = __pn533_send_cmd_frame_async(dev, dev->out_frame, dev->in_frame, | ||
| 1100 | dev->in_maxlen, pn533_start_poll_complete, | ||
| 1101 | NULL, GFP_ATOMIC); | ||
| 1102 | |||
| 1103 | if (rc == -EPERM) { | ||
| 1104 | nfc_dev_dbg(&dev->interface->dev, "Cannot poll next modulation" | ||
| 1105 | " because poll has been stopped"); | ||
| 1106 | goto stop_poll; | ||
| 1107 | } | ||
| 1108 | |||
| 1109 | if (rc) { | ||
| 1110 | nfc_dev_err(&dev->interface->dev, "Error %d when trying to poll" | ||
| 1111 | " next modulation", rc); | ||
| 1112 | goto stop_poll; | ||
| 1113 | } | 1083 | } |
| 1114 | 1084 | ||
| 1115 | /* Inform caller function to do not up the semaphore */ | 1085 | return -EAGAIN; |
| 1116 | return -EINPROGRESS; | ||
| 1117 | |||
| 1118 | stop_poll: | ||
| 1119 | pn533_poll_reset_mod_list(dev); | ||
| 1120 | dev->poll_protocols = 0; | ||
| 1121 | return 0; | ||
| 1122 | } | 1086 | } |
| 1123 | 1087 | ||
| 1124 | static int pn533_init_target_frame(struct pn533_frame *frame, | 1088 | static int pn533_init_target_frame(struct pn533_frame *frame, |
| @@ -1286,83 +1250,136 @@ static int pn533_init_target_complete(struct pn533 *dev, void *arg, | |||
| 1286 | return 0; | 1250 | return 0; |
| 1287 | } | 1251 | } |
| 1288 | 1252 | ||
| 1289 | static int pn533_init_target(struct nfc_dev *nfc_dev, u32 protocols) | 1253 | static void pn533_listen_mode_timer(unsigned long data) |
| 1290 | { | 1254 | { |
| 1291 | struct pn533 *dev = nfc_get_drvdata(nfc_dev); | 1255 | struct pn533 *dev = (struct pn533 *) data; |
| 1292 | u8 *gb; | 1256 | |
| 1293 | size_t gb_len; | 1257 | nfc_dev_dbg(&dev->interface->dev, "Listen mode timeout"); |
| 1258 | |||
| 1259 | /* An ack will cancel the last issued command (poll) */ | ||
| 1260 | pn533_send_ack(dev, GFP_ATOMIC); | ||
| 1261 | |||
| 1262 | dev->cancel_listen = 1; | ||
| 1263 | |||
| 1264 | up(&dev->cmd_lock); | ||
| 1265 | |||
| 1266 | pn533_poll_next_mod(dev); | ||
| 1267 | |||
| 1268 | queue_work(dev->wq, &dev->poll_work); | ||
| 1269 | } | ||
| 1270 | |||
| 1271 | static int pn533_poll_complete(struct pn533 *dev, void *arg, | ||
| 1272 | u8 *params, int params_len) | ||
| 1273 | { | ||
| 1274 | struct pn533_poll_modulations *cur_mod; | ||
| 1294 | int rc; | 1275 | int rc; |
| 1295 | 1276 | ||
| 1296 | pn533_poll_reset_mod_list(dev); | 1277 | nfc_dev_dbg(&dev->interface->dev, "%s", __func__); |
| 1297 | 1278 | ||
| 1298 | gb = nfc_get_local_general_bytes(nfc_dev, &gb_len); | 1279 | if (params_len == -ENOENT) { |
| 1299 | if (gb == NULL) | 1280 | if (dev->poll_mod_count != 0) |
| 1300 | return -ENOMEM; | 1281 | return 0; |
| 1301 | 1282 | ||
| 1302 | rc = pn533_init_target_frame(dev->out_frame, gb, gb_len); | 1283 | nfc_dev_err(&dev->interface->dev, |
| 1303 | if (rc < 0) | 1284 | "Polling operation has been stopped"); |
| 1304 | return rc; | ||
| 1305 | 1285 | ||
| 1306 | rc = pn533_send_cmd_frame_async(dev, dev->out_frame, dev->in_frame, | 1286 | goto stop_poll; |
| 1307 | dev->in_maxlen, | 1287 | } |
| 1308 | pn533_init_target_complete, | ||
| 1309 | NULL, GFP_KERNEL); | ||
| 1310 | 1288 | ||
| 1311 | if (rc) | 1289 | if (params_len < 0) { |
| 1312 | nfc_dev_err(&dev->interface->dev, | 1290 | nfc_dev_err(&dev->interface->dev, |
| 1313 | "Error %d when trying to initiate as a target", rc); | 1291 | "Error %d when running poll", params_len); |
| 1314 | 1292 | ||
| 1315 | dev->poll_mod_count++; | 1293 | goto stop_poll; |
| 1294 | } | ||
| 1316 | 1295 | ||
| 1317 | return rc; | 1296 | cur_mod = dev->poll_mod_active[dev->poll_mod_curr]; |
| 1297 | |||
| 1298 | if (cur_mod->len == 0) { | ||
| 1299 | del_timer(&dev->listen_timer); | ||
| 1300 | |||
| 1301 | return pn533_init_target_complete(dev, arg, params, params_len); | ||
| 1302 | } else { | ||
| 1303 | rc = pn533_start_poll_complete(dev, arg, params, params_len); | ||
| 1304 | if (!rc) | ||
| 1305 | return rc; | ||
| 1306 | } | ||
| 1307 | |||
| 1308 | pn533_poll_next_mod(dev); | ||
| 1309 | |||
| 1310 | queue_work(dev->wq, &dev->poll_work); | ||
| 1311 | |||
| 1312 | return 0; | ||
| 1313 | |||
| 1314 | stop_poll: | ||
| 1315 | pn533_poll_reset_mod_list(dev); | ||
| 1316 | dev->poll_protocols = 0; | ||
| 1317 | return 0; | ||
| 1318 | } | 1318 | } |
| 1319 | 1319 | ||
| 1320 | static int pn533_start_im_poll(struct nfc_dev *nfc_dev, u32 protocols) | 1320 | static void pn533_build_poll_frame(struct pn533 *dev, |
| 1321 | struct pn533_frame *frame, | ||
| 1322 | struct pn533_poll_modulations *mod) | ||
| 1321 | { | 1323 | { |
| 1322 | struct pn533 *dev = nfc_get_drvdata(nfc_dev); | 1324 | nfc_dev_dbg(&dev->interface->dev, "mod len %d\n", mod->len); |
| 1323 | struct pn533_poll_modulations *start_mod; | ||
| 1324 | int rc; | ||
| 1325 | 1325 | ||
| 1326 | if (dev->poll_mod_count) { | 1326 | if (mod->len == 0) { |
| 1327 | nfc_dev_err(&dev->interface->dev, "Polling operation already" | 1327 | /* Listen mode */ |
| 1328 | " active"); | 1328 | pn533_init_target_frame(frame, dev->gb, dev->gb_len); |
| 1329 | return -EBUSY; | 1329 | } else { |
| 1330 | } | 1330 | /* Polling mode */ |
| 1331 | pn533_tx_frame_init(frame, PN533_CMD_IN_LIST_PASSIVE_TARGET); | ||
| 1331 | 1332 | ||
| 1332 | pn533_poll_create_mod_list(dev, protocols); | 1333 | memcpy(PN533_FRAME_CMD_PARAMS_PTR(frame), &mod->data, mod->len); |
| 1334 | frame->datalen += mod->len; | ||
| 1333 | 1335 | ||
| 1334 | if (!dev->poll_mod_count) { | 1336 | pn533_tx_frame_finish(frame); |
| 1335 | nfc_dev_err(&dev->interface->dev, "No valid protocols" | ||
| 1336 | " specified"); | ||
| 1337 | rc = -EINVAL; | ||
| 1338 | goto error; | ||
| 1339 | } | 1337 | } |
| 1338 | } | ||
| 1340 | 1339 | ||
| 1341 | nfc_dev_dbg(&dev->interface->dev, "It will poll %d modulations types", | 1340 | static int pn533_send_poll_frame(struct pn533 *dev) |
| 1342 | dev->poll_mod_count); | 1341 | { |
| 1342 | struct pn533_poll_modulations *cur_mod; | ||
| 1343 | int rc; | ||
| 1343 | 1344 | ||
| 1344 | dev->poll_mod_curr = 0; | 1345 | cur_mod = dev->poll_mod_active[dev->poll_mod_curr]; |
| 1345 | start_mod = dev->poll_mod_active[dev->poll_mod_curr]; | ||
| 1346 | 1346 | ||
| 1347 | pn533_start_poll_frame(dev->out_frame, start_mod); | 1347 | pn533_build_poll_frame(dev, dev->out_frame, cur_mod); |
| 1348 | 1348 | ||
| 1349 | rc = pn533_send_cmd_frame_async(dev, dev->out_frame, dev->in_frame, | 1349 | rc = pn533_send_cmd_frame_async(dev, dev->out_frame, dev->in_frame, |
| 1350 | dev->in_maxlen, pn533_start_poll_complete, | 1350 | dev->in_maxlen, pn533_poll_complete, |
| 1351 | NULL, GFP_KERNEL); | 1351 | NULL, GFP_KERNEL); |
| 1352 | if (rc) | ||
| 1353 | nfc_dev_err(&dev->interface->dev, "Polling loop error %d", rc); | ||
| 1352 | 1354 | ||
| 1353 | if (rc) { | 1355 | return rc; |
| 1354 | nfc_dev_err(&dev->interface->dev, "Error %d when trying to" | 1356 | } |
| 1355 | " start poll", rc); | 1357 | |
| 1356 | goto error; | 1358 | static void pn533_wq_poll(struct work_struct *work) |
| 1359 | { | ||
| 1360 | struct pn533 *dev = container_of(work, struct pn533, poll_work); | ||
| 1361 | struct pn533_poll_modulations *cur_mod; | ||
| 1362 | int rc; | ||
| 1363 | |||
| 1364 | cur_mod = dev->poll_mod_active[dev->poll_mod_curr]; | ||
| 1365 | |||
| 1366 | nfc_dev_dbg(&dev->interface->dev, | ||
| 1367 | "%s cancel_listen %d modulation len %d", | ||
| 1368 | __func__, dev->cancel_listen, cur_mod->len); | ||
| 1369 | |||
| 1370 | if (dev->cancel_listen == 1) { | ||
| 1371 | dev->cancel_listen = 0; | ||
| 1372 | usb_kill_urb(dev->in_urb); | ||
| 1357 | } | 1373 | } |
| 1358 | 1374 | ||
| 1359 | dev->poll_protocols = protocols; | 1375 | rc = pn533_send_poll_frame(dev); |
| 1376 | if (rc) | ||
| 1377 | return; | ||
| 1360 | 1378 | ||
| 1361 | return 0; | 1379 | if (cur_mod->len == 0 && dev->poll_mod_count > 1) |
| 1380 | mod_timer(&dev->listen_timer, jiffies + PN533_LISTEN_TIME * HZ); | ||
| 1362 | 1381 | ||
| 1363 | error: | 1382 | return; |
| 1364 | pn533_poll_reset_mod_list(dev); | ||
| 1365 | return rc; | ||
| 1366 | } | 1383 | } |
| 1367 | 1384 | ||
| 1368 | static int pn533_start_poll(struct nfc_dev *nfc_dev, | 1385 | static int pn533_start_poll(struct nfc_dev *nfc_dev, |
| @@ -1380,13 +1397,18 @@ static int pn533_start_poll(struct nfc_dev *nfc_dev, | |||
| 1380 | return -EBUSY; | 1397 | return -EBUSY; |
| 1381 | } | 1398 | } |
| 1382 | 1399 | ||
| 1383 | if (im_protocols) | 1400 | if (tm_protocols) { |
| 1384 | return pn533_start_im_poll(nfc_dev, im_protocols); | 1401 | dev->gb = nfc_get_local_general_bytes(nfc_dev, &dev->gb_len); |
| 1402 | if (dev->gb == NULL) | ||
| 1403 | tm_protocols = 0; | ||
| 1404 | } | ||
| 1385 | 1405 | ||
| 1386 | if (tm_protocols) | 1406 | dev->poll_mod_curr = 0; |
| 1387 | return pn533_init_target(nfc_dev, tm_protocols); | 1407 | pn533_poll_create_mod_list(dev, im_protocols, tm_protocols); |
| 1408 | dev->poll_protocols = im_protocols; | ||
| 1409 | dev->listen_protocols = tm_protocols; | ||
| 1388 | 1410 | ||
| 1389 | return -EINVAL; | 1411 | return pn533_send_poll_frame(dev); |
| 1390 | } | 1412 | } |
| 1391 | 1413 | ||
| 1392 | static void pn533_stop_poll(struct nfc_dev *nfc_dev) | 1414 | static void pn533_stop_poll(struct nfc_dev *nfc_dev) |
| @@ -1395,6 +1417,8 @@ static void pn533_stop_poll(struct nfc_dev *nfc_dev) | |||
| 1395 | 1417 | ||
| 1396 | nfc_dev_dbg(&dev->interface->dev, "%s", __func__); | 1418 | nfc_dev_dbg(&dev->interface->dev, "%s", __func__); |
| 1397 | 1419 | ||
| 1420 | del_timer(&dev->listen_timer); | ||
| 1421 | |||
| 1398 | if (!dev->poll_mod_count) { | 1422 | if (!dev->poll_mod_count) { |
| 1399 | nfc_dev_dbg(&dev->interface->dev, "Polling operation was not" | 1423 | nfc_dev_dbg(&dev->interface->dev, "Polling operation was not" |
| 1400 | " running"); | 1424 | " running"); |
| @@ -1676,6 +1700,10 @@ out: | |||
| 1676 | 1700 | ||
| 1677 | static int pn533_dep_link_down(struct nfc_dev *nfc_dev) | 1701 | static int pn533_dep_link_down(struct nfc_dev *nfc_dev) |
| 1678 | { | 1702 | { |
| 1703 | struct pn533 *dev = nfc_get_drvdata(nfc_dev); | ||
| 1704 | |||
| 1705 | pn533_poll_reset_mod_list(dev); | ||
| 1706 | |||
| 1679 | pn533_deactivate_target(nfc_dev, 0); | 1707 | pn533_deactivate_target(nfc_dev, 0); |
| 1680 | 1708 | ||
| 1681 | return 0; | 1709 | return 0; |
| @@ -2110,12 +2138,17 @@ static int pn533_probe(struct usb_interface *interface, | |||
| 2110 | INIT_WORK(&dev->cmd_work, pn533_wq_cmd_complete); | 2138 | INIT_WORK(&dev->cmd_work, pn533_wq_cmd_complete); |
| 2111 | INIT_WORK(&dev->mi_work, pn533_wq_mi_recv); | 2139 | INIT_WORK(&dev->mi_work, pn533_wq_mi_recv); |
| 2112 | INIT_WORK(&dev->tg_work, pn533_wq_tg_get_data); | 2140 | INIT_WORK(&dev->tg_work, pn533_wq_tg_get_data); |
| 2141 | INIT_WORK(&dev->poll_work, pn533_wq_poll); | ||
| 2113 | dev->wq = alloc_workqueue("pn533", | 2142 | dev->wq = alloc_workqueue("pn533", |
| 2114 | WQ_NON_REENTRANT | WQ_UNBOUND | WQ_MEM_RECLAIM, | 2143 | WQ_NON_REENTRANT | WQ_UNBOUND | WQ_MEM_RECLAIM, |
| 2115 | 1); | 2144 | 1); |
| 2116 | if (dev->wq == NULL) | 2145 | if (dev->wq == NULL) |
| 2117 | goto error; | 2146 | goto error; |
| 2118 | 2147 | ||
| 2148 | init_timer(&dev->listen_timer); | ||
| 2149 | dev->listen_timer.data = (unsigned long) dev; | ||
| 2150 | dev->listen_timer.function = pn533_listen_mode_timer; | ||
| 2151 | |||
| 2119 | skb_queue_head_init(&dev->resp_q); | 2152 | skb_queue_head_init(&dev->resp_q); |
| 2120 | 2153 | ||
| 2121 | usb_set_intfdata(interface, dev); | 2154 | usb_set_intfdata(interface, dev); |
| @@ -2212,6 +2245,8 @@ static void pn533_disconnect(struct usb_interface *interface) | |||
| 2212 | 2245 | ||
| 2213 | skb_queue_purge(&dev->resp_q); | 2246 | skb_queue_purge(&dev->resp_q); |
| 2214 | 2247 | ||
| 2248 | del_timer(&dev->listen_timer); | ||
| 2249 | |||
| 2215 | kfree(dev->in_frame); | 2250 | kfree(dev->in_frame); |
| 2216 | usb_free_urb(dev->in_urb); | 2251 | usb_free_urb(dev->in_urb); |
| 2217 | kfree(dev->out_frame); | 2252 | kfree(dev->out_frame); |
