diff options
author | Andrey Rusalin <arusalin@dev.rtsoft.ru> | 2016-12-28 12:10:58 -0500 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2017-04-01 19:06:22 -0400 |
commit | 5dd9c1bd61a7b684e54897a3a2546124c4077eda (patch) | |
tree | 850011cebb87f7b8c82ab68e17a209bf21a2eb98 | |
parent | 068a496c4525c638ffab56449d905b88ef97fe32 (diff) |
NFC: pn533: improve cmd queue handling
Make sure cmd is set before a frame is passed to the transport layer for
sending. In addition pn533_send_async_complete checks if cmd is set before
accessing its members.
Signed-off-by: Michael Thalmeier <michael.thalmeier@hale.at>
Rework a little bit changes in pn532_send_async_complete.
Signed-off-by: Andrey Rusalin <arusalin@dev.rtsoft.ru>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
-rw-r--r-- | drivers/nfc/pn533/pn533.c | 40 |
1 files changed, 27 insertions, 13 deletions
diff --git a/drivers/nfc/pn533/pn533.c b/drivers/nfc/pn533/pn533.c index a966c6a85ea8..712aa67e1770 100644 --- a/drivers/nfc/pn533/pn533.c +++ b/drivers/nfc/pn533/pn533.c | |||
@@ -383,14 +383,18 @@ static void pn533_build_cmd_frame(struct pn533 *dev, u8 cmd_code, | |||
383 | static int pn533_send_async_complete(struct pn533 *dev) | 383 | static int pn533_send_async_complete(struct pn533 *dev) |
384 | { | 384 | { |
385 | struct pn533_cmd *cmd = dev->cmd; | 385 | struct pn533_cmd *cmd = dev->cmd; |
386 | int status = cmd->status; | 386 | struct sk_buff *resp; |
387 | int status, rc = 0; | ||
387 | 388 | ||
388 | struct sk_buff *req = cmd->req; | 389 | if (!cmd) { |
389 | struct sk_buff *resp = cmd->resp; | 390 | dev_dbg(dev->dev, "%s: cmd not set\n", __func__); |
391 | goto done; | ||
392 | } | ||
390 | 393 | ||
391 | int rc; | 394 | dev_kfree_skb(cmd->req); |
392 | 395 | ||
393 | dev_kfree_skb(req); | 396 | status = cmd->status; |
397 | resp = cmd->resp; | ||
394 | 398 | ||
395 | if (status < 0) { | 399 | if (status < 0) { |
396 | rc = cmd->complete_cb(dev, cmd->complete_cb_context, | 400 | rc = cmd->complete_cb(dev, cmd->complete_cb_context, |
@@ -399,8 +403,14 @@ static int pn533_send_async_complete(struct pn533 *dev) | |||
399 | goto done; | 403 | goto done; |
400 | } | 404 | } |
401 | 405 | ||
402 | skb_pull(resp, dev->ops->rx_header_len); | 406 | /* when no response is set we got interrupted */ |
403 | skb_trim(resp, resp->len - dev->ops->rx_tail_len); | 407 | if (!resp) |
408 | resp = ERR_PTR(-EINTR); | ||
409 | |||
410 | if (!IS_ERR(resp)) { | ||
411 | skb_pull(resp, dev->ops->rx_header_len); | ||
412 | skb_trim(resp, resp->len - dev->ops->rx_tail_len); | ||
413 | } | ||
404 | 414 | ||
405 | rc = cmd->complete_cb(dev, cmd->complete_cb_context, resp); | 415 | rc = cmd->complete_cb(dev, cmd->complete_cb_context, resp); |
406 | 416 | ||
@@ -434,12 +444,14 @@ static int __pn533_send_async(struct pn533 *dev, u8 cmd_code, | |||
434 | mutex_lock(&dev->cmd_lock); | 444 | mutex_lock(&dev->cmd_lock); |
435 | 445 | ||
436 | if (!dev->cmd_pending) { | 446 | if (!dev->cmd_pending) { |
447 | dev->cmd = cmd; | ||
437 | rc = dev->phy_ops->send_frame(dev, req); | 448 | rc = dev->phy_ops->send_frame(dev, req); |
438 | if (rc) | 449 | if (rc) { |
450 | dev->cmd = NULL; | ||
439 | goto error; | 451 | goto error; |
452 | } | ||
440 | 453 | ||
441 | dev->cmd_pending = 1; | 454 | dev->cmd_pending = 1; |
442 | dev->cmd = cmd; | ||
443 | goto unlock; | 455 | goto unlock; |
444 | } | 456 | } |
445 | 457 | ||
@@ -511,11 +523,12 @@ static int pn533_send_cmd_direct_async(struct pn533 *dev, u8 cmd_code, | |||
511 | 523 | ||
512 | pn533_build_cmd_frame(dev, cmd_code, req); | 524 | pn533_build_cmd_frame(dev, cmd_code, req); |
513 | 525 | ||
526 | dev->cmd = cmd; | ||
514 | rc = dev->phy_ops->send_frame(dev, req); | 527 | rc = dev->phy_ops->send_frame(dev, req); |
515 | if (rc < 0) | 528 | if (rc < 0) { |
529 | dev->cmd = NULL; | ||
516 | kfree(cmd); | 530 | kfree(cmd); |
517 | else | 531 | } |
518 | dev->cmd = cmd; | ||
519 | 532 | ||
520 | return rc; | 533 | return rc; |
521 | } | 534 | } |
@@ -550,14 +563,15 @@ static void pn533_wq_cmd(struct work_struct *work) | |||
550 | 563 | ||
551 | mutex_unlock(&dev->cmd_lock); | 564 | mutex_unlock(&dev->cmd_lock); |
552 | 565 | ||
566 | dev->cmd = cmd; | ||
553 | rc = dev->phy_ops->send_frame(dev, cmd->req); | 567 | rc = dev->phy_ops->send_frame(dev, cmd->req); |
554 | if (rc < 0) { | 568 | if (rc < 0) { |
569 | dev->cmd = NULL; | ||
555 | dev_kfree_skb(cmd->req); | 570 | dev_kfree_skb(cmd->req); |
556 | kfree(cmd); | 571 | kfree(cmd); |
557 | return; | 572 | return; |
558 | } | 573 | } |
559 | 574 | ||
560 | dev->cmd = cmd; | ||
561 | } | 575 | } |
562 | 576 | ||
563 | struct pn533_sync_cmd_response { | 577 | struct pn533_sync_cmd_response { |