NFC: pn533: Add a new pn533_send_sync iface
authorWaldemar Rymarkiewicz <waldemar.rymarkiewicz@tieto.com>
Mon, 26 Nov 2012 13:18:36 +0000 (14:18 +0100)
committerSamuel Ortiz <sameo@linux.intel.com>
Wed, 9 Jan 2013 23:44:29 +0000 (00:44 +0100)
It is intended to replace pn533_send_cmd_frame_sync() iface which
requires from the caller to create complete frame.

The new function constructs a complete frame itself and sends it out
in sync manner. This way frame logic is hidden from the caller.

pn533_send_cmd_sync() returns ERR_PTR in case of an error or a pointer
to valid response sk_buff otherwise. The pointer must be freed by the
caller when it's been consumed.

Signed-off-by: Waldemar Rymarkiewicz <waldemar.rymarkiewicz@tieto.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
drivers/nfc/pn533.c

index 0e9bf9dfbbb543ee3d1099dc8cd43dd73c7498f8..94c88bb601cdde2caf7edfb0abcccb591f10b52b 100644 (file)
@@ -945,6 +945,7 @@ unlock:
 
 struct pn533_sync_cmd_response {
        int rc;
+       struct sk_buff *resp;
        struct completion done;
 };
 
@@ -965,6 +966,58 @@ static int pn533_sync_cmd_complete(struct pn533 *dev, void *_arg,
        return 0;
 }
 
+static int pn533_send_sync_complete(struct pn533 *dev, void *_arg,
+                                   struct sk_buff *resp)
+{
+       struct pn533_sync_cmd_response *arg = _arg;
+
+       nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
+
+       arg->resp = resp;
+       complete(&arg->done);
+
+       return 0;
+}
+
+/*  pn533_send_cmd_sync
+ *
+ *  Please note the req parameter is freed inside the function to
+ *  limit a number of return value interpretations by the caller.
+ *
+ *  1. negative in case of error during TX path -> req should be freed
+ *
+ *  2. negative in case of error during RX path -> req should not be freed
+ *     as it's been already freed at the begining of RX path by
+ *     async_complete_cb.
+ *
+ *  3. valid pointer in case of succesfult RX path
+ *
+ *  A caller has to check a return value with IS_ERR macro. If the test pass,
+ *  the returned pointer is valid.
+ *
+ * */
+static struct sk_buff *pn533_send_cmd_sync(struct pn533 *dev, u8 cmd_code,
+                                              struct sk_buff *req)
+{
+       int rc;
+       struct pn533_sync_cmd_response arg;
+
+       nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
+
+       init_completion(&arg.done);
+
+       rc = pn533_send_cmd_async(dev, cmd_code, req,
+                                 pn533_send_sync_complete, &arg);
+       if (rc) {
+               dev_kfree_skb(req);
+               return ERR_PTR(rc);
+       }
+
+       wait_for_completion(&arg.done);
+
+       return arg.resp;
+}
+
 static int pn533_send_cmd_frame_sync(struct pn533 *dev,
                                                struct pn533_frame *out_frame,
                                                struct pn533_frame *in_frame,
@@ -2432,7 +2485,7 @@ static int pn533_fw_reset(struct pn533 *dev)
        rc = pn533_send_cmd_frame_sync(dev, dev->out_frame, dev->in_frame,
                                       PN533_NORMAL_FRAME_MAX_LEN);
 
-       return rc;
+       return 0;
 }
 
 static struct nfc_ops pn533_nfc_ops = {