summaryrefslogtreecommitdiffstats
path: root/drivers/nfc/pn533.c
diff options
context:
space:
mode:
authorSamuel Ortiz <sameo@linux.intel.com>2012-05-31 20:01:32 +0200
committerSamuel Ortiz <sameo@linux.intel.com>2012-06-04 21:34:34 +0200
commit51ad304cc8db5589d1e7b0a9df3858381753d788 (patch)
tree352608624988d0bbc1262896cc1094c8b25e7f2f /drivers/nfc/pn533.c
parentNFC: Convert pn533 from semaphore to mutex (diff)
downloadlinux-51ad304cc8db5589d1e7b0a9df3858381753d788.tar.xz
linux-51ad304cc8db5589d1e7b0a9df3858381753d788.zip
NFC: Monitor pn533 target mode
When receiving a DEP link down event, we should cancel all pending URBs if we're activated as a target or if we're an initiator. Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers/nfc/pn533.c')
-rw-r--r--drivers/nfc/pn533.c23
1 files changed, 22 insertions, 1 deletions
diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c
index 58c1641cf658..9ac829e22e73 100644
--- a/drivers/nfc/pn533.c
+++ b/drivers/nfc/pn533.c
@@ -343,6 +343,7 @@ struct pn533 {
u8 tgt_available_prots;
u8 tgt_active_prot;
+ u8 tgt_mode;
};
struct pn533_frame {
@@ -1158,6 +1159,8 @@ static int pn533_tm_get_data_complete(struct pn533 *dev, void *arg,
if (params_len > 0 && params[0] != 0) {
nfc_tm_deactivated(dev->nfc_dev);
+ dev->tgt_mode = 0;
+
kfree_skb(skb_resp);
return 0;
}
@@ -1245,6 +1248,8 @@ static int pn533_init_target_complete(struct pn533 *dev, void *arg,
return rc;
}
+ dev->tgt_mode = 1;
+
queue_work(dev->wq, &dev->tg_work);
return 0;
@@ -1397,6 +1402,12 @@ static int pn533_start_poll(struct nfc_dev *nfc_dev,
return -EBUSY;
}
+ if (dev->tgt_mode) {
+ nfc_dev_err(&dev->interface->dev,
+ "Cannot poll while already being activated");
+ return -EBUSY;
+ }
+
if (tm_protocols) {
dev->gb = nfc_get_local_general_bytes(nfc_dev, &dev->gb_len);
if (dev->gb == NULL)
@@ -1725,7 +1736,15 @@ static int pn533_dep_link_down(struct nfc_dev *nfc_dev)
pn533_poll_reset_mod_list(dev);
- pn533_deactivate_target(nfc_dev, 0);
+ if (dev->tgt_mode || dev->tgt_active_prot) {
+ pn533_send_ack(dev, GFP_KERNEL);
+ usb_kill_urb(dev->in_urb);
+ }
+
+ dev->tgt_active_prot = 0;
+ dev->tgt_mode = 0;
+
+ skb_queue_purge(&dev->resp_q);
return 0;
}
@@ -1956,6 +1975,8 @@ static int pn533_tm_send_complete(struct pn533 *dev, void *arg,
if (params_len > 0 && params[0] != 0) {
nfc_tm_deactivated(dev->nfc_dev);
+ dev->tgt_mode = 0;
+
return 0;
}