summaryrefslogtreecommitdiffstats
path: root/net/nfc
diff options
context:
space:
mode:
authorChristophe Ricard <christophe.ricard@gmail.com>2015-10-25 17:54:25 -0400
committerSamuel Ortiz <sameo@linux.intel.com>2015-10-26 01:53:13 -0400
commita1b0b9415817c14d207921582f269d03f848b69f (patch)
tree207337705492431a3750a1ec014d26259ea6c2e5 /net/nfc
parent8a49943f5bc5ff4f835d50451ecf2380eab44d2e (diff)
NFC: nci: Create pipe on specific gate in nci_hci_connect_gate
Some gates might need to have their pipes explicitly created. Add a call to nci_hci_create_pipe in nci_hci_connect_gate for every gate that is different than NCI_HCI_LINK_MGMT_GATE or NCI_HCI_ADMIN_GATE. In case of an error when opening a pipe, like in hci layer, delete the pipe if it was created. Signed-off-by: Christophe Ricard <christophe-h.ricard@st.com> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'net/nfc')
-rw-r--r--net/nfc/nci/hci.c56
1 files changed, 55 insertions, 1 deletions
diff --git a/net/nfc/nci/hci.c b/net/nfc/nci/hci.c
index af401fff72d9..c96830421097 100644
--- a/net/nfc/nci/hci.c
+++ b/net/nfc/nci/hci.c
@@ -79,6 +79,8 @@ struct nci_hcp_packet {
79#define NCI_EVT_HOT_PLUG 0x03 79#define NCI_EVT_HOT_PLUG 0x03
80 80
81#define NCI_HCI_ADMIN_PARAM_SESSION_IDENTITY 0x01 81#define NCI_HCI_ADMIN_PARAM_SESSION_IDENTITY 0x01
82#define NCI_HCI_ADM_CREATE_PIPE 0x10
83#define NCI_HCI_ADM_DELETE_PIPE 0x11
82 84
83/* HCP headers */ 85/* HCP headers */
84#define NCI_HCI_HCP_PACKET_HEADER_LEN 1 86#define NCI_HCI_HCP_PACKET_HEADER_LEN 1
@@ -523,6 +525,43 @@ int nci_hci_open_pipe(struct nci_dev *ndev, u8 pipe)
523} 525}
524EXPORT_SYMBOL(nci_hci_open_pipe); 526EXPORT_SYMBOL(nci_hci_open_pipe);
525 527
528static u8 nci_hci_create_pipe(struct nci_dev *ndev, u8 dest_host,
529 u8 dest_gate, int *result)
530{
531 u8 pipe;
532 struct sk_buff *skb;
533 struct nci_hci_create_pipe_params params;
534 struct nci_hci_create_pipe_resp *resp;
535
536 pr_debug("gate=%d\n", dest_gate);
537
538 params.src_gate = NCI_HCI_ADMIN_GATE;
539 params.dest_host = dest_host;
540 params.dest_gate = dest_gate;
541
542 *result = nci_hci_send_cmd(ndev, NCI_HCI_ADMIN_GATE,
543 NCI_HCI_ADM_CREATE_PIPE,
544 (u8 *)&params, sizeof(params), &skb);
545 if (*result < 0)
546 return NCI_HCI_INVALID_PIPE;
547
548 resp = (struct nci_hci_create_pipe_resp *)skb->data;
549 pipe = resp->pipe;
550 kfree_skb(skb);
551
552 pr_debug("pipe created=%d\n", pipe);
553
554 return pipe;
555}
556
557static int nci_hci_delete_pipe(struct nci_dev *ndev, u8 pipe)
558{
559 pr_debug("\n");
560
561 return nci_hci_send_cmd(ndev, NCI_HCI_ADMIN_GATE,
562 NCI_HCI_ADM_DELETE_PIPE, &pipe, 1, NULL);
563}
564
526int nci_hci_set_param(struct nci_dev *ndev, u8 gate, u8 idx, 565int nci_hci_set_param(struct nci_dev *ndev, u8 gate, u8 idx,
527 const u8 *param, size_t param_len) 566 const u8 *param, size_t param_len)
528{ 567{
@@ -616,6 +655,7 @@ EXPORT_SYMBOL(nci_hci_get_param);
616int nci_hci_connect_gate(struct nci_dev *ndev, 655int nci_hci_connect_gate(struct nci_dev *ndev,
617 u8 dest_host, u8 dest_gate, u8 pipe) 656 u8 dest_host, u8 dest_gate, u8 pipe)
618{ 657{
658 bool pipe_created = false;
619 int r; 659 int r;
620 660
621 if (pipe == NCI_HCI_DO_NOT_OPEN_PIPE) 661 if (pipe == NCI_HCI_DO_NOT_OPEN_PIPE)
@@ -634,12 +674,26 @@ int nci_hci_connect_gate(struct nci_dev *ndev,
634 case NCI_HCI_ADMIN_GATE: 674 case NCI_HCI_ADMIN_GATE:
635 pipe = NCI_HCI_ADMIN_PIPE; 675 pipe = NCI_HCI_ADMIN_PIPE;
636 break; 676 break;
677 default:
678 pipe = nci_hci_create_pipe(ndev, dest_host, dest_gate, &r);
679 if (pipe < 0)
680 return r;
681 pipe_created = true;
682 break;
637 } 683 }
638 684
639open_pipe: 685open_pipe:
640 r = nci_hci_open_pipe(ndev, pipe); 686 r = nci_hci_open_pipe(ndev, pipe);
641 if (r < 0) 687 if (r < 0) {
688 if (pipe_created) {
689 if (nci_hci_delete_pipe(ndev, pipe) < 0) {
690 /* TODO: Cannot clean by deleting pipe...
691 * -> inconsistent state
692 */
693 }
694 }
642 return r; 695 return r;
696 }
643 697
644 ndev->hci_dev->pipes[pipe].gate = dest_gate; 698 ndev->hci_dev->pipes[pipe].gate = dest_gate;
645 ndev->hci_dev->pipes[pipe].host = dest_host; 699 ndev->hci_dev->pipes[pipe].host = dest_host;