]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.10-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 10 Nov 2014 05:18:17 +0000 (14:18 +0900)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 10 Nov 2014 05:18:17 +0000 (14:18 +0900)
added patches:
usb-do-not-allow-usb_alloc_streams-on-unconfigured-devices.patch
usb-opticon-fix-non-atomic-allocation-in-write-path.patch
usb-storage-handle-a-skipped-data-phase.patch

queue-3.10/series
queue-3.10/usb-do-not-allow-usb_alloc_streams-on-unconfigured-devices.patch [new file with mode: 0644]
queue-3.10/usb-opticon-fix-non-atomic-allocation-in-write-path.patch [new file with mode: 0644]
queue-3.10/usb-storage-handle-a-skipped-data-phase.patch [new file with mode: 0644]

index 7c4f78e416f1b04143451d0c07ab39e866776ea5..cc696de76aff06288760b4223fcbf327448099b6 100644 (file)
@@ -90,3 +90,6 @@ wireless-rt2x00-add-new-rt2800usb-device.patch
 usb-dwc3-gadget-properly-initialize-link-trb.patch
 spi-pl022-fix-incorrect-dma_unmap_sg.patch
 spi-pxa2xx-toggle-clocks-on-suspend-if-not-disabled-by-runtime-pm.patch
+usb-storage-handle-a-skipped-data-phase.patch
+usb-opticon-fix-non-atomic-allocation-in-write-path.patch
+usb-do-not-allow-usb_alloc_streams-on-unconfigured-devices.patch
diff --git a/queue-3.10/usb-do-not-allow-usb_alloc_streams-on-unconfigured-devices.patch b/queue-3.10/usb-do-not-allow-usb_alloc_streams-on-unconfigured-devices.patch
new file mode 100644 (file)
index 0000000..cfc91f4
--- /dev/null
@@ -0,0 +1,76 @@
+From 90a646c770c50cc206ceba0d7b50453c46c13c36 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+Date: Wed, 1 Oct 2014 11:29:14 +0200
+Subject: usb: Do not allow usb_alloc_streams on unconfigured devices
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+commit 90a646c770c50cc206ceba0d7b50453c46c13c36 upstream.
+
+This commit fixes the following oops:
+
+[10238.622067] scsi host3: uas_eh_bus_reset_handler start
+[10240.766164] usb 3-4: reset SuperSpeed USB device number 3 using xhci_hcd
+[10245.779365] usb 3-4: device descriptor read/8, error -110
+[10245.883331] usb 3-4: reset SuperSpeed USB device number 3 using xhci_hcd
+[10250.897603] usb 3-4: device descriptor read/8, error -110
+[10251.058200] BUG: unable to handle kernel NULL pointer dereference at  0000000000000040
+[10251.058244] IP: [<ffffffff815ac6e1>] xhci_check_streams_endpoint+0x91/0x140
+<snip>
+[10251.059473] Call Trace:
+[10251.059487]  [<ffffffff815aca6c>] xhci_calculate_streams_and_bitmask+0xbc/0x130
+[10251.059520]  [<ffffffff815aeb5f>] xhci_alloc_streams+0x10f/0x5a0
+[10251.059548]  [<ffffffff810a4685>] ? check_preempt_curr+0x75/0xa0
+[10251.059575]  [<ffffffff810a46dc>] ? ttwu_do_wakeup+0x2c/0x100
+[10251.059601]  [<ffffffff810a49e6>] ? ttwu_do_activate.constprop.111+0x66/0x70
+[10251.059635]  [<ffffffff815779ab>] usb_alloc_streams+0xab/0xf0
+[10251.059662]  [<ffffffffc0616b48>] uas_configure_endpoints+0x128/0x150 [uas]
+[10251.059694]  [<ffffffffc0616bac>] uas_post_reset+0x3c/0xb0 [uas]
+[10251.059722]  [<ffffffff815727d9>] usb_reset_device+0x1b9/0x2a0
+[10251.059749]  [<ffffffffc0616f42>] uas_eh_bus_reset_handler+0xb2/0x190 [uas]
+[10251.059781]  [<ffffffff81514293>] scsi_try_bus_reset+0x53/0x110
+[10251.059808]  [<ffffffff815163b7>] scsi_eh_bus_reset+0xf7/0x270
+<snip>
+
+The problem is the following call sequence (simplified):
+
+1) usb_reset_device
+2)  usb_reset_and_verify_device
+2)   hub_port_init
+3)    hub_port_finish_reset
+3)     xhci_discover_or_reset_device
+        This frees xhci->devs[slot_id]->eps[ep_index].ring for all eps but 0
+4)    usb_get_device_descriptor
+       This fails
+5)   hub_port_init fails
+6)  usb_reset_and_verify_device fails, does not restore device config
+7)  uas_post_reset
+8)   xhci_alloc_streams
+      NULL deref on the free-ed ring
+
+This commit fixes this by not allowing usb_alloc_streams to continue if
+the device is not configured.
+
+Note that we do allow usb_free_streams to continue after a (logical)
+disconnect, as it is necessary to explicitly free the streams at the xhci
+controller level.
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/hcd.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/usb/core/hcd.c
++++ b/drivers/usb/core/hcd.c
+@@ -1947,6 +1947,8 @@ int usb_alloc_streams(struct usb_interfa
+               return -EINVAL;
+       if (dev->speed != USB_SPEED_SUPER)
+               return -EINVAL;
++      if (dev->state < USB_STATE_CONFIGURED)
++              return -ENODEV;
+       /* Streams only apply to bulk endpoints. */
+       for (i = 0; i < num_eps; i++)
diff --git a/queue-3.10/usb-opticon-fix-non-atomic-allocation-in-write-path.patch b/queue-3.10/usb-opticon-fix-non-atomic-allocation-in-write-path.patch
new file mode 100644 (file)
index 0000000..c368b1d
--- /dev/null
@@ -0,0 +1,31 @@
+From e681286de221af78fc85db9222b6a203148c005a Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Wed, 29 Oct 2014 09:07:31 +0100
+Subject: USB: opticon: fix non-atomic allocation in write path
+
+From: Johan Hovold <johan@kernel.org>
+
+commit e681286de221af78fc85db9222b6a203148c005a upstream.
+
+Write may be called from interrupt context so make sure to use
+GFP_ATOMIC for all allocations in write.
+
+Fixes: 0d930e51cfe6 ("USB: opticon: Add Opticon OPN2001 write support")
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/opticon.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/serial/opticon.c
++++ b/drivers/usb/serial/opticon.c
+@@ -219,7 +219,7 @@ static int opticon_write(struct tty_stru
+       /* The conncected devices do not have a bulk write endpoint,
+        * to transmit data to de barcode device the control endpoint is used */
+-      dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_NOIO);
++      dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_ATOMIC);
+       if (!dr) {
+               dev_err(&port->dev, "out of memory\n");
+               count = -ENOMEM;
diff --git a/queue-3.10/usb-storage-handle-a-skipped-data-phase.patch b/queue-3.10/usb-storage-handle-a-skipped-data-phase.patch
new file mode 100644 (file)
index 0000000..6d48884
--- /dev/null
@@ -0,0 +1,81 @@
+From 93c9bf4d1838d5851a18ca398b0ad66397f05056 Mon Sep 17 00:00:00 2001
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Fri, 31 Oct 2014 14:49:47 -0400
+Subject: usb-storage: handle a skipped data phase
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+commit 93c9bf4d1838d5851a18ca398b0ad66397f05056 upstream.
+
+Sometimes mass-storage devices using the Bulk-only transport will
+mistakenly skip the data phase of a command.  Rather than sending the
+data expected by the host or sending a zero-length packet, they go
+directly to the status phase and send the CSW.
+
+This causes problems for usb-storage, for obvious reasons.  The driver
+will interpret the CSW as a short data transfer and will wait to
+receive a CSW.  The device won't have anything left to send, so the
+command eventually times out.
+
+The SCSI layer doesn't retry commands after they time out (this is a
+relatively recent change).  Therefore we should do our best to detect
+a skipped data phase and handle it promptly.
+
+This patch adds code to do that.  If usb-storage receives a short
+13-byte data transfer from the device, and if the first four bytes of
+the data match the CSW signature, the driver will set the residue to
+the full transfer length and interpret the data as a CSW.
+
+This fixes Bugzilla #86611.
+
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+CC: Matthew Dharm <mdharm-usb@one-eyed-alien.net>
+Tested-by: Paul Osmialowski <newchief@king.net.pl>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/storage/transport.c |   26 ++++++++++++++++++++++++++
+ 1 file changed, 26 insertions(+)
+
+--- a/drivers/usb/storage/transport.c
++++ b/drivers/usb/storage/transport.c
+@@ -1118,6 +1118,31 @@ int usb_stor_Bulk_transport(struct scsi_
+                */
+               if (result == USB_STOR_XFER_LONG)
+                       fake_sense = 1;
++
++              /*
++               * Sometimes a device will mistakenly skip the data phase
++               * and go directly to the status phase without sending a
++               * zero-length packet.  If we get a 13-byte response here,
++               * check whether it really is a CSW.
++               */
++              if (result == USB_STOR_XFER_SHORT &&
++                              srb->sc_data_direction == DMA_FROM_DEVICE &&
++                              transfer_length - scsi_get_resid(srb) ==
++                                      US_BULK_CS_WRAP_LEN) {
++                      struct scatterlist *sg = NULL;
++                      unsigned int offset = 0;
++
++                      if (usb_stor_access_xfer_buf((unsigned char *) bcs,
++                                      US_BULK_CS_WRAP_LEN, srb, &sg,
++                                      &offset, FROM_XFER_BUF) ==
++                                              US_BULK_CS_WRAP_LEN &&
++                                      bcs->Signature ==
++                                              cpu_to_le32(US_BULK_CS_SIGN)) {
++                              usb_stor_dbg(us, "Device skipped data phase\n");
++                              scsi_set_resid(srb, transfer_length);
++                              goto skipped_data_phase;
++                      }
++              }
+       }
+       /* See flow chart on pg 15 of the Bulk Only Transport spec for
+@@ -1153,6 +1178,7 @@ int usb_stor_Bulk_transport(struct scsi_
+       if (result != USB_STOR_XFER_GOOD)
+               return USB_STOR_TRANSPORT_ERROR;
++ skipped_data_phase:
+       /* check bulk status */
+       residue = le32_to_cpu(bcs->Residue);
+       usb_stor_dbg(us, "Bulk Status S 0x%x T 0x%x R %u Stat 0x%x\n",