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;
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;
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);
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;
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;
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;
goto error;
}
- if (dev->polling || dev->activated_target_idx != NFC_TARGET_IDX_NONE) {
+ if (dev->polling || dev->active_target) {
rc = -EBUSY;
goto error;
}
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);
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);
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);
}
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);
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 +
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);
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;
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 +
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],
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;
}
}
/* 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);
}
}
-
return dev;
}
EXPORT_SYMBOL(nfc_allocate_device);
}
}
-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:
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)) {
}
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;
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");
}
}
-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");