linux-intel: nfc: backport pn533_usb stack fix 47/14947/2
authorMatt Ranostay <matt.ranostay@konsulko.com>
Mon, 2 Jul 2018 21:44:40 +0000 (14:44 -0700)
committerJan-Simon Moeller <jsmoeller@linuxfoundation.org>
Wed, 4 Jul 2018 10:05:56 +0000 (10:05 +0000)
pn533_usb based NFC devices wouldn't work on recent x86 builds, and
requires a patchset from the upstream kernel

Bug-AGL: SPEC-1553
Change-Id: I8113cccd1afc027b80495272bfa8aca42aec7691
Signed-off-by: Matt Ranostay <matt.ranostay@konsulko.com>
meta-agl-bsp/meta-intel/recipes-kernel/linux/files/0001-NFC-pn533-don-t-send-USB-data-off-of-the-stack.patch [new file with mode: 0644]
meta-agl-bsp/meta-intel/recipes-kernel/linux/linux-intel_4.14%.bbappend

diff --git a/meta-agl-bsp/meta-intel/recipes-kernel/linux/files/0001-NFC-pn533-don-t-send-USB-data-off-of-the-stack.patch b/meta-agl-bsp/meta-intel/recipes-kernel/linux/files/0001-NFC-pn533-don-t-send-USB-data-off-of-the-stack.patch
new file mode 100644 (file)
index 0000000..b64cc16
--- /dev/null
@@ -0,0 +1,145 @@
+From dbafc28955fa6779dc23d1607a0fee5e509a278b Mon Sep 17 00:00:00 2001
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Date: Sun, 20 May 2018 15:19:46 +0200
+Subject: [PATCH] NFC: pn533: don't send USB data off of the stack
+
+It's amazing that this driver ever worked, but now that x86 doesn't
+allow USB data to be sent off of the stack, it really does not work at
+all.  Fix this up by properly allocating the data for the small
+"commands" that get sent to the device off of the stack.
+
+We do this for one command by having a whole urb just for ack messages,
+as they can be submitted in interrupt context, so we can not use
+usb_bulk_msg().  But the poweron command can sleep (and does), so use
+usb_bulk_msg() for that transfer.
+
+Reported-by: Carlos Manuel Santos <cmmpsantos@gmail.com>
+Cc: Samuel Ortiz <sameo@linux.intel.com>
+Cc: Stephen Hemminger <stephen@networkplumber.org>
+Cc: stable <stable@vger.kernel.org>
+Reviewed-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nfc/pn533/usb.c | 42 +++++++++++++++++++++++++++++------------
+ 1 file changed, 30 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/nfc/pn533/usb.c b/drivers/nfc/pn533/usb.c
+index e153e8b64bb8..d5553c47014f 100644
+--- a/drivers/nfc/pn533/usb.c
++++ b/drivers/nfc/pn533/usb.c
+@@ -62,6 +62,9 @@ struct pn533_usb_phy {
+       struct urb *out_urb;
+       struct urb *in_urb;
++      struct urb *ack_urb;
++      u8 *ack_buffer;
++
+       struct pn533 *priv;
+ };
+@@ -150,13 +153,16 @@ static int pn533_usb_send_ack(struct pn533 *dev, gfp_t flags)
+       struct pn533_usb_phy *phy = dev->phy;
+       static const u8 ack[6] = {0x00, 0x00, 0xff, 0x00, 0xff, 0x00};
+       /* spec 7.1.1.3:  Preamble, SoPC (2), ACK Code (2), Postamble */
+-      int rc;
+-      phy->out_urb->transfer_buffer = (u8 *)ack;
+-      phy->out_urb->transfer_buffer_length = sizeof(ack);
+-      rc = usb_submit_urb(phy->out_urb, flags);
++      if (!phy->ack_buffer) {
++              phy->ack_buffer = kmemdup(ack, sizeof(ack), flags);
++              if (!phy->ack_buffer)
++                      return -ENOMEM;
++      }
+-      return rc;
++      phy->ack_urb->transfer_buffer = phy->ack_buffer;
++      phy->ack_urb->transfer_buffer_length = sizeof(ack);
++      return usb_submit_urb(phy->ack_urb, flags);
+ }
+ static int pn533_usb_send_frame(struct pn533 *dev,
+@@ -375,26 +381,31 @@ static int pn533_acr122_poweron_rdr(struct pn533_usb_phy *phy)
+       /* Power on th reader (CCID cmd) */
+       u8 cmd[10] = {PN533_ACR122_PC_TO_RDR_ICCPOWERON,
+                     0, 0, 0, 0, 0, 0, 3, 0, 0};
++      char *buffer;
++      int transferred;
+       int rc;
+       void *cntx;
+       struct pn533_acr122_poweron_rdr_arg arg;
+       dev_dbg(&phy->udev->dev, "%s\n", __func__);
++      buffer = kmemdup(cmd, sizeof(cmd), GFP_KERNEL);
++      if (!buffer)
++              return -ENOMEM;
++
+       init_completion(&arg.done);
+       cntx = phy->in_urb->context;  /* backup context */
+       phy->in_urb->complete = pn533_acr122_poweron_rdr_resp;
+       phy->in_urb->context = &arg;
+-      phy->out_urb->transfer_buffer = cmd;
+-      phy->out_urb->transfer_buffer_length = sizeof(cmd);
+-
+       print_hex_dump_debug("ACR122 TX: ", DUMP_PREFIX_NONE, 16, 1,
+                      cmd, sizeof(cmd), false);
+-      rc = usb_submit_urb(phy->out_urb, GFP_KERNEL);
+-      if (rc) {
++      rc = usb_bulk_msg(phy->udev, phy->out_urb->pipe, buffer, sizeof(cmd),
++                        &transferred, 0);
++      kfree(buffer);
++      if (rc || (transferred != sizeof(cmd))) {
+               nfc_err(&phy->udev->dev,
+                       "Reader power on cmd error %d\n", rc);
+               return rc;
+@@ -490,8 +501,9 @@ static int pn533_usb_probe(struct usb_interface *interface,
+       phy->in_urb = usb_alloc_urb(0, GFP_KERNEL);
+       phy->out_urb = usb_alloc_urb(0, GFP_KERNEL);
++      phy->ack_urb = usb_alloc_urb(0, GFP_KERNEL);
+-      if (!phy->in_urb || !phy->out_urb)
++      if (!phy->in_urb || !phy->out_urb || !phy->ack_urb)
+               goto error;
+       usb_fill_bulk_urb(phy->in_urb, phy->udev,
+@@ -501,7 +513,9 @@ static int pn533_usb_probe(struct usb_interface *interface,
+       usb_fill_bulk_urb(phy->out_urb, phy->udev,
+                         usb_sndbulkpipe(phy->udev, out_endpoint),
+                         NULL, 0, pn533_send_complete, phy);
+-
++      usb_fill_bulk_urb(phy->ack_urb, phy->udev,
++                        usb_sndbulkpipe(phy->udev, out_endpoint),
++                        NULL, 0, pn533_send_complete, phy);
+       switch (id->driver_info) {
+       case PN533_DEVICE_STD:
+@@ -554,6 +568,7 @@ static int pn533_usb_probe(struct usb_interface *interface,
+ error:
+       usb_free_urb(phy->in_urb);
+       usb_free_urb(phy->out_urb);
++      usb_free_urb(phy->ack_urb);
+       usb_put_dev(phy->udev);
+       kfree(in_buf);
+@@ -573,10 +588,13 @@ static void pn533_usb_disconnect(struct usb_interface *interface)
+       usb_kill_urb(phy->in_urb);
+       usb_kill_urb(phy->out_urb);
++      usb_kill_urb(phy->ack_urb);
+       kfree(phy->in_urb->transfer_buffer);
+       usb_free_urb(phy->in_urb);
+       usb_free_urb(phy->out_urb);
++      usb_free_urb(phy->ack_urb);
++      kfree(phy->ack_buffer);
+       nfc_info(&interface->dev, "NXP PN533 NFC device disconnected\n");
+ }
+-- 
+2.17.1
+
index c49b8ec..62c264d 100644 (file)
@@ -15,6 +15,9 @@ KERNEL_CONFIG_FRAGMENTS_append = " ${WORKDIR}/net-devices.cfg"
 # Ensure we have a startup.nsh file
 SRC_URI_append = " file://startup.nsh"
 
+# SPEC-1553 fix for pn333_usb devices not being functional
+SRC_URI_append = " file://0001-NFC-pn533-don-t-send-USB-data-off-of-the-stack.patch"
+
 do_deploy_append() {
        install -m 0755 ${WORKDIR}/startup.nsh ${DEPLOYDIR}/
 }