NFC: Implement pn533 polling loop
After going through all the modulations, the pn533 driver spends 2 seconds listening for targets. Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
This commit is contained in:
parent
51d9e803b9
commit
6fbbdc16be
1 changed files with 169 additions and 134 deletions
|
@ -45,6 +45,9 @@ static const struct usb_device_id pn533_table[] = {
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(usb, pn533_table);
|
MODULE_DEVICE_TABLE(usb, pn533_table);
|
||||||
|
|
||||||
|
/* How much time we spend listening for initiators */
|
||||||
|
#define PN533_LISTEN_TIME 2
|
||||||
|
|
||||||
/* frame definitions */
|
/* frame definitions */
|
||||||
#define PN533_FRAME_TAIL_SIZE 2
|
#define PN533_FRAME_TAIL_SIZE 2
|
||||||
#define PN533_FRAME_SIZE(f) (sizeof(struct pn533_frame) + f->datalen + \
|
#define PN533_FRAME_SIZE(f) (sizeof(struct pn533_frame) + f->datalen + \
|
||||||
|
@ -163,6 +166,7 @@ enum {
|
||||||
PN533_POLL_MOD_424KBPS_FELICA,
|
PN533_POLL_MOD_424KBPS_FELICA,
|
||||||
PN533_POLL_MOD_106KBPS_JEWEL,
|
PN533_POLL_MOD_106KBPS_JEWEL,
|
||||||
PN533_POLL_MOD_847KBPS_B,
|
PN533_POLL_MOD_847KBPS_B,
|
||||||
|
PN533_LISTEN_MOD,
|
||||||
|
|
||||||
__PN533_POLL_MOD_AFTER_LAST,
|
__PN533_POLL_MOD_AFTER_LAST,
|
||||||
};
|
};
|
||||||
|
@ -230,6 +234,9 @@ const struct pn533_poll_modulations poll_mod[] = {
|
||||||
},
|
},
|
||||||
.len = 3,
|
.len = 3,
|
||||||
},
|
},
|
||||||
|
[PN533_LISTEN_MOD] = {
|
||||||
|
.len = 0,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
/* PN533_CMD_IN_ATR */
|
/* PN533_CMD_IN_ATR */
|
||||||
|
@ -312,10 +319,13 @@ struct pn533 {
|
||||||
|
|
||||||
struct workqueue_struct *wq;
|
struct workqueue_struct *wq;
|
||||||
struct work_struct cmd_work;
|
struct work_struct cmd_work;
|
||||||
|
struct work_struct poll_work;
|
||||||
struct work_struct mi_work;
|
struct work_struct mi_work;
|
||||||
struct work_struct tg_work;
|
struct work_struct tg_work;
|
||||||
|
struct timer_list listen_timer;
|
||||||
struct pn533_frame *wq_in_frame;
|
struct pn533_frame *wq_in_frame;
|
||||||
int wq_in_error;
|
int wq_in_error;
|
||||||
|
int cancel_listen;
|
||||||
|
|
||||||
pn533_cmd_complete_t cmd_complete;
|
pn533_cmd_complete_t cmd_complete;
|
||||||
void *cmd_complete_arg;
|
void *cmd_complete_arg;
|
||||||
|
@ -326,6 +336,10 @@ struct pn533 {
|
||||||
u8 poll_mod_count;
|
u8 poll_mod_count;
|
||||||
u8 poll_mod_curr;
|
u8 poll_mod_curr;
|
||||||
u32 poll_protocols;
|
u32 poll_protocols;
|
||||||
|
u32 listen_protocols;
|
||||||
|
|
||||||
|
u8 *gb;
|
||||||
|
size_t gb_len;
|
||||||
|
|
||||||
u8 tgt_available_prots;
|
u8 tgt_available_prots;
|
||||||
u8 tgt_active_prot;
|
u8 tgt_active_prot;
|
||||||
|
@ -1006,6 +1020,11 @@ static int pn533_target_found(struct pn533 *dev,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void pn533_poll_next_mod(struct pn533 *dev)
|
||||||
|
{
|
||||||
|
dev->poll_mod_curr = (dev->poll_mod_curr + 1) % dev->poll_mod_count;
|
||||||
|
}
|
||||||
|
|
||||||
static void pn533_poll_reset_mod_list(struct pn533 *dev)
|
static void pn533_poll_reset_mod_list(struct pn533 *dev)
|
||||||
{
|
{
|
||||||
dev->poll_mod_count = 0;
|
dev->poll_mod_count = 0;
|
||||||
|
@ -1018,107 +1037,52 @@ static void pn533_poll_add_mod(struct pn533 *dev, u8 mod_index)
|
||||||
dev->poll_mod_count++;
|
dev->poll_mod_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pn533_poll_create_mod_list(struct pn533 *dev, u32 protocols)
|
static void pn533_poll_create_mod_list(struct pn533 *dev,
|
||||||
|
u32 im_protocols, u32 tm_protocols)
|
||||||
{
|
{
|
||||||
pn533_poll_reset_mod_list(dev);
|
pn533_poll_reset_mod_list(dev);
|
||||||
|
|
||||||
if (protocols & NFC_PROTO_MIFARE_MASK
|
if (im_protocols & NFC_PROTO_MIFARE_MASK
|
||||||
|| protocols & NFC_PROTO_ISO14443_MASK
|
|| im_protocols & NFC_PROTO_ISO14443_MASK
|
||||||
|| protocols & NFC_PROTO_NFC_DEP_MASK)
|
|| im_protocols & NFC_PROTO_NFC_DEP_MASK)
|
||||||
pn533_poll_add_mod(dev, PN533_POLL_MOD_106KBPS_A);
|
pn533_poll_add_mod(dev, PN533_POLL_MOD_106KBPS_A);
|
||||||
|
|
||||||
if (protocols & NFC_PROTO_FELICA_MASK
|
if (im_protocols & NFC_PROTO_FELICA_MASK
|
||||||
|| protocols & NFC_PROTO_NFC_DEP_MASK) {
|
|| im_protocols & NFC_PROTO_NFC_DEP_MASK) {
|
||||||
pn533_poll_add_mod(dev, PN533_POLL_MOD_212KBPS_FELICA);
|
pn533_poll_add_mod(dev, PN533_POLL_MOD_212KBPS_FELICA);
|
||||||
pn533_poll_add_mod(dev, PN533_POLL_MOD_424KBPS_FELICA);
|
pn533_poll_add_mod(dev, PN533_POLL_MOD_424KBPS_FELICA);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (protocols & NFC_PROTO_JEWEL_MASK)
|
if (im_protocols & NFC_PROTO_JEWEL_MASK)
|
||||||
pn533_poll_add_mod(dev, PN533_POLL_MOD_106KBPS_JEWEL);
|
pn533_poll_add_mod(dev, PN533_POLL_MOD_106KBPS_JEWEL);
|
||||||
|
|
||||||
if (protocols & NFC_PROTO_ISO14443_MASK)
|
if (im_protocols & NFC_PROTO_ISO14443_MASK)
|
||||||
pn533_poll_add_mod(dev, PN533_POLL_MOD_847KBPS_B);
|
pn533_poll_add_mod(dev, PN533_POLL_MOD_847KBPS_B);
|
||||||
}
|
|
||||||
|
|
||||||
static void pn533_start_poll_frame(struct pn533_frame *frame,
|
if (tm_protocols)
|
||||||
struct pn533_poll_modulations *mod)
|
pn533_poll_add_mod(dev, PN533_LISTEN_MOD);
|
||||||
{
|
|
||||||
|
|
||||||
pn533_tx_frame_init(frame, PN533_CMD_IN_LIST_PASSIVE_TARGET);
|
|
||||||
|
|
||||||
memcpy(PN533_FRAME_CMD_PARAMS_PTR(frame), &mod->data, mod->len);
|
|
||||||
frame->datalen += mod->len;
|
|
||||||
|
|
||||||
pn533_tx_frame_finish(frame);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pn533_start_poll_complete(struct pn533 *dev, void *arg,
|
static int pn533_start_poll_complete(struct pn533 *dev, void *arg,
|
||||||
u8 *params, int params_len)
|
u8 *params, int params_len)
|
||||||
{
|
{
|
||||||
struct pn533_poll_response *resp;
|
struct pn533_poll_response *resp;
|
||||||
struct pn533_poll_modulations *next_mod;
|
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
|
nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
|
||||||
|
|
||||||
if (params_len == -ENOENT) {
|
|
||||||
nfc_dev_dbg(&dev->interface->dev, "Polling operation has been"
|
|
||||||
" stopped");
|
|
||||||
goto stop_poll;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (params_len < 0) {
|
|
||||||
nfc_dev_err(&dev->interface->dev, "Error %d when running poll",
|
|
||||||
params_len);
|
|
||||||
goto stop_poll;
|
|
||||||
}
|
|
||||||
|
|
||||||
resp = (struct pn533_poll_response *) params;
|
resp = (struct pn533_poll_response *) params;
|
||||||
if (resp->nbtg) {
|
if (resp->nbtg) {
|
||||||
rc = pn533_target_found(dev, resp, params_len);
|
rc = pn533_target_found(dev, resp, params_len);
|
||||||
|
|
||||||
/* We must stop the poll after a valid target found */
|
/* We must stop the poll after a valid target found */
|
||||||
if (rc == 0)
|
if (rc == 0) {
|
||||||
goto stop_poll;
|
pn533_poll_reset_mod_list(dev);
|
||||||
|
return 0;
|
||||||
if (rc != -EAGAIN)
|
}
|
||||||
nfc_dev_err(&dev->interface->dev, "The target found is"
|
|
||||||
" not valid - continuing to poll");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dev->poll_mod_curr = (dev->poll_mod_curr + 1) % dev->poll_mod_count;
|
return -EAGAIN;
|
||||||
|
|
||||||
next_mod = dev->poll_mod_active[dev->poll_mod_curr];
|
|
||||||
|
|
||||||
nfc_dev_dbg(&dev->interface->dev, "Polling next modulation (0x%x)",
|
|
||||||
dev->poll_mod_curr);
|
|
||||||
|
|
||||||
pn533_start_poll_frame(dev->out_frame, next_mod);
|
|
||||||
|
|
||||||
/* Don't need to down the semaphore again */
|
|
||||||
rc = __pn533_send_cmd_frame_async(dev, dev->out_frame, dev->in_frame,
|
|
||||||
dev->in_maxlen, pn533_start_poll_complete,
|
|
||||||
NULL, GFP_ATOMIC);
|
|
||||||
|
|
||||||
if (rc == -EPERM) {
|
|
||||||
nfc_dev_dbg(&dev->interface->dev, "Cannot poll next modulation"
|
|
||||||
" because poll has been stopped");
|
|
||||||
goto stop_poll;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rc) {
|
|
||||||
nfc_dev_err(&dev->interface->dev, "Error %d when trying to poll"
|
|
||||||
" next modulation", rc);
|
|
||||||
goto stop_poll;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Inform caller function to do not up the semaphore */
|
|
||||||
return -EINPROGRESS;
|
|
||||||
|
|
||||||
stop_poll:
|
|
||||||
pn533_poll_reset_mod_list(dev);
|
|
||||||
dev->poll_protocols = 0;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pn533_init_target_frame(struct pn533_frame *frame,
|
static int pn533_init_target_frame(struct pn533_frame *frame,
|
||||||
|
@ -1286,83 +1250,136 @@ static int pn533_init_target_complete(struct pn533 *dev, void *arg,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pn533_init_target(struct nfc_dev *nfc_dev, u32 protocols)
|
static void pn533_listen_mode_timer(unsigned long data)
|
||||||
{
|
{
|
||||||
struct pn533 *dev = nfc_get_drvdata(nfc_dev);
|
struct pn533 *dev = (struct pn533 *) data;
|
||||||
u8 *gb;
|
|
||||||
size_t gb_len;
|
nfc_dev_dbg(&dev->interface->dev, "Listen mode timeout");
|
||||||
|
|
||||||
|
/* An ack will cancel the last issued command (poll) */
|
||||||
|
pn533_send_ack(dev, GFP_ATOMIC);
|
||||||
|
|
||||||
|
dev->cancel_listen = 1;
|
||||||
|
|
||||||
|
up(&dev->cmd_lock);
|
||||||
|
|
||||||
|
pn533_poll_next_mod(dev);
|
||||||
|
|
||||||
|
queue_work(dev->wq, &dev->poll_work);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int pn533_poll_complete(struct pn533 *dev, void *arg,
|
||||||
|
u8 *params, int params_len)
|
||||||
|
{
|
||||||
|
struct pn533_poll_modulations *cur_mod;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
|
||||||
|
|
||||||
|
if (params_len == -ENOENT) {
|
||||||
|
if (dev->poll_mod_count != 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
nfc_dev_err(&dev->interface->dev,
|
||||||
|
"Polling operation has been stopped");
|
||||||
|
|
||||||
|
goto stop_poll;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (params_len < 0) {
|
||||||
|
nfc_dev_err(&dev->interface->dev,
|
||||||
|
"Error %d when running poll", params_len);
|
||||||
|
|
||||||
|
goto stop_poll;
|
||||||
|
}
|
||||||
|
|
||||||
|
cur_mod = dev->poll_mod_active[dev->poll_mod_curr];
|
||||||
|
|
||||||
|
if (cur_mod->len == 0) {
|
||||||
|
del_timer(&dev->listen_timer);
|
||||||
|
|
||||||
|
return pn533_init_target_complete(dev, arg, params, params_len);
|
||||||
|
} else {
|
||||||
|
rc = pn533_start_poll_complete(dev, arg, params, params_len);
|
||||||
|
if (!rc)
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
pn533_poll_next_mod(dev);
|
||||||
|
|
||||||
|
queue_work(dev->wq, &dev->poll_work);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
stop_poll:
|
||||||
pn533_poll_reset_mod_list(dev);
|
pn533_poll_reset_mod_list(dev);
|
||||||
|
dev->poll_protocols = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
gb = nfc_get_local_general_bytes(nfc_dev, &gb_len);
|
static void pn533_build_poll_frame(struct pn533 *dev,
|
||||||
if (gb == NULL)
|
struct pn533_frame *frame,
|
||||||
return -ENOMEM;
|
struct pn533_poll_modulations *mod)
|
||||||
|
{
|
||||||
|
nfc_dev_dbg(&dev->interface->dev, "mod len %d\n", mod->len);
|
||||||
|
|
||||||
rc = pn533_init_target_frame(dev->out_frame, gb, gb_len);
|
if (mod->len == 0) {
|
||||||
if (rc < 0)
|
/* Listen mode */
|
||||||
return rc;
|
pn533_init_target_frame(frame, dev->gb, dev->gb_len);
|
||||||
|
} else {
|
||||||
|
/* Polling mode */
|
||||||
|
pn533_tx_frame_init(frame, PN533_CMD_IN_LIST_PASSIVE_TARGET);
|
||||||
|
|
||||||
|
memcpy(PN533_FRAME_CMD_PARAMS_PTR(frame), &mod->data, mod->len);
|
||||||
|
frame->datalen += mod->len;
|
||||||
|
|
||||||
|
pn533_tx_frame_finish(frame);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int pn533_send_poll_frame(struct pn533 *dev)
|
||||||
|
{
|
||||||
|
struct pn533_poll_modulations *cur_mod;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
cur_mod = dev->poll_mod_active[dev->poll_mod_curr];
|
||||||
|
|
||||||
|
pn533_build_poll_frame(dev, dev->out_frame, cur_mod);
|
||||||
|
|
||||||
rc = pn533_send_cmd_frame_async(dev, dev->out_frame, dev->in_frame,
|
rc = pn533_send_cmd_frame_async(dev, dev->out_frame, dev->in_frame,
|
||||||
dev->in_maxlen,
|
dev->in_maxlen, pn533_poll_complete,
|
||||||
pn533_init_target_complete,
|
NULL, GFP_KERNEL);
|
||||||
NULL, GFP_KERNEL);
|
|
||||||
|
|
||||||
if (rc)
|
if (rc)
|
||||||
nfc_dev_err(&dev->interface->dev,
|
nfc_dev_err(&dev->interface->dev, "Polling loop error %d", rc);
|
||||||
"Error %d when trying to initiate as a target", rc);
|
|
||||||
|
|
||||||
dev->poll_mod_count++;
|
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pn533_start_im_poll(struct nfc_dev *nfc_dev, u32 protocols)
|
static void pn533_wq_poll(struct work_struct *work)
|
||||||
{
|
{
|
||||||
struct pn533 *dev = nfc_get_drvdata(nfc_dev);
|
struct pn533 *dev = container_of(work, struct pn533, poll_work);
|
||||||
struct pn533_poll_modulations *start_mod;
|
struct pn533_poll_modulations *cur_mod;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if (dev->poll_mod_count) {
|
cur_mod = dev->poll_mod_active[dev->poll_mod_curr];
|
||||||
nfc_dev_err(&dev->interface->dev, "Polling operation already"
|
|
||||||
" active");
|
nfc_dev_dbg(&dev->interface->dev,
|
||||||
return -EBUSY;
|
"%s cancel_listen %d modulation len %d",
|
||||||
|
__func__, dev->cancel_listen, cur_mod->len);
|
||||||
|
|
||||||
|
if (dev->cancel_listen == 1) {
|
||||||
|
dev->cancel_listen = 0;
|
||||||
|
usb_kill_urb(dev->in_urb);
|
||||||
}
|
}
|
||||||
|
|
||||||
pn533_poll_create_mod_list(dev, protocols);
|
rc = pn533_send_poll_frame(dev);
|
||||||
|
if (rc)
|
||||||
|
return;
|
||||||
|
|
||||||
if (!dev->poll_mod_count) {
|
if (cur_mod->len == 0 && dev->poll_mod_count > 1)
|
||||||
nfc_dev_err(&dev->interface->dev, "No valid protocols"
|
mod_timer(&dev->listen_timer, jiffies + PN533_LISTEN_TIME * HZ);
|
||||||
" specified");
|
|
||||||
rc = -EINVAL;
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
nfc_dev_dbg(&dev->interface->dev, "It will poll %d modulations types",
|
return;
|
||||||
dev->poll_mod_count);
|
|
||||||
|
|
||||||
dev->poll_mod_curr = 0;
|
|
||||||
start_mod = dev->poll_mod_active[dev->poll_mod_curr];
|
|
||||||
|
|
||||||
pn533_start_poll_frame(dev->out_frame, start_mod);
|
|
||||||
|
|
||||||
rc = pn533_send_cmd_frame_async(dev, dev->out_frame, dev->in_frame,
|
|
||||||
dev->in_maxlen, pn533_start_poll_complete,
|
|
||||||
NULL, GFP_KERNEL);
|
|
||||||
|
|
||||||
if (rc) {
|
|
||||||
nfc_dev_err(&dev->interface->dev, "Error %d when trying to"
|
|
||||||
" start poll", rc);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
dev->poll_protocols = protocols;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
error:
|
|
||||||
pn533_poll_reset_mod_list(dev);
|
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pn533_start_poll(struct nfc_dev *nfc_dev,
|
static int pn533_start_poll(struct nfc_dev *nfc_dev,
|
||||||
|
@ -1380,13 +1397,18 @@ static int pn533_start_poll(struct nfc_dev *nfc_dev,
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (im_protocols)
|
if (tm_protocols) {
|
||||||
return pn533_start_im_poll(nfc_dev, im_protocols);
|
dev->gb = nfc_get_local_general_bytes(nfc_dev, &dev->gb_len);
|
||||||
|
if (dev->gb == NULL)
|
||||||
|
tm_protocols = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (tm_protocols)
|
dev->poll_mod_curr = 0;
|
||||||
return pn533_init_target(nfc_dev, tm_protocols);
|
pn533_poll_create_mod_list(dev, im_protocols, tm_protocols);
|
||||||
|
dev->poll_protocols = im_protocols;
|
||||||
|
dev->listen_protocols = tm_protocols;
|
||||||
|
|
||||||
return -EINVAL;
|
return pn533_send_poll_frame(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pn533_stop_poll(struct nfc_dev *nfc_dev)
|
static void pn533_stop_poll(struct nfc_dev *nfc_dev)
|
||||||
|
@ -1395,6 +1417,8 @@ static void pn533_stop_poll(struct nfc_dev *nfc_dev)
|
||||||
|
|
||||||
nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
|
nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
|
||||||
|
|
||||||
|
del_timer(&dev->listen_timer);
|
||||||
|
|
||||||
if (!dev->poll_mod_count) {
|
if (!dev->poll_mod_count) {
|
||||||
nfc_dev_dbg(&dev->interface->dev, "Polling operation was not"
|
nfc_dev_dbg(&dev->interface->dev, "Polling operation was not"
|
||||||
" running");
|
" running");
|
||||||
|
@ -1676,6 +1700,10 @@ static int pn533_dep_link_up(struct nfc_dev *nfc_dev, struct nfc_target *target,
|
||||||
|
|
||||||
static int pn533_dep_link_down(struct nfc_dev *nfc_dev)
|
static int pn533_dep_link_down(struct nfc_dev *nfc_dev)
|
||||||
{
|
{
|
||||||
|
struct pn533 *dev = nfc_get_drvdata(nfc_dev);
|
||||||
|
|
||||||
|
pn533_poll_reset_mod_list(dev);
|
||||||
|
|
||||||
pn533_deactivate_target(nfc_dev, 0);
|
pn533_deactivate_target(nfc_dev, 0);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -2110,12 +2138,17 @@ 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);
|
INIT_WORK(&dev->tg_work, pn533_wq_tg_get_data);
|
||||||
|
INIT_WORK(&dev->poll_work, pn533_wq_poll);
|
||||||
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);
|
||||||
if (dev->wq == NULL)
|
if (dev->wq == NULL)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
init_timer(&dev->listen_timer);
|
||||||
|
dev->listen_timer.data = (unsigned long) dev;
|
||||||
|
dev->listen_timer.function = pn533_listen_mode_timer;
|
||||||
|
|
||||||
skb_queue_head_init(&dev->resp_q);
|
skb_queue_head_init(&dev->resp_q);
|
||||||
|
|
||||||
usb_set_intfdata(interface, dev);
|
usb_set_intfdata(interface, dev);
|
||||||
|
@ -2212,6 +2245,8 @@ static void pn533_disconnect(struct usb_interface *interface)
|
||||||
|
|
||||||
skb_queue_purge(&dev->resp_q);
|
skb_queue_purge(&dev->resp_q);
|
||||||
|
|
||||||
|
del_timer(&dev->listen_timer);
|
||||||
|
|
||||||
kfree(dev->in_frame);
|
kfree(dev->in_frame);
|
||||||
usb_free_urb(dev->in_urb);
|
usb_free_urb(dev->in_urb);
|
||||||
kfree(dev->out_frame);
|
kfree(dev->out_frame);
|
||||||
|
|
Loading…
Reference in a new issue