Skip to content

Commit

Permalink
NFC: Cache the core NFC active target pointer instead of its index
Browse files Browse the repository at this point in the history
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.

Cc: Ilan Elias <ilane@ti.com>
Signed-off-by: Eric Lapuyade <eric.lapuyade@intel.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Eric Lapuyade authored and linvjw committed May 15, 2012
1 parent 536acc0 commit 9009943
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 79 deletions.
16 changes: 8 additions & 8 deletions drivers/nfc/pn533.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -1552,10 +1553,9 @@ static int pn533_data_exchange_complete(struct pn533 *dev, void *_arg,
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;
Expand Down
18 changes: 10 additions & 8 deletions include/net/nfc/nfc.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 0xffffffff

struct nfc_target {
u32 idx;
Expand Down Expand Up @@ -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;
Expand Down
81 changes: 61 additions & 20 deletions net/nfc/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ int nfc_dev_down(struct nfc_dev *dev)
goto error;
}

if (dev->polling || dev->activated_target_idx != NFC_TARGET_IDX_NONE) {
if (dev->polling || dev->active_target) {
rc = -EBUSY;
goto error;
}
Expand Down Expand Up @@ -183,11 +183,27 @@ int nfc_stop_poll(struct nfc_dev *dev)
return rc;
}

static struct nfc_target *nfc_find_target(struct nfc_dev *dev, u32 target_idx)
{
int i;

if (dev->n_targets == 0)
return NULL;

for (i = 0; i < dev->n_targets ; i++) {
if (dev->targets[i].idx == target_idx)
return &dev->targets[i];
}

return NULL;
}

int nfc_dep_link_up(struct nfc_dev *dev, int target_index, u8 comm_mode)
{
int rc = 0;
u8 *gb;
size_t gb_len;
struct nfc_target *target;

pr_debug("dev_name=%s comm %d\n", dev_name(&dev->dev), comm_mode);

Expand All @@ -212,9 +228,15 @@ int nfc_dep_link_up(struct nfc_dev *dev, int target_index, u8 comm_mode)
goto error;
}

rc = dev->ops->dep_link_up(dev, target_index, comm_mode, gb, gb_len);
target = nfc_find_target(dev, target_index);
if (target == NULL) {
rc = -ENOTCONN;
goto error;
}

rc = dev->ops->dep_link_up(dev, target, comm_mode, gb, gb_len);
if (!rc)
dev->activated_target_idx = target_index;
dev->active_target = target;

error:
device_unlock(&dev->dev);
Expand Down Expand Up @@ -250,7 +272,7 @@ int nfc_dep_link_down(struct nfc_dev *dev)
rc = dev->ops->dep_link_down(dev);
if (!rc) {
dev->dep_link_up = false;
dev->activated_target_idx = NFC_TARGET_IDX_NONE;
dev->active_target = NULL;
nfc_llcp_mac_is_down(dev);
nfc_genl_dep_link_down_event(dev);
}
Expand Down Expand Up @@ -282,6 +304,7 @@ EXPORT_SYMBOL(nfc_dep_link_is_up);
int nfc_activate_target(struct nfc_dev *dev, u32 target_idx, u32 protocol)
{
int rc;
struct nfc_target *target;

pr_debug("dev_name=%s target_idx=%u protocol=%u\n",
dev_name(&dev->dev), target_idx, protocol);
Expand All @@ -293,9 +316,20 @@ int nfc_activate_target(struct nfc_dev *dev, u32 target_idx, u32 protocol)
goto error;
}

rc = dev->ops->activate_target(dev, target_idx, protocol);
if (dev->active_target) {
rc = -EBUSY;
goto error;
}

target = nfc_find_target(dev, target_idx);
if (target == NULL) {
rc = -ENOTCONN;
goto error;
}

rc = dev->ops->activate_target(dev, target, protocol);
if (!rc) {
dev->activated_target_idx = target_idx;
dev->active_target = target;

if (dev->ops->check_presence)
mod_timer(&dev->check_pres_timer, jiffies +
Expand Down Expand Up @@ -327,11 +361,21 @@ int nfc_deactivate_target(struct nfc_dev *dev, u32 target_idx)
goto error;
}

if (dev->active_target == NULL) {
rc = -ENOTCONN;
goto error;
}

if (dev->active_target->idx != target_idx) {
rc = -ENOTCONN;
goto error;
}

if (dev->ops->check_presence)
del_timer_sync(&dev->check_pres_timer);

dev->ops->deactivate_target(dev, target_idx);
dev->activated_target_idx = NFC_TARGET_IDX_NONE;
dev->ops->deactivate_target(dev, dev->active_target);
dev->active_target = NULL;

error:
device_unlock(&dev->dev);
Expand Down Expand Up @@ -365,13 +409,13 @@ int nfc_data_exchange(struct nfc_dev *dev, u32 target_idx, struct sk_buff *skb,
goto error;
}

if (dev->activated_target_idx == NFC_TARGET_IDX_NONE) {
if (dev->active_target == NULL) {
rc = -ENOTCONN;
kfree_skb(skb);
goto error;
}

if (target_idx != dev->activated_target_idx) {
if (dev->active_target->idx != target_idx) {
rc = -EADDRNOTAVAIL;
kfree_skb(skb);
goto error;
Expand All @@ -380,7 +424,8 @@ int nfc_data_exchange(struct nfc_dev *dev, u32 target_idx, struct sk_buff *skb,
if (dev->ops->check_presence)
del_timer_sync(&dev->check_pres_timer);

rc = dev->ops->data_exchange(dev, target_idx, skb, cb, cb_context);
rc = dev->ops->data_exchange(dev, dev->active_target, skb, cb,
cb_context);

if (!rc && dev->ops->check_presence)
mod_timer(&dev->check_pres_timer, jiffies +
Expand Down Expand Up @@ -514,7 +559,7 @@ int nfc_target_lost(struct nfc_dev *dev, u32 target_idx)

dev->targets_generation++;
dev->n_targets--;
dev->activated_target_idx = NFC_TARGET_IDX_NONE;
dev->active_target = NULL;

if (dev->n_targets) {
memcpy(&dev->targets[i], &dev->targets[i + 1],
Expand Down Expand Up @@ -556,15 +601,14 @@ static void nfc_check_pres_work(struct work_struct *work)

device_lock(&dev->dev);

if (dev->activated_target_idx != NFC_TARGET_IDX_NONE &&
timer_pending(&dev->check_pres_timer) == 0) {
rc = dev->ops->check_presence(dev, dev->activated_target_idx);
if (dev->active_target && timer_pending(&dev->check_pres_timer) == 0) {
rc = dev->ops->check_presence(dev, dev->active_target);
if (!rc) {
mod_timer(&dev->check_pres_timer, jiffies +
msecs_to_jiffies(NFC_CHECK_PRES_FREQ_MS));
} else {
nfc_target_lost(dev, dev->activated_target_idx);
dev->activated_target_idx = NFC_TARGET_IDX_NONE;
nfc_target_lost(dev, dev->active_target->idx);
dev->active_target = NULL;
}
}

Expand Down Expand Up @@ -643,8 +687,6 @@ struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops,
/* first generation must not be 0 */
dev->targets_generation = 1;

dev->activated_target_idx = NFC_TARGET_IDX_NONE;

if (ops->check_presence) {
char name[32];
init_timer(&dev->check_pres_timer);
Expand All @@ -662,7 +704,6 @@ struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops,
}
}


return dev;
}
EXPORT_SYMBOL(nfc_allocate_device);
Expand Down
36 changes: 6 additions & 30 deletions net/nfc/hci/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
Loading

0 comments on commit 9009943

Please sign in to comment.