From b16ae7160a836c4a1e443ea6efca31421e86bae1 Mon Sep 17 00:00:00 2001 From: Christophe Ricard Date: Tue, 3 Feb 2015 19:48:05 +0100 Subject: NFC: nci: Support all destinations type when creating a connection The current implementation limits nci_core_conn_create_req() to only manage NCI_DESTINATION_NFCEE. Add new parameters to nci_core_conn_create() to support all destination types described in the NCI specification. Because there are some parameters with variable size dynamic buffer allocation is needed. Signed-off-by: Christophe Ricard Signed-off-by: Samuel Ortiz --- net/nfc/nci/core.c | 48 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 15 deletions(-) (limited to 'net/nfc') diff --git a/net/nfc/nci/core.c b/net/nfc/nci/core.c index 17ff5f83393c..ddfe91e43c88 100644 --- a/net/nfc/nci/core.c +++ b/net/nfc/nci/core.c @@ -41,6 +41,11 @@ #include #include +struct core_conn_create_data { + int length; + struct nci_core_conn_create_cmd *cmd; +}; + static void nci_cmd_work(struct work_struct *work); static void nci_rx_work(struct work_struct *work); static void nci_tx_work(struct work_struct *work); @@ -509,25 +514,38 @@ EXPORT_SYMBOL(nci_nfcee_mode_set); static void nci_core_conn_create_req(struct nci_dev *ndev, unsigned long opt) { - struct nci_core_conn_create_cmd cmd; - struct core_conn_create_dest_spec_params *params = - (struct core_conn_create_dest_spec_params *)opt; - - cmd.destination_type = NCI_DESTINATION_NFCEE; - cmd.number_destination_params = 1; - memcpy(&cmd.params.type, params, - sizeof(struct core_conn_create_dest_spec_params)); - nci_send_cmd(ndev, NCI_OP_CORE_CONN_CREATE_CMD, - sizeof(struct nci_core_conn_create_cmd), &cmd); + struct core_conn_create_data *data = + (struct core_conn_create_data *)opt; + + nci_send_cmd(ndev, NCI_OP_CORE_CONN_CREATE_CMD, data->length, data->cmd); } -int nci_core_conn_create(struct nci_dev *ndev, +int nci_core_conn_create(struct nci_dev *ndev, u8 destination_type, + u8 number_destination_params, + size_t params_len, struct core_conn_create_dest_spec_params *params) { - ndev->cur_id = params->value.id; - return nci_request(ndev, nci_core_conn_create_req, - (unsigned long)params, - msecs_to_jiffies(NCI_CMD_TIMEOUT)); + int r; + struct nci_core_conn_create_cmd *cmd; + struct core_conn_create_data data; + + data.length = params_len + sizeof(struct nci_core_conn_create_cmd); + cmd = kzalloc(data.length, GFP_KERNEL); + if (!cmd) + return -ENOMEM; + + cmd->destination_type = destination_type; + cmd->number_destination_params = number_destination_params; + memcpy(cmd->params, params, params_len); + + data.cmd = cmd; + ndev->cur_id = params->value[DEST_SPEC_PARAMS_ID_INDEX]; + + r = __nci_request(ndev, nci_core_conn_create_req, + (unsigned long)&data, + msecs_to_jiffies(NCI_CMD_TIMEOUT)); + kfree(cmd); + return r; } EXPORT_SYMBOL(nci_core_conn_create); -- cgit v1.2.3