Skip to content

Commit

Permalink
Merge tag 'nfc-next-3.7-1' of git://git.kernel.org/pub/scm/linux/kern…
Browse files Browse the repository at this point in the history
…el/git/sameo/nfc-3.0

So says Samuel Ortiz <sameo@linux.intel.com>:

This is the first NFC pull request for the 3.7 merge window.

With this one we get:

- HCI and LLC layers separation. We now can support various LLC
  protocols for HCI drivers, SHDLC being one of them. This will be needed as
  we're planning to support raw HCI chipsets that do the SHDLC encapsulation
  in firmware. So for now we have an SHDLC and a NOP LLC layers.

- pn533 command queueing implementation. This simplifies the pn533 locking
  logic and fixes a kernel warning.

- NCI p2p initiator mode implementation.

- Replace custom workqueues with system ones, for HCI and LLCP.

- Raw pn544 driver removal, as scheduled on the features-removal.txt file.

- A few HCI, SHDLC and LLCP fixes.

Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
John W. Linville committed Sep 25, 2012
2 parents 90e6274 + 4c0ba9a commit 0c49b69
Show file tree
Hide file tree
Showing 30 changed files with 1,283 additions and 1,686 deletions.
12 changes: 0 additions & 12 deletions Documentation/feature-removal-schedule.txt
Original file line number Diff line number Diff line change
Expand Up @@ -516,18 +516,6 @@ Who: Kees Cook <keescook@chromium.org>

----------------------------

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 <sameo@linux.intel.com>

----------------------------

What: setitimer accepts user NULL pointer (value)
When: 3.6
Why: setitimer is not returning -EFAULT if user pointer is NULL. This
Expand Down
1 change: 1 addition & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -4793,6 +4793,7 @@ M: Lauro Ramos Venancio <lauro.venancio@openbossa.org>
M: Aloisio Almeida Jr <aloisio.almeida@openbossa.org>
M: Samuel Ortiz <sameo@linux.intel.com>
L: linux-wireless@vger.kernel.org
L: linux-nfc@lists.01.org (moderated for non-subscribers)
S: Maintained
F: net/nfc/
F: include/linux/nfc.h
Expand Down
14 changes: 1 addition & 13 deletions drivers/nfc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,9 @@
menu "Near Field Communication (NFC) devices"
depends on NFC

config PN544_NFC
tristate "PN544 NFC driver"
depends on I2C
select CRC_CCITT
default n
---help---
Say yes if you want PN544 Near Field Communication driver.
This is for i2c connected version. If unsure, say N here.

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
depends on I2C && NFC_HCI && NFC_SHDLC
select CRC_CCITT
default n
---help---
Expand Down
1 change: 0 additions & 1 deletion drivers/nfc/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
# Makefile for nfc devices
#

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
Expand Down
20 changes: 3 additions & 17 deletions drivers/nfc/nfcwilink.c
Original file line number Diff line number Diff line change
Expand Up @@ -352,8 +352,6 @@ static long nfcwilink_receive(void *priv_data, struct sk_buff *skb)
struct nfcwilink *drv = priv_data;
int rc;

nfc_dev_dbg(&drv->pdev->dev, "receive entry, len %d", skb->len);

if (!skb)
return -EFAULT;

Expand All @@ -362,6 +360,8 @@ static long nfcwilink_receive(void *priv_data, struct sk_buff *skb)
return -EFAULT;
}

nfc_dev_dbg(&drv->pdev->dev, "receive entry, len %d", skb->len);

/* strip the ST header
(apart for the chnl byte, which is not received in the hdr) */
skb_pull(skb, (NFCWILINK_HDR_LEN-1));
Expand Down Expand Up @@ -604,21 +604,7 @@ static struct platform_driver nfcwilink_driver = {
},
};

/* ------- Module Init/Exit interfaces ------ */
static int __init nfcwilink_init(void)
{
printk(KERN_INFO "NFC Driver for TI WiLink");

return platform_driver_register(&nfcwilink_driver);
}

