static int st95hf_in_send_cmd()

in st95hf/core.c [916:987]


static int st95hf_in_send_cmd(struct nfc_digital_dev *ddev,
			      struct sk_buff *skb,
			      u16 timeout,
			      nfc_digital_cmd_complete_t cb,
			      void *arg)
{
	struct st95hf_context *stcontext = nfc_digital_get_drvdata(ddev);
	int rc;
	struct sk_buff *skb_resp;
	int len_data_to_tag = 0;

	skb_resp = nfc_alloc_recv_skb(MAX_RESPONSE_BUFFER_SIZE, GFP_KERNEL);
	if (!skb_resp)
		return -ENOMEM;

	switch (stcontext->current_rf_tech) {
	case NFC_DIGITAL_RF_TECH_106A:
		len_data_to_tag = skb->len + 1;
		skb_put_u8(skb, stcontext->sendrcv_trflag);
		break;
	case NFC_DIGITAL_RF_TECH_106B:
	case NFC_DIGITAL_RF_TECH_ISO15693:
		len_data_to_tag = skb->len;
		break;
	default:
		rc = -EINVAL;
		goto free_skb_resp;
	}

	skb_push(skb, 3);
	skb->data[0] = ST95HF_COMMAND_SEND;
	skb->data[1] = SEND_RECEIVE_CMD;
	skb->data[2] = len_data_to_tag;

	stcontext->complete_cb_arg.skb_resp = skb_resp;
	stcontext->complete_cb_arg.cb_usrarg = arg;
	stcontext->complete_cb_arg.complete_cb = cb;

	if ((skb->data[3] == ISO14443A_RATS_REQ) &&
	    ddev->curr_protocol == NFC_PROTO_ISO14443)
		stcontext->complete_cb_arg.rats = true;

	/*
	 * down the semaphore to indicate to remove func that an
	 * ISR is pending, note that it will not block here in any case.
	 * If found blocked, it is a BUG!
	 */
	rc = down_killable(&stcontext->exchange_lock);
	if (rc) {
		WARN(1, "Semaphore is not found up in st95hf_in_send_cmd\n");
		goto free_skb_resp;
	}

	rc = st95hf_spi_send(&stcontext->spicontext, skb->data,
			     skb->len,
			     ASYNC);
	if (rc) {
		dev_err(&stcontext->nfcdev->dev,
			"Error %d trying to perform data_exchange", rc);
		/* up the semaphore since ISR will never come in this case */
		up(&stcontext->exchange_lock);
		goto free_skb_resp;
	}

	kfree_skb(skb);

	return rc;

free_skb_resp:
	kfree_skb(skb_resp);
	return rc;
}