From 8d25ca799783788742bc7d9647eec44b6754766e Mon Sep 17 00:00:00 2001 From: Waldemar Rymarkiewicz Date: Mon, 26 Nov 2012 14:18:30 +0100 Subject: NFC: pn533: Remove in/out_maxlen as it is not used in_maxlen and out_maxlen was replaced with PN533_NORMAL_FRAME_MAX_LEN Signed-off-by: Waldemar Rymarkiewicz Signed-off-by: Samuel Ortiz --- drivers/nfc/pn533.c | 36 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 20 deletions(-) (limited to 'drivers/nfc') diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c index ada681b01a1..cf94113b174 100644 --- a/drivers/nfc/pn533.c +++ b/drivers/nfc/pn533.c @@ -349,11 +349,9 @@ struct pn533 { struct nfc_dev *nfc_dev; struct urb *out_urb; - int out_maxlen; struct pn533_frame *out_frame; struct urb *in_urb; - int in_maxlen; struct pn533_frame *in_frame; struct sk_buff_head resp_q; @@ -1454,8 +1452,9 @@ static int pn533_send_poll_frame(struct pn533 *dev) pn533_build_poll_frame(dev, dev->out_frame, cur_mod); rc = pn533_send_cmd_frame_async(dev, dev->out_frame, dev->in_frame, - dev->in_maxlen, pn533_poll_complete, - NULL, GFP_KERNEL); + PN533_NORMAL_FRAME_MAX_LEN, + pn533_poll_complete, + NULL, GFP_KERNEL); if (rc) nfc_dev_err(&dev->interface->dev, "Polling loop error %d", rc); @@ -1567,7 +1566,7 @@ static int pn533_activate_target_nfcdep(struct pn533 *dev) pn533_tx_frame_finish(dev->out_frame); rc = pn533_send_cmd_frame_sync(dev, dev->out_frame, dev->in_frame, - dev->in_maxlen); + PN533_NORMAL_FRAME_MAX_LEN); if (rc) return rc; @@ -1661,7 +1660,7 @@ static void pn533_deactivate_target(struct nfc_dev *nfc_dev, pn533_tx_frame_finish(dev->out_frame); rc = pn533_send_cmd_frame_sync(dev, dev->out_frame, dev->in_frame, - dev->in_maxlen); + PN533_NORMAL_FRAME_MAX_LEN); if (rc) { nfc_dev_err(&dev->interface->dev, "Error when sending release" " command to the controller"); @@ -1822,8 +1821,9 @@ static int pn533_dep_link_up(struct nfc_dev *nfc_dev, struct nfc_target *target, pn533_tx_frame_finish(dev->out_frame); rc = pn533_send_cmd_frame_async(dev, dev->out_frame, dev->in_frame, - dev->in_maxlen, pn533_in_dep_link_up_complete, - cmd, GFP_KERNEL); + PN533_NORMAL_FRAME_MAX_LEN, + pn533_in_dep_link_up_complete, cmd, + GFP_KERNEL); if (rc < 0) kfree(cmd); @@ -2121,8 +2121,9 @@ static int pn533_tm_send(struct nfc_dev *nfc_dev, struct sk_buff *skb) out_frame = (struct pn533_frame *) skb->data; rc = pn533_send_cmd_frame_async(dev, out_frame, dev->in_frame, - dev->in_maxlen, pn533_tm_send_complete, - skb, GFP_KERNEL); + PN533_NORMAL_FRAME_MAX_LEN, + pn533_tm_send_complete, skb, + GFP_KERNEL); if (rc) { nfc_dev_err(&dev->interface->dev, "Error %d when trying to send data", rc); @@ -2217,7 +2218,7 @@ static int pn533_set_configuration(struct pn533 *dev, u8 cfgitem, u8 *cfgdata, pn533_tx_frame_finish(dev->out_frame); rc = pn533_send_cmd_frame_sync(dev, dev->out_frame, dev->in_frame, - dev->in_maxlen); + PN533_NORMAL_FRAME_MAX_LEN); return rc; } @@ -2238,7 +2239,7 @@ static int pn533_fw_reset(struct pn533 *dev) pn533_tx_frame_finish(dev->out_frame); rc = pn533_send_cmd_frame_sync(dev, dev->out_frame, dev->in_frame, - dev->in_maxlen); + PN533_NORMAL_FRAME_MAX_LEN); return rc; } @@ -2359,16 +2360,11 @@ static int pn533_probe(struct usb_interface *interface, for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { endpoint = &iface_desc->endpoint[i].desc; - if (!in_endpoint && usb_endpoint_is_bulk_in(endpoint)) { - dev->in_maxlen = le16_to_cpu(endpoint->wMaxPacketSize); + if (!in_endpoint && usb_endpoint_is_bulk_in(endpoint)) in_endpoint = endpoint->bEndpointAddress; - } - if (!out_endpoint && usb_endpoint_is_bulk_out(endpoint)) { - dev->out_maxlen = - le16_to_cpu(endpoint->wMaxPacketSize); + if (!out_endpoint && usb_endpoint_is_bulk_out(endpoint)) out_endpoint = endpoint->bEndpointAddress; - } } if (!in_endpoint || !out_endpoint) { @@ -2418,7 +2414,7 @@ static int pn533_probe(struct usb_interface *interface, pn533_tx_frame_finish(dev->out_frame); rc = pn533_send_cmd_frame_sync(dev, dev->out_frame, dev->in_frame, - dev->in_maxlen); + PN533_NORMAL_FRAME_MAX_LEN); if (rc) goto destroy_wq; -- cgit v1.2.3-18-g5258 From a449ae1cbdcb5ab45c894362602b239e1d8d96c3 Mon Sep 17 00:00:00 2001 From: Waldemar Rymarkiewicz Date: Mon, 26 Nov 2012 14:18:31 +0100 Subject: NFC: pn533: Remove unused definitions Signed-off-by: Waldemar Rymarkiewicz Signed-off-by: Samuel Ortiz --- drivers/nfc/pn533.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'drivers/nfc') diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c index cf94113b174..ed8ecb3589b 100644 --- a/drivers/nfc/pn533.c +++ b/drivers/nfc/pn533.c @@ -41,11 +41,6 @@ #define SONY_VENDOR_ID 0x054c #define PASORI_PRODUCT_ID 0x02e1 -#define PN533_QUIRKS_TYPE_A BIT(0) -#define PN533_QUIRKS_TYPE_F BIT(1) -#define PN533_QUIRKS_DEP BIT(2) -#define PN533_QUIRKS_RAW_EXCHANGE BIT(3) - #define PN533_DEVICE_STD 0x1 #define PN533_DEVICE_PASORI 0x2 @@ -128,9 +123,6 @@ MODULE_DEVICE_TABLE(usb, pn533_table); #define PN533_CMD_MI_MASK 0x40 #define PN533_CMD_RET_SUCCESS 0x00 -/* PN533 status codes */ -#define PN533_STATUS_TARGET_RELEASED 0x29 - struct pn533; typedef int (*pn533_cmd_complete_t) (struct pn533 *dev, void *arg, -- cgit v1.2.3-18-g5258 From b1bb290ac2308616b24c5986665d7199ff7b9df3 Mon Sep 17 00:00:00 2001 From: Waldemar Rymarkiewicz Date: Mon, 26 Nov 2012 14:18:32 +0100 Subject: NFC: pn533: Add frame header length define PN533_CMD_DATAEXCH_HEAD_LEN includes a frame header length which is not seen at a glance. It can be missleading, so split it and define the frame header length explicitly. Signed-off-by: Waldemar Rymarkiewicz Signed-off-by: Samuel Ortiz --- drivers/nfc/pn533.c | 53 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 33 insertions(+), 20 deletions(-) (limited to 'drivers/nfc') diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c index ed8ecb3589b..7040106cb7f 100644 --- a/drivers/nfc/pn533.c +++ b/drivers/nfc/pn533.c @@ -82,10 +82,12 @@ MODULE_DEVICE_TABLE(usb, pn533_table); #define PN533_NORMAL_FRAME_MAX_LEN 262 /* 6 (PREAMBLE, SOF, LEN, LCS, TFI) 254 (DATA) 2 (DCS, postamble) */ +#define PN533_FRAME_HEADER_LEN (sizeof(struct pn533_frame) \ + + 2) /* data[0] TFI, data[1] CC */ +#define PN533_FRAME_TAIL_LEN 2 /* data[len] DCS, data[len + 1] postamble*/ -#define PN533_FRAME_TAIL_SIZE 2 #define PN533_FRAME_SIZE(f) (sizeof(struct pn533_frame) + f->datalen + \ - PN533_FRAME_TAIL_SIZE) + PN533_FRAME_TAIL_LEN) #define PN533_FRAME_ACK_SIZE (sizeof(struct pn533_frame) + 1) #define PN533_FRAME_CHECKSUM(f) (f->data[f->datalen]) #define PN533_FRAME_POSTAMBLE(f) (f->data[f->datalen + 1]) @@ -1233,7 +1235,7 @@ static int pn533_init_target_frame(struct pn533_frame *frame, return 0; } -#define PN533_CMD_DATAEXCH_HEAD_LEN (sizeof(struct pn533_frame) + 3) +#define PN533_CMD_DATAEXCH_HEAD_LEN 1 #define PN533_CMD_DATAEXCH_DATA_MAXLEN 262 static int pn533_tm_get_data_complete(struct pn533 *dev, void *arg, u8 *params, int params_len) @@ -1261,8 +1263,9 @@ static int pn533_tm_get_data_complete(struct pn533 *dev, void *arg, } skb_put(skb_resp, PN533_FRAME_SIZE(in_frame)); - skb_pull(skb_resp, PN533_CMD_DATAEXCH_HEAD_LEN); - skb_trim(skb_resp, skb_resp->len - PN533_FRAME_TAIL_SIZE); + skb_pull(skb_resp, + PN533_FRAME_HEADER_LEN + PN533_CMD_DATAEXCH_HEAD_LEN); + skb_trim(skb_resp, skb_resp->len - PN533_FRAME_TAIL_LEN); return nfc_tm_data_received(dev->nfc_dev, skb_resp); } @@ -1276,9 +1279,10 @@ static void pn533_wq_tg_get_data(struct work_struct *work) nfc_dev_dbg(&dev->interface->dev, "%s", __func__); - skb_resp_len = PN533_CMD_DATAEXCH_HEAD_LEN + - PN533_CMD_DATAEXCH_DATA_MAXLEN + - PN533_FRAME_TAIL_SIZE; + skb_resp_len = PN533_FRAME_HEADER_LEN + + PN533_CMD_DATAEXCH_HEAD_LEN + + PN533_CMD_DATAEXCH_DATA_MAXLEN + + PN533_FRAME_TAIL_LEN; skb_resp = nfc_alloc_recv_skb(skb_resp_len, GFP_KERNEL); if (!skb_resp) @@ -1859,11 +1863,12 @@ static int pn533_build_tx_frame(struct pn533 *dev, struct sk_buff *skb, return -ENOSYS; } + skb_push(skb, PN533_FRAME_HEADER_LEN); + if (target == true) { switch (dev->device_type) { case PN533_DEVICE_PASORI: if (dev->tgt_active_prot == NFC_PROTO_FELICA) { - skb_push(skb, PN533_CMD_DATAEXCH_HEAD_LEN - 1); out_frame = (struct pn533_frame *) skb->data; pn533_tx_frame_init(out_frame, PN533_CMD_IN_COMM_THRU); @@ -1895,7 +1900,7 @@ static int pn533_build_tx_frame(struct pn533 *dev, struct sk_buff *skb, out_frame->datalen += payload_len; pn533_tx_frame_finish(out_frame); - skb_put(skb, PN533_FRAME_TAIL_SIZE); + skb_put(skb, PN533_FRAME_TAIL_LEN); return 0; } @@ -1975,8 +1980,9 @@ static int pn533_data_exchange_complete(struct pn533 *dev, void *_arg, } skb_put(skb_resp, PN533_FRAME_SIZE(in_frame)); + skb_pull(skb_resp, PN533_FRAME_HEADER_LEN); skb_pull(skb_resp, PN533_CMD_DATAEXCH_HEAD_LEN); - skb_trim(skb_resp, skb_resp->len - PN533_FRAME_TAIL_SIZE); + skb_trim(skb_resp, skb_resp->len - PN533_FRAME_TAIL_LEN); skb_queue_tail(&dev->resp_q, skb_resp); if (status & PN533_CMD_MI_MASK) { @@ -2024,9 +2030,10 @@ static int pn533_transceive(struct nfc_dev *nfc_dev, if (rc) goto error; - skb_resp_len = PN533_CMD_DATAEXCH_HEAD_LEN + - PN533_CMD_DATAEXCH_DATA_MAXLEN + - PN533_FRAME_TAIL_SIZE; + skb_resp_len = PN533_FRAME_HEADER_LEN + + PN533_CMD_DATAEXCH_HEAD_LEN + + PN533_CMD_DATAEXCH_DATA_MAXLEN + + PN533_FRAME_TAIL_LEN; skb_resp = nfc_alloc_recv_skb(skb_resp_len, GFP_KERNEL); if (!skb_resp) { @@ -2143,20 +2150,25 @@ static void pn533_wq_mi_recv(struct work_struct *work) nfc_dev_dbg(&dev->interface->dev, "%s", __func__); /* This is a zero payload size skb */ - skb_cmd = alloc_skb(PN533_CMD_DATAEXCH_HEAD_LEN + PN533_FRAME_TAIL_SIZE, + skb_cmd = alloc_skb(PN533_FRAME_HEADER_LEN + + PN533_CMD_DATAEXCH_HEAD_LEN + + PN533_FRAME_TAIL_LEN, GFP_KERNEL); if (skb_cmd == NULL) goto error_cmd; - skb_reserve(skb_cmd, PN533_CMD_DATAEXCH_HEAD_LEN); + skb_reserve(skb_cmd, + PN533_FRAME_HEADER_LEN + PN533_CMD_DATAEXCH_HEAD_LEN); rc = pn533_build_tx_frame(dev, skb_cmd, true); if (rc) goto error_frame; - skb_resp_len = PN533_CMD_DATAEXCH_HEAD_LEN + - PN533_CMD_DATAEXCH_DATA_MAXLEN + - PN533_FRAME_TAIL_SIZE; + skb_resp_len = PN533_FRAME_HEADER_LEN + + PN533_CMD_DATAEXCH_HEAD_LEN + + PN533_CMD_DATAEXCH_DATA_MAXLEN + + PN533_FRAME_TAIL_LEN; + skb_resp = alloc_skb(skb_resp_len, GFP_KERNEL); if (!skb_resp) { rc = -ENOMEM; @@ -2433,8 +2445,9 @@ static int pn533_probe(struct usb_interface *interface, } dev->nfc_dev = nfc_allocate_device(&pn533_nfc_ops, protocols, + PN533_FRAME_HEADER_LEN + PN533_CMD_DATAEXCH_HEAD_LEN, - PN533_FRAME_TAIL_SIZE); + PN533_FRAME_TAIL_LEN); if (!dev->nfc_dev) goto destroy_wq; -- cgit v1.2.3-18-g5258 From d94ea4f54516b32affeda7ef097b93bca6e6fd32 Mon Sep 17 00:00:00 2001 From: Waldemar Rymarkiewicz Date: Mon, 26 Nov 2012 14:18:33 +0100 Subject: NFC: pn533: Remove pointless flags param __pn533_send_cmd_frame_async() is called when lock is held so GFP_KERNEL flag will be always used. Thus, having extra param does not optimise the code. Signed-off-by: Waldemar Rymarkiewicz Signed-off-by: Samuel Ortiz --- drivers/nfc/pn533.c | 33 ++++++++++++++------------------- 1 file changed, 14 insertions(+), 19 deletions(-) (limited to 'drivers/nfc') diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c index 7040106cb7f..5f3459d11e7 100644 --- a/drivers/nfc/pn533.c +++ b/drivers/nfc/pn533.c @@ -392,7 +392,6 @@ struct pn533_cmd { int in_frame_len; pn533_cmd_complete_t cmd_complete; void *arg; - gfp_t flags; }; struct pn533_frame { @@ -646,7 +645,7 @@ static int __pn533_send_cmd_frame_async(struct pn533 *dev, struct pn533_frame *in_frame, int in_frame_len, pn533_cmd_complete_t cmd_complete, - void *arg, gfp_t flags) + void *arg) { int rc; @@ -664,11 +663,11 @@ static int __pn533_send_cmd_frame_async(struct pn533 *dev, dev->in_urb->transfer_buffer = in_frame; dev->in_urb->transfer_buffer_length = in_frame_len; - rc = usb_submit_urb(dev->out_urb, flags); + rc = usb_submit_urb(dev->out_urb, GFP_KERNEL); if (rc) return rc; - rc = pn533_submit_urb_for_ack(dev, flags); + rc = pn533_submit_urb_for_ack(dev, GFP_KERNEL); if (rc) goto error; @@ -700,7 +699,7 @@ static void pn533_wq_cmd(struct work_struct *work) __pn533_send_cmd_frame_async(dev, cmd->out_frame, cmd->in_frame, cmd->in_frame_len, cmd->cmd_complete, - cmd->arg, cmd->flags); + cmd->arg); kfree(cmd); } @@ -710,7 +709,7 @@ static int pn533_send_cmd_frame_async(struct pn533 *dev, struct pn533_frame *in_frame, int in_frame_len, pn533_cmd_complete_t cmd_complete, - void *arg, gfp_t flags) + void *arg) { struct pn533_cmd *cmd; int rc = 0; @@ -722,7 +721,7 @@ static int pn533_send_cmd_frame_async(struct pn533 *dev, if (!dev->cmd_pending) { rc = __pn533_send_cmd_frame_async(dev, out_frame, in_frame, in_frame_len, cmd_complete, - arg, flags); + arg); if (!rc) dev->cmd_pending = 1; @@ -731,7 +730,7 @@ static int pn533_send_cmd_frame_async(struct pn533 *dev, nfc_dev_dbg(&dev->interface->dev, "%s Queueing command", __func__); - cmd = kzalloc(sizeof(struct pn533_cmd), flags); + cmd = kzalloc(sizeof(struct pn533_cmd), GFP_KERNEL); if (!cmd) { rc = -ENOMEM; goto unlock; @@ -743,7 +742,6 @@ static int pn533_send_cmd_frame_async(struct pn533 *dev, cmd->in_frame_len = in_frame_len; cmd->cmd_complete = cmd_complete; cmd->arg = arg; - cmd->flags = flags; list_add_tail(&cmd->queue, &dev->cmd_queue); @@ -788,7 +786,7 @@ static int pn533_send_cmd_frame_sync(struct pn533 *dev, init_completion(&arg.done); rc = pn533_send_cmd_frame_async(dev, out_frame, in_frame, in_frame_len, - pn533_sync_cmd_complete, &arg, GFP_KERNEL); + pn533_sync_cmd_complete, &arg); if (rc) return rc; @@ -1296,7 +1294,7 @@ static void pn533_wq_tg_get_data(struct work_struct *work) pn533_send_cmd_frame_async(dev, dev->out_frame, in_frame, skb_resp_len, pn533_tm_get_data_complete, - skb_resp, GFP_KERNEL); + skb_resp); return; } @@ -1450,7 +1448,7 @@ static int pn533_send_poll_frame(struct pn533 *dev) rc = pn533_send_cmd_frame_async(dev, dev->out_frame, dev->in_frame, PN533_NORMAL_FRAME_MAX_LEN, pn533_poll_complete, - NULL, GFP_KERNEL); + NULL); if (rc) nfc_dev_err(&dev->interface->dev, "Polling loop error %d", rc); @@ -1818,8 +1816,7 @@ static int pn533_dep_link_up(struct nfc_dev *nfc_dev, struct nfc_target *target, rc = pn533_send_cmd_frame_async(dev, dev->out_frame, dev->in_frame, PN533_NORMAL_FRAME_MAX_LEN, - pn533_in_dep_link_up_complete, cmd, - GFP_KERNEL); + pn533_in_dep_link_up_complete, cmd); if (rc < 0) kfree(cmd); @@ -2056,8 +2053,7 @@ static int pn533_transceive(struct nfc_dev *nfc_dev, arg->cb_context = cb_context; rc = pn533_send_cmd_frame_async(dev, out_frame, in_frame, skb_resp_len, - pn533_data_exchange_complete, arg, - GFP_KERNEL); + pn533_data_exchange_complete, arg); if (rc) { nfc_dev_err(&dev->interface->dev, "Error %d when trying to" " perform data_exchange", rc); @@ -2121,8 +2117,7 @@ static int pn533_tm_send(struct nfc_dev *nfc_dev, struct sk_buff *skb) rc = pn533_send_cmd_frame_async(dev, out_frame, dev->in_frame, PN533_NORMAL_FRAME_MAX_LEN, - pn533_tm_send_complete, skb, - GFP_KERNEL); + pn533_tm_send_complete, skb); if (rc) { nfc_dev_err(&dev->interface->dev, "Error %d when trying to send data", rc); @@ -2184,7 +2179,7 @@ static void pn533_wq_mi_recv(struct work_struct *work) rc = __pn533_send_cmd_frame_async(dev, out_frame, in_frame, skb_resp_len, pn533_data_exchange_complete, - dev->cmd_complete_arg, GFP_KERNEL); + dev->cmd_complete_arg); if (!rc) return; -- cgit v1.2.3-18-g5258 From aada17ac70e33b127c8f8dd425fc735cc0d30e25 Mon Sep 17 00:00:00 2001 From: Waldemar Rymarkiewicz Date: Mon, 26 Nov 2012 14:18:34 +0100 Subject: NFC: pn533: Add a new pn533_send_cmd_async iface This is intendend to replace pn533_send_cmd_frame_async() which requires from the caller to create a complete frame. The new function constructs a frame and sends it out which hides the frame logic and avoid code duplication. The caller has to allocate skb and put its payload there, and finally provide the skb together with a complete cb to pn533_send_cmd_async(). Response skb is allocated by the core part and pass to the caller cb. Next, the caller has to free it when is not needed anymore or pass it up to the stack. Signed-off-by: Waldemar Rymarkiewicz Signed-off-by: Samuel Ortiz --- drivers/nfc/pn533.c | 167 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 164 insertions(+), 3 deletions(-) (limited to 'drivers/nfc') diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c index 5f3459d11e7..89f747479a4 100644 --- a/drivers/nfc/pn533.c +++ b/drivers/nfc/pn533.c @@ -117,6 +117,7 @@ MODULE_DEVICE_TABLE(usb, pn533_table); #define PN533_CMD_TG_INIT_AS_TARGET 0x8c #define PN533_CMD_TG_GET_DATA 0x86 #define PN533_CMD_TG_SET_DATA 0x8e +#define PN533_CMD_UNDEF 0xff #define PN533_CMD_RESPONSE(cmd) (cmd + 1) @@ -130,6 +131,9 @@ struct pn533; typedef int (*pn533_cmd_complete_t) (struct pn533 *dev, void *arg, u8 *params, int params_len); +typedef int (*pn533_send_async_complete_t) (struct pn533 *dev, void *arg, + struct sk_buff *resp); + /* structs for pn533 commands */ /* PN533_CMD_GET_FIRMWARE_VERSION */ @@ -390,6 +394,9 @@ struct pn533_cmd { struct pn533_frame *out_frame; struct pn533_frame *in_frame; int in_frame_len; + u8 cmd_code; + struct sk_buff *req; + struct sk_buff *resp; pn533_cmd_complete_t cmd_complete; void *arg; }; @@ -678,6 +685,151 @@ error: return rc; } +static void pn533_build_cmd_frame(u8 cmd_code, struct sk_buff *skb) +{ + struct pn533_frame *frame; + /* payload is already there, just update datalen */ + int payload_len = skb->len; + + skb_push(skb, PN533_FRAME_HEADER_LEN); + skb_put(skb, PN533_FRAME_TAIL_LEN); + + frame = (struct pn533_frame *)skb->data; + + pn533_tx_frame_init(frame, cmd_code); + frame->datalen += payload_len; + pn533_tx_frame_finish(frame); +} + +struct pn533_send_async_complete_arg { + pn533_send_async_complete_t complete_cb; + void *complete_cb_context; + struct sk_buff *resp; + struct sk_buff *req; +}; + +static int pn533_send_async_complete(struct pn533 *dev, void *_arg, u8 *params, + int params_len) +{ + struct pn533_send_async_complete_arg *arg = _arg; + + struct sk_buff *req = arg->req; + struct sk_buff *resp = arg->resp; + + struct pn533_frame *frame = (struct pn533_frame *)resp->data; + int rc; + + dev_kfree_skb(req); + + if (params_len < 0) { + nfc_dev_err(&dev->interface->dev, + "Error %d when starting as a target", + params_len); + + arg->complete_cb(dev, arg->complete_cb_context, + ERR_PTR(params_len)); + rc = params_len; + dev_kfree_skb(resp); + goto out; + } + + skb_put(resp, PN533_FRAME_SIZE(frame)); + skb_pull(resp, PN533_FRAME_HEADER_LEN); + skb_trim(resp, resp->len - PN533_FRAME_TAIL_LEN); + + rc = arg->complete_cb(dev, arg->complete_cb_context, resp); + +out: + kfree(arg); + return rc; +} + +static int __pn533_send_async(struct pn533 *dev, u8 cmd_code, + struct sk_buff *req, struct sk_buff *resp, + int resp_len, + pn533_send_async_complete_t complete_cb, + void *complete_cb_context) +{ + struct pn533_cmd *cmd; + struct pn533_send_async_complete_arg *arg; + int rc = 0; + + nfc_dev_dbg(&dev->interface->dev, "%s", __func__); + + arg = kzalloc(sizeof(arg), GFP_KERNEL); + if (!arg) + return -ENOMEM; + + arg->complete_cb = complete_cb; + arg->complete_cb_context = complete_cb_context; + arg->resp = resp; + arg->req = req; + + pn533_build_cmd_frame(cmd_code, req); + + mutex_lock(&dev->cmd_lock); + + if (!dev->cmd_pending) { + rc = __pn533_send_cmd_frame_async(dev, + (struct pn533_frame *)req->data, + (struct pn533_frame *)resp->data, + resp_len, pn533_send_async_complete, + arg); + if (rc) + goto error; + + dev->cmd_pending = 1; + goto unlock; + } + + nfc_dev_dbg(&dev->interface->dev, "%s Queueing command", __func__); + + cmd = kzalloc(sizeof(struct pn533_cmd), GFP_KERNEL); + if (!cmd) { + rc = -ENOMEM; + goto error; + } + + INIT_LIST_HEAD(&cmd->queue); + cmd->cmd_code = cmd_code; + cmd->req = req; + cmd->resp = resp; + cmd->arg = arg; + + list_add_tail(&cmd->queue, &dev->cmd_queue); + + goto unlock; + +error: + kfree(arg); +unlock: + mutex_unlock(&dev->cmd_lock); + return rc; +} + +static int pn533_send_cmd_async(struct pn533 *dev, u8 cmd_code, + struct sk_buff *req, + pn533_send_async_complete_t complete_cb, + void *complete_cb_context) +{ + struct sk_buff *resp; + int rc; + + nfc_dev_dbg(&dev->interface->dev, "%s", __func__); + + resp = alloc_skb(PN533_NORMAL_FRAME_MAX_LEN, GFP_KERNEL); + if (!resp) + return -ENOMEM; + + rc = __pn533_send_async(dev, cmd_code, req, resp, + PN533_NORMAL_FRAME_MAX_LEN, + complete_cb, complete_cb_context); + if (rc) + dev_kfree_skb(resp); + + return rc; +} + static void pn533_wq_cmd(struct work_struct *work) { struct pn533 *dev = container_of(work, struct pn533, cmd_work); @@ -697,9 +849,17 @@ static void pn533_wq_cmd(struct work_struct *work) mutex_unlock(&dev->cmd_lock); - __pn533_send_cmd_frame_async(dev, cmd->out_frame, cmd->in_frame, - cmd->in_frame_len, cmd->cmd_complete, - cmd->arg); + if (cmd->cmd_code != PN533_CMD_UNDEF) + __pn533_send_cmd_frame_async(dev, + (struct pn533_frame *)cmd->req->data, + (struct pn533_frame *)cmd->resp->data, + PN533_NORMAL_FRAME_MAX_LEN, + pn533_send_async_complete, + cmd->arg); + else + __pn533_send_cmd_frame_async(dev, cmd->out_frame, cmd->in_frame, + cmd->in_frame_len, + cmd->cmd_complete, cmd->arg); kfree(cmd); } @@ -740,6 +900,7 @@ static int pn533_send_cmd_frame_async(struct pn533 *dev, cmd->out_frame = out_frame; cmd->in_frame = in_frame; cmd->in_frame_len = in_frame_len; + cmd->cmd_code = PN533_CMD_UNDEF; cmd->cmd_complete = cmd_complete; cmd->arg = arg; -- cgit v1.2.3-18-g5258 From 15461aeb53ae2d3bbde6b374de913e3df81d1ad0 Mon Sep 17 00:00:00 2001 From: Waldemar Rymarkiewicz Date: Mon, 26 Nov 2012 14:18:35 +0100 Subject: NFC: pn533: Add a new pn533_send_data_async iface This iface is intended to be used with DEP transfers. It differs from pn533_send_cmd_async() in the way the response skb is allocated. Signed-off-by: Waldemar Rymarkiewicz Signed-off-by: Samuel Ortiz --- drivers/nfc/pn533.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'drivers/nfc') diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c index 89f747479a4..0e9bf9dfbbb 100644 --- a/drivers/nfc/pn533.c +++ b/drivers/nfc/pn533.c @@ -86,6 +86,12 @@ MODULE_DEVICE_TABLE(usb, pn533_table); + 2) /* data[0] TFI, data[1] CC */ #define PN533_FRAME_TAIL_LEN 2 /* data[len] DCS, data[len + 1] postamble*/ +/* + * Max extended frame payload len, excluding TFI and CC + * which are already in PN533_FRAME_HEADER_LEN. + */ +#define PN533_FRAME_MAX_PAYLOAD_LEN 263 + #define PN533_FRAME_SIZE(f) (sizeof(struct pn533_frame) + f->datalen + \ PN533_FRAME_TAIL_LEN) #define PN533_FRAME_ACK_SIZE (sizeof(struct pn533_frame) + 1) @@ -807,6 +813,31 @@ unlock: return rc; } +static int pn533_send_data_async(struct pn533 *dev, u8 cmd_code, + struct sk_buff *req, + pn533_send_async_complete_t complete_cb, + void *complete_cb_context) +{ + struct sk_buff *resp; + int rc; + int resp_len = PN533_FRAME_HEADER_LEN + + PN533_FRAME_MAX_PAYLOAD_LEN + + PN533_FRAME_TAIL_LEN; + + nfc_dev_dbg(&dev->interface->dev, "%s", __func__); + + resp = nfc_alloc_recv_skb(resp_len, GFP_KERNEL); + if (!resp) + return -ENOMEM; + + rc = __pn533_send_async(dev, cmd_code, req, resp, resp_len, complete_cb, + complete_cb_context); + if (rc) + dev_kfree_skb(resp); + + return rc; +} + static int pn533_send_cmd_async(struct pn533 *dev, u8 cmd_code, struct sk_buff *req, pn533_send_async_complete_t complete_cb, -- cgit v1.2.3-18-g5258 From 94c5c1561dde894766b1a9135e47b056fdbe13a4 Mon Sep 17 00:00:00 2001 From: Waldemar Rymarkiewicz Date: Mon, 26 Nov 2012 14:18:36 +0100 Subject: NFC: pn533: Add a new pn533_send_sync iface It is intended to replace pn533_send_cmd_frame_sync() iface which requires from the caller to create complete frame. The new function constructs a complete frame itself and sends it out in sync manner. This way frame logic is hidden from the caller. pn533_send_cmd_sync() returns ERR_PTR in case of an error or a pointer to valid response sk_buff otherwise. The pointer must be freed by the caller when it's been consumed. Signed-off-by: Waldemar Rymarkiewicz Signed-off-by: Samuel Ortiz --- drivers/nfc/pn533.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) (limited to 'drivers/nfc') diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c index 0e9bf9dfbbb..94c88bb601c 100644 --- a/drivers/nfc/pn533.c +++ b/drivers/nfc/pn533.c @@ -945,6 +945,7 @@ unlock: struct pn533_sync_cmd_response { int rc; + struct sk_buff *resp; struct completion done; }; @@ -965,6 +966,58 @@ static int pn533_sync_cmd_complete(struct pn533 *dev, void *_arg, return 0; } +static int pn533_send_sync_complete(struct pn533 *dev, void *_arg, + struct sk_buff *resp) +{ + struct pn533_sync_cmd_response *arg = _arg; + + nfc_dev_dbg(&dev->interface->dev, "%s", __func__); + + arg->resp = resp; + complete(&arg->done); + + return 0; +} + +/* pn533_send_cmd_sync + * + * Please note the req parameter is freed inside the function to + * limit a number of return value interpretations by the caller. + * + * 1. negative in case of error during TX path -> req should be freed + * + * 2. negative in case of error during RX path -> req should not be freed + * as it's been already freed at the begining of RX path by + * async_complete_cb. + * + * 3. valid pointer in case of succesfult RX path + * + * A caller has to check a return value with IS_ERR macro. If the test pass, + * the returned pointer is valid. + * + * */ +static struct sk_buff *pn533_send_cmd_sync(struct pn533 *dev, u8 cmd_code, + struct sk_buff *req) +{ + int rc; + struct pn533_sync_cmd_response arg; + + nfc_dev_dbg(&dev->interface->dev, "%s", __func__); + + init_completion(&arg.done); + + rc = pn533_send_cmd_async(dev, cmd_code, req, + pn533_send_sync_complete, &arg); + if (rc) { + dev_kfree_skb(req); + return ERR_PTR(rc); + } + + wait_for_completion(&arg.done); + + return arg.resp; +} + static int pn533_send_cmd_frame_sync(struct pn533 *dev, struct pn533_frame *out_frame, struct pn533_frame *in_frame, @@ -2432,7 +2485,7 @@ static int pn533_fw_reset(struct pn533 *dev) rc = pn533_send_cmd_frame_sync(dev, dev->out_frame, dev->in_frame, PN533_NORMAL_FRAME_MAX_LEN); - return rc; + return 0; } static struct nfc_ops pn533_nfc_ops = { -- cgit v1.2.3-18-g5258 From d22b2db69035ae3b8f71a58dfe0bd10ae1ee58d5 Mon Sep 17 00:00:00 2001 From: Waldemar Rymarkiewicz Date: Mon, 26 Nov 2012 14:18:37 +0100 Subject: NFC: pn533: Add pn533_alloc_skb for req allocation Allocate sk_buff for the request. Signed-off-by: Waldemar Rymarkiewicz Signed-off-by: Samuel Ortiz --- drivers/nfc/pn533.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) (limited to 'drivers/nfc') diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c index 94c88bb601c..c34acd0dc5f 100644 --- a/drivers/nfc/pn533.c +++ b/drivers/nfc/pn533.c @@ -1062,6 +1062,20 @@ static void pn533_send_complete(struct urb *urb) } } +static struct sk_buff *pn533_alloc_skb(unsigned int size) +{ + struct sk_buff *skb; + + skb = alloc_skb(PN533_FRAME_HEADER_LEN + + size + + PN533_FRAME_TAIL_LEN, GFP_KERNEL); + + if (skb) + skb_reserve(skb, PN533_FRAME_HEADER_LEN); + + return skb; +} + struct pn533_target_type_a { __be16 sens_res; u8 sel_res; @@ -2390,15 +2404,11 @@ static void pn533_wq_mi_recv(struct work_struct *work) nfc_dev_dbg(&dev->interface->dev, "%s", __func__); /* This is a zero payload size skb */ - skb_cmd = alloc_skb(PN533_FRAME_HEADER_LEN + - PN533_CMD_DATAEXCH_HEAD_LEN + - PN533_FRAME_TAIL_LEN, - GFP_KERNEL); + skb_cmd = pn533_alloc_skb(PN533_CMD_DATAEXCH_HEAD_LEN); if (skb_cmd == NULL) goto error_cmd; - skb_reserve(skb_cmd, - PN533_FRAME_HEADER_LEN + PN533_CMD_DATAEXCH_HEAD_LEN); + skb_reserve(skb_cmd, PN533_CMD_DATAEXCH_HEAD_LEN); rc = pn533_build_tx_frame(dev, skb_cmd, true); if (rc) -- cgit v1.2.3-18-g5258 From cb950d9304b2965bef07e26d6c0eb34a0b1f75fe Mon Sep 17 00:00:00 2001 From: Waldemar Rymarkiewicz Date: Mon, 26 Nov 2012 14:18:38 +0100 Subject: NFC: pn533: Remove pn533_send_cmd_frame_sync Remove obsolate pn533_send_cmd_frame_sync() and use previously added new iface for sync send. The new interface require the use of individual skb for each cmd which removes some memcpy calls and hides frame logic. Signed-off-by: Waldemar Rymarkiewicz Signed-off-by: Samuel Ortiz --- drivers/nfc/pn533.c | 197 +++++++++++++++++++++++----------------------------- 1 file changed, 85 insertions(+), 112 deletions(-) (limited to 'drivers/nfc') diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c index c34acd0dc5f..e5615f538aa 100644 --- a/drivers/nfc/pn533.c +++ b/drivers/nfc/pn533.c @@ -286,11 +286,6 @@ const struct pn533_poll_modulations poll_mod[] = { /* PN533_CMD_IN_ATR */ -struct pn533_cmd_activate_param { - u8 tg; - u8 next; -} __packed; - struct pn533_cmd_activate_response { u8 status; u8 nfcid3t[10]; @@ -944,28 +939,10 @@ unlock: } struct pn533_sync_cmd_response { - int rc; struct sk_buff *resp; struct completion done; }; -static int pn533_sync_cmd_complete(struct pn533 *dev, void *_arg, - u8 *params, int params_len) -{ - struct pn533_sync_cmd_response *arg = _arg; - - nfc_dev_dbg(&dev->interface->dev, "%s", __func__); - - arg->rc = 0; - - if (params_len < 0) /* error */ - arg->rc = params_len; - - complete(&arg->done); - - return 0; -} - static int pn533_send_sync_complete(struct pn533 *dev, void *_arg, struct sk_buff *resp) { @@ -1018,28 +995,6 @@ static struct sk_buff *pn533_send_cmd_sync(struct pn533 *dev, u8 cmd_code, return arg.resp; } -static int pn533_send_cmd_frame_sync(struct pn533 *dev, - struct pn533_frame *out_frame, - struct pn533_frame *in_frame, - int in_frame_len) -{ - int rc; - struct pn533_sync_cmd_response arg; - - nfc_dev_dbg(&dev->interface->dev, "%s", __func__); - - init_completion(&arg.done); - - rc = pn533_send_cmd_frame_async(dev, out_frame, in_frame, in_frame_len, - pn533_sync_cmd_complete, &arg); - if (rc) - return rc; - - wait_for_completion(&arg.done); - - return arg.rc; -} - static void pn533_send_complete(struct urb *urb) { struct pn533 *dev = urb->context; @@ -1801,38 +1756,37 @@ static void pn533_stop_poll(struct nfc_dev *nfc_dev) static int pn533_activate_target_nfcdep(struct pn533 *dev) { - struct pn533_cmd_activate_param param; - struct pn533_cmd_activate_response *resp; + struct pn533_cmd_activate_response *rsp; u16 gt_len; int rc; - nfc_dev_dbg(&dev->interface->dev, "%s", __func__); + struct sk_buff *skb; + struct sk_buff *resp; - pn533_tx_frame_init(dev->out_frame, PN533_CMD_IN_ATR); + nfc_dev_dbg(&dev->interface->dev, "%s", __func__); - param.tg = 1; - param.next = 0; - memcpy(PN533_FRAME_CMD_PARAMS_PTR(dev->out_frame), ¶m, - sizeof(struct pn533_cmd_activate_param)); - dev->out_frame->datalen += sizeof(struct pn533_cmd_activate_param); + skb = pn533_alloc_skb(sizeof(u8) * 2); /*TG + Next*/ + if (!skb) + return -ENOMEM; - pn533_tx_frame_finish(dev->out_frame); + *skb_put(skb, sizeof(u8)) = 1; /* TG */ + *skb_put(skb, sizeof(u8)) = 0; /* Next */ - rc = pn533_send_cmd_frame_sync(dev, dev->out_frame, dev->in_frame, - PN533_NORMAL_FRAME_MAX_LEN); - if (rc) - return rc; + resp = pn533_send_cmd_sync(dev, PN533_CMD_IN_ATR, skb); + if (IS_ERR(resp)) + return PTR_ERR(resp); - resp = (struct pn533_cmd_activate_response *) - PN533_FRAME_CMD_PARAMS_PTR(dev->in_frame); - rc = resp->status & PN533_CMD_RET_MASK; + rsp = (struct pn533_cmd_activate_response *) resp->data; + rc = rsp->status & PN533_CMD_RET_MASK; if (rc != PN533_CMD_RET_SUCCESS) + dev_kfree_skb(resp); return -EIO; /* ATR_RES general bytes are located at offset 16 */ - gt_len = PN533_FRAME_CMD_PARAMS_LEN(dev->in_frame) - 16; - rc = nfc_set_remote_general_bytes(dev->nfc_dev, resp->gt, gt_len); + gt_len = resp->len - 16; + rc = nfc_set_remote_general_bytes(dev->nfc_dev, rsp->gt, gt_len); + dev_kfree_skb(resp); return rc; } @@ -1889,8 +1843,10 @@ static void pn533_deactivate_target(struct nfc_dev *nfc_dev, struct nfc_target *target) { struct pn533 *dev = nfc_get_drvdata(nfc_dev); - u8 tg; - u8 status; + + struct sk_buff *skb; + struct sk_buff *resp; + int rc; nfc_dev_dbg(&dev->interface->dev, "%s", __func__); @@ -1901,31 +1857,24 @@ static void pn533_deactivate_target(struct nfc_dev *nfc_dev, } dev->tgt_active_prot = 0; - skb_queue_purge(&dev->resp_q); - pn533_tx_frame_init(dev->out_frame, PN533_CMD_IN_RELEASE); - - tg = 1; - memcpy(PN533_FRAME_CMD_PARAMS_PTR(dev->out_frame), &tg, sizeof(u8)); - dev->out_frame->datalen += sizeof(u8); + skb = pn533_alloc_skb(sizeof(u8)); + if (!skb) + return; - pn533_tx_frame_finish(dev->out_frame); + *skb_put(skb, 1) = 1; /* TG*/ - rc = pn533_send_cmd_frame_sync(dev, dev->out_frame, dev->in_frame, - PN533_NORMAL_FRAME_MAX_LEN); - if (rc) { - nfc_dev_err(&dev->interface->dev, "Error when sending release" - " command to the controller"); + resp = pn533_send_cmd_sync(dev, PN533_CMD_IN_RELEASE, skb); + if (IS_ERR(resp)) return; - } - status = PN533_FRAME_CMD_PARAMS_PTR(dev->in_frame)[0]; - rc = status & PN533_CMD_RET_MASK; + rc = resp->data[0] & PN533_CMD_RET_MASK; if (rc != PN533_CMD_RET_SUCCESS) nfc_dev_err(&dev->interface->dev, "Error 0x%x when releasing" " the target", rc); + dev_kfree_skb(resp); return; } @@ -2457,43 +2406,71 @@ error_cmd: static int pn533_set_configuration(struct pn533 *dev, u8 cfgitem, u8 *cfgdata, u8 cfgdata_len) { - int rc; - u8 *params; + struct sk_buff *skb; + struct sk_buff *resp; + + int skb_len; nfc_dev_dbg(&dev->interface->dev, "%s", __func__); - pn533_tx_frame_init(dev->out_frame, PN533_CMD_RF_CONFIGURATION); + skb_len = sizeof(cfgitem) + cfgdata_len; /* cfgitem + cfgdata */ - params = PN533_FRAME_CMD_PARAMS_PTR(dev->out_frame); - params[0] = cfgitem; - memcpy(¶ms[1], cfgdata, cfgdata_len); - dev->out_frame->datalen += (1 + cfgdata_len); + skb = pn533_alloc_skb(skb_len); + if (!skb) + return -ENOMEM; - pn533_tx_frame_finish(dev->out_frame); + *skb_put(skb, sizeof(cfgitem)) = cfgitem; + memcpy(skb_put(skb, cfgdata_len), cfgdata, cfgdata_len); - rc = pn533_send_cmd_frame_sync(dev, dev->out_frame, dev->in_frame, - PN533_NORMAL_FRAME_MAX_LEN); + resp = pn533_send_cmd_sync(dev, PN533_CMD_RF_CONFIGURATION, skb); + if (IS_ERR(resp)) + return PTR_ERR(resp); - return rc; + dev_kfree_skb(resp); + return 0; +} + +static int pn533_get_firmware_version(struct pn533 *dev, + struct pn533_fw_version *fv) +{ + struct sk_buff *skb; + struct sk_buff *resp; + + skb = pn533_alloc_skb(0); + if (!skb) + return -ENOMEM; + + resp = pn533_send_cmd_sync(dev, PN533_CMD_GET_FIRMWARE_VERSION, skb); + if (IS_ERR(resp)) + return PTR_ERR(resp); + + fv->ic = resp->data[0]; + fv->ver = resp->data[1]; + fv->rev = resp->data[2]; + fv->support = resp->data[3]; + + dev_kfree_skb(resp); + return 0; } static int pn533_fw_reset(struct pn533 *dev) { - int rc; - u8 *params; + struct sk_buff *skb; + struct sk_buff *resp; nfc_dev_dbg(&dev->interface->dev, "%s", __func__); - pn533_tx_frame_init(dev->out_frame, 0x18); + skb = pn533_alloc_skb(sizeof(u8)); + if (!skb) + return -ENOMEM; - params = PN533_FRAME_CMD_PARAMS_PTR(dev->out_frame); - params[0] = 0x1; - dev->out_frame->datalen += 1; + *skb_put(skb, sizeof(u8)) = 0x1; - pn533_tx_frame_finish(dev->out_frame); + resp = pn533_send_cmd_sync(dev, 0x18, skb); + if (IS_ERR(resp)) + return PTR_ERR(resp); - rc = pn533_send_cmd_frame_sync(dev, dev->out_frame, dev->in_frame, - PN533_NORMAL_FRAME_MAX_LEN); + dev_kfree_skb(resp); return 0; } @@ -2592,7 +2569,7 @@ static int pn533_setup(struct pn533 *dev) static int pn533_probe(struct usb_interface *interface, const struct usb_device_id *id) { - struct pn533_fw_version *fw_ver; + struct pn533_fw_version fw_ver; struct pn533 *dev; struct usb_host_interface *iface_desc; struct usb_endpoint_descriptor *endpoint; @@ -2664,18 +2641,14 @@ static int pn533_probe(struct usb_interface *interface, usb_set_intfdata(interface, dev); - pn533_tx_frame_init(dev->out_frame, PN533_CMD_GET_FIRMWARE_VERSION); - pn533_tx_frame_finish(dev->out_frame); - - rc = pn533_send_cmd_frame_sync(dev, dev->out_frame, dev->in_frame, - PN533_NORMAL_FRAME_MAX_LEN); - if (rc) + memset(&fw_ver, 0, sizeof(fw_ver)); + rc = pn533_get_firmware_version(dev, &fw_ver); + if (rc < 0) goto destroy_wq; - fw_ver = (struct pn533_fw_version *) - PN533_FRAME_CMD_PARAMS_PTR(dev->in_frame); - nfc_dev_info(&dev->interface->dev, "NXP PN533 firmware ver %d.%d now" - " attached", fw_ver->ver, fw_ver->rev); + nfc_dev_info(&dev->interface->dev, + "NXP PN533 firmware ver %d.%d now attached", + fw_ver.ver, fw_ver.rev); dev->device_type = id->driver_info; switch (dev->device_type) { -- cgit v1.2.3-18-g5258 From e487882345a80a17b534182ab1f259f2321e4fed Mon Sep 17 00:00:00 2001 From: Waldemar Rymarkiewicz Date: Mon, 10 Dec 2012 14:42:44 +0100 Subject: NFC: pn533: Del frame logic from TgGet/SetData cmd Remove frame logic from TgSetData and TgGetData commands using the new iface for async send. Signed-off-by: Waldemar Rymarkiewicz Signed-off-by: Samuel Ortiz --- drivers/nfc/pn533.c | 97 ++++++++++++++++++----------------------------------- 1 file changed, 33 insertions(+), 64 deletions(-) (limited to 'drivers/nfc') diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c index e5615f538aa..9912824030f 100644 --- a/drivers/nfc/pn533.c +++ b/drivers/nfc/pn533.c @@ -1450,65 +1450,46 @@ static int pn533_init_target_frame(struct pn533_frame *frame, #define PN533_CMD_DATAEXCH_HEAD_LEN 1 #define PN533_CMD_DATAEXCH_DATA_MAXLEN 262 static int pn533_tm_get_data_complete(struct pn533 *dev, void *arg, - u8 *params, int params_len) + struct sk_buff *resp) { - struct sk_buff *skb_resp = arg; - struct pn533_frame *in_frame = (struct pn533_frame *) skb_resp->data; + u8 status; nfc_dev_dbg(&dev->interface->dev, "%s", __func__); - if (params_len < 0) { - nfc_dev_err(&dev->interface->dev, - "Error %d when starting as a target", - params_len); + if (IS_ERR(resp)) + return PTR_ERR(resp); - return params_len; - } + status = resp->data[0]; + skb_pull(resp, sizeof(status)); - if (params_len > 0 && params[0] != 0) { + if (status != 0) { nfc_tm_deactivated(dev->nfc_dev); - dev->tgt_mode = 0; - - kfree_skb(skb_resp); + dev_kfree_skb(resp); return 0; } - skb_put(skb_resp, PN533_FRAME_SIZE(in_frame)); - skb_pull(skb_resp, - PN533_FRAME_HEADER_LEN + PN533_CMD_DATAEXCH_HEAD_LEN); - skb_trim(skb_resp, skb_resp->len - PN533_FRAME_TAIL_LEN); - - return nfc_tm_data_received(dev->nfc_dev, skb_resp); + return nfc_tm_data_received(dev->nfc_dev, resp); } static void pn533_wq_tg_get_data(struct work_struct *work) { struct pn533 *dev = container_of(work, struct pn533, tg_work); - struct pn533_frame *in_frame; - struct sk_buff *skb_resp; - size_t skb_resp_len; - nfc_dev_dbg(&dev->interface->dev, "%s", __func__); + struct sk_buff *skb; + int rc; - skb_resp_len = PN533_FRAME_HEADER_LEN + - PN533_CMD_DATAEXCH_HEAD_LEN + - PN533_CMD_DATAEXCH_DATA_MAXLEN + - PN533_FRAME_TAIL_LEN; + nfc_dev_dbg(&dev->interface->dev, "%s", __func__); - skb_resp = nfc_alloc_recv_skb(skb_resp_len, GFP_KERNEL); - if (!skb_resp) + skb = pn533_alloc_skb(0); + if (!skb) return; - in_frame = (struct pn533_frame *)skb_resp->data; - - pn533_tx_frame_init(dev->out_frame, PN533_CMD_TG_GET_DATA); - pn533_tx_frame_finish(dev->out_frame); + rc = pn533_send_data_async(dev, PN533_CMD_TG_GET_DATA, skb, + pn533_tm_get_data_complete, NULL); - pn533_send_cmd_frame_async(dev, dev->out_frame, in_frame, - skb_resp_len, - pn533_tm_get_data_complete, - skb_resp); + if (rc < 0) + dev_kfree_skb(skb); return; } @@ -2280,23 +2261,20 @@ error: } static int pn533_tm_send_complete(struct pn533 *dev, void *arg, - u8 *params, int params_len) + struct sk_buff *resp) { - struct sk_buff *skb_out = arg; + u8 status; nfc_dev_dbg(&dev->interface->dev, "%s", __func__); - dev_kfree_skb(skb_out); + if (IS_ERR(resp)) + return PTR_ERR(resp); - if (params_len < 0) { - nfc_dev_err(&dev->interface->dev, - "Error %d when sending data", - params_len); + status = resp->data[0]; - return params_len; - } + dev_kfree_skb(resp); - if (params_len > 0 && params[0] != 0) { + if (status != 0) { nfc_tm_deactivated(dev->nfc_dev); dev->tgt_mode = 0; @@ -2312,30 +2290,21 @@ static int pn533_tm_send_complete(struct pn533 *dev, void *arg, static int pn533_tm_send(struct nfc_dev *nfc_dev, struct sk_buff *skb) { struct pn533 *dev = nfc_get_drvdata(nfc_dev); - struct pn533_frame *out_frame; int rc; nfc_dev_dbg(&dev->interface->dev, "%s", __func__); - rc = pn533_build_tx_frame(dev, skb, false); - if (rc) - goto error; - - out_frame = (struct pn533_frame *) skb->data; - - rc = pn533_send_cmd_frame_async(dev, out_frame, dev->in_frame, - PN533_NORMAL_FRAME_MAX_LEN, - pn533_tm_send_complete, skb); - if (rc) { + if (skb->len > PN533_CMD_DATAEXCH_DATA_MAXLEN) { nfc_dev_err(&dev->interface->dev, - "Error %d when trying to send data", rc); - goto error; + "Data length greater than the max allowed: %d", + PN533_CMD_DATAEXCH_DATA_MAXLEN); + return -ENOSYS; } - return 0; - -error: - kfree_skb(skb); + rc = pn533_send_data_async(dev, PN533_CMD_TG_SET_DATA, skb, + pn533_tm_send_complete, NULL); + if (rc < 0) + dev_kfree_skb(skb); return rc; } -- cgit v1.2.3-18-g5258 From 13003649b1ebb4ea51341a9405a2ec5b10cf4f7e Mon Sep 17 00:00:00 2001 From: Waldemar Rymarkiewicz Date: Mon, 10 Dec 2012 14:42:45 +0100 Subject: NFC: pn533: Del frame logic from InJumForDep cmd Remove frame logic from InJmumpForDEP command using the new iface for async send. Signed-off-by: Waldemar Rymarkiewicz Signed-off-by: Samuel Ortiz --- drivers/nfc/pn533.c | 117 ++++++++++++++++++++++++---------------------------- 1 file changed, 55 insertions(+), 62 deletions(-) (limited to 'drivers/nfc') diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c index 9912824030f..aa7803f1677 100644 --- a/drivers/nfc/pn533.c +++ b/drivers/nfc/pn533.c @@ -298,14 +298,6 @@ struct pn533_cmd_activate_response { u8 gt[]; } __packed; -/* PN533_CMD_IN_JUMP_FOR_DEP */ -struct pn533_cmd_jump_dep { - u8 active; - u8 baud; - u8 next; - u8 data[]; -} __packed; - struct pn533_cmd_jump_dep_response { u8 status; u8 tg; @@ -1861,53 +1853,46 @@ static void pn533_deactivate_target(struct nfc_dev *nfc_dev, static int pn533_in_dep_link_up_complete(struct pn533 *dev, void *arg, - u8 *params, int params_len) + struct sk_buff *resp) { - struct pn533_cmd_jump_dep_response *resp; - struct nfc_target nfc_target; + struct pn533_cmd_jump_dep_response *rsp; u8 target_gt_len; int rc; - struct pn533_cmd_jump_dep *cmd = (struct pn533_cmd_jump_dep *)arg; - u8 active = cmd->active; + u8 active = *(u8 *)arg; kfree(arg); - if (params_len == -ENOENT) { - nfc_dev_dbg(&dev->interface->dev, ""); - return 0; - } - - if (params_len < 0) { - nfc_dev_err(&dev->interface->dev, - "Error %d when bringing DEP link up", - params_len); - return 0; - } + if (IS_ERR(resp)) + return PTR_ERR(resp); if (dev->tgt_available_prots && !(dev->tgt_available_prots & (1 << NFC_PROTO_NFC_DEP))) { nfc_dev_err(&dev->interface->dev, "The target does not support DEP"); - return -EINVAL; + rc = -EINVAL; + goto error; } - resp = (struct pn533_cmd_jump_dep_response *) params; - rc = resp->status & PN533_CMD_RET_MASK; + rsp = (struct pn533_cmd_jump_dep_response *)resp->data; + + rc = rsp->status & PN533_CMD_RET_MASK; if (rc != PN533_CMD_RET_SUCCESS) { nfc_dev_err(&dev->interface->dev, "Bringing DEP link up failed %d", rc); - return 0; + goto error; } if (!dev->tgt_available_prots) { + struct nfc_target nfc_target; + nfc_dev_dbg(&dev->interface->dev, "Creating new target"); nfc_target.supported_protocols = NFC_PROTO_NFC_DEP_MASK; nfc_target.nfcid1_len = 10; - memcpy(nfc_target.nfcid1, resp->nfcid3t, nfc_target.nfcid1_len); + memcpy(nfc_target.nfcid1, rsp->nfcid3t, nfc_target.nfcid1_len); rc = nfc_targets_found(dev->nfc_dev, &nfc_target, 1); if (rc) - return 0; + goto error; dev->tgt_available_prots = 0; } @@ -1915,15 +1900,17 @@ static int pn533_in_dep_link_up_complete(struct pn533 *dev, void *arg, dev->tgt_active_prot = NFC_PROTO_NFC_DEP; /* ATR_RES general bytes are located at offset 17 */ - target_gt_len = PN533_FRAME_CMD_PARAMS_LEN(dev->in_frame) - 17; + target_gt_len = resp->len - 17; rc = nfc_set_remote_general_bytes(dev->nfc_dev, - resp->gt, target_gt_len); + rsp->gt, target_gt_len); if (rc == 0) rc = nfc_dep_link_is_up(dev->nfc_dev, - dev->nfc_dev->targets[0].idx, - !active, NFC_RF_INITIATOR); + dev->nfc_dev->targets[0].idx, + !active, NFC_RF_INITIATOR); - return 0; +error: + dev_kfree_skb(resp); + return rc; } static int pn533_mod_to_baud(struct pn533 *dev) @@ -1945,10 +1932,11 @@ static int pn533_dep_link_up(struct nfc_dev *nfc_dev, struct nfc_target *target, u8 comm_mode, u8* gb, size_t gb_len) { struct pn533 *dev = nfc_get_drvdata(nfc_dev); - struct pn533_cmd_jump_dep *cmd; - u8 cmd_len, *data_ptr; + struct sk_buff *skb; + int rc, baud, skb_len; + u8 *next, *arg; + u8 passive_data[PASSIVE_DATA_LEN] = {0x00, 0xff, 0xff, 0x00, 0x3}; - int rc, baud; nfc_dev_dbg(&dev->interface->dev, "%s", __func__); @@ -1971,43 +1959,48 @@ static int pn533_dep_link_up(struct nfc_dev *nfc_dev, struct nfc_target *target, return baud; } - cmd_len = sizeof(struct pn533_cmd_jump_dep) + gb_len; + skb_len = 3 + gb_len; /* ActPass + BR + Next */ if (comm_mode == NFC_COMM_PASSIVE) - cmd_len += PASSIVE_DATA_LEN; + skb_len += PASSIVE_DATA_LEN; - cmd = kzalloc(cmd_len, GFP_KERNEL); - if (cmd == NULL) + skb = pn533_alloc_skb(skb_len); + if (!skb) return -ENOMEM; - pn533_tx_frame_init(dev->out_frame, PN533_CMD_IN_JUMP_FOR_DEP); + *skb_put(skb, 1) = !comm_mode; /* ActPass */ + *skb_put(skb, 1) = baud; /* Baud rate */ + + next = skb_put(skb, 1); /* Next */ + *next = 0; - cmd->active = !comm_mode; - cmd->next = 0; - cmd->baud = baud; - data_ptr = cmd->data; - if (comm_mode == NFC_COMM_PASSIVE && cmd->baud > 0) { - memcpy(data_ptr, passive_data, PASSIVE_DATA_LEN); - cmd->next |= 1; - data_ptr += PASSIVE_DATA_LEN; + if (comm_mode == NFC_COMM_PASSIVE && baud > 0) { + memcpy(skb_put(skb, PASSIVE_DATA_LEN), passive_data, + PASSIVE_DATA_LEN); + *next |= 1; } if (gb != NULL && gb_len > 0) { - cmd->next |= 4; /* We have some Gi */ - memcpy(data_ptr, gb, gb_len); + memcpy(skb_put(skb, gb_len), gb, gb_len); + *next |= 4; /* We have some Gi */ } else { - cmd->next = 0; + *next = 0; } - memcpy(PN533_FRAME_CMD_PARAMS_PTR(dev->out_frame), cmd, cmd_len); - dev->out_frame->datalen += cmd_len; + arg = kmalloc(sizeof(*arg), GFP_KERNEL); + if (!arg) { + dev_kfree_skb(skb); + return -ENOMEM; + } - pn533_tx_frame_finish(dev->out_frame); + *arg = !comm_mode; - rc = pn533_send_cmd_frame_async(dev, dev->out_frame, dev->in_frame, - PN533_NORMAL_FRAME_MAX_LEN, - pn533_in_dep_link_up_complete, cmd); - if (rc < 0) - kfree(cmd); + rc = pn533_send_cmd_async(dev, PN533_CMD_IN_JUMP_FOR_DEP, skb, + pn533_in_dep_link_up_complete, arg); + + if (rc < 0) { + dev_kfree_skb(skb); + kfree(arg); + } return rc; } -- cgit v1.2.3-18-g5258 From b1e666f503b5479efe9adf79fb46f09fe4f04af5 Mon Sep 17 00:00:00 2001 From: Waldemar Rymarkiewicz Date: Mon, 10 Dec 2012 14:42:46 +0100 Subject: NFC: pn533: Del frame logic from Data Exchange cmd Remove frame logic from transceive cb using new iface for async send. For pn533_wq_mi_recv() use pn533_send_cmd_direct_async which sends the cmd directly to the hardware, skipping cmd queue. Signed-off-by: Waldemar Rymarkiewicz Signed-off-by: Samuel Ortiz --- drivers/nfc/pn533.c | 309 ++++++++++++++++++++++++---------------------------- 1 file changed, 141 insertions(+), 168 deletions(-) (limited to 'drivers/nfc') diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c index aa7803f1677..91e1594dfd1 100644 --- a/drivers/nfc/pn533.c +++ b/drivers/nfc/pn533.c @@ -360,6 +360,7 @@ struct pn533 { pn533_cmd_complete_t cmd_complete; void *cmd_complete_arg; + void *cmd_complete_mi_arg; struct mutex cmd_lock; u8 cmd; @@ -848,6 +849,57 @@ static int pn533_send_cmd_async(struct pn533 *dev, u8 cmd_code, return rc; } +/* + * pn533_send_cmd_direct_async + * + * The function sends a piority cmd directly to the chip omiting the cmd + * queue. It's intended to be used by chaining mechanism of received responses + * where the host has to request every single chunk of data before scheduling + * next cmd from the queue. + */ +static int pn533_send_cmd_direct_async(struct pn533 *dev, u8 cmd_code, + struct sk_buff *req, + pn533_send_async_complete_t complete_cb, + void *complete_cb_context) +{ + struct pn533_send_async_complete_arg *arg; + struct sk_buff *resp; + int rc; + int resp_len = PN533_FRAME_HEADER_LEN + + PN533_FRAME_MAX_PAYLOAD_LEN + + PN533_FRAME_TAIL_LEN; + + nfc_dev_dbg(&dev->interface->dev, "%s", __func__); + + resp = alloc_skb(resp_len, GFP_KERNEL); + if (!resp) + return -ENOMEM; + + arg = kzalloc(sizeof(arg), GFP_KERNEL); + if (!arg) { + dev_kfree_skb(resp); + return -ENOMEM; + } + + arg->complete_cb = complete_cb; + arg->complete_cb_context = complete_cb_context; + arg->resp = resp; + arg->req = req; + + pn533_build_cmd_frame(cmd_code, req); + + rc = __pn533_send_cmd_frame_async(dev, (struct pn533_frame *)req->data, + (struct pn533_frame *)resp->data, + resp_len, pn533_send_async_complete, + arg); + if (rc < 0) { + dev_kfree_skb(resp); + kfree(arg); + } + + return rc; +} + static void pn533_wq_cmd(struct work_struct *work) { struct pn533 *dev = container_of(work, struct pn533, cmd_work); @@ -2024,69 +2076,7 @@ static int pn533_dep_link_down(struct nfc_dev *nfc_dev) return 0; } -static int pn533_build_tx_frame(struct pn533 *dev, struct sk_buff *skb, - bool target) -{ - int payload_len = skb->len; - struct pn533_frame *out_frame; - u8 tg; - - nfc_dev_dbg(&dev->interface->dev, "%s - Sending %d bytes", __func__, - payload_len); - - if (payload_len > PN533_CMD_DATAEXCH_DATA_MAXLEN) { - /* TODO: Implement support to multi-part data exchange */ - nfc_dev_err(&dev->interface->dev, "Data length greater than the" - " max allowed: %d", - PN533_CMD_DATAEXCH_DATA_MAXLEN); - return -ENOSYS; - } - - skb_push(skb, PN533_FRAME_HEADER_LEN); - - if (target == true) { - switch (dev->device_type) { - case PN533_DEVICE_PASORI: - if (dev->tgt_active_prot == NFC_PROTO_FELICA) { - out_frame = (struct pn533_frame *) skb->data; - pn533_tx_frame_init(out_frame, - PN533_CMD_IN_COMM_THRU); - - break; - } - - default: - skb_push(skb, PN533_CMD_DATAEXCH_HEAD_LEN); - out_frame = (struct pn533_frame *) skb->data; - pn533_tx_frame_init(out_frame, - PN533_CMD_IN_DATA_EXCHANGE); - tg = 1; - memcpy(PN533_FRAME_CMD_PARAMS_PTR(out_frame), - &tg, sizeof(u8)); - out_frame->datalen += sizeof(u8); - - break; - } - - } else { - skb_push(skb, PN533_CMD_DATAEXCH_HEAD_LEN - 1); - out_frame = (struct pn533_frame *) skb->data; - pn533_tx_frame_init(out_frame, PN533_CMD_TG_SET_DATA); - } - - - /* The data is already in the out_frame, just update the datalen */ - out_frame->datalen += payload_len; - - pn533_tx_frame_finish(out_frame); - skb_put(skb, PN533_FRAME_TAIL_LEN); - - return 0; -} - struct pn533_data_exchange_arg { - struct sk_buff *skb_resp; - struct sk_buff *skb_out; data_exchange_cb_t cb; void *cb_context; }; @@ -2130,47 +2120,44 @@ out: } static int pn533_data_exchange_complete(struct pn533 *dev, void *_arg, - u8 *params, int params_len) + struct sk_buff *resp) { struct pn533_data_exchange_arg *arg = _arg; - struct sk_buff *skb = NULL, *skb_resp = arg->skb_resp; - struct pn533_frame *in_frame = (struct pn533_frame *) skb_resp->data; - int err = 0; - u8 status; - u8 cmd_ret; + struct sk_buff *skb; + int rc = 0; + u8 status, ret, mi; nfc_dev_dbg(&dev->interface->dev, "%s", __func__); - dev_kfree_skb(arg->skb_out); - - if (params_len < 0) { /* error */ - err = params_len; - goto error; + if (IS_ERR(resp)) { + rc = PTR_ERR(resp); + goto _error; } - status = params[0]; + status = resp->data[0]; + ret = status & PN533_CMD_RET_MASK; + mi = status & PN533_CMD_MI_MASK; + + skb_pull(resp, sizeof(status)); - cmd_ret = status & PN533_CMD_RET_MASK; - if (cmd_ret != PN533_CMD_RET_SUCCESS) { - nfc_dev_err(&dev->interface->dev, "PN533 reported error %d when" - " exchanging data", cmd_ret); - err = -EIO; + if (ret != PN533_CMD_RET_SUCCESS) { + nfc_dev_err(&dev->interface->dev, + "PN533 reported error %d when exchanging data", + ret); + rc = -EIO; goto error; } - skb_put(skb_resp, PN533_FRAME_SIZE(in_frame)); - skb_pull(skb_resp, PN533_FRAME_HEADER_LEN); - skb_pull(skb_resp, PN533_CMD_DATAEXCH_HEAD_LEN); - skb_trim(skb_resp, skb_resp->len - PN533_FRAME_TAIL_LEN); - skb_queue_tail(&dev->resp_q, skb_resp); + skb_queue_tail(&dev->resp_q, resp); - if (status & PN533_CMD_MI_MASK) { + if (mi) { + dev->cmd_complete_mi_arg = arg; queue_work(dev->wq, &dev->mi_work); return -EINPROGRESS; } skb = pn533_build_response(dev); - if (skb == NULL) + if (!skb) goto error; arg->cb(arg->cb_context, skb, 0); @@ -2178,11 +2165,12 @@ static int pn533_data_exchange_complete(struct pn533 *dev, void *_arg, return 0; error: + dev_kfree_skb(resp); +_error: skb_queue_purge(&dev->resp_q); - dev_kfree_skb(skb_resp); - arg->cb(arg->cb_context, NULL, err); + arg->cb(arg->cb_context, NULL, rc); kfree(arg); - return 0; + return rc; } static int pn533_transceive(struct nfc_dev *nfc_dev, @@ -2190,14 +2178,20 @@ static int pn533_transceive(struct nfc_dev *nfc_dev, data_exchange_cb_t cb, void *cb_context) { struct pn533 *dev = nfc_get_drvdata(nfc_dev); - struct pn533_frame *out_frame, *in_frame; - struct pn533_data_exchange_arg *arg; - struct sk_buff *skb_resp; - int skb_resp_len; + struct pn533_data_exchange_arg *arg = NULL; int rc; nfc_dev_dbg(&dev->interface->dev, "%s", __func__); + if (skb->len > PN533_CMD_DATAEXCH_DATA_MAXLEN) { + /* TODO: Implement support to multi-part data exchange */ + nfc_dev_err(&dev->interface->dev, + "Data length greater than the max allowed: %d", + PN533_CMD_DATAEXCH_DATA_MAXLEN); + rc = -ENOSYS; + goto error; + } + if (!dev->tgt_active_prot) { nfc_dev_err(&dev->interface->dev, "Cannot exchange data if" " there is no active target"); @@ -2205,51 +2199,43 @@ static int pn533_transceive(struct nfc_dev *nfc_dev, goto error; } - rc = pn533_build_tx_frame(dev, skb, true); - if (rc) - goto error; - - skb_resp_len = PN533_FRAME_HEADER_LEN + - PN533_CMD_DATAEXCH_HEAD_LEN + - PN533_CMD_DATAEXCH_DATA_MAXLEN + - PN533_FRAME_TAIL_LEN; - - skb_resp = nfc_alloc_recv_skb(skb_resp_len, GFP_KERNEL); - if (!skb_resp) { - rc = -ENOMEM; - goto error; - } - - in_frame = (struct pn533_frame *) skb_resp->data; - out_frame = (struct pn533_frame *) skb->data; - - arg = kmalloc(sizeof(struct pn533_data_exchange_arg), GFP_KERNEL); + arg = kmalloc(sizeof(*arg), GFP_KERNEL); if (!arg) { rc = -ENOMEM; - goto free_skb_resp; + goto error; } - arg->skb_resp = skb_resp; - arg->skb_out = skb; arg->cb = cb; arg->cb_context = cb_context; - rc = pn533_send_cmd_frame_async(dev, out_frame, in_frame, skb_resp_len, - pn533_data_exchange_complete, arg); - if (rc) { - nfc_dev_err(&dev->interface->dev, "Error %d when trying to" - " perform data_exchange", rc); - goto free_arg; + 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; + } + default: + *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; -free_arg: - kfree(arg); -free_skb_resp: - kfree_skb(skb_resp); error: - kfree_skb(skb); + kfree(arg); + dev_kfree_skb(skb); return rc; } @@ -2305,63 +2291,50 @@ static int pn533_tm_send(struct nfc_dev *nfc_dev, struct sk_buff *skb) static void pn533_wq_mi_recv(struct work_struct *work) { struct pn533 *dev = container_of(work, struct pn533, mi_work); - struct sk_buff *skb_cmd; - struct pn533_data_exchange_arg *arg = dev->cmd_complete_arg; - struct pn533_frame *out_frame, *in_frame; - struct sk_buff *skb_resp; - int skb_resp_len; + + struct sk_buff *skb; int rc; nfc_dev_dbg(&dev->interface->dev, "%s", __func__); - /* This is a zero payload size skb */ - skb_cmd = pn533_alloc_skb(PN533_CMD_DATAEXCH_HEAD_LEN); - if (skb_cmd == NULL) - goto error_cmd; + skb = pn533_alloc_skb(PN533_CMD_DATAEXCH_HEAD_LEN); + if (!skb) + goto error; - skb_reserve(skb_cmd, PN533_CMD_DATAEXCH_HEAD_LEN); + switch (dev->device_type) { + case PN533_DEVICE_PASORI: + if (dev->tgt_active_prot == NFC_PROTO_FELICA) { + rc = pn533_send_cmd_direct_async(dev, + PN533_CMD_IN_COMM_THRU, + skb, + pn533_data_exchange_complete, + dev->cmd_complete_mi_arg); - rc = pn533_build_tx_frame(dev, skb_cmd, true); - if (rc) - goto error_frame; + break; + } + default: + *skb_put(skb, sizeof(u8)) = 1; /*TG*/ - skb_resp_len = PN533_FRAME_HEADER_LEN + - PN533_CMD_DATAEXCH_HEAD_LEN + - PN533_CMD_DATAEXCH_DATA_MAXLEN + - PN533_FRAME_TAIL_LEN; + rc = pn533_send_cmd_direct_async(dev, + PN533_CMD_IN_DATA_EXCHANGE, + skb, + pn533_data_exchange_complete, + dev->cmd_complete_mi_arg); - skb_resp = alloc_skb(skb_resp_len, GFP_KERNEL); - if (!skb_resp) { - rc = -ENOMEM; - goto error_frame; + break; } - in_frame = (struct pn533_frame *) skb_resp->data; - out_frame = (struct pn533_frame *) skb_cmd->data; - - arg->skb_resp = skb_resp; - arg->skb_out = skb_cmd; - - rc = __pn533_send_cmd_frame_async(dev, out_frame, in_frame, - skb_resp_len, - pn533_data_exchange_complete, - dev->cmd_complete_arg); - if (!rc) + if (rc == 0) /* success */ return; - nfc_dev_err(&dev->interface->dev, "Error %d when trying to" - " perform data_exchange", rc); - - kfree_skb(skb_resp); + nfc_dev_err(&dev->interface->dev, + "Error %d when trying to perform data_exchange", rc); -error_frame: - kfree_skb(skb_cmd); + dev_kfree_skb(skb); + kfree(dev->cmd_complete_arg); -error_cmd: +error: pn533_send_ack(dev, GFP_KERNEL); - - kfree(arg); - queue_work(dev->wq, &dev->cmd_work); } -- cgit v1.2.3-18-g5258 From 99e591be3d95e55412585729624b05862bb5463c Mon Sep 17 00:00:00 2001 From: Waldemar Rymarkiewicz Date: Mon, 10 Dec 2012 14:42:47 +0100 Subject: NFC: pn533: Dump tx and rx data in debug mode Signed-off-by: Waldemar Rymarkiewicz Signed-off-by: Samuel Ortiz --- drivers/nfc/pn533.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers/nfc') diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c index 91e1594dfd1..b445f0339e0 100644 --- a/drivers/nfc/pn533.c +++ b/drivers/nfc/pn533.c @@ -542,6 +542,9 @@ static void pn533_recv_response(struct urb *urb) in_frame = dev->in_urb->transfer_buffer; + print_hex_dump(KERN_DEBUG, "PN533 RX: ", DUMP_PREFIX_NONE, 16, 1, + in_frame, PN533_FRAME_SIZE(in_frame), false); + if (!pn533_rx_frame_is_valid(in_frame)) { nfc_dev_err(&dev->interface->dev, "Received an invalid frame"); dev->wq_in_error = -EIO; @@ -664,6 +667,9 @@ static int __pn533_send_cmd_frame_async(struct pn533 *dev, dev->in_urb->transfer_buffer = in_frame; dev->in_urb->transfer_buffer_length = in_frame_len; + print_hex_dump(KERN_DEBUG, "PN533 TX: ", DUMP_PREFIX_NONE, 16, 1, + out_frame, PN533_FRAME_SIZE(out_frame), false); + rc = usb_submit_urb(dev->out_urb, GFP_KERNEL); if (rc) return rc; -- cgit v1.2.3-18-g5258 From b5193e5da24fb278c68fc0493c0a1073a1b27ab9 Mon Sep 17 00:00:00 2001 From: Waldemar Rymarkiewicz Date: Mon, 10 Dec 2012 14:42:48 +0100 Subject: NFC: pn533: Remove frame logic from poll cmds Remove frame logic from start_pool cb using the new iface for async send. Signed-off-by: Waldemar Rymarkiewicz Signed-off-by: Samuel Ortiz --- drivers/nfc/pn533.c | 270 ++++++++++++++++++++++++---------------------------- 1 file changed, 126 insertions(+), 144 deletions(-) (limited to 'drivers/nfc') diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c index b445f0339e0..1016e096206 100644 --- a/drivers/nfc/pn533.c +++ b/drivers/nfc/pn533.c @@ -320,20 +320,6 @@ struct pn533_cmd_jump_dep_response { #define PN533_INIT_TARGET_RESP_ACTIVE 0x1 #define PN533_INIT_TARGET_RESP_DEP 0x4 -struct pn533_cmd_init_target { - u8 mode; - u8 mifare[6]; - u8 felica[18]; - u8 nfcid3[10]; - u8 gb_len; - u8 gb[]; -} __packed; - -struct pn533_cmd_init_target_response { - u8 mode; - u8 cmd[]; -} __packed; - struct pn533 { struct usb_device *udev; struct usb_interface *interface; @@ -1315,50 +1301,37 @@ static int pn533_target_found_type_b(struct nfc_target *nfc_tgt, u8 *tgt_data, return 0; } -struct pn533_poll_response { - u8 nbtg; - u8 tg; - u8 target_data[]; -} __packed; - -static int pn533_target_found(struct pn533 *dev, - struct pn533_poll_response *resp, int resp_len) +static int pn533_target_found(struct pn533 *dev, u8 tg, u8 *tgdata, + int tgdata_len) { - int target_data_len; struct nfc_target nfc_tgt; int rc; nfc_dev_dbg(&dev->interface->dev, "%s - modulation=%d", __func__, - dev->poll_mod_curr); + dev->poll_mod_curr); - if (resp->tg != 1) + if (tg != 1) return -EPROTO; memset(&nfc_tgt, 0, sizeof(struct nfc_target)); - target_data_len = resp_len - sizeof(stru