static void __exit nfcwilink_exit(void)
{
platform_driver_unregister(&nfcwilink_driver);
}

module_init(nfcwilink_init);
module_exit(nfcwilink_exit);
module_platform_driver(nfcwilink_driver);

/* ------ Module Info ------ */

Expand Down
106 changes: 86 additions & 20 deletions drivers/nfc/pn533.c
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,7 @@ struct pn533 {

struct workqueue_struct *wq;
struct work_struct cmd_work;
struct work_struct cmd_complete_work;
struct work_struct poll_work;
struct work_struct mi_work;
struct work_struct tg_work;
Expand Down Expand Up @@ -383,6 +384,19 @@ struct pn533 {
u8 tgt_mode;

u32 device_type;

struct list_head cmd_queue;
u8 cmd_pending;
};

struct pn533_cmd {
struct list_head queue;
struct pn533_frame *out_frame;
struct pn533_frame *in_frame;
int in_frame_len;
pn533_cmd_complete_t cmd_complete;
void *arg;
gfp_t flags;
};

struct pn533_frame {
Expand Down Expand Up @@ -487,7 +501,7 @@ static bool pn533_rx_frame_is_cmd_response(struct pn533_frame *frame, u8 cmd)

static void pn533_wq_cmd_complete(struct work_struct *work)
{
struct pn533 *dev = container_of(work, struct pn533, cmd_work);
struct pn533 *dev = container_of(work, struct pn533, cmd_complete_work);
struct pn533_frame *in_frame;
int rc;

Expand All @@ -502,7 +516,7 @@ static void pn533_wq_cmd_complete(struct work_struct *work)
PN533_FRAME_CMD_PARAMS_LEN(in_frame));

if (rc != -EINPROGRESS)
mutex_unlock(&dev->cmd_lock);
queue_work(dev->wq, &dev->cmd_work);
}

static void pn533_recv_response(struct urb *urb)
Expand Down Expand Up @@ -550,7 +564,7 @@ static void pn533_recv_response(struct urb *urb)
dev->wq_in_frame = in_frame;

sched_wq:
queue_work(dev->wq, &dev->cmd_work);
queue_work(dev->wq, &dev->cmd_complete_work);
}

static int pn533_submit_urb_for_response(struct pn533 *dev, gfp_t flags)
Expand Down Expand Up @@ -606,7 +620,7 @@ static void pn533_recv_ack(struct urb *urb)

sched_wq:
dev->wq_in_frame = NULL;
queue_work(dev->wq, &dev->cmd_work);
queue_work(dev->wq, &dev->cmd_complete_work);
}

static int pn533_submit_urb_for_ack(struct pn533 *dev, gfp_t flags)
Expand Down Expand Up @@ -669,29 +683,76 @@ static int __pn533_send_cmd_frame_async(struct pn533 *dev,
return rc;
}

static void pn533_wq_cmd(struct work_struct *work)
{
struct pn533 *dev = container_of(work, struct pn533, cmd_work);
struct pn533_cmd *cmd;

mutex_lock(&dev->cmd_lock);

if (list_empty(&dev->cmd_queue)) {
dev->cmd_pending = 0;
mutex_unlock(&dev->cmd_lock);
return;
}

cmd = list_first_entry(&dev->cmd_queue, struct pn533_cmd, queue);

mutex_unlock(&dev->cmd_lock);

__pn533_send_cmd_frame_async(dev, cmd->out_frame, cmd->in_frame,
cmd->in_frame_len, cmd->cmd_complete,
cmd->arg, cmd->flags);

list_del(&cmd->queue);
kfree(cmd);
}

