aboutsummaryrefslogtreecommitdiffstats
path: root/meta-agl-bsp/meta-core
diff options
context:
space:
mode:
Diffstat (limited to 'meta-agl-bsp/meta-core')
-rw-r--r--meta-agl-bsp/meta-core/recipes-kernel/linux/linux-yocto/0001-NFC-pn533-don-t-send-USB-data-off-of-the-stack.patch145
-rwxr-xr-xmeta-agl-bsp/meta-core/recipes-kernel/linux/linux-yocto_4.12.bbappend3
2 files changed, 148 insertions, 0 deletions
diff --git a/meta-agl-bsp/meta-core/recipes-kernel/linux/linux-yocto/0001-NFC-pn533-don-t-send-USB-data-off-of-the-stack.patch b/meta-agl-bsp/meta-core/recipes-kernel/linux/linux-yocto/0001-NFC-pn533-don-t-send-USB-data-off-of-the-stack.patch
new file mode 100644
index 000000000..b64cc16cf
--- /dev/null
+++ b/meta-agl-bsp/meta-core/recipes-kernel/linux/linux-yocto/0001-NFC-pn533-don-t-send-USB-data-off-of-the-stack.patch
@@ -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
+
diff --git a/meta-agl-bsp/meta-core/recipes-kernel/linux/linux-yocto_4.12.bbappend b/meta-agl-bsp/meta-core/recipes-kernel/linux/linux-yocto_4.12.bbappend
new file mode 100755
index 000000000..7464138aa
--- /dev/null
+++ b/meta-agl-bsp/meta-core/recipes-kernel/linux/linux-yocto_4.12.bbappend
@@ -0,0 +1,3 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/linux-yocto:"
+
+SRC_URI_append = "file://0001-NFC-pn533-don-t-send-USB-data-off-of-the-stack.patch"