From 15d4a8da0e440faf589a26346c8287e1ed0abe6c Mon Sep 17 00:00:00 2001 From: Christophe Ricard Date: Tue, 3 Feb 2015 19:48:07 +0100 Subject: [PATCH] NFC: nci: Move logical connection structure allocation conn_info is currently allocated only after nfcee_discovery_ntf which is not generic enough for logical connection other than NFCEE. The corresponding conn_info is now created in nci_core_conn_create_rsp(). Signed-off-by: Christophe Ricard Signed-off-by: Samuel Ortiz --- drivers/nfc/st21nfcb/st21nfcb_se.c | 2 +- include/net/nfc/nci_core.h | 1 + net/nfc/nci/hci.c | 8 ++++++++ net/nfc/nci/ntf.c | 23 ++--------------------- net/nfc/nci/rsp.c | 29 ++++++++++++++++++++++++----- 5 files changed, 36 insertions(+), 27 deletions(-) diff --git a/drivers/nfc/st21nfcb/st21nfcb_se.c b/drivers/nfc/st21nfcb/st21nfcb_se.c index 3b465e4c85e3..d23e8f27c4aa 100644 --- a/drivers/nfc/st21nfcb/st21nfcb_se.c +++ b/drivers/nfc/st21nfcb/st21nfcb_se.c @@ -513,7 +513,7 @@ static int st21nfcb_hci_network_init(struct nci_dev *ndev) dest_params->type = NCI_DESTINATION_SPECIFIC_PARAM_NFCEE_TYPE; dest_params->length = sizeof(struct dest_spec_params); - spec_params.id = ndev->hci_dev->conn_info->id; + spec_params.id = ndev->hci_dev->nfcee_id; spec_params.protocol = NCI_NFCEE_INTERFACE_HCI_ACCESS; memcpy(dest_params->value, &spec_params, sizeof(struct dest_spec_params)); r = nci_core_conn_create(ndev, NCI_DESTINATION_NFCEE, 1, diff --git a/include/net/nfc/nci_core.h b/include/net/nfc/nci_core.h index d34c1b2295d7..ff87f8611fa3 100644 --- a/include/net/nfc/nci_core.h +++ b/include/net/nfc/nci_core.h @@ -159,6 +159,7 @@ struct nci_hci_init_data { #define NCI_HCI_MAX_GATES 256 struct nci_hci_dev { + u8 nfcee_id; struct nci_dev *ndev; struct nci_conn_info *conn_info; diff --git a/net/nfc/nci/hci.c b/net/nfc/nci/hci.c index ecf253942606..ed54ec533836 100644 --- a/net/nfc/nci/hci.c +++ b/net/nfc/nci/hci.c @@ -615,12 +615,20 @@ static int nci_hci_dev_connect_gates(struct nci_dev *ndev, int nci_hci_dev_session_init(struct nci_dev *ndev) { + struct nci_conn_info *conn_info; struct sk_buff *skb; int r; ndev->hci_dev->count_pipes = 0; ndev->hci_dev->expected_pipes = 0; + conn_info = ndev->hci_dev->conn_info; + if (!conn_info) + return -EPROTO; + + conn_info->data_exchange_cb = nci_hci_data_received_cb; + conn_info->data_exchange_cb_context = ndev; + nci_hci_reset_pipes(ndev->hci_dev); if (ndev->hci_dev->init_data.gates[0].gate != NCI_HCI_ADMIN_GATE) diff --git a/net/nfc/nci/ntf.c b/net/nfc/nci/ntf.c index 6bbbf6fdacc0..3218071072ac 100644 --- a/net/nfc/nci/ntf.c +++ b/net/nfc/nci/ntf.c @@ -723,7 +723,6 @@ static void nci_nfcee_discover_ntf_packet(struct nci_dev *ndev, struct sk_buff *skb) { u8 status = NCI_STATUS_OK; - struct nci_conn_info *conn_info; struct nci_nfcee_discover_ntf *nfcee_ntf = (struct nci_nfcee_discover_ntf *)skb->data; @@ -734,27 +733,9 @@ static void nci_nfcee_discover_ntf_packet(struct nci_dev *ndev, * and only one, NFCEE_DISCOVER_NTF with a Protocol type of * “HCI Access”, even if the HCI Network contains multiple NFCEEs. */ - if (!ndev->hci_dev->conn_info) { - conn_info = devm_kzalloc(&ndev->nfc_dev->dev, - sizeof(*conn_info), GFP_KERNEL); - if (!conn_info) { - status = NCI_STATUS_REJECTED; - goto exit; - } + ndev->hci_dev->nfcee_id = nfcee_ntf->nfcee_id; + ndev->cur_id = nfcee_ntf->nfcee_id; - conn_info->id = nfcee_ntf->nfcee_id; - conn_info->conn_id = NCI_INVALID_CONN_ID; - - conn_info->data_exchange_cb = nci_hci_data_received_cb; - conn_info->data_exchange_cb_context = ndev; - - INIT_LIST_HEAD(&conn_info->list); - list_add(&conn_info->list, &ndev->conn_info_list); - - ndev->hci_dev->conn_info = conn_info; - } - -exit: nci_req_complete(ndev, status); } diff --git a/net/nfc/nci/rsp.c b/net/nfc/nci/rsp.c index b419fed77ea3..02486bc2ceea 100644 --- a/net/nfc/nci/rsp.c +++ b/net/nfc/nci/rsp.c @@ -233,16 +233,27 @@ static void nci_core_conn_create_rsp_packet(struct nci_dev *ndev, if (status == NCI_STATUS_OK) { rsp = (struct nci_core_conn_create_rsp *)skb->data; - list_for_each_entry(conn_info, &ndev->conn_info_list, list) { - if (conn_info->id == ndev->cur_id) - break; - } - if (!conn_info || conn_info->id != ndev->cur_id) { + conn_info = devm_kzalloc(&ndev->nfc_dev->dev, + sizeof(*conn_info), GFP_KERNEL); + if (!conn_info) { status = NCI_STATUS_REJECTED; goto exit; } + conn_info->id = ndev->cur_id; + conn_info->conn_id = rsp->conn_id; + + /* Note: data_exchange_cb and data_exchange_cb_context need to + * be specify out of nci_core_conn_create_rsp_packet + */ + + INIT_LIST_HEAD(&conn_info->list); + list_add(&conn_info->list, &ndev->conn_info_list); + + if (ndev->cur_id == ndev->hci_dev->nfcee_id) + ndev->hci_dev->conn_info = conn_info; + conn_info->conn_id = rsp->conn_id; conn_info->max_pkt_payload_len = rsp->max_ctrl_pkt_payload_len; atomic_set(&conn_info->credits_cnt, rsp->credits_cnt); @@ -255,9 +266,17 @@ exit: static void nci_core_conn_close_rsp_packet(struct nci_dev *ndev, struct sk_buff *skb) { + struct nci_conn_info *conn_info; __u8 status = skb->data[0]; pr_debug("status 0x%x\n", status); + if (status == NCI_STATUS_OK) { + conn_info = nci_get_conn_info_by_conn_id(ndev, ndev->cur_id); + if (conn_info) { + list_del(&conn_info->list); + devm_kfree(&ndev->nfc_dev->dev, conn_info); + } + } nci_req_complete(ndev, status); }