Loading drivers/nfc/pn533.c +80 −5 Original line number Original line Diff line number Diff line Loading @@ -75,6 +75,7 @@ MODULE_DEVICE_TABLE(usb, pn533_table); #define PN533_CMD_IN_JUMP_FOR_DEP 0x56 #define PN533_CMD_IN_JUMP_FOR_DEP 0x56 #define PN533_CMD_TG_INIT_AS_TARGET 0x8c #define PN533_CMD_TG_INIT_AS_TARGET 0x8c #define PN533_CMD_TG_GET_DATA 0x86 #define PN533_CMD_RESPONSE(cmd) (cmd + 1) #define PN533_CMD_RESPONSE(cmd) (cmd + 1) Loading @@ -83,6 +84,9 @@ MODULE_DEVICE_TABLE(usb, pn533_table); #define PN533_CMD_MI_MASK 0x40 #define PN533_CMD_MI_MASK 0x40 #define PN533_CMD_RET_SUCCESS 0x00 #define PN533_CMD_RET_SUCCESS 0x00 /* PN533 status codes */ #define PN533_STATUS_TARGET_RELEASED 0x29 struct pn533; struct pn533; typedef int (*pn533_cmd_complete_t) (struct pn533 *dev, void *arg, typedef int (*pn533_cmd_complete_t) (struct pn533 *dev, void *arg, Loading Loading @@ -296,6 +300,7 @@ struct pn533 { struct workqueue_struct *wq; struct workqueue_struct *wq; struct work_struct cmd_work; struct work_struct cmd_work; struct work_struct mi_work; struct work_struct mi_work; struct work_struct tg_work; struct pn533_frame *wq_in_frame; struct pn533_frame *wq_in_frame; int wq_in_error; int wq_in_error; Loading Loading @@ -1132,6 +1137,68 @@ static int pn533_init_target_frame(struct pn533_frame *frame, return 0; return 0; } } #define PN533_CMD_DATAEXCH_HEAD_LEN (sizeof(struct pn533_frame) + 3) #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 *skb_resp = arg; struct pn533_frame *in_frame = (struct pn533_frame *) skb_resp->data; 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); return params_len; } if (params_len > 0 && params[0] != 0) { nfc_tm_deactivated(dev->nfc_dev); kfree_skb(skb_resp); return 0; } 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); return nfc_tm_data_received(dev->nfc_dev, skb_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__); skb_resp_len = PN533_CMD_DATAEXCH_HEAD_LEN + PN533_CMD_DATAEXCH_DATA_MAXLEN + PN533_FRAME_TAIL_SIZE; skb_resp = nfc_alloc_recv_skb(skb_resp_len, GFP_KERNEL); if (!skb_resp) 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); pn533_send_cmd_frame_async(dev, dev->out_frame, in_frame, skb_resp_len, pn533_tm_get_data_complete, skb_resp, GFP_KERNEL); return; } #define ATR_REQ_GB_OFFSET 17 #define ATR_REQ_GB_OFFSET 17 static int pn533_init_target_complete(struct pn533 *dev, void *arg, static int pn533_init_target_complete(struct pn533 *dev, void *arg, u8 *params, int params_len) u8 *params, int params_len) Loading @@ -1139,6 +1206,7 @@ static int pn533_init_target_complete(struct pn533 *dev, void *arg, struct pn533_cmd_init_target_response *resp; struct pn533_cmd_init_target_response *resp; u8 frame, comm_mode = NFC_COMM_PASSIVE, *gb; u8 frame, comm_mode = NFC_COMM_PASSIVE, *gb; size_t gb_len; size_t gb_len; int rc; nfc_dev_dbg(&dev->interface->dev, "%s", __func__); nfc_dev_dbg(&dev->interface->dev, "%s", __func__); Loading Loading @@ -1169,8 +1237,17 @@ static int pn533_init_target_complete(struct pn533 *dev, void *arg, gb = resp->cmd + ATR_REQ_GB_OFFSET; gb = resp->cmd + ATR_REQ_GB_OFFSET; gb_len = params_len - (ATR_REQ_GB_OFFSET + 1); gb_len = params_len - (ATR_REQ_GB_OFFSET + 1); return nfc_tm_activated(dev->nfc_dev, NFC_PROTO_NFC_DEP_MASK, rc = nfc_tm_activated(dev->nfc_dev, NFC_PROTO_NFC_DEP_MASK, comm_mode, gb, gb_len); comm_mode, gb, gb_len); if (rc < 0) { nfc_dev_err(&dev->interface->dev, "Error when signaling target activation"); return rc; } queue_work(dev->wq, &dev->tg_work); return 0; } } static int pn533_init_target(struct nfc_dev *nfc_dev, u32 protocols) static int pn533_init_target(struct nfc_dev *nfc_dev, u32 protocols) Loading Loading @@ -1553,9 +1630,6 @@ static int pn533_dep_link_down(struct nfc_dev *nfc_dev) return 0; return 0; } } #define PN533_CMD_DATAEXCH_HEAD_LEN (sizeof(struct pn533_frame) + 3) #define PN533_CMD_DATAEXCH_DATA_MAXLEN 262 static int pn533_data_exchange_tx_frame(struct pn533 *dev, struct sk_buff *skb) static int pn533_data_exchange_tx_frame(struct pn533 *dev, struct sk_buff *skb) { { int payload_len = skb->len; int payload_len = skb->len; Loading Loading @@ -1920,6 +1994,7 @@ static int pn533_probe(struct usb_interface *interface, INIT_WORK(&dev->cmd_work, pn533_wq_cmd_complete); INIT_WORK(&dev->cmd_work, pn533_wq_cmd_complete); INIT_WORK(&dev->mi_work, pn533_wq_mi_recv); INIT_WORK(&dev->mi_work, pn533_wq_mi_recv); INIT_WORK(&dev->tg_work, pn533_wq_tg_get_data); dev->wq = alloc_workqueue("pn533", dev->wq = alloc_workqueue("pn533", WQ_NON_REENTRANT | WQ_UNBOUND | WQ_MEM_RECLAIM, WQ_NON_REENTRANT | WQ_UNBOUND | WQ_MEM_RECLAIM, 1); 1); Loading Loading
drivers/nfc/pn533.c +80 −5 Original line number Original line Diff line number Diff line Loading @@ -75,6 +75,7 @@ MODULE_DEVICE_TABLE(usb, pn533_table); #define PN533_CMD_IN_JUMP_FOR_DEP 0x56 #define PN533_CMD_IN_JUMP_FOR_DEP 0x56 #define PN533_CMD_TG_INIT_AS_TARGET 0x8c #define PN533_CMD_TG_INIT_AS_TARGET 0x8c #define PN533_CMD_TG_GET_DATA 0x86 #define PN533_CMD_RESPONSE(cmd) (cmd + 1) #define PN533_CMD_RESPONSE(cmd) (cmd + 1) Loading @@ -83,6 +84,9 @@ MODULE_DEVICE_TABLE(usb, pn533_table); #define PN533_CMD_MI_MASK 0x40 #define PN533_CMD_MI_MASK 0x40 #define PN533_CMD_RET_SUCCESS 0x00 #define PN533_CMD_RET_SUCCESS 0x00 /* PN533 status codes */ #define PN533_STATUS_TARGET_RELEASED 0x29 struct pn533; struct pn533; typedef int (*pn533_cmd_complete_t) (struct pn533 *dev, void *arg, typedef int (*pn533_cmd_complete_t) (struct pn533 *dev, void *arg, Loading Loading @@ -296,6 +300,7 @@ struct pn533 { struct workqueue_struct *wq; struct workqueue_struct *wq; struct work_struct cmd_work; struct work_struct cmd_work; struct work_struct mi_work; struct work_struct mi_work; struct work_struct tg_work; struct pn533_frame *wq_in_frame; struct pn533_frame *wq_in_frame; int wq_in_error; int wq_in_error; Loading Loading @@ -1132,6 +1137,68 @@ static int pn533_init_target_frame(struct pn533_frame *frame, return 0; return 0; } } #define PN533_CMD_DATAEXCH_HEAD_LEN (sizeof(struct pn533_frame) + 3) #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 *skb_resp = arg; struct pn533_frame *in_frame = (struct pn533_frame *) skb_resp->data; 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); return params_len; } if (params_len > 0 && params[0] != 0) { nfc_tm_deactivated(dev->nfc_dev); kfree_skb(skb_resp); return 0; } 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); return nfc_tm_data_received(dev->nfc_dev, skb_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__); skb_resp_len = PN533_CMD_DATAEXCH_HEAD_LEN + PN533_CMD_DATAEXCH_DATA_MAXLEN + PN533_FRAME_TAIL_SIZE; skb_resp = nfc_alloc_recv_skb(skb_resp_len, GFP_KERNEL); if (!skb_resp) 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); pn533_send_cmd_frame_async(dev, dev->out_frame, in_frame, skb_resp_len, pn533_tm_get_data_complete, skb_resp, GFP_KERNEL); return; } #define ATR_REQ_GB_OFFSET 17 #define ATR_REQ_GB_OFFSET 17 static int pn533_init_target_complete(struct pn533 *dev, void *arg, static int pn533_init_target_complete(struct pn533 *dev, void *arg, u8 *params, int params_len) u8 *params, int params_len) Loading @@ -1139,6 +1206,7 @@ static int pn533_init_target_complete(struct pn533 *dev, void *arg, struct pn533_cmd_init_target_response *resp; struct pn533_cmd_init_target_response *resp; u8 frame, comm_mode = NFC_COMM_PASSIVE, *gb; u8 frame, comm_mode = NFC_COMM_PASSIVE, *gb; size_t gb_len; size_t gb_len; int rc; nfc_dev_dbg(&dev->interface->dev, "%s", __func__); nfc_dev_dbg(&dev->interface->dev, "%s", __func__); Loading Loading @@ -1169,8 +1237,17 @@ static int pn533_init_target_complete(struct pn533 *dev, void *arg, gb = resp->cmd + ATR_REQ_GB_OFFSET; gb = resp->cmd + ATR_REQ_GB_OFFSET; gb_len = params_len - (ATR_REQ_GB_OFFSET + 1); gb_len = params_len - (ATR_REQ_GB_OFFSET + 1); return nfc_tm_activated(dev->nfc_dev, NFC_PROTO_NFC_DEP_MASK, rc = nfc_tm_activated(dev->nfc_dev, NFC_PROTO_NFC_DEP_MASK, comm_mode, gb, gb_len); comm_mode, gb, gb_len); if (rc < 0) { nfc_dev_err(&dev->interface->dev, "Error when signaling target activation"); return rc; } queue_work(dev->wq, &dev->tg_work); return 0; } } static int pn533_init_target(struct nfc_dev *nfc_dev, u32 protocols) static int pn533_init_target(struct nfc_dev *nfc_dev, u32 protocols) Loading Loading @@ -1553,9 +1630,6 @@ static int pn533_dep_link_down(struct nfc_dev *nfc_dev) return 0; return 0; } } #define PN533_CMD_DATAEXCH_HEAD_LEN (sizeof(struct pn533_frame) + 3) #define PN533_CMD_DATAEXCH_DATA_MAXLEN 262 static int pn533_data_exchange_tx_frame(struct pn533 *dev, struct sk_buff *skb) static int pn533_data_exchange_tx_frame(struct pn533 *dev, struct sk_buff *skb) { { int payload_len = skb->len; int payload_len = skb->len; Loading Loading @@ -1920,6 +1994,7 @@ static int pn533_probe(struct usb_interface *interface, INIT_WORK(&dev->cmd_work, pn533_wq_cmd_complete); INIT_WORK(&dev->cmd_work, pn533_wq_cmd_complete); INIT_WORK(&dev->mi_work, pn533_wq_mi_recv); INIT_WORK(&dev->mi_work, pn533_wq_mi_recv); INIT_WORK(&dev->tg_work, pn533_wq_tg_get_data); dev->wq = alloc_workqueue("pn533", dev->wq = alloc_workqueue("pn533", WQ_NON_REENTRANT | WQ_UNBOUND | WQ_MEM_RECLAIM, WQ_NON_REENTRANT | WQ_UNBOUND | WQ_MEM_RECLAIM, 1); 1); Loading