From fe7484834bb614c2c205726647635171ce6cc070 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 18 Nov 2011 09:52:10 -0800 Subject: USB: convert some miscellanies drivers to use module_usb_driver() This converts the remaining USB drivers in the kernel to use the module_usb_driver() macro which makes the code smaller and a bit simpler. Added bonus is that it removes some unneeded kernel log messages about drivers loading and/or unloading. Cc: Guenter Roeck Cc: Jean Delvare Cc: Ben Dooks Cc: Till Harbaum Cc: Karsten Keil Cc: Chris Ball Cc: David Woodhouse Cc: Lauro Ramos Venancio Cc: Aloisio Almeida Jr Cc: Samuel Ortiz Cc: Steve Glendinning Cc: Florian Tobias Schandinat Cc: Evgeniy Polyakov Cc: Wim Van Sebroeck Cc: "David S. Miller" Cc: Jesper Juhl Cc: Artem Bityutskiy Cc: Jamie Iles Cc: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/nfc/pn533.c | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) (limited to 'drivers/nfc/pn533.c') diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c index 7bcb1febef0d..bd023847efb2 100644 --- a/drivers/nfc/pn533.c +++ b/drivers/nfc/pn533.c @@ -1597,24 +1597,7 @@ static struct usb_driver pn533_driver = { .id_table = pn533_table, }; -static int __init pn533_init(void) -{ - int rc; - - rc = usb_register(&pn533_driver); - if (rc) - err("usb_register failed. Error number %d", rc); - - return rc; -} - -static void __exit pn533_exit(void) -{ - usb_deregister(&pn533_driver); -} - -module_init(pn533_init); -module_exit(pn533_exit); +module_usb_driver(pn533_driver); MODULE_AUTHOR("Lauro Ramos Venancio ," " Aloisio Almeida Jr "); -- cgit v1.2.3 From 85eb28a36215b3d872384e027403b14ff483d60b Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Wed, 30 Nov 2011 18:18:06 +0800 Subject: NFC: pn533: Staticise pn533_data_exchange() It is not used outside this driver so no need to make the symbol global. Signed-off-by: Axel Lin Signed-off-by: John W. Linville --- drivers/nfc/pn533.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/nfc/pn533.c') diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c index 7bcb1febef0d..dbf214ef7321 100644 --- a/drivers/nfc/pn533.c +++ b/drivers/nfc/pn533.c @@ -1339,7 +1339,7 @@ error: return 0; } -int pn533_data_exchange(struct nfc_dev *nfc_dev, u32 target_idx, +static int pn533_data_exchange(struct nfc_dev *nfc_dev, u32 target_idx, struct sk_buff *skb, data_exchange_cb_t cb, void *cb_context) -- cgit v1.2.3 From 7c7cd3bfec68fee33b30d177df6a6a0c4bbdc59d Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Wed, 14 Dec 2011 16:43:06 +0100 Subject: NFC: Add tx skb allocation routine This is a factorization of the current rawsock tx skb allocation routine, as it will be used by the LLCP code. We also rename nfc_alloc_skb to nfc_alloc_recv_skb for consistency sake. Signed-off-by: Samuel Ortiz Signed-off-by: John W. Linville --- drivers/nfc/pn533.c | 2 +- include/net/nfc/nfc.h | 5 ++++- net/nfc/core.c | 30 +++++++++++++++++++++++++++--- net/nfc/rawsock.c | 7 ++----- 4 files changed, 34 insertions(+), 10 deletions(-) (limited to 'drivers/nfc/pn533.c') diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c index dbf214ef7321..ea1caaeed13c 100644 --- a/drivers/nfc/pn533.c +++ b/drivers/nfc/pn533.c @@ -1368,7 +1368,7 @@ static int pn533_data_exchange(struct nfc_dev *nfc_dev, u32 target_idx, PN533_CMD_DATAEXCH_DATA_MAXLEN + PN533_FRAME_TAIL_SIZE; - skb_resp = nfc_alloc_skb(skb_resp_len, GFP_KERNEL); + skb_resp = nfc_alloc_recv_skb(skb_resp_len, GFP_KERNEL); if (!skb_resp) { rc = -ENOMEM; goto error; diff --git a/include/net/nfc/nfc.h b/include/net/nfc/nfc.h index 6a7f602aa841..3a3304c094d7 100644 --- a/include/net/nfc/nfc.h +++ b/include/net/nfc/nfc.h @@ -157,7 +157,10 @@ static inline const char *nfc_device_name(struct nfc_dev *dev) return dev_name(&dev->dev); } -struct sk_buff *nfc_alloc_skb(unsigned int size, gfp_t gfp); +struct sk_buff *nfc_alloc_send_skb(struct nfc_dev *dev, struct sock *sk, + unsigned int flags, unsigned int size, + unsigned int *err); +struct sk_buff *nfc_alloc_recv_skb(unsigned int size, gfp_t gfp); int nfc_targets_found(struct nfc_dev *dev, struct nfc_target *targets, int ntargets); diff --git a/net/nfc/core.c b/net/nfc/core.c index 2a838b099d82..f53f88ada687 100644 --- a/net/nfc/core.c +++ b/net/nfc/core.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "nfc.h" @@ -275,12 +276,35 @@ error: } /** - * nfc_alloc_skb - allocate a skb for data exchange responses + * nfc_alloc_send_skb - allocate a skb for data exchange responses * * @size: size to allocate * @gfp: gfp flags */ -struct sk_buff *nfc_alloc_skb(unsigned int size, gfp_t gfp) +struct sk_buff *nfc_alloc_send_skb(struct nfc_dev *dev, struct sock *sk, + unsigned int flags, unsigned int size, + unsigned int *err) +{ + struct sk_buff *skb; + unsigned int total_size; + + total_size = size + + dev->tx_headroom + dev->tx_tailroom + NFC_HEADER_SIZE; + + skb = sock_alloc_send_skb(sk, total_size, flags & MSG_DONTWAIT, err); + if (skb) + skb_reserve(skb, dev->tx_headroom + NFC_HEADER_SIZE); + + return skb; +} + +/** + * nfc_alloc_recv_skb - allocate a skb for data exchange responses + * + * @size: size to allocate + * @gfp: gfp flags + */ +struct sk_buff *nfc_alloc_recv_skb(unsigned int size, gfp_t gfp) { struct sk_buff *skb; unsigned int total_size; @@ -293,7 +317,7 @@ struct sk_buff *nfc_alloc_skb(unsigned int size, gfp_t gfp) return skb; } -EXPORT_SYMBOL(nfc_alloc_skb); +EXPORT_SYMBOL(nfc_alloc_recv_skb); /** * nfc_targets_found - inform that targets were found diff --git a/net/nfc/rawsock.c b/net/nfc/rawsock.c index 5e9b991eac13..11ac0a17156e 100644 --- a/net/nfc/rawsock.c +++ b/net/nfc/rawsock.c @@ -208,13 +208,10 @@ static int rawsock_sendmsg(struct kiocb *iocb, struct socket *sock, if (sock->state != SS_CONNECTED) return -ENOTCONN; - skb = sock_alloc_send_skb(sk, len + dev->tx_headroom + dev->tx_tailroom + NFC_HEADER_SIZE, - msg->msg_flags & MSG_DONTWAIT, &rc); - if (!skb) + skb = nfc_alloc_send_skb(dev, sk, msg->msg_flags, len, &rc); + if (skb == NULL) return rc; - skb_reserve(skb, dev->tx_headroom + NFC_HEADER_SIZE); - rc = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len); if (rc < 0) { kfree_skb(skb); -- cgit v1.2.3 From 541d920b05b538ec0d9ae8ce619ee4fc6fb19e32 Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Wed, 14 Dec 2011 16:43:10 +0100 Subject: NFC: Set and get DEP general bytes Without an API for setting and getting the local and remote general bytes, drivers won't be able to properly establish a DEP link. This API also allows them to propagate the remote general bytes they get from the DEP link establishment up to the LLCP layer. Signed-off-by: Samuel Ortiz Signed-off-by: John W. Linville --- drivers/nfc/pn533.c | 7 ++++++- include/net/nfc/nfc.h | 5 +++++ net/nfc/core.c | 18 ++++++++++++++++++ 3 files changed, 29 insertions(+), 1 deletion(-) (limited to 'drivers/nfc/pn533.c') diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c index ea1caaeed13c..dccd96552f5d 100644 --- a/drivers/nfc/pn533.c +++ b/drivers/nfc/pn533.c @@ -1121,6 +1121,7 @@ static int pn533_activate_target_nfcdep(struct pn533 *dev) { struct pn533_cmd_activate_param param; struct pn533_cmd_activate_response *resp; + u16 gt_len; int rc; nfc_dev_dbg(&dev->interface->dev, "%s", __func__); @@ -1146,7 +1147,11 @@ static int pn533_activate_target_nfcdep(struct pn533 *dev) if (rc != PN533_CMD_RET_SUCCESS) return -EIO; - return 0; + /* 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); + + return rc; } static int pn533_activate_target(struct nfc_dev *nfc_dev, u32 target_idx, diff --git a/include/net/nfc/nfc.h b/include/net/nfc/nfc.h index bf82d292d68c..ccfe757a94ec 100644 --- a/include/net/nfc/nfc.h +++ b/include/net/nfc/nfc.h @@ -170,6 +170,11 @@ struct sk_buff *nfc_alloc_send_skb(struct nfc_dev *dev, struct sock *sk, unsigned int *err); struct sk_buff *nfc_alloc_recv_skb(unsigned int size, gfp_t gfp); +int nfc_set_remote_general_bytes(struct nfc_dev *dev, + u8 *gt, u8 gt_len); + +u8 *nfc_get_local_general_bytes(struct nfc_dev *dev, u8 *gt_len); + int nfc_targets_found(struct nfc_dev *dev, struct nfc_target *targets, int ntargets); diff --git a/net/nfc/core.c b/net/nfc/core.c index 785f1f20c7ba..3a45f21b3b97 100644 --- a/net/nfc/core.c +++ b/net/nfc/core.c @@ -352,6 +352,24 @@ error: return rc; } +int nfc_set_remote_general_bytes(struct nfc_dev *dev, u8 *gb, u8 gb_len) +{ + pr_debug("dev_name=%s gb_len=%d\n", + dev_name(&dev->dev), gb_len); + + if (gb_len > NFC_MAX_GT_LEN) + return -EINVAL; + + return 0; +} +EXPORT_SYMBOL(nfc_set_remote_general_bytes); + +u8 *nfc_get_local_general_bytes(struct nfc_dev *dev, u8 *gt_len) +{ + return NULL; +} +EXPORT_SYMBOL(nfc_get_local_general_bytes); + /** * nfc_alloc_send_skb - allocate a skb for data exchange responses * -- cgit v1.2.3 From 361f3cb7f9cfdb82c80926d0e7843c098c034545 Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Wed, 14 Dec 2011 16:43:11 +0100 Subject: NFC: DEP link hook implementation for pn533 Signed-off-by: Samuel Ortiz Signed-off-by: John W. Linville --- drivers/nfc/pn533.c | 159 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 159 insertions(+) (limited to 'drivers/nfc/pn533.c') diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c index dccd96552f5d..b8b6c2abbd4a 100644 --- a/drivers/nfc/pn533.c +++ b/drivers/nfc/pn533.c @@ -72,6 +72,7 @@ MODULE_DEVICE_TABLE(usb, pn533_table); #define PN533_CMD_IN_LIST_PASSIVE_TARGET 0x4A #define PN533_CMD_IN_ATR 0x50 #define PN533_CMD_IN_RELEASE 0x52 +#define PN533_CMD_IN_JUMP_FOR_DEP 0x56 #define PN533_CMD_RESPONSE(cmd) (cmd + 1) @@ -231,6 +232,26 @@ 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 gt[]; +} __packed; + +struct pn533_cmd_jump_dep_response { + u8 status; + u8 tg; + u8 nfcid3t[10]; + u8 didt; + u8 bst; + u8 brt; + u8 to; + u8 ppt; + /* optional */ + u8 gt[]; +} __packed; struct pn533 { struct usb_device *udev; @@ -1244,6 +1265,142 @@ static void pn533_deactivate_target(struct nfc_dev *nfc_dev, u32 target_idx) return; } + +static int pn533_in_dep_link_up_complete(struct pn533 *dev, void *arg, + u8 *params, int params_len) +{ + struct pn533_cmd_jump_dep *cmd; + struct pn533_cmd_jump_dep_response *resp; + struct nfc_target nfc_target; + u8 target_gt_len; + int rc; + + 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 (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; + } + + resp = (struct pn533_cmd_jump_dep_response *) params; + cmd = (struct pn533_cmd_jump_dep *) arg; + rc = resp->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; + } + + if (!dev->tgt_available_prots) { + nfc_dev_dbg(&dev->interface->dev, "Creating new target"); + + nfc_target.supported_protocols = NFC_PROTO_NFC_DEP_MASK; + rc = nfc_targets_found(dev->nfc_dev, &nfc_target, 1); + if (rc) + return 0; + + dev->tgt_available_prots = 0; + } + + 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; + rc = nfc_set_remote_general_bytes(dev->nfc_dev, + resp->gt, target_gt_len); + if (rc == 0) + rc = nfc_dep_link_is_up(dev->nfc_dev, + dev->nfc_dev->targets[0].idx, + !cmd->active, NFC_RF_INITIATOR); + + return 0; +} + +static int pn533_dep_link_up(struct nfc_dev *nfc_dev, int target_idx, + u8 comm_mode, u8 rf_mode) +{ + struct pn533 *dev = nfc_get_drvdata(nfc_dev); + struct pn533_cmd_jump_dep *cmd; + u8 cmd_len, local_gt_len, *local_gt; + int rc; + + nfc_dev_dbg(&dev->interface->dev, "%s", __func__); + + if (rf_mode == NFC_RF_TARGET) { + nfc_dev_err(&dev->interface->dev, "Target mode not supported"); + return -EOPNOTSUPP; + } + + + if (dev->poll_mod_count) { + nfc_dev_err(&dev->interface->dev, + "Cannot bring the DEP link up while polling"); + return -EBUSY; + } + + if (dev->tgt_active_prot) { + nfc_dev_err(&dev->interface->dev, + "There is already an active target"); + return -EBUSY; + } + + local_gt = nfc_get_local_general_bytes(dev->nfc_dev, &local_gt_len); + if (local_gt_len > NFC_MAX_GT_LEN) + return -EINVAL; + + cmd_len = sizeof(struct pn533_cmd_jump_dep) + local_gt_len; + cmd = kzalloc(cmd_len, GFP_KERNEL); + if (cmd == NULL) + return -ENOMEM; + + pn533_tx_frame_init(dev->out_frame, PN533_CMD_IN_JUMP_FOR_DEP); + + cmd->active = !comm_mode; + cmd->baud = 0; + if (local_gt != NULL) { + cmd->next = 4; /* We have some Gi */ + memcpy(cmd->gt, local_gt, local_gt_len); + } else { + cmd->next = 0; + } + + memcpy(PN533_FRAME_CMD_PARAMS_PTR(dev->out_frame), cmd, cmd_len); + dev->out_frame->datalen += cmd_len; + + 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); + if (rc) + goto out; + + +out: + kfree(cmd); + + return rc; +} + +static int pn533_dep_link_down(struct nfc_dev *nfc_dev) +{ + pn533_deactivate_target(nfc_dev, 0); + + return 0; +} + #define PN533_CMD_DATAEXCH_HEAD_LEN (sizeof(struct pn533_frame) + 3) #define PN533_CMD_DATAEXCH_DATA_MAXLEN 262 @@ -1439,6 +1596,8 @@ static int pn533_set_configuration(struct pn533 *dev, u8 cfgitem, u8 *cfgdata, struct nfc_ops pn533_nfc_ops = { .dev_up = NULL, .dev_down = NULL, + .dep_link_up = pn533_dep_link_up, + .dep_link_down = pn533_dep_link_down, .start_poll = pn533_start_poll, .stop_poll = pn533_stop_poll, .activate_target = pn533_activate_target, -- cgit v1.2.3