diff options
author | Waldemar Rymarkiewicz <waldemar.rymarkiewicz@tieto.com> | 2012-11-26 14:18:36 +0100 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2013-01-10 00:44:29 +0100 |
commit | 94c5c1561dde894766b1a9135e47b056fdbe13a4 (patch) | |
tree | 95786a6a016fee1fdcd2228ff713d4f44109fcda /drivers/nfc | |
parent | 15461aeb53ae2d3bbde6b374de913e3df81d1ad0 (diff) |
NFC: pn533: Add a new pn533_send_sync iface
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>
Diffstat (limited to 'drivers/nfc')
-rw-r--r-- | drivers/nfc/pn533.c | 55 |
1 files changed, 54 insertions, 1 deletions
diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c index 0e9bf9dfbbb5..94c88bb601cd 100644 --- a/drivers/nfc/pn533.c +++ b/drivers/nfc/pn533.c @@ -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 = { |