static int pn533_send_cmd_frame_async(struct pn533 *dev,
struct pn533_frame *out_frame,
struct pn533_frame *in_frame,
int in_frame_len,
pn533_cmd_complete_t cmd_complete,
void *arg, gfp_t flags)
{
struct pn533_cmd *cmd;
int rc;

nfc_dev_dbg(&dev->interface->dev, "%s", __func__);

if (!mutex_trylock(&dev->cmd_lock))
return -EBUSY;
mutex_lock(&dev->cmd_lock);

rc = __pn533_send_cmd_frame_async(dev, out_frame, in_frame,
in_frame_len, cmd_complete, arg, flags);
if (rc)
goto error;
if (!dev->cmd_pending) {
rc = __pn533_send_cmd_frame_async(dev, out_frame, in_frame,
in_frame_len, cmd_complete,
arg, flags);
if (!rc)
dev->cmd_pending = 1;

mutex_unlock(&dev->cmd_lock);

return rc;
}

nfc_dev_dbg(&dev->interface->dev, "%s Queueing command", __func__);

cmd = kzalloc(sizeof(struct pn533_cmd), flags);
if (!cmd)
return -ENOMEM;

INIT_LIST_HEAD(&cmd->queue);
cmd->out_frame = out_frame;
cmd->in_frame = in_frame;
cmd->in_frame_len = in_frame_len;
cmd->cmd_complete = cmd_complete;
cmd->arg = arg;
cmd->flags = flags;

list_add_tail(&cmd->queue, &dev->cmd_queue);

return 0;
error:
mutex_unlock(&dev->cmd_lock);
return rc;

return 0;
}

struct pn533_sync_cmd_response {
Expand Down Expand Up @@ -1305,8 +1366,6 @@ static void pn533_listen_mode_timer(unsigned long data)

dev->cancel_listen = 1;

mutex_unlock(&dev->cmd_lock);

pn533_poll_next_mod(dev);

queue_work(dev->wq, &dev->poll_work);
Expand Down Expand Up @@ -2131,7 +2190,7 @@ static void pn533_wq_mi_recv(struct work_struct *work)

kfree(arg);

mutex_unlock(&dev->cmd_lock);
queue_work(dev->wq, &dev->cmd_work);
}

static int pn533_set_configuration(struct pn533 *dev, u8 cfgitem, u8 *cfgdata,
Expand Down Expand Up @@ -2330,13 +2389,12 @@ static int pn533_probe(struct usb_interface *interface,
NULL, 0,
pn533_send_complete, dev);

INIT_WORK(&dev->cmd_work, pn533_wq_cmd_complete);
INIT_WORK(&dev->cmd_work, pn533_wq_cmd);
INIT_WORK(&dev->cmd_complete_work, pn533_wq_cmd_complete);
INIT_WORK(&dev->mi_work, pn533_wq_mi_recv);
INIT_WORK(&dev->tg_work, pn533_wq_tg_get_data);
INIT_WORK(&dev->poll_work, pn533_wq_poll);
dev->wq = alloc_workqueue("pn533",
WQ_NON_REENTRANT | WQ_UNBOUND | WQ_MEM_RECLAIM,
1);
dev->wq = alloc_ordered_workqueue("pn533", 0);
if (dev->wq == NULL)
goto error;

Expand All @@ -2346,6 +2404,8 @@ static int pn533_probe(struct usb_interface *interface,

skb_queue_head_init(&dev->resp_q);

INIT_LIST_HEAD(&dev->cmd_queue);

usb_set_intfdata(interface, dev);

pn533_tx_frame_init(dev->out_frame, PN533_CMD_GET_FIRMWARE_VERSION);
Expand Down Expand Up @@ -2417,6 +2477,7 @@ static int pn533_probe(struct usb_interface *interface,
static void pn533_disconnect(struct usb_interface *interface)
{
struct pn533 *dev;
struct pn533_cmd *cmd, *n;

dev = usb_get_intfdata(interface);
usb_set_intfdata(interface, NULL);
Expand All @@ -2433,6 +2494,11 @@ static void pn533_disconnect(struct usb_interface *interface)

del_timer(&dev->listen_timer);

list_for_each_entry_safe(cmd, n, &dev->cmd_queue, queue) {
list_del(&cmd->queue);
kfree(cmd);
}

kfree(dev->in_frame);
usb_free_urb(dev->in_urb);
kfree(dev->out_frame);
Expand Down
Loading

0 comments on commit 0c49b69

Please sign in to comment.