static int pn533_transceive()

in pn533/pn533.c [2249:2316]


static int pn533_transceive(struct nfc_dev *nfc_dev,
			    struct nfc_target *target, struct sk_buff *skb,
			    data_exchange_cb_t cb, void *cb_context)
{
	struct pn533 *dev = nfc_get_drvdata(nfc_dev);
	struct pn533_data_exchange_arg *arg = NULL;
	int rc;

	if (!dev->tgt_active_prot) {
		nfc_err(dev->dev,
			"Can't exchange data if there is no active target\n");
		rc = -EINVAL;
		goto error;
	}

	arg = kmalloc(sizeof(*arg), GFP_KERNEL);
	if (!arg) {
		rc = -ENOMEM;
		goto error;
	}

	arg->cb = cb;
	arg->cb_context = cb_context;

	switch (dev->device_type) {
	case PN533_DEVICE_PASORI:
		if (dev->tgt_active_prot == NFC_PROTO_FELICA) {
			rc = pn533_send_data_async(dev, PN533_CMD_IN_COMM_THRU,
						   skb,
						   pn533_data_exchange_complete,
						   arg);

			break;
		}
		fallthrough;
	default:
		/* jumbo frame ? */
		if (skb->len > PN533_CMD_DATAEXCH_DATA_MAXLEN) {
			rc = pn533_fill_fragment_skbs(dev, skb);
			if (rc < 0)
				goto error;

			skb = skb_dequeue(&dev->fragment_skb);
			if (!skb) {
				rc = -EIO;
				goto error;
			}
		} else {
			*(u8 *)skb_push(skb, sizeof(u8)) =  1; /* TG */
		}

		rc = pn533_send_data_async(dev, PN533_CMD_IN_DATA_EXCHANGE,
					   skb, pn533_data_exchange_complete,
					   arg);

		break;
	}

	if (rc < 0) /* rc from send_async */
		goto error;

	return 0;

error:
	kfree(arg);
	dev_kfree_skb(skb);
	return rc;
}