NFC updates for 3.5
Subsystems (3)
cover NFC updates for 3.5
Hi John,
Here comes my 2nd NFC batch for the next 3.5 merge window.
Besides the sparse, warning and LLCP fixes, we have a new pn544 driver based on the existing NFC HCI APIs. We will be living with 2 pn544 drivers for a while as I wanted to keep a transition period for whoever is using the existing driver. I'm planning to remove it for 3.6, but this could be extended if someone screams about it.
You can also pull those patches from:
git://git.kernel.org/pub/scm/linux/kernel/git/sameo/nfc-3.0.git nfc-next
They should apply cleanly on top of your wireless-next tree.
Dan Carpenter (1):
NFC: Remove unneeded pn533 dev NULL check
Eric Lapuyade (7):
NFC: Cache the core NFC active target pointer instead of its index
NFC: Remove useless HCI private nfc target table
NFC: Specify usage for targets found and target lost events
NFC: Add HCI/SHDLC support to let driver check for tag presence
NFC: Update Documentation/nfc-hci.txt
NFC: HCI based pn544 driver
NFC: HCI drivers don't have to keep track of polling state
H Hartley Sweeten (5):
NFC: Quiet nci/data.c sparse noise about plain integer as NULL
pointer
NFC: Include nci_core.h to nci/lib.c
NFC: Quiet nci/ntf.c sparse noise about plain integer as NULL pointer
NFC: HCI ops should not be exposed globally
NFC: The NFC genl family structure should not be exposed globally
Samuel Ortiz (5):
NFC: LLCP connect must wait for a CC frame
NFC: Update the LLCP poll mask
NFC: Return the amount of LLCP bytes queued to sock_sendmsg
NFC: Send device index instead of its name when target is lost
feature-removal: Remove pn544 raw driver
Stephen Rothwell (1):
NFC: Fix up for NLA_PUT_ api changes
joseph daniel (1):
NFC: Fix LLCP compilation warning
Documentation/feature-removal-schedule.txt | 12 + Documentation/nfc/nfc-hci.txt | 45 +- drivers/nfc/Kconfig | 13 + drivers/nfc/Makefile | 1 + drivers/nfc/pn533.c | 19 +- drivers/nfc/pn544_hci.c | 947 ++++++++++++++++++++++++++++ include/linux/nfc/pn544.h | 7 + include/net/nfc/hci.h | 6 +- include/net/nfc/nfc.h | 19 +- include/net/nfc/shdlc.h | 2 + net/nfc/core.c | 112 +++- net/nfc/hci/core.c | 78 +-- net/nfc/hci/shdlc.c | 12 + net/nfc/llcp/commands.c | 2 +- net/nfc/llcp/llcp.c | 7 + net/nfc/llcp/sock.c | 57 ++- net/nfc/nci/core.c | 27 +- net/nfc/nci/data.c | 8 +- net/nfc/nci/lib.c | 1 + net/nfc/nci/ntf.c | 2 +- net/nfc/netlink.c | 12 +- net/nfc/nfc.h | 2 +- 22 files changed, 1248 insertions(+), 143 deletions(-) create mode 100644 drivers/nfc/pn544_hci.c
Signature · 1 line
1.7.9.1
PATCH 1/20 NFC: Fix up for NLA_PUT_ api changes
From: Stephen Rothwell <[email protected]>
--- net/nfc/netlink.c | 6 ++++-- 1 files changed, 4 insertions(+), 2 deletions(-)
net/nfc/netlink.c +4 -2
@@ -197,8 +197,10 @@ int nfc_genl_target_lost(struct nfc_dev *dev, u32 target_idx)if (!hdr) goto free_msg; -NLA_PUT_STRING (msg,NFC_ATTR_DEVICE_NAME ,nfc_device_name (dev)); -NLA_PUT_U32 (msg,NFC_ATTR_TARGET_INDEX , target_idx); +if (nla_put_string (msg,NFC_ATTR_DEVICE_NAME ,nfc_device_name (dev))) + goto nla_put_failure; +if (nla_put_u32 (msg,NFC_ATTR_TARGET_INDEX , target_idx)) + goto nla_put_failure;genlmsg_end (msg, hdr);
Signature · 1 line
1.7.9.1
Re: [PATCH 01/20] NFC: Fix up for NLA_PUT_ api changes
Hi Samuel,
Quoted 15 lines · On Mon, 7 May 2012 12:31:12 +0200 Samuel Ortiz <[email protected]> wrote:
From: Stephen Rothwell <[email protected]>
Signed-off-by Stephen Rothwell <[email protected]>Signed-off-by Samuel Ortiz <[email protected]>--- net/nfc/netlink.c | 6 ++++-- 1 files changed, 4 insertions(+), 2 deletions(-)net/nfc/netlink.c +0
-0@@ -197,8 +197,10 @@ int nfc_genl_target_lost(struct nfc_dev *dev, u32 target_idx)if (!hdr)
net/nfc/netlink.c int nfc_genl_target_lost(struct nfc_dev *dev, u32 target_idx) · line 205
Quoted 10 lines
net/nfc/netlink.c +4
-2goto free_msg; -NLA_PUT_STRING (msg,NFC_ATTR_DEVICE_NAME ,nfc_device_name (dev)); -NLA_PUT_U32 (msg,NFC_ATTR_TARGET_INDEX , target_idx); +if (nla_put_string (msg,NFC_ATTR_DEVICE_NAME ,nfc_device_name (dev))) + goto nla_put_failure; +if (nla_put_u32 (msg,NFC_ATTR_TARGET_INDEX , target_idx)) + goto nla_put_failure;genlmsg_end (msg, hdr);
This has been superceded by the merge fix Dave Miller did when he merged the wireless-next tree into the net-next tree.
Signature · 2 lines
Cheers, Stephen Rothwell [email protected]
PATCH 2/20 NFC: Cache the core NFC active target pointer instead of its index
In reply to Samuel OrtizFrom: Eric Lapuyade <[email protected]>
The NFC Core now caches the active nfc target pointer, thereby avoiding the need to lookup the target table for each invocation of a driver ops. Consequently, pn533, HCI and NCI now directly receive an nfc_target pointer instead of a target index.
--- drivers/nfc/pn533.c | 16 +++++----- include/net/nfc/nfc.h | 18 ++++++----- net/nfc/core.c | 81 +++++++++++++++++++++++++++++++++++++------------ net/nfc/hci/core.c | 36 ++++------------------ net/nfc/nci/core.c | 27 ++++++++-------- 5 files changed, 99 insertions(+), 79 deletions(-)
drivers/nfc/pn533.c +8 -8
@@ -1194,8 +1194,8 @@ static int pn533_activate_target_nfcdep(struct pn533 *dev)return rc; } -static int pn533_activate_target (struct nfc_dev *nfc_dev,u32 target_idx, -u32 protocol) +static int pn533_activate_target (struct nfc_dev *nfc_dev, +struct nfc_target *target,u32 protocol) {struct pn533 *dev =nfc_get_drvdata (nfc_dev);int rc;
@@ -1243,7 +1243,8 @@ static int pn533_activate_target(struct nfc_dev *nfc_dev, u32 target_idx,return 0 ; } -static void pn533_deactivate_target (struct nfc_dev *nfc_dev,u32 target_idx) +static void pn533_deactivate_target (struct nfc_dev *nfc_dev, +struct nfc_target *target) {struct pn533 *dev =nfc_get_drvdata (nfc_dev);u8 tg;
@@ -1351,7 +1352,7 @@ static int pn533_in_dep_link_up_complete(struct pn533 *dev, void *arg,return 0 ; } -static int pn533_dep_link_up (struct nfc_dev *nfc_dev,int target_idx, +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);
@@ -1552,10 +1553,9 @@ error:return 0 ; } -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) +static int pn533_data_exchange (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_frame *out_frame, *in_frame;
include/net/nfc/nfc.h +10 -8
@@ -48,26 +48,28 @@ struct nfc_dev;typedef void (*data_exchange_cb_t )(void *context,struct sk_buff *skb,int err); +struct nfc_target ; +struct nfc_ops {int (*dev_up)(struct nfc_dev *dev);int (*dev_down)(struct nfc_dev *dev);int (*start_poll)(struct nfc_dev *dev,u32 protocols);void (*stop_poll)(struct nfc_dev *dev); -int (*dep_link_up)(struct nfc_dev *dev,int target_idx,u8 comm_mode, -u8 *gb,size_t gb_len); +int (*dep_link_up)(struct nfc_dev *dev,struct nfc_target *target, +u8 comm_mode,u8 *gb,size_t gb_len);int (*dep_link_down)(struct nfc_dev *dev); -int (*activate_target)(struct nfc_dev *dev,u32 target_idx, +int (*activate_target)(struct nfc_dev *dev,struct nfc_target *target,u32 protocol); -void (*deactivate_target)(struct nfc_dev *dev,u32 target_idx); -int (*data_exchange)(struct nfc_dev *dev,u32 target_idx, +void (*deactivate_target)(struct nfc_dev *dev, +struct nfc_target *target); +int (*data_exchange)(struct nfc_dev *dev,struct nfc_target *target,struct sk_buff *skb,data_exchange_cb_t cb,void *cb_context); -int (*check_presence)(struct nfc_dev *dev,u32 target_idx); +int (*check_presence)(struct nfc_dev *dev,struct nfc_target *target); };#define NFC_TARGET_IDX_ANY -1#define NFC_MAX_GT_LEN 48 -#define NFC_TARGET_IDX_NONE 0xffffffffstruct nfc_target {u32 idx;
@@ -99,7 +101,7 @@ struct nfc_dev {struct device dev;bool dev_up;bool polling; -u32 activated_target_idx; +struct nfc_target *active_target;bool dep_link_up;u32 dep_rf_mode;struct nfc_genl_data genl_data;
net/nfc/core.c +61 -20
178 lines not on this page · raw message
net/nfc/hci/core.c +6 -30
@@ -520,50 +520,26 @@ static void hci_stop_poll(struct nfc_dev *nfc_dev) } } -static struct nfc_target *hci_find_target (struct nfc_hci_dev *hdev, -u32 target_idx) +static int hci_activate_target (struct nfc_dev *nfc_dev, +struct nfc_target *target,u32 protocol) { -int i; -if (hdev->poll_started == false || hdev->targets ==NULL ) -return NULL ; - -for (i =0 ; i < hdev->target_count; i++) { -if (hdev->targets[i].idx == target_idx) -return &hdev->targets[i]; - } - -return NULL ; -} - -static int hci_activate_target (struct nfc_dev *nfc_dev,u32 target_idx, -u32 protocol) -{ -struct nfc_hci_dev *hdev =nfc_get_drvdata (nfc_dev); - -if (hci_find_target (hdev, target_idx) ==NULL ) -return -ENOMEDIUM ; -return 0 ; } -static void hci_deactivate_target (struct nfc_dev *nfc_dev,u32 target_idx) +static void hci_deactivate_target (struct nfc_dev *nfc_dev, +struct nfc_target *target) { } -static int hci_data_exchange (struct nfc_dev *nfc_dev,u32 target_idx, +static int hci_data_exchange (struct nfc_dev *nfc_dev,struct nfc_target *target,struct sk_buff *skb,data_exchange_cb_t cb,void *cb_context) {struct nfc_hci_dev *hdev =nfc_get_drvdata (nfc_dev);int r; -struct nfc_target *target;struct sk_buff *res_skb =NULL ; -pr_debug ("target_idx=%d\n" , target_idx); - - target =hci_find_target (hdev, target_idx); -if (target ==NULL ) -return -ENOMEDIUM ; +pr_debug ("target_idx=%d\n" , target->idx);switch (target->hci_reader_gate) {case NFC_HCI_RF_READER_A_GATE :
net/nfc/nci/core.c +14 -13
@@ -436,16 +436,16 @@ static void nci_stop_poll(struct nfc_dev *nfc_dev) msecs_to_jiffies(NCI_RF_DEACTIVATE_TIMEOUT)); } -static int nci_activate_target (struct nfc_dev *nfc_dev,__u32 target_idx, -__u32 protocol) +static int nci_activate_target (struct nfc_dev *nfc_dev, +struct nfc_target *target,__u32 protocol) {struct nci_dev *ndev =nfc_get_drvdata (nfc_dev);struct nci_rf_discover_select_param param; -struct nfc_target *target =NULL ; +struct nfc_target *nci_target =NULL ;int i;int rc =0 ; -pr_debug ("target_idx %d, protocol 0x%x\n" , target_idx, protocol); +pr_debug ("target_idx %d, protocol 0x%x\n" , target->idx, protocol);if ((atomic_read (&ndev->state) !=NCI_W4_HOST_SELECT ) && (atomic_read (&ndev->state) !=NCI_POLL_ACTIVE )) {
@@ -459,25 +459,25 @@ static int nci_activate_target(struct nfc_dev *nfc_dev, __u32 target_idx, }for (i =0 ; i < ndev->n_targets; i++) { -if (ndev->targets[i].idx == target_idx) { - target = &ndev->targets[i]; +if (ndev->targets[i].idx == target->idx) { + nci_target = &ndev->targets[i];break ; } } -if (!target) { +if (!nci_target) {pr_err ("unable to find the selected target\n" );return -EINVAL ; } -if (!(target->supported_protocols & (1 << protocol))) { +if (!(nci_target->supported_protocols & (1 << protocol))) {pr_err ("target does not support the requested protocol 0x%x\n" , protocol);return -EINVAL ; }if (atomic_read (&ndev->state) ==NCI_W4_HOST_SELECT ) { - param.rf_discovery_id = target->logical_idx; + param.rf_discovery_id = nci_target->logical_idx;if (protocol ==NFC_PROTO_JEWEL ) param.rf_protocol =NCI_RF_PROTOCOL_T1T ;
@@ -501,11 +501,12 @@ static int nci_activate_target(struct nfc_dev *nfc_dev, __u32 target_idx,return rc; } -static void nci_deactivate_target (struct nfc_dev *nfc_dev,__u32 target_idx) +static void nci_deactivate_target (struct nfc_dev *nfc_dev, +struct nfc_target *target) {struct nci_dev *ndev =nfc_get_drvdata (nfc_dev); -pr_debug ("target_idx %d\n" , target_idx); +pr_debug ("target_idx %d\n" , target->idx);if (!ndev->target_active_prot) {pr_err ("unable to deactivate target, no active target\n" );
@@ -520,14 +521,14 @@ static void nci_deactivate_target(struct nfc_dev *nfc_dev, __u32 target_idx) } } -static int nci_data_exchange (struct nfc_dev *nfc_dev,__u32 target_idx, +static int nci_data_exchange (struct nfc_dev *nfc_dev,struct nfc_target *target,struct sk_buff *skb,data_exchange_cb_t cb,void *cb_context) {struct nci_dev *ndev =nfc_get_drvdata (nfc_dev);int rc; -pr_debug ("target_idx %d, len %d\n" , target_idx, skb->len); +pr_debug ("target_idx %d, len %d\n" , target->idx, skb->len);if (!ndev->target_active_prot) {pr_err ("unable to exchange data, no active target\n" );
Signature · 1 line
1.7.9.1
PATCH 3/20 NFC: Remove useless HCI private nfc target table
In reply to Samuel OrtizFrom: Eric Lapuyade <[email protected]>
--- include/net/nfc/hci.h | 2 -- net/nfc/hci/core.c | 7 ------- 2 files changed, 0 insertions(+), 9 deletions(-)
include/net/nfc/hci.h +0 -2
@@ -83,8 +83,6 @@ struct nfc_hci_dev {u8 gate2pipe[NFC_HCI_MAX_GATES ];bool poll_started; -struct nfc_target *targets; -int target_count;u8 sw_romlib;u8 sw_patch;
net/nfc/hci/core.c +0 -7
@@ -235,13 +235,6 @@ static int nfc_hci_target_discovered(struct nfc_hci_dev *hdev, u8 gate) targets->hci_reader_gate = gate; r =nfc_targets_found (hdev->ndev, targets,1 ); -if (r <0 ) - goto exit; - -kfree (hdev->targets); - hdev->targets = targets; - targets =NULL ; - hdev->target_count =1 ; exit:kfree (targets);
Signature · 1 line
1.7.9.1
PATCH 4/20 NFC: Specify usage for targets found and target lost events
In reply to Samuel OrtizFrom: Eric Lapuyade <[email protected]>
It is now specified that nfc_target_found() and nfc_target_lost() core functions must not be called from an atomic context. This allow us to serialize calls and protect the targets table using the nfc device lock instead of a spinlock.
--- include/net/nfc/nfc.h | 1 - net/nfc/core.c | 35 ++++++++++++++++++++++++++--------- net/nfc/netlink.c | 4 ++-- 3 files changed, 28 insertions(+), 12 deletions(-)
include/net/nfc/nfc.h +0 -1
@@ -97,7 +97,6 @@ struct nfc_dev {struct nfc_target *targets;int n_targets;int targets_generation; -spinlock_t targets_lock;struct device dev;bool dev_up;bool polling;
net/nfc/core.c +26 -9
@@ -501,6 +501,9 @@ EXPORT_SYMBOL(nfc_alloc_recv_skb);* The device driver must call this function when one or many nfc targets * are found. After calling this function, the device driver must stop * polling for targets. +* IMPORTANT: this function must not be called from an atomic context. +* In addition, it must also not be called from a context that would prevent +* the NFC Core to call other nfc ops entry point concurrently. */ int nfc_targets_found (struct nfc_dev *dev,struct nfc_target *targets,int n_targets)
@@ -514,7 +517,7 @@ int nfc_targets_found(struct nfc_dev *dev,for (i =0 ; i < n_targets; i++) targets[i].idx = dev->target_next_idx++; -spin_lock_bh (&dev->targets_lock); +device_lock (&dev->dev); dev->targets_generation++;
@@ -524,12 +527,12 @@ int nfc_targets_found(struct nfc_dev *dev,if (!dev->targets) { dev->n_targets =0 ; -spin_unlock_bh (&dev->targets_lock); +device_unlock (&dev->dev);return -ENOMEM ; } dev->n_targets = n_targets; -spin_unlock_bh (&dev->targets_lock); +device_unlock (&dev->dev);nfc_genl_targets_found (dev);
@@ -537,6 +540,18 @@ int nfc_targets_found(struct nfc_dev *dev, }EXPORT_SYMBOL (nfc_targets_found); +/** +* nfc_target_lost - inform that an activated target went out of field +* +* @dev: The nfc device that had the activated target in field +* @target_idx: the nfc index of the target +* +* The device driver must call this function when the activated target +* goes out of the field. +* IMPORTANT: this function must not be called from an atomic context. +* In addition, it must also not be called from a context that would prevent +* the NFC Core to call other nfc ops entry point concurrently. +*/ int nfc_target_lost (struct nfc_dev *dev,u32 target_idx) {struct nfc_target *tg;
@@ -544,7 +559,7 @@ int nfc_target_lost(struct nfc_dev *dev, u32 target_idx)pr_debug ("dev_name %s n_target %d\n" ,dev_name (&dev->dev), target_idx); -spin_lock_bh (&dev->targets_lock); +device_lock (&dev->dev);for (i =0 ; i < dev->n_targets; i++) { tg = &dev->targets[i];
@@ -553,7 +568,7 @@ int nfc_target_lost(struct nfc_dev *dev, u32 target_idx) }if (i == dev->n_targets) { -spin_unlock_bh (&dev->targets_lock); +device_unlock (&dev->dev);return -EINVAL ; }
@@ -569,7 +584,7 @@ int nfc_target_lost(struct nfc_dev *dev, u32 target_idx) dev->targets =NULL ; } -spin_unlock_bh (&dev->targets_lock); +device_unlock (&dev->dev);nfc_genl_target_lost (dev, target_idx);
@@ -607,8 +622,10 @@ static void nfc_check_pres_work(struct work_struct *work)mod_timer (&dev->check_pres_timer, jiffies +msecs_to_jiffies (NFC_CHECK_PRES_FREQ_MS )); }else { -nfc_target_lost (dev, dev->active_target->idx); - dev->active_target =NULL ; +u32 active_target_idx = dev->active_target->idx; +device_unlock (&dev->dev); +nfc_target_lost (dev, active_target_idx); +return ; } }
@@ -681,9 +698,9 @@ struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops, dev->tx_headroom = tx_headroom; dev->tx_tailroom = tx_tailroom; -spin_lock_init (&dev->targets_lock);nfc_genl_data_init (&dev->genl_data); +/* first generation must not be 0 */ dev->targets_generation =1 ;
net/nfc/netlink.c +2 -2
@@ -124,7 +124,7 @@ static int nfc_genl_dump_targets(struct sk_buff *skb, cb->args[1 ] = (long ) dev; } -spin_lock_bh (&dev->targets_lock); +device_lock (&dev->dev); cb->seq = dev->targets_generation;
@@ -137,7 +137,7 @@ static int nfc_genl_dump_targets(struct sk_buff *skb, i++; } -spin_unlock_bh (&dev->targets_lock); +device_unlock (&dev->dev); cb->args[0 ] = i;
Signature · 1 line
1.7.9.1
PATCH 5/20 NFC: Add HCI/SHDLC support to let driver check for tag presence
In reply to Samuel OrtizFrom: Eric Lapuyade <[email protected]>
--- include/net/nfc/hci.h | 2 ++ include/net/nfc/shdlc.h | 2 ++ net/nfc/hci/core.c | 12 ++++++++++++ net/nfc/hci/shdlc.c | 12 ++++++++++++ 4 files changed, 28 insertions(+), 0 deletions(-)
include/net/nfc/hci.h +2 -0
@@ -39,6 +39,8 @@ struct nfc_hci_ops {int (*data_exchange) (struct nfc_hci_dev *hdev,struct nfc_target *target,struct sk_buff *skb,struct sk_buff **res_skb); +int (*check_presence)(struct nfc_hci_dev *hdev, +struct nfc_target *target); };#define NFC_HCI_MAX_CUSTOM_GATES 15
include/net/nfc/shdlc.h +2 -0
@@ -35,6 +35,8 @@ struct nfc_shdlc_ops {int (*data_exchange) (struct nfc_shdlc *shdlc,struct nfc_target *target,struct sk_buff *skb,struct sk_buff **res_skb); +int (*check_presence)(struct nfc_shdlc *shdlc, +struct nfc_target *target); };enum shdlc_state {
net/nfc/hci/core.c +12 -0
@@ -574,6 +574,17 @@ static int hci_data_exchange(struct nfc_dev *nfc_dev, struct nfc_target *target,return 0 ; } +static int hci_check_presence (struct nfc_dev *nfc_dev, +struct nfc_target *target) +{ +struct nfc_hci_dev *hdev =nfc_get_drvdata (nfc_dev); + +if (hdev->ops->check_presence) +return hdev->ops->check_presence (hdev, target); + +return 0 ; +} +struct nfc_ops hci_nfc_ops = { .dev_up = hci_dev_up, .dev_down = hci_dev_down,
@@ -582,6 +593,7 @@ struct nfc_ops hci_nfc_ops = { .activate_target = hci_activate_target, .deactivate_target = hci_deactivate_target, .data_exchange = hci_data_exchange, + .check_presence = hci_check_presence, }; struct nfc_hci_dev *nfc_hci_allocate_device(struct nfc_hci_ops *ops,
net/nfc/hci/shdlc.c +12 -0
@@ -816,6 +816,17 @@ static int nfc_shdlc_data_exchange(struct nfc_hci_dev *hdev,return -EPERM ; } +static int nfc_shdlc_check_presence (struct nfc_hci_dev *hdev, +struct nfc_target *target) +{ +struct nfc_shdlc *shdlc =nfc_hci_get_clientdata (hdev); + +if (shdlc->ops->check_presence) +return shdlc->ops->check_presence (shdlc, target); + +return 0 ; +} +static struct nfc_hci_ops shdlc_ops = { .open = nfc_shdlc_open, .close = nfc_shdlc_close,
@@ -825,6 +836,7 @@ static struct nfc_hci_ops shdlc_ops = { .target_from_gate = nfc_shdlc_target_from_gate, .complete_target_discovered = nfc_shdlc_complete_target_discovered, .data_exchange = nfc_shdlc_data_exchange, + .check_presence = nfc_shdlc_check_presence, }; struct nfc_shdlc *nfc_shdlc_allocate(struct nfc_shdlc_ops *ops,
Signature · 1 line
1.7.9.1
PATCH 6/20 NFC: Update Documentation/nfc-hci.txt
In reply to Samuel OrtizFrom: Eric Lapuyade <[email protected]>
Document the new HCI ops and fix a few typos and spelling mistakes.
--- Documentation/nfc/nfc-hci.txt | 45 +++++++++++++++++++++++++++++++--------- 1 files changed, 35 insertions(+), 10 deletions(-)
Documentation/nfc/nfc-hci.txt +35 -10
@@ -22,9 +22,9 @@ response to arrive. HCI events can also be received from the host controller. They will be handled and a translation will be forwarded to NFC Core as needed. HCI uses 2 execution contexts: -- one if for executing commands : nfc_hci_msg_tx_work(). Only one command +- one for executing commands : nfc_hci_msg_tx_work(). Only one command can be executing at any given moment. -- one if for dispatching received events and responses : nfc_hci_msg_rx_work() +- one for dispatching received events and commands : nfc_hci_msg_rx_work(). HCI Session initialization: ---------------------------
@@ -52,18 +52,42 @@ entry points: struct nfc_hci_ops { int (*open)(struct nfc_hci_dev *hdev); void (*close)(struct nfc_hci_dev *hdev); + int (*hci_ready) (struct nfc_hci_dev *hdev); int (*xmit)(struct nfc_hci_dev *hdev, struct sk_buff *skb); int (*start_poll)(struct nfc_hci_dev *hdev, u32 protocols); int (*target_from_gate)(struct nfc_hci_dev *hdev, u8 gate, struct nfc_target *target); + int (*complete_target_discovered) (struct nfc_hci_dev *hdev, u8 gate, + struct nfc_target *target); + int (*data_exchange) (struct nfc_hci_dev *hdev, + struct nfc_target *target, + struct sk_buff *skb, struct sk_buff **res_skb); + int (*check_presence)(struct nfc_hci_dev *hdev, + struct nfc_target *target); }; -open() and close() shall turn the hardware on and off. xmit() shall simply -write a frame to the chip. start_poll() is an optional entrypoint that shall -set the hardware in polling mode. This must be implemented only if the hardware -uses proprietary gates or a mechanism slightly different from the HCI standard. -target_from_gate() is another optional entrypoint to return the protocols +- open() and close() shall turn the hardware on and off. +- hci_ready() is an optional entry point that is called right after the hci +session has been set up. The driver can use it to do additional initialization +that must be performed using HCI commands. +- xmit() shall simply write a frame to the chip. +- start_poll() is an optional entrypoint that shall set the hardware in polling +mode. This must be implemented only if the hardware uses proprietary gates or a +mechanism slightly different from the HCI standard. +- target_from_gate() is an optional entrypoint to return the nfc protocols corresponding to a proprietary gate. +- complete_target_discovered() is an optional entry point to let the driver +perform additional proprietary processing necessary to auto activate the +discovered target. +- data_exchange() must be implemented by the driver if proprietary HCI commands +are required to send data to the tag. Some tag types will require custom +commands, others can be written to using the standard HCI commands. The driver +can check the tag type and either do proprietary processing, or return 1 to ask +for standard processing. +- check_presence() is an optional entry point that will be called regularly +by the core to check that an activated tag is still in the field. If this is +not implemented, the core will not be able to push tag_lost events to the user +space On the rx path, the driver is responsible to push incoming HCP frames to HCI using nfc_hci_recv_frame(). HCI will take care of re-aggregation and handling
@@ -99,7 +123,8 @@ fast, cannot sleep. stores incoming frames into an shdlc rx queue handles shdlc rx & tx queues. Dispatches HCI cmd responses. - HCI Tx Cmd worker (MSGTXWQ) -Serialize execution of HCI commands. Complete execution in case of resp timeout. +Serializes execution of HCI commands. Completes execution in case of response +timeout. - HCI Rx worker (MSGRXWQ) Dispatches incoming HCI commands or events.
@@ -133,11 +158,11 @@ able to complete the command with a timeout error if no response arrive. SMW context gets scheduled and invokes nfc_shdlc_sm_work(). This function handles shdlc framing in and out. It uses the driver xmit to send frames and receives incoming frames in an skb queue filled from the driver IRQ handler. -SHDLC I(nformation) frames payload are HCP fragments. They are agregated to +SHDLC I(nformation) frames payload are HCP fragments. They are aggregated to form complete HCI frames, which can be a response, command, or event. HCI Responses are dispatched immediately from this context to unblock -waiting command execution. Reponse processing involves invoking the completion +waiting command execution. Response processing involves invoking the completion callback that was provided by nfc_hci_msg_tx_work() when it sent the command. The completion callback will then wake the syscall context.
Signature · 1 line
1.7.9.1
PATCH 7/20 NFC: Remove unneeded pn533 dev NULL check
In reply to Samuel OrtizFrom: Dan Carpenter <[email protected]>
container_of() works by subtracting the offset of the member. The math can't really return a zero here. Sometimes people check it when they actually meant to check something else but in this case we can just remove the check.
--- drivers/nfc/pn533.c | 3 --- 1 files changed, 0 insertions(+), 3 deletions(-)
drivers/nfc/pn533.c +0 -3
@@ -394,9 +394,6 @@ static void pn533_wq_cmd_complete(struct work_struct *work)struct pn533_frame *in_frame;int rc; -if (dev ==NULL ) -return ; - in_frame = dev->wq_in_frame;if (dev->wq_in_error)
Signature · 1 line
1.7.9.1
PATCH 8/20 NFC: LLCP connect must wait for a CC frame
In reply to Samuel OrtizBlocking sockets should sleep on a CC (Connection Complete) reception from the connect() call.
--- net/nfc/llcp/llcp.c | 7 +++++++ net/nfc/llcp/sock.c | 42 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 48 insertions(+), 1 deletions(-)
net/nfc/llcp/llcp.c +7 -0
@@ -448,6 +448,8 @@ static struct nfc_llcp_sock *nfc_llcp_sock_get(struct nfc_llcp_local *local, {struct nfc_llcp_sock *sock, *llcp_sock, *n; +pr_debug ("ssap dsap %d %d\n" , ssap, dsap); +if (ssap ==0 && dsap ==0 )return NULL ;
@@ -783,6 +785,7 @@ static void nfc_llcp_recv_disc(struct nfc_llcp_local *local,static void nfc_llcp_recv_cc (struct nfc_llcp_local *local,struct sk_buff *skb) {struct nfc_llcp_sock *llcp_sock; +struct sock *sk;u8 dsap, ssap; dsap =nfc_llcp_dsap (skb);
@@ -801,10 +804,14 @@ static void nfc_llcp_recv_cc(struct nfc_llcp_local *local, struct sk_buff *skb) } llcp_sock->dsap = ssap; + sk = &llcp_sock->sk;nfc_llcp_parse_tlv (local, &skb->data[LLCP_HEADER_SIZE ], skb->len -LLCP_HEADER_SIZE ); + sk->sk_state =LLCP_CONNECTED ; + sk->sk_state_change (sk); +nfc_llcp_sock_put (llcp_sock); }
net/nfc/llcp/sock.c +41 -1
56 lines not on this page · raw message
Signature · 1 line
1.7.9.1
PATCH 9/20 NFC: Update the LLCP poll mask
In reply to Samuel OrtizFix the poll mask depending on the socket state. POLLOUT was missing for example.
--- net/nfc/llcp/sock.c | 15 ++++++++++++++- 1 files changed, 14 insertions(+), 1 deletions(-)
net/nfc/llcp/sock.c +14 -1
@@ -340,11 +340,24 @@ static unsigned int llcp_sock_poll(struct file *file, struct socket *sock, mask |=POLLERR ;if (!skb_queue_empty (&sk->sk_receive_queue)) - mask |=POLLIN ; + mask |=POLLIN |POLLRDNORM ;if (sk->sk_state ==LLCP_CLOSED ) mask |=POLLHUP ; +if (sk->sk_shutdown &RCV_SHUTDOWN ) + mask |=POLLRDHUP |POLLIN |POLLRDNORM ; + +if (sk->sk_shutdown ==SHUTDOWN_MASK ) + mask |=POLLHUP ; + +if (sock_writeable (sk)) + mask |=POLLOUT |POLLWRNORM |POLLWRBAND ; +else +set_bit (SOCK_ASYNC_NOSPACE , &sk->sk_socket->flags); + +pr_debug ("mask 0x%x\n" , mask); +return mask; }
Signature · 1 line
1.7.9.1
PATCH 10/20 NFC: Return the amount of LLCP bytes queued to sock_sendmsg
In reply to Samuel OrtizOtherwise an LLCP send() always returns 0.
--- net/nfc/llcp/commands.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
net/nfc/llcp/commands.c +1 -1
@@ -502,7 +502,7 @@ int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock,kfree (msg_data); -return 0 ; +return len; }int nfc_llcp_send_rr (struct nfc_llcp_sock *sock)
Signature · 1 line
1.7.9.1
PATCH 11/20 NFC: Send device index instead of its name when target is lost
In reply to Samuel Ortiz--- net/nfc/netlink.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
net/nfc/netlink.c +1 -1
@@ -197,7 +197,7 @@ int nfc_genl_target_lost(struct nfc_dev *dev, u32 target_idx)if (!hdr) goto free_msg; -if (nla_put_string (msg,NFC_ATTR_DEVICE_NAME ,nfc_device_name (dev))) +if (nla_put_u32 (msg,NFC_ATTR_DEVICE_INDEX , dev->idx)) goto nla_put_failure;if (nla_put_u32 (msg,NFC_ATTR_TARGET_INDEX , target_idx)) goto nla_put_failure;
Signature · 1 line
1.7.9.1
PATCH 12/20 NFC: Fix LLCP compilation warning
In reply to Samuel OrtizFrom: joseph daniel <[email protected]>
nfc_llcp_general_bytes is defined in nfc/core.c as:nfc_llcp_general_bytes(struct nfc_dev *dev, size_t *gb_len).
as in nfc/nfc.h:nfc_llcp_general_bytes(struct nfc_dev *dev, u8 *gb_len), if CONFIG_NFC_LLCP is not defined.
so we got some warnings,net/nfc/core.c:207:2: warning: passing argument 2 of ‘nfc_llcp_general_bytes’ from incompatible pointer type [enabled by default] net/nfc/nfc.h:87:19: note: expected ‘u8 *’ but argument is of type ‘size_t *’
--- net/nfc/nfc.h | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
net/nfc/nfc.h +1 -1
@@ -84,7 +84,7 @@ static inline int nfc_llcp_set_remote_gb(struct nfc_dev *dev,return 0 ; } -static inline u8 *nfc_llcp_general_bytes (struct nfc_dev *dev,u8 *gb_len) +static inline u8 *nfc_llcp_general_bytes (struct nfc_dev *dev,size_t *gb_len) { *gb_len =0 ;return NULL ;
Signature · 1 line
1.7.9.1
PATCH 13/20 NFC: Quiet nci/data.c sparse noise about plain integer as NULL pointer
In reply to Samuel OrtizFrom: H Hartley Sweeten <[email protected]>
Pointers should be cleared with NULL, not 0.
Quiets a couple sparse warnings of the type:
warning: Using plain integer as NULL pointer
--- net/nfc/nci/data.c | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-)
net/nfc/nci/data.c +4 -4
@@ -49,7 +49,7 @@ void nci_data_exchange_complete(struct nci_dev *ndev, struct sk_buff *skb,if (cb) { ndev->data_exchange_cb =NULL ; - ndev->data_exchange_cb_context =0 ; + ndev->data_exchange_cb_context =NULL ;/* forward skb to nfc core */ cb (cb_context, skb, err);
@@ -200,10 +200,10 @@ static void nci_add_rx_data_frag(struct nci_dev *ndev,pr_err ("error adding room for accumulated rx data\n" );kfree_skb (skb); - skb =0 ; + skb =NULL ;kfree_skb (ndev->rx_data_reassembly); - ndev->rx_data_reassembly =0 ; + ndev->rx_data_reassembly =NULL ; err = -ENOMEM ; goto exit;
@@ -216,7 +216,7 @@ static void nci_add_rx_data_frag(struct nci_dev *ndev,/* third, free old reassembly */ kfree_skb (ndev->rx_data_reassembly); - ndev->rx_data_reassembly =0 ; + ndev->rx_data_reassembly =NULL ; }if (pbf ==NCI_PBF_CONT ) {
Signature · 1 line
1.7.9.1
PATCH 14/20 NFC: Include nci_core.h to nci/lib.c
In reply to Samuel OrtizFrom: H Hartley Sweeten <[email protected]>
Include the header to pickup the exported symbol prototype.
Quites the sparse warning:
warning: symbol 'nci_to_errno' was not declared. Should it be static?
--- net/nfc/nci/lib.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-)
net/nfc/nci/lib.c +1 -0
@@ -31,6 +31,7 @@#include <linux/errno.h> #include <net/nfc/nci.h> +#include <net/nfc/nci_core.h> /* NCI status codes to Unix errno mapping */ int nci_to_errno (__u8 code)
Signature · 1 line
1.7.9.1
PATCH 15/20 NFC: Quiet nci/ntf.c sparse noise about plain integer as NULL pointer
In reply to Samuel OrtizFrom: H Hartley Sweeten <[email protected]>
Pointers should be cleared with NULL, not 0.
Quiets a couple sparse warnings of the type:
warning: Using plain integer as NULL pointer
--- net/nfc/nci/ntf.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
net/nfc/nci/ntf.c +1 -1
@@ -497,7 +497,7 @@ static void nci_rf_deactivate_ntf_packet(struct nci_dev *ndev,/* drop partial rx data packet */ if (ndev->rx_data_reassembly) {kfree_skb (ndev->rx_data_reassembly); - ndev->rx_data_reassembly =0 ; + ndev->rx_data_reassembly =NULL ; }/* complete the data exchange transaction, if exists */
Signature · 1 line
1.7.9.1
PATCH 16/20 NFC: HCI ops should not be exposed globally
In reply to Samuel OrtizFrom: H Hartley Sweeten <[email protected]>
The variable 'hci_nfc_ops' is only referenced in this file and should be marked static to prevent it from being exposed globally.
Quites the sparse warning:
warning: symbol 'hci_nfc_ops' was not declared. Should it be static?
--- net/nfc/hci/core.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
net/nfc/hci/core.c +1 -1
@@ -585,7 +585,7 @@ static int hci_check_presence(struct nfc_dev *nfc_dev,return 0 ; } -struct nfc_ops hci_nfc_ops = { +static struct nfc_ops hci_nfc_ops = { .dev_up = hci_dev_up, .dev_down = hci_dev_down, .start_poll = hci_start_poll,
Signature · 1 line
1.7.9.1
PATCH 17/20 NFC: The NFC genl family structure should not be exposed globally
In reply to Samuel OrtizFrom: H Hartley Sweeten <[email protected]>
The variable 'nfc_genl_family' is only referenced in this file and should be marked static to prevent it from being exposed globally.
Quites the sparse warning:
warning: symbol 'nfc_genl_family' was not declared. Should it be static?
--- net/nfc/netlink.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
net/nfc/netlink.c +1 -1
@@ -33,7 +33,7 @@ static struct genl_multicast_group nfc_genl_event_mcgrp = { .name = NFC_GENL_MCAST_EVENT_NAME, }; -struct genl_family nfc_genl_family = { +static struct genl_family nfc_genl_family = { .id =GENL_ID_GENERATE , .hdrsize =0 , .name =NFC_GENL_NAME ,
Signature · 1 line
1.7.9.1
PATCH 18/20 NFC: HCI based pn544 driver
In reply to Samuel OrtizFrom: Eric Lapuyade <[email protected]>
This is an NFC driver for NXP pn544.
Unlike pn544.c, this one is based on the NFC HCI and SHDLC kernel layers.
--- drivers/nfc/Kconfig | 13 + drivers/nfc/Makefile | 1 + drivers/nfc/pn544_hci.c | 947 +++++++++++++++++++++++++++++++++++++++++++++ include/linux/nfc/pn544.h | 7 + 4 files changed, 968 insertions(+), 0 deletions(-) create mode 100644 drivers/nfc/pn544_hci.c
drivers/nfc/Kconfig +13 -0
@@ -17,6 +17,19 @@ config PN544_NFC To compile this driver as a module, choose m here. The module will be called pn544. +config PN544_HCI_NFC + tristate "HCI PN544 NFC driver" + depends on I2C && NFC_SHDLC + select CRC_CCITT + default n + ---help--- + NXP PN544 i2c driver. + This is a driver based on the SHDLC and HCI NFC kernel layers and + will thus not work with NXP libnfc library. + + To compile this driver as a module, choose m here. The module will + be called pn544_hci. + config NFC_PN533 tristate "NXP PN533 USB driver" depends on USB
drivers/nfc/Makefile +1 -0
@@ -3,6 +3,7 @@ # obj-$(CONFIG_PN544_NFC) += pn544.o +obj-$(CONFIG_PN544_HCI_NFC) += pn544_hci.o obj-$(CONFIG_NFC_PN533) += pn533.o obj-$(CONFIG_NFC_WILINK) += nfcwilink.o
drivers/nfc/pn544_hci.c new file +947 -0
947 lines not on this page · raw message
include/linux/nfc/pn544.h +7 -0
@@ -84,6 +84,12 @@ struct pn544_fw_packet { }; #ifdef __KERNEL__ +enum { + NFC_GPIO_ENABLE, + NFC_GPIO_FW_RESET, + NFC_GPIO_IRQ +}; + /* board config */ struct pn544_nfc_platform_data { int (*request_resources) (struct i2c_client *client);
@@ -91,6 +97,7 @@ struct pn544_nfc_platform_data {void (*enable) (int fw);int (*test) (void );void (*disable) (void ); + int (*get_gpio)(int type); };#endif /* __KERNEL__ */
Signature · 1 line
1.7.9.1
PATCH 19/20 feature-removal: Remove pn544 raw driver
In reply to Samuel OrtizThe pn544_hci driver uses the kernel NFC APIs while pn544 does not. Moreover pn544 is outdated and not maintained.
--- Documentation/feature-removal-schedule.txt | 12 ++++++++++++ 1 files changed, 12 insertions(+), 0 deletions(-)
Documentation/feature-removal-schedule.txt +12 -0
@@ -531,3 +531,15 @@ Why: There appear to be no production users of the get_robust_list syscall, of ASLR. It was only ever intended for debugging, so it should be removed. Who: Kees Cook <[email protected]> + +---------------------------- + +What: Removing the pn544 raw driver. +When: 3.6 +Why: With the introduction of the NFC HCI and SHDL kernel layers, pn544.c + is being replaced by pn544_hci.c which is accessible through the netlink + and socket NFC APIs. Moreover, pn544.c is outdated and does not seem to + work properly with the latest Android stacks. + Having 2 drivers for the same hardware is confusing and as such we + should only keep the one following the kernel NFC APIs. +Who: Samuel Ortiz <[email protected]>
Signature · 1 line
1.7.9.1
PATCH 20/20 NFC: HCI drivers don't have to keep track of polling state
In reply to Samuel OrtizFrom: Eric Lapuyade <[email protected]>
The NFC core code already does that for them.
--- include/net/nfc/hci.h | 2 -- net/nfc/hci/core.c | 21 ++++----------------- 2 files changed, 4 insertions(+), 19 deletions(-)
include/net/nfc/hci.h +0 -2
@@ -84,8 +84,6 @@ struct nfc_hci_dev {u8 gate2pipe[NFC_HCI_MAX_GATES ]; -bool poll_started; -u8 sw_romlib;u8 sw_patch;u8 sw_flashlib_major;
net/nfc/hci/core.c +4 -17
@@ -251,11 +251,6 @@ void nfc_hci_event_received(struct nfc_hci_dev *hdev, u8 pipe, u8 event,switch (event) {case NFC_HCI_EVT_TARGET_DISCOVERED : -if (hdev->poll_started == false) { - r = -EPROTO ; - goto exit; - } -if (skb->len <1 ) {/* no status data? */ r = -EPROTO ; goto exit;
@@ -489,28 +484,20 @@ static int hci_dev_down(struct nfc_dev *nfc_dev)static int hci_start_poll (struct nfc_dev *nfc_dev,u32 protocols) {struct nfc_hci_dev *hdev =nfc_get_drvdata (nfc_dev); -int r;if (hdev->ops->start_poll) - r = hdev->ops->start_poll (hdev, protocols); +return hdev->ops->start_poll (hdev, protocols);else - r =nfc_hci_send_event (hdev,NFC_HCI_RF_READER_A_GATE , +return nfc_hci_send_event (hdev,NFC_HCI_RF_READER_A_GATE ,NFC_HCI_EVT_READER_REQUESTED ,NULL ,0 ); -if (r ==0 ) - hdev->poll_started = true; - -return r; }static void hci_stop_poll (struct nfc_dev *nfc_dev) {struct nfc_hci_dev *hdev =nfc_get_drvdata (nfc_dev); -if (hdev->poll_started) { -nfc_hci_send_event (hdev,NFC_HCI_RF_READER_A_GATE , -NFC_HCI_EVT_END_OPERATION ,NULL ,0 ); - hdev->poll_started = false; - } +nfc_hci_send_event (hdev,NFC_HCI_RF_READER_A_GATE , +NFC_HCI_EVT_END_OPERATION ,NULL ,0 ); } static int hci_activate_target(struct nfc_dev *nfc_dev,
Signature · 1 line
1.7.9.1