int nci_nfcc_loopback(struct nci_dev *ndev, const void *data, size_t data_len,
		      struct sk_buff **resp)
{
	int r;
	struct nci_loopback_data loopback_data;
	struct nci_conn_info *conn_info;
	struct sk_buff *skb;
	int conn_id = nci_get_conn_info_by_dest_type_params(ndev,
					NCI_DESTINATION_NFCC_LOOPBACK, NULL);

	if (conn_id < 0) {
		r = nci_core_conn_create(ndev, NCI_DESTINATION_NFCC_LOOPBACK,
					 0, 0, NULL);
		if (r != NCI_STATUS_OK)
			return r;

		conn_id = nci_get_conn_info_by_dest_type_params(ndev,
					NCI_DESTINATION_NFCC_LOOPBACK,
					NULL);
	}

	conn_info = nci_get_conn_info_by_conn_id(ndev, conn_id);
	if (!conn_info)
		return -EPROTO;

	/* store cb and context to be used on receiving data */
	conn_info->data_exchange_cb = nci_nfcc_loopback_cb;
	conn_info->data_exchange_cb_context = ndev;

	skb = nci_skb_alloc(ndev, NCI_DATA_HDR_SIZE + data_len, GFP_KERNEL);
	if (!skb)
		return -ENOMEM;

	skb_reserve(skb, NCI_DATA_HDR_SIZE);
	skb_put_data(skb, data, data_len);

	loopback_data.conn_id = conn_id;
	loopback_data.data = skb;

	ndev->cur_conn_id = conn_id;
	r = nci_request(ndev, nci_send_data_req, &loopback_data,
			msecs_to_jiffies(NCI_DATA_TIMEOUT));
	if (r == NCI_STATUS_OK && resp)
		*resp = conn_info->rx_skb;

	return r;
}
int nci_nfcc_loopback(struct nci_dev *ndev, const void *data, size_t data_len,
		      struct sk_buff **resp)
{
	int r;
	struct nci_loopback_data loopback_data;
	struct nci_conn_info *conn_info;
	struct sk_buff *skb;
	int conn_id = nci_get_conn_info_by_dest_type_params(ndev,
					NCI_DESTINATION_NFCC_LOOPBACK, NULL);

	if (conn_id < 0) {
		r = nci_core_conn_create(ndev, NCI_DESTINATION_NFCC_LOOPBACK,
					 0, 0, NULL);
		if (r != NCI_STATUS_OK)
			return r;

		conn_id = nci_get_conn_info_by_dest_type_params(ndev,
					NCI_DESTINATION_NFCC_LOOPBACK,
					NULL);
	}

	conn_info = nci_get_conn_info_by_conn_id(ndev, conn_id);
	if (!conn_info)
		return -EPROTO;

	 
	conn_info->data_exchange_cb = nci_nfcc_loopback_cb;
	conn_info->data_exchange_cb_context = ndev;

	skb = nci_skb_alloc(ndev, NCI_DATA_HDR_SIZE + data_len, GFP_KERNEL);
	if (!skb)
		return -ENOMEM;

	skb_reserve(skb, NCI_DATA_HDR_SIZE);
	skb_put_data(skb, data, data_len);

	loopback_data.conn_id = conn_id;
	loopback_data.data = skb;

	ndev->cur_conn_id = conn_id;
	r = nci_request(ndev, nci_send_data_req, &loopback_data,
			msecs_to_jiffies(NCI_DATA_TIMEOUT));
	if (r == NCI_STATUS_OK && resp)
		*resp = conn_info->rx_skb;

	return r;
}