From: Greg Kroah-Hartman Date: Mon, 9 Oct 2017 11:31:26 +0000 (+0200) Subject: 4.13-stable patches X-Git-Tag: v3.18.75~37 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=fc5fda928c4c6e604e814901a62597f6e6f95555;p=thirdparty%2Fkernel%2Fstable-queue.git 4.13-stable patches added patches: alsa-usb-audio-check-out-of-bounds-access-by-corrupted-buffer-descriptor.patch usb-cdc-wdm-ignore-epipe-from-getencapsulatedresponse.patch usb-devio-don-t-corrupt-user-memory.patch usb-devio-prevent-integer-overflow-in-proc_do_submiturb.patch usb-dummy-hcd-fix-connection-failures-wrong-speed.patch usb-dummy-hcd-fix-erroneous-synchronization-change.patch usb-dummy-hcd-fix-infinite-loop-resubmission-bug.patch usb-gadget-udc-atmel-set-vbus-irqflags-explicitly.patch usb-gadget-udc-renesas_usb3-fix-for-no-data-control-transfer.patch usb-gadget-udc-renesas_usb3-fix-pn_rammap.pn_mpkt-value.patch usb-gadget-udc-renesas_usb3-fix-return-value-of-usb3_write_pipe.patch usb-gadgetfs-fix-copy_to_user-while-holding-spinlock.patch usb-pci-quirks.c-corrected-timeout-values-used-in-handshake.patch usb-renesas_usbhs-fix-the-bclr-setting-condition-for-non-dcp-pipe.patch usb-renesas_usbhs-fix-usbhsf_fifo_clear-for-rx-direction.patch usb-storage-fix-bogus-hardware-error-messages-for-ata-pass-thru-devices.patch usb-storage-unusual_devs-entry-to-fix-write-access-regression-for-seagate-external-drives.patch --- diff --git a/queue-4.13/alsa-usb-audio-check-out-of-bounds-access-by-corrupted-buffer-descriptor.patch b/queue-4.13/alsa-usb-audio-check-out-of-bounds-access-by-corrupted-buffer-descriptor.patch new file mode 100644 index 00000000000..a2655ad056e --- /dev/null +++ b/queue-4.13/alsa-usb-audio-check-out-of-bounds-access-by-corrupted-buffer-descriptor.patch @@ -0,0 +1,117 @@ +From bfc81a8bc18e3c4ba0cbaa7666ff76be2f998991 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Fri, 22 Sep 2017 16:18:53 +0200 +Subject: ALSA: usb-audio: Check out-of-bounds access by corrupted buffer descriptor + +From: Takashi Iwai + +commit bfc81a8bc18e3c4ba0cbaa7666ff76be2f998991 upstream. + +When a USB-audio device receives a maliciously adjusted or corrupted +buffer descriptor, the USB-audio driver may access an out-of-bounce +value at its parser. This was detected by syzkaller, something like: + + BUG: KASAN: slab-out-of-bounds in usb_audio_probe+0x27b2/0x2ab0 + Read of size 1 at addr ffff88006b83a9e8 by task kworker/0:1/24 + CPU: 0 PID: 24 Comm: kworker/0:1 Not tainted 4.14.0-rc1-42251-gebb2c2437d80 #224 + Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 + Workqueue: usb_hub_wq hub_event + Call Trace: + __dump_stack lib/dump_stack.c:16 + dump_stack+0x292/0x395 lib/dump_stack.c:52 + print_address_description+0x78/0x280 mm/kasan/report.c:252 + kasan_report_error mm/kasan/report.c:351 + kasan_report+0x22f/0x340 mm/kasan/report.c:409 + __asan_report_load1_noabort+0x19/0x20 mm/kasan/report.c:427 + snd_usb_create_streams sound/usb/card.c:248 + usb_audio_probe+0x27b2/0x2ab0 sound/usb/card.c:605 + usb_probe_interface+0x35d/0x8e0 drivers/usb/core/driver.c:361 + really_probe drivers/base/dd.c:413 + driver_probe_device+0x610/0xa00 drivers/base/dd.c:557 + __device_attach_driver+0x230/0x290 drivers/base/dd.c:653 + bus_for_each_drv+0x161/0x210 drivers/base/bus.c:463 + __device_attach+0x26e/0x3d0 drivers/base/dd.c:710 + device_initial_probe+0x1f/0x30 drivers/base/dd.c:757 + bus_probe_device+0x1eb/0x290 drivers/base/bus.c:523 + device_add+0xd0b/0x1660 drivers/base/core.c:1835 + usb_set_configuration+0x104e/0x1870 drivers/usb/core/message.c:1932 + generic_probe+0x73/0xe0 drivers/usb/core/generic.c:174 + usb_probe_device+0xaf/0xe0 drivers/usb/core/driver.c:266 + really_probe drivers/base/dd.c:413 + driver_probe_device+0x610/0xa00 drivers/base/dd.c:557 + __device_attach_driver+0x230/0x290 drivers/base/dd.c:653 + bus_for_each_drv+0x161/0x210 drivers/base/bus.c:463 + __device_attach+0x26e/0x3d0 drivers/base/dd.c:710 + device_initial_probe+0x1f/0x30 drivers/base/dd.c:757 + bus_probe_device+0x1eb/0x290 drivers/base/bus.c:523 + device_add+0xd0b/0x1660 drivers/base/core.c:1835 + usb_new_device+0x7b8/0x1020 drivers/usb/core/hub.c:2457 + hub_port_connect drivers/usb/core/hub.c:4903 + hub_port_connect_change drivers/usb/core/hub.c:5009 + port_event drivers/usb/core/hub.c:5115 + hub_event+0x194d/0x3740 drivers/usb/core/hub.c:5195 + process_one_work+0xc7f/0x1db0 kernel/workqueue.c:2119 + worker_thread+0x221/0x1850 kernel/workqueue.c:2253 + kthread+0x3a1/0x470 kernel/kthread.c:231 + ret_from_fork+0x2a/0x40 arch/x86/entry/entry_64.S:431 + +This patch adds the checks of out-of-bounce accesses at appropriate +places and bails out when it goes out of the given buffer. + +Reported-by: Andrey Konovalov +Tested-by: Andrey Konovalov +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/usb/card.c | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + +--- a/sound/usb/card.c ++++ b/sound/usb/card.c +@@ -221,6 +221,7 @@ static int snd_usb_create_streams(struct + struct usb_interface_descriptor *altsd; + void *control_header; + int i, protocol; ++ int rest_bytes; + + /* find audiocontrol interface */ + host_iface = &usb_ifnum_to_if(dev, ctrlif)->altsetting[0]; +@@ -235,6 +236,15 @@ static int snd_usb_create_streams(struct + return -EINVAL; + } + ++ rest_bytes = (void *)(host_iface->extra + host_iface->extralen) - ++ control_header; ++ ++ /* just to be sure -- this shouldn't hit at all */ ++ if (rest_bytes <= 0) { ++ dev_err(&dev->dev, "invalid control header\n"); ++ return -EINVAL; ++ } ++ + switch (protocol) { + default: + dev_warn(&dev->dev, +@@ -245,11 +255,21 @@ static int snd_usb_create_streams(struct + case UAC_VERSION_1: { + struct uac1_ac_header_descriptor *h1 = control_header; + ++ if (rest_bytes < sizeof(*h1)) { ++ dev_err(&dev->dev, "too short v1 buffer descriptor\n"); ++ return -EINVAL; ++ } ++ + if (!h1->bInCollection) { + dev_info(&dev->dev, "skipping empty audio interface (v1)\n"); + return -EINVAL; + } + ++ if (rest_bytes < h1->bLength) { ++ dev_err(&dev->dev, "invalid buffer length (v1)\n"); ++ return -EINVAL; ++ } ++ + if (h1->bLength < sizeof(*h1) + h1->bInCollection) { + dev_err(&dev->dev, "invalid UAC_HEADER (v1)\n"); + return -EINVAL; diff --git a/queue-4.13/series b/queue-4.13/series index d70dbb9cb8f..a05bf053793 100644 --- a/queue-4.13/series +++ b/queue-4.13/series @@ -49,3 +49,20 @@ net-rtnetlink-fix-info-leak-in-rtm_getstats-call.patch bpf-fix-bpf_tail_call-x64-jit.patch usb-gadget-core-fix-udc_set_speed-logic.patch usb-gadgetfs-fix-crash-caused-by-inadequate-synchronization.patch +usb-gadgetfs-fix-copy_to_user-while-holding-spinlock.patch +usb-gadget-udc-atmel-set-vbus-irqflags-explicitly.patch +usb-gadget-udc-renesas_usb3-fix-for-no-data-control-transfer.patch +usb-gadget-udc-renesas_usb3-fix-pn_rammap.pn_mpkt-value.patch +usb-gadget-udc-renesas_usb3-fix-return-value-of-usb3_write_pipe.patch +usb-storage-unusual_devs-entry-to-fix-write-access-regression-for-seagate-external-drives.patch +usb-storage-fix-bogus-hardware-error-messages-for-ata-pass-thru-devices.patch +usb-renesas_usbhs-fix-the-bclr-setting-condition-for-non-dcp-pipe.patch +usb-renesas_usbhs-fix-usbhsf_fifo_clear-for-rx-direction.patch +alsa-usb-audio-check-out-of-bounds-access-by-corrupted-buffer-descriptor.patch +usb-pci-quirks.c-corrected-timeout-values-used-in-handshake.patch +usb-cdc-wdm-ignore-epipe-from-getencapsulatedresponse.patch +usb-dummy-hcd-fix-connection-failures-wrong-speed.patch +usb-dummy-hcd-fix-infinite-loop-resubmission-bug.patch +usb-dummy-hcd-fix-erroneous-synchronization-change.patch +usb-devio-prevent-integer-overflow-in-proc_do_submiturb.patch +usb-devio-don-t-corrupt-user-memory.patch diff --git a/queue-4.13/usb-cdc-wdm-ignore-epipe-from-getencapsulatedresponse.patch b/queue-4.13/usb-cdc-wdm-ignore-epipe-from-getencapsulatedresponse.patch new file mode 100644 index 00000000000..f6ea10e1135 --- /dev/null +++ b/queue-4.13/usb-cdc-wdm-ignore-epipe-from-getencapsulatedresponse.patch @@ -0,0 +1,69 @@ +From 8fec9355a968ad240f3a2e9ad55b823cf1cc52ff Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= +Date: Fri, 22 Sep 2017 22:18:18 +0200 +Subject: USB: cdc-wdm: ignore -EPIPE from GetEncapsulatedResponse +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Bjørn Mork + +commit 8fec9355a968ad240f3a2e9ad55b823cf1cc52ff upstream. + +The driver will forward errors to userspace after turning most of them +into -EIO. But all status codes are not equal. The -EPIPE (stall) in +particular can be seen more as a result of normal USB signaling than +an actual error. The state is automatically cleared by the USB core +without intervention from either driver or userspace. + +And most devices and firmwares will never trigger a stall as a result +of GetEncapsulatedResponse. This is in fact a requirement for CDC WDM +devices. Quoting from section 7.1 of the CDC WMC spec revision 1.1: + + The function shall not return STALL in response to + GetEncapsulatedResponse. + +But this driver is also handling GetEncapsulatedResponse on behalf of +the qmi_wwan and cdc_mbim drivers. Unfortunately the relevant specs +are not as clear wrt stall. So some QMI and MBIM devices *will* +occasionally stall, causing the GetEncapsulatedResponse to return an +-EPIPE status. Translating this into -EIO for userspace has proven to +be harmful. Treating it as an empty read is safer, making the driver +behave as if the device was conforming to the CDC WDM spec. + +There have been numerous reports of issues related to -EPIPE errors +from some newer CDC MBIM devices in particular, like for example the +Fibocom L831-EAU. Testing on this device has shown that the issues +go away if we simply ignore the -EPIPE status. Similar handling of +-EPIPE is already known from e.g. usb_get_string() + +The -EPIPE log message is still kept to let us track devices with this +unexpected behaviour, hoping that it attracts attention from firmware +developers. + +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=100938 +Reported-and-tested-by: Christian Ehrig +Reported-and-tested-by: Patrick Chilton +Reported-and-tested-by: Andreas Böhler +Signed-off-by: Bjørn Mork +Acked-by: Oliver Neukum +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/class/cdc-wdm.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/usb/class/cdc-wdm.c ++++ b/drivers/usb/class/cdc-wdm.c +@@ -194,8 +194,10 @@ static void wdm_in_callback(struct urb * + /* + * only set a new error if there is no previous error. + * Errors are only cleared during read/open ++ * Avoid propagating -EPIPE (stall) to userspace since it is ++ * better handled as an empty read + */ +- if (desc->rerr == 0) ++ if (desc->rerr == 0 && status != -EPIPE) + desc->rerr = status; + + if (length + desc->length > desc->wMaxCommand) { diff --git a/queue-4.13/usb-devio-don-t-corrupt-user-memory.patch b/queue-4.13/usb-devio-don-t-corrupt-user-memory.patch new file mode 100644 index 00000000000..245ea2b8e4b --- /dev/null +++ b/queue-4.13/usb-devio-don-t-corrupt-user-memory.patch @@ -0,0 +1,38 @@ +From fa1ed74eb1c233be6131ec92df21ab46499a15b6 Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Fri, 22 Sep 2017 23:43:46 +0300 +Subject: USB: devio: Don't corrupt user memory + +From: Dan Carpenter + +commit fa1ed74eb1c233be6131ec92df21ab46499a15b6 upstream. + +The user buffer has "uurb->buffer_length" bytes. If the kernel has more +information than that, we should truncate it instead of writing past +the end of the user's buffer. I added a WARN_ONCE() to help the user +debug the issue. + +Reported-by: Alan Stern +Signed-off-by: Dan Carpenter +Acked-by: Alan Stern +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/devio.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/drivers/usb/core/devio.c ++++ b/drivers/usb/core/devio.c +@@ -1576,7 +1576,11 @@ static int proc_do_submiturb(struct usb_ + totlen += isopkt[u].length; + } + u *= sizeof(struct usb_iso_packet_descriptor); +- uurb->buffer_length = totlen; ++ if (totlen <= uurb->buffer_length) ++ uurb->buffer_length = totlen; ++ else ++ WARN_ONCE(1, "uurb->buffer_length is too short %d vs %d", ++ totlen, uurb->buffer_length); + break; + + default: diff --git a/queue-4.13/usb-devio-prevent-integer-overflow-in-proc_do_submiturb.patch b/queue-4.13/usb-devio-prevent-integer-overflow-in-proc_do_submiturb.patch new file mode 100644 index 00000000000..60b371cf0c1 --- /dev/null +++ b/queue-4.13/usb-devio-prevent-integer-overflow-in-proc_do_submiturb.patch @@ -0,0 +1,52 @@ +From 57999d1107c1e60c2ca7088f2ac0f819e2f554b3 Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Fri, 22 Sep 2017 23:43:25 +0300 +Subject: USB: devio: Prevent integer overflow in proc_do_submiturb() + +From: Dan Carpenter + +commit 57999d1107c1e60c2ca7088f2ac0f819e2f554b3 upstream. + +There used to be an integer overflow check in proc_do_submiturb() but +we removed it. It turns out that it's still required. The +uurb->buffer_length variable is a signed integer and it's controlled by +the user. It can lead to an integer overflow when we do: + + num_sgs = DIV_ROUND_UP(uurb->buffer_length, USB_SG_SIZE); + +If we strip away the macro then that line looks like this: + + num_sgs = (uurb->buffer_length + USB_SG_SIZE - 1) / USB_SG_SIZE; + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +It's the first addition which can overflow. + +Fixes: 1129d270cbfb ("USB: Increase usbfs transfer limit") +Signed-off-by: Dan Carpenter +Acked-by: Alan Stern +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/devio.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/drivers/usb/core/devio.c ++++ b/drivers/usb/core/devio.c +@@ -140,6 +140,9 @@ module_param(usbfs_memory_mb, uint, 0644 + MODULE_PARM_DESC(usbfs_memory_mb, + "maximum MB allowed for usbfs buffers (0 = no limit)"); + ++/* Hard limit, necessary to avoid arithmetic overflow */ ++#define USBFS_XFER_MAX (UINT_MAX / 2 - 1000000) ++ + static atomic64_t usbfs_memory_usage; /* Total memory currently allocated */ + + /* Check whether it's okay to allocate more memory for a transfer */ +@@ -1460,6 +1463,8 @@ static int proc_do_submiturb(struct usb_ + USBDEVFS_URB_ZERO_PACKET | + USBDEVFS_URB_NO_INTERRUPT)) + return -EINVAL; ++ if ((unsigned int)uurb->buffer_length >= USBFS_XFER_MAX) ++ return -EINVAL; + if (uurb->buffer_length > 0 && !uurb->buffer) + return -EINVAL; + if (!(uurb->type == USBDEVFS_URB_TYPE_CONTROL && diff --git a/queue-4.13/usb-dummy-hcd-fix-connection-failures-wrong-speed.patch b/queue-4.13/usb-dummy-hcd-fix-connection-failures-wrong-speed.patch new file mode 100644 index 00000000000..156b953982f --- /dev/null +++ b/queue-4.13/usb-dummy-hcd-fix-connection-failures-wrong-speed.patch @@ -0,0 +1,70 @@ +From fe659bcc9b173bcfdd958ce2aec75e47651e74e1 Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Tue, 26 Sep 2017 15:15:22 -0400 +Subject: USB: dummy-hcd: fix connection failures (wrong speed) + +From: Alan Stern + +commit fe659bcc9b173bcfdd958ce2aec75e47651e74e1 upstream. + +The dummy-hcd UDC driver is not careful about the way it handles +connection speeds. It ignores the module parameter that is supposed +to govern the maximum connection speed and it doesn't set the HCD +flags properly for the case where it ends up running at full speed. + +The result is that in many cases, gadget enumeration over dummy-hcd +fails because the bMaxPacketSize byte in the device descriptor is set +incorrectly. For example, the default settings call for a high-speed +connection, but the maxpacket value for ep0 ends up being set for a +Super-Speed connection. + +This patch fixes the problem by initializing the gadget's max_speed +and the HCD flags correctly. + +Signed-off-by: Alan Stern +Signed-off-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/gadget/udc/dummy_hcd.c | 15 +++++++++++---- + 1 file changed, 11 insertions(+), 4 deletions(-) + +--- a/drivers/usb/gadget/udc/dummy_hcd.c ++++ b/drivers/usb/gadget/udc/dummy_hcd.c +@@ -1037,7 +1037,12 @@ static int dummy_udc_probe(struct platfo + memzero_explicit(&dum->gadget, sizeof(struct usb_gadget)); + dum->gadget.name = gadget_name; + dum->gadget.ops = &dummy_ops; +- dum->gadget.max_speed = USB_SPEED_SUPER; ++ if (mod_data.is_super_speed) ++ dum->gadget.max_speed = USB_SPEED_SUPER; ++ else if (mod_data.is_high_speed) ++ dum->gadget.max_speed = USB_SPEED_HIGH; ++ else ++ dum->gadget.max_speed = USB_SPEED_FULL; + + dum->gadget.dev.parent = &pdev->dev; + init_dummy_udc_hw(dum); +@@ -2561,8 +2566,6 @@ static struct hc_driver dummy_hcd = { + .product_desc = "Dummy host controller", + .hcd_priv_size = sizeof(struct dummy_hcd), + +- .flags = HCD_USB3 | HCD_SHARED, +- + .reset = dummy_setup, + .start = dummy_start, + .stop = dummy_stop, +@@ -2591,8 +2594,12 @@ static int dummy_hcd_probe(struct platfo + dev_info(&pdev->dev, "%s, driver " DRIVER_VERSION "\n", driver_desc); + dum = *((void **)dev_get_platdata(&pdev->dev)); + +- if (!mod_data.is_super_speed) ++ if (mod_data.is_super_speed) ++ dummy_hcd.flags = HCD_USB3 | HCD_SHARED; ++ else if (mod_data.is_high_speed) + dummy_hcd.flags = HCD_USB2; ++ else ++ dummy_hcd.flags = HCD_USB11; + hs_hcd = usb_create_hcd(&dummy_hcd, &pdev->dev, dev_name(&pdev->dev)); + if (!hs_hcd) + return -ENOMEM; diff --git a/queue-4.13/usb-dummy-hcd-fix-erroneous-synchronization-change.patch b/queue-4.13/usb-dummy-hcd-fix-erroneous-synchronization-change.patch new file mode 100644 index 00000000000..59d1f1cd3ce --- /dev/null +++ b/queue-4.13/usb-dummy-hcd-fix-erroneous-synchronization-change.patch @@ -0,0 +1,138 @@ +From 7dbd8f4cabd96db5a50513de9d83a8105a5ffc81 Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Tue, 26 Sep 2017 15:15:49 -0400 +Subject: USB: dummy-hcd: Fix erroneous synchronization change + +From: Alan Stern + +commit 7dbd8f4cabd96db5a50513de9d83a8105a5ffc81 upstream. + +A recent change to the synchronization in dummy-hcd was incorrect. +The issue was that dummy_udc_stop() contained no locking and therefore +could race with various gadget driver callbacks, and the fix was to +add locking and issue the callbacks with the private spinlock held. + +UDC drivers aren't supposed to do this. Gadget driver callback +routines are allowed to invoke functions in the UDC driver, and these +functions will generally try to acquire the private spinlock. This +would deadlock the driver. + +The correct solution is to drop the spinlock before issuing callbacks, +and avoid races by emulating the synchronize_irq() call that all real +UDC drivers must perform in their ->udc_stop() routines after +disabling interrupts. This involves adding a flag to dummy-hcd's +private structure to keep track of whether interrupts are supposed to +be enabled, and adding a counter to keep track of ongoing callbacks so +that dummy_udc_stop() can wait for them all to finish. + +A real UDC driver won't receive disconnect, reset, suspend, resume, or +setup events once it has disabled interrupts. dummy-hcd will receive +them but won't try to issue any gadget driver callbacks, which should +be just as good. + +Signed-off-by: Alan Stern +Fixes: f16443a034c7 ("USB: gadgetfs, dummy-hcd, net2280: fix locking for callbacks") +Signed-off-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/gadget/udc/dummy_hcd.c | 32 ++++++++++++++++++++++++++++++-- + 1 file changed, 30 insertions(+), 2 deletions(-) + +--- a/drivers/usb/gadget/udc/dummy_hcd.c ++++ b/drivers/usb/gadget/udc/dummy_hcd.c +@@ -255,11 +255,13 @@ struct dummy { + */ + struct dummy_ep ep[DUMMY_ENDPOINTS]; + int address; ++ int callback_usage; + struct usb_gadget gadget; + struct usb_gadget_driver *driver; + struct dummy_request fifo_req; + u8 fifo_buf[FIFO_SIZE]; + u16 devstatus; ++ unsigned ints_enabled:1; + unsigned udc_suspended:1; + unsigned pullup:1; + +@@ -442,18 +444,27 @@ static void set_link_state(struct dummy_ + (~dum_hcd->old_status) & dum_hcd->port_status; + + /* Report reset and disconnect events to the driver */ +- if (dum->driver && (disconnect || reset)) { ++ if (dum->ints_enabled && (disconnect || reset)) { + stop_activity(dum); ++ ++dum->callback_usage; ++ spin_unlock(&dum->lock); + if (reset) + usb_gadget_udc_reset(&dum->gadget, dum->driver); + else + dum->driver->disconnect(&dum->gadget); ++ spin_lock(&dum->lock); ++ --dum->callback_usage; + } +- } else if (dum_hcd->active != dum_hcd->old_active) { ++ } else if (dum_hcd->active != dum_hcd->old_active && ++ dum->ints_enabled) { ++ ++dum->callback_usage; ++ spin_unlock(&dum->lock); + if (dum_hcd->old_active && dum->driver->suspend) + dum->driver->suspend(&dum->gadget); + else if (!dum_hcd->old_active && dum->driver->resume) + dum->driver->resume(&dum->gadget); ++ spin_lock(&dum->lock); ++ --dum->callback_usage; + } + + dum_hcd->old_status = dum_hcd->port_status; +@@ -974,8 +985,11 @@ static int dummy_udc_start(struct usb_ga + * can't enumerate without help from the driver we're binding. + */ + ++ spin_lock_irq(&dum->lock); + dum->devstatus = 0; + dum->driver = driver; ++ dum->ints_enabled = 1; ++ spin_unlock_irq(&dum->lock); + + return 0; + } +@@ -986,6 +1000,16 @@ static int dummy_udc_stop(struct usb_gad + struct dummy *dum = dum_hcd->dum; + + spin_lock_irq(&dum->lock); ++ dum->ints_enabled = 0; ++ stop_activity(dum); ++ ++ /* emulate synchronize_irq(): wait for callbacks to finish */ ++ while (dum->callback_usage > 0) { ++ spin_unlock_irq(&dum->lock); ++ usleep_range(1000, 2000); ++ spin_lock_irq(&dum->lock); ++ } ++ + dum->driver = NULL; + spin_unlock_irq(&dum->lock); + +@@ -1530,6 +1554,8 @@ static struct dummy_ep *find_endpoint(st + if (!is_active((dum->gadget.speed == USB_SPEED_SUPER ? + dum->ss_hcd : dum->hs_hcd))) + return NULL; ++ if (!dum->ints_enabled) ++ return NULL; + if ((address & ~USB_DIR_IN) == 0) + return &dum->ep[0]; + for (i = 1; i < DUMMY_ENDPOINTS; i++) { +@@ -1871,10 +1897,12 @@ restart: + * until setup() returns; no reentrancy issues etc. + */ + if (value > 0) { ++ ++dum->callback_usage; + spin_unlock(&dum->lock); + value = dum->driver->setup(&dum->gadget, + &setup); + spin_lock(&dum->lock); ++ --dum->callback_usage; + + if (value >= 0) { + /* no delays (max 64KB data stage) */ diff --git a/queue-4.13/usb-dummy-hcd-fix-infinite-loop-resubmission-bug.patch b/queue-4.13/usb-dummy-hcd-fix-infinite-loop-resubmission-bug.patch new file mode 100644 index 00000000000..2f3c32a375b --- /dev/null +++ b/queue-4.13/usb-dummy-hcd-fix-infinite-loop-resubmission-bug.patch @@ -0,0 +1,79 @@ +From 0173a68bfb0ad1c72a6ee39cc485aa2c97540b98 Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Tue, 26 Sep 2017 15:15:40 -0400 +Subject: USB: dummy-hcd: fix infinite-loop resubmission bug + +From: Alan Stern + +commit 0173a68bfb0ad1c72a6ee39cc485aa2c97540b98 upstream. + +The dummy-hcd HCD/UDC emulator tries not to do too much work during +each timer interrupt. But it doesn't try very hard; currently all +it does is limit the total amount of bulk data transferred. Other +transfer types aren't limited, and URBs that transfer no data (because +of an error, perhaps) don't count toward the limit, even though on a +real USB bus they would consume at least a minimum overhead. + +This means it's possible to get the driver stuck in an infinite loop, +for example, if the host class driver resubmits an URB every time it +completes (which is common for interrupt URBs). Each time the URB is +resubmitted it gets added to the end of the pending-URBs list, and +dummy-hcd doesn't stop until that list is empty. Andrey Konovalov was +able to trigger this failure mode using the syzkaller fuzzer. + +This patch fixes the infinite-loop problem by restricting the URBs +handled during each timer interrupt to those that were already on the +pending list when the interrupt routine started. Newly added URBs +won't be processed until the next timer interrupt. The problem of +properly accounting for non-bulk bandwidth (as well as packet and +transaction overhead) is not addressed here. + +Signed-off-by: Alan Stern +Reported-by: Andrey Konovalov +Tested-by: Andrey Konovalov +Signed-off-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/gadget/udc/dummy_hcd.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +--- a/drivers/usb/gadget/udc/dummy_hcd.c ++++ b/drivers/usb/gadget/udc/dummy_hcd.c +@@ -237,6 +237,8 @@ struct dummy_hcd { + + struct usb_device *udev; + struct list_head urbp_list; ++ struct urbp *next_frame_urbp; ++ + u32 stream_en_ep; + u8 num_stream[30 / 2]; + +@@ -1251,6 +1253,8 @@ static int dummy_urb_enqueue( + + list_add_tail(&urbp->urbp_list, &dum_hcd->urbp_list); + urb->hcpriv = urbp; ++ if (!dum_hcd->next_frame_urbp) ++ dum_hcd->next_frame_urbp = urbp; + if (usb_pipetype(urb->pipe) == PIPE_CONTROL) + urb->error_count = 1; /* mark as a new urb */ + +@@ -1767,6 +1771,7 @@ static void dummy_timer(unsigned long _d + spin_unlock_irqrestore(&dum->lock, flags); + return; + } ++ dum_hcd->next_frame_urbp = NULL; + + for (i = 0; i < DUMMY_ENDPOINTS; i++) { + if (!ep_info[i].name) +@@ -1783,6 +1788,10 @@ restart: + int type; + int status = -EINPROGRESS; + ++ /* stop when we reach URBs queued after the timer interrupt */ ++ if (urbp == dum_hcd->next_frame_urbp) ++ break; ++ + urb = urbp->urb; + if (urb->unlinked) + goto return_urb; diff --git a/queue-4.13/usb-gadget-udc-atmel-set-vbus-irqflags-explicitly.patch b/queue-4.13/usb-gadget-udc-atmel-set-vbus-irqflags-explicitly.patch new file mode 100644 index 00000000000..0ae7dcd3907 --- /dev/null +++ b/queue-4.13/usb-gadget-udc-atmel-set-vbus-irqflags-explicitly.patch @@ -0,0 +1,47 @@ +From 6baeda120d90aa637b08f7604de104ab00ce9126 Mon Sep 17 00:00:00 2001 +From: Nicolas Ferre +Date: Thu, 31 Aug 2017 14:51:40 +0200 +Subject: usb: gadget: udc: atmel: set vbus irqflags explicitly + +From: Nicolas Ferre + +commit 6baeda120d90aa637b08f7604de104ab00ce9126 upstream. + +The driver triggers actions on both edges of the vbus signal. + +The former PIO controller was triggering IRQs on both falling and rising edges +by default. Newer PIO controller don't, so it's better to set it explicitly to +IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING. + +Without this patch we may trigger the connection with host but only on some +bouncing signal conditions and thus lose connecting events. + +Acked-by: Ludovic Desroches +Signed-off-by: Nicolas Ferre +Signed-off-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/gadget/udc/atmel_usba_udc.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/usb/gadget/udc/atmel_usba_udc.c ++++ b/drivers/usb/gadget/udc/atmel_usba_udc.c +@@ -29,6 +29,8 @@ + #include + + #include "atmel_usba_udc.h" ++#define USBA_VBUS_IRQFLAGS (IRQF_ONESHOT \ ++ | IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING) + + #ifdef CONFIG_USB_GADGET_DEBUG_FS + #include +@@ -2361,7 +2363,7 @@ static int usba_udc_probe(struct platfor + IRQ_NOAUTOEN); + ret = devm_request_threaded_irq(&pdev->dev, + gpio_to_irq(udc->vbus_pin), NULL, +- usba_vbus_irq_thread, IRQF_ONESHOT, ++ usba_vbus_irq_thread, USBA_VBUS_IRQFLAGS, + "atmel_usba_udc", udc); + if (ret) { + udc->vbus_pin = -ENODEV; diff --git a/queue-4.13/usb-gadget-udc-renesas_usb3-fix-for-no-data-control-transfer.patch b/queue-4.13/usb-gadget-udc-renesas_usb3-fix-for-no-data-control-transfer.patch new file mode 100644 index 00000000000..f589ba8d6ee --- /dev/null +++ b/queue-4.13/usb-gadget-udc-renesas_usb3-fix-for-no-data-control-transfer.patch @@ -0,0 +1,34 @@ +From 4dcf4bab4a409e81284b8202137e4a85b96b34de Mon Sep 17 00:00:00 2001 +From: Yoshihiro Shimoda +Date: Mon, 25 Sep 2017 17:01:23 +0900 +Subject: usb: gadget: udc: renesas_usb3: fix for no-data control transfer + +From: Yoshihiro Shimoda + +commit 4dcf4bab4a409e81284b8202137e4a85b96b34de upstream. + +When bRequestType & USB_DIR_IN is false and req.length is 0 in control +transfer, since it means non-data, this driver should not set the mode +as control write. So, this patch fixes it. + +Fixes: 746bfe63bba3 ("usb: gadget: renesas_usb3: add support for Renesas USB3.0 peripheral controller") +Signed-off-by: Yoshihiro Shimoda +Signed-off-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/gadget/udc/renesas_usb3.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/usb/gadget/udc/renesas_usb3.c ++++ b/drivers/usb/gadget/udc/renesas_usb3.c +@@ -1144,7 +1144,8 @@ static void usb3_start_pipe0(struct rene + usb3_set_p0_con_for_ctrl_read_data(usb3); + } else { + usb3_clear_bit(usb3, P0_MOD_DIR, USB3_P0_MOD); +- usb3_set_p0_con_for_ctrl_write_data(usb3); ++ if (usb3_req->req.length) ++ usb3_set_p0_con_for_ctrl_write_data(usb3); + } + + usb3_p0_xfer(usb3_ep, usb3_req); diff --git a/queue-4.13/usb-gadget-udc-renesas_usb3-fix-pn_rammap.pn_mpkt-value.patch b/queue-4.13/usb-gadget-udc-renesas_usb3-fix-pn_rammap.pn_mpkt-value.patch new file mode 100644 index 00000000000..a8c7749e806 --- /dev/null +++ b/queue-4.13/usb-gadget-udc-renesas_usb3-fix-pn_rammap.pn_mpkt-value.patch @@ -0,0 +1,43 @@ +From 73f2f5745f18b4ccfe9484deac4e84a1378d19fd Mon Sep 17 00:00:00 2001 +From: Yoshihiro Shimoda +Date: Mon, 25 Sep 2017 17:01:24 +0900 +Subject: usb: gadget: udc: renesas_usb3: fix Pn_RAMMAP.Pn_MPKT value + +From: Yoshihiro Shimoda + +commit 73f2f5745f18b4ccfe9484deac4e84a1378d19fd upstream. + +According to the datasheet of R-Car Gen3, the Pn_RAMMAP.Pn_MPKT should +be set to one of 8, 16, 32, 64, 512 and 1024. Otherwise, when a gadget +driver uses an interrupt endpoint, unexpected behavior happens. So, +this patch fixes it. + +Fixes: 746bfe63bba3 ("usb: gadget: renesas_usb3: add support for Renesas USB3.0 peripheral controller") +Signed-off-by: Yoshihiro Shimoda +Signed-off-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/gadget/udc/renesas_usb3.c | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +--- a/drivers/usb/gadget/udc/renesas_usb3.c ++++ b/drivers/usb/gadget/udc/renesas_usb3.c +@@ -2048,7 +2048,16 @@ static u32 usb3_calc_ramarea(int ram_siz + static u32 usb3_calc_rammap_val(struct renesas_usb3_ep *usb3_ep, + const struct usb_endpoint_descriptor *desc) + { +- return usb3_ep->rammap_val | PN_RAMMAP_MPKT(usb_endpoint_maxp(desc)); ++ int i; ++ const u32 max_packet_array[] = {8, 16, 32, 64, 512}; ++ u32 mpkt = PN_RAMMAP_MPKT(1024); ++ ++ for (i = 0; i < ARRAY_SIZE(max_packet_array); i++) { ++ if (usb_endpoint_maxp(desc) <= max_packet_array[i]) ++ mpkt = PN_RAMMAP_MPKT(max_packet_array[i]); ++ } ++ ++ return usb3_ep->rammap_val | mpkt; + } + + static int usb3_enable_pipe_n(struct renesas_usb3_ep *usb3_ep, diff --git a/queue-4.13/usb-gadget-udc-renesas_usb3-fix-return-value-of-usb3_write_pipe.patch b/queue-4.13/usb-gadget-udc-renesas_usb3-fix-return-value-of-usb3_write_pipe.patch new file mode 100644 index 00000000000..b931b8ea3d9 --- /dev/null +++ b/queue-4.13/usb-gadget-udc-renesas_usb3-fix-return-value-of-usb3_write_pipe.patch @@ -0,0 +1,44 @@ +From 447b8a01b84f048d93d43bfe1fcaa4fcc56595cc Mon Sep 17 00:00:00 2001 +From: Yoshihiro Shimoda +Date: Mon, 25 Sep 2017 17:01:25 +0900 +Subject: usb: gadget: udc: renesas_usb3: Fix return value of usb3_write_pipe() + +From: Yoshihiro Shimoda + +commit 447b8a01b84f048d93d43bfe1fcaa4fcc56595cc upstream. + +This patch fixes an issue that this driver cannot go status stage +in control read when the req.zero is set to 1 and the len in +usb3_write_pipe() is set to 0. Otherwise, if we use g_ncm driver, +usb enumeration takes long time (5 seconds or more). + +Fixes: 746bfe63bba3 ("usb: gadget: renesas_usb3: add support for Renesas USB3.0 peripheral controller") +Signed-off-by: Yoshihiro Shimoda +Signed-off-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/gadget/udc/renesas_usb3.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/drivers/usb/gadget/udc/renesas_usb3.c ++++ b/drivers/usb/gadget/udc/renesas_usb3.c +@@ -1032,7 +1032,7 @@ static int usb3_write_pipe(struct renesa + usb3_ep->ep.maxpacket); + u8 *buf = usb3_req->req.buf + usb3_req->req.actual; + u32 tmp = 0; +- bool is_last; ++ bool is_last = !len ? true : false; + + if (usb3_wait_pipe_status(usb3_ep, PX_STA_BUFSTS) < 0) + return -EBUSY; +@@ -1053,7 +1053,8 @@ static int usb3_write_pipe(struct renesa + usb3_write(usb3, tmp, fifo_reg); + } + +- is_last = usb3_is_transfer_complete(usb3_ep, usb3_req); ++ if (!is_last) ++ is_last = usb3_is_transfer_complete(usb3_ep, usb3_req); + /* Send the data */ + usb3_set_px_con_send(usb3_ep, len, is_last); + diff --git a/queue-4.13/usb-gadgetfs-fix-copy_to_user-while-holding-spinlock.patch b/queue-4.13/usb-gadgetfs-fix-copy_to_user-while-holding-spinlock.patch new file mode 100644 index 00000000000..277ee603e5f --- /dev/null +++ b/queue-4.13/usb-gadgetfs-fix-copy_to_user-while-holding-spinlock.patch @@ -0,0 +1,42 @@ +From 6e76c01e71551cb221c1f3deacb9dcd9a7346784 Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Thu, 21 Sep 2017 16:12:01 -0400 +Subject: USB: gadgetfs: fix copy_to_user while holding spinlock + +From: Alan Stern + +commit 6e76c01e71551cb221c1f3deacb9dcd9a7346784 upstream. + +The gadgetfs driver as a long-outstanding FIXME, regarding a call of +copy_to_user() made while holding a spinlock. This patch fixes the +issue by dropping the spinlock and using the dev->udc_usage mechanism +introduced by another recent patch to guard against status changes +while the lock isn't held. + +Signed-off-by: Alan Stern +Reported-by: Andrey Konovalov +Acked-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/gadget/legacy/inode.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/drivers/usb/gadget/legacy/inode.c ++++ b/drivers/usb/gadget/legacy/inode.c +@@ -986,11 +986,14 @@ ep0_read (struct file *fd, char __user * + retval = -EIO; + else { + len = min (len, (size_t)dev->req->actual); +-// FIXME don't call this with the spinlock held ... ++ ++dev->udc_usage; ++ spin_unlock_irq(&dev->lock); + if (copy_to_user (buf, dev->req->buf, len)) + retval = -EFAULT; + else + retval = len; ++ spin_lock_irq(&dev->lock); ++ --dev->udc_usage; + clean_req (dev->gadget->ep0, dev->req); + /* NOTE userspace can't yet choose to stall */ + } diff --git a/queue-4.13/usb-pci-quirks.c-corrected-timeout-values-used-in-handshake.patch b/queue-4.13/usb-pci-quirks.c-corrected-timeout-values-used-in-handshake.patch new file mode 100644 index 00000000000..fc758689d0c --- /dev/null +++ b/queue-4.13/usb-pci-quirks.c-corrected-timeout-values-used-in-handshake.patch @@ -0,0 +1,58 @@ +From 114ec3a6f9096d211a4aff4277793ba969a62c73 Mon Sep 17 00:00:00 2001 +From: Jim Dickerson +Date: Mon, 18 Sep 2017 17:39:14 +0300 +Subject: usb: pci-quirks.c: Corrected timeout values used in handshake + +From: Jim Dickerson + +commit 114ec3a6f9096d211a4aff4277793ba969a62c73 upstream. + +Servers were emitting failed handoff messages but were not +waiting the full 1 second as designated in section 4.22.1 of +the eXtensible Host Controller Interface specifications. The +handshake was using wrong units so calls were made with milliseconds +not microseconds. Comments referenced 5 seconds not 1 second as +in specs. + +The wrong units were also corrected in a second handshake call. + +Signed-off-by: Jim Dickerson +Signed-off-by: Mathias Nyman +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/pci-quirks.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/usb/host/pci-quirks.c ++++ b/drivers/usb/host/pci-quirks.c +@@ -1022,7 +1022,7 @@ EXPORT_SYMBOL_GPL(usb_disable_xhci_ports + * + * Takes care of the handoff between the Pre-OS (i.e. BIOS) and the OS. + * It signals to the BIOS that the OS wants control of the host controller, +- * and then waits 5 seconds for the BIOS to hand over control. ++ * and then waits 1 second for the BIOS to hand over control. + * If we timeout, assume the BIOS is broken and take control anyway. + */ + static void quirk_usb_handoff_xhci(struct pci_dev *pdev) +@@ -1069,9 +1069,9 @@ static void quirk_usb_handoff_xhci(struc + if (val & XHCI_HC_BIOS_OWNED) { + writel(val | XHCI_HC_OS_OWNED, base + ext_cap_offset); + +- /* Wait for 5 seconds with 10 microsecond polling interval */ ++ /* Wait for 1 second with 10 microsecond polling interval */ + timeout = handshake(base + ext_cap_offset, XHCI_HC_BIOS_OWNED, +- 0, 5000, 10); ++ 0, 1000000, 10); + + /* Assume a buggy BIOS and take HC ownership anyway */ + if (timeout) { +@@ -1100,7 +1100,7 @@ hc_init: + * operational or runtime registers. Wait 5 seconds and no more. + */ + timeout = handshake(op_reg_base + XHCI_STS_OFFSET, XHCI_STS_CNR, 0, +- 5000, 10); ++ 5000000, 10); + /* Assume a buggy HC and start HC initialization anyway */ + if (timeout) { + val = readl(op_reg_base + XHCI_STS_OFFSET); diff --git a/queue-4.13/usb-renesas_usbhs-fix-the-bclr-setting-condition-for-non-dcp-pipe.patch b/queue-4.13/usb-renesas_usbhs-fix-the-bclr-setting-condition-for-non-dcp-pipe.patch new file mode 100644 index 00000000000..3f3538f4250 --- /dev/null +++ b/queue-4.13/usb-renesas_usbhs-fix-the-bclr-setting-condition-for-non-dcp-pipe.patch @@ -0,0 +1,44 @@ +From 6124607acc88fffeaadf3aacfeb3cc1304c87387 Mon Sep 17 00:00:00 2001 +From: Yoshihiro Shimoda +Date: Wed, 27 Sep 2017 18:47:12 +0900 +Subject: usb: renesas_usbhs: fix the BCLR setting condition for non-DCP pipe + +From: Yoshihiro Shimoda + +commit 6124607acc88fffeaadf3aacfeb3cc1304c87387 upstream. + +This patch fixes an issue that the driver sets the BCLR bit of +{C,Dn}FIFOCTR register to 1 even when it's non-DCP pipe and +the FRDY bit of {C,Dn}FIFOCTR register is set to 1. + +Fixes: e8d548d54968 ("usb: renesas_usbhs: fifo became independent from pipe.") +Signed-off-by: Yoshihiro Shimoda +Signed-off-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/renesas_usbhs/fifo.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +--- a/drivers/usb/renesas_usbhs/fifo.c ++++ b/drivers/usb/renesas_usbhs/fifo.c +@@ -282,11 +282,17 @@ static void usbhsf_fifo_clear(struct usb + struct usbhs_fifo *fifo) + { + struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); ++ int ret = 0; + + if (!usbhs_pipe_is_dcp(pipe)) +- usbhsf_fifo_barrier(priv, fifo); ++ ret = usbhsf_fifo_barrier(priv, fifo); + +- usbhs_write(priv, fifo->ctr, BCLR); ++ /* ++ * if non-DCP pipe, this driver should set BCLR when ++ * usbhsf_fifo_barrier() returns 0. ++ */ ++ if (!ret) ++ usbhs_write(priv, fifo->ctr, BCLR); + } + + static int usbhsf_fifo_rcv_len(struct usbhs_priv *priv, diff --git a/queue-4.13/usb-renesas_usbhs-fix-usbhsf_fifo_clear-for-rx-direction.patch b/queue-4.13/usb-renesas_usbhs-fix-usbhsf_fifo_clear-for-rx-direction.patch new file mode 100644 index 00000000000..5ffbc7b2ab2 --- /dev/null +++ b/queue-4.13/usb-renesas_usbhs-fix-usbhsf_fifo_clear-for-rx-direction.patch @@ -0,0 +1,44 @@ +From 0a2ce62b61f2c76d0213edf4e37aaf54a8ddf295 Mon Sep 17 00:00:00 2001 +From: Yoshihiro Shimoda +Date: Wed, 27 Sep 2017 18:47:13 +0900 +Subject: usb: renesas_usbhs: fix usbhsf_fifo_clear() for RX direction + +From: Yoshihiro Shimoda + +commit 0a2ce62b61f2c76d0213edf4e37aaf54a8ddf295 upstream. + +This patch fixes an issue that the usbhsf_fifo_clear() is possible +to cause 10 msec delay if the pipe is RX direction and empty because +the FRDY bit will never be set to 1 in such case. + +Fixes: e8d548d54968 ("usb: renesas_usbhs: fifo became independent from pipe.") +Signed-off-by: Yoshihiro Shimoda +Signed-off-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/renesas_usbhs/fifo.c | 13 +++++++++++-- + 1 file changed, 11 insertions(+), 2 deletions(-) + +--- a/drivers/usb/renesas_usbhs/fifo.c ++++ b/drivers/usb/renesas_usbhs/fifo.c +@@ -284,8 +284,17 @@ static void usbhsf_fifo_clear(struct usb + struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); + int ret = 0; + +- if (!usbhs_pipe_is_dcp(pipe)) +- ret = usbhsf_fifo_barrier(priv, fifo); ++ if (!usbhs_pipe_is_dcp(pipe)) { ++ /* ++ * This driver checks the pipe condition first to avoid -EBUSY ++ * from usbhsf_fifo_barrier() with about 10 msec delay in ++ * the interrupt handler if the pipe is RX direction and empty. ++ */ ++ if (usbhs_pipe_is_dir_in(pipe)) ++ ret = usbhs_pipe_is_accessible(pipe); ++ if (!ret) ++ ret = usbhsf_fifo_barrier(priv, fifo); ++ } + + /* + * if non-DCP pipe, this driver should set BCLR when diff --git a/queue-4.13/usb-storage-fix-bogus-hardware-error-messages-for-ata-pass-thru-devices.patch b/queue-4.13/usb-storage-fix-bogus-hardware-error-messages-for-ata-pass-thru-devices.patch new file mode 100644 index 00000000000..75ec35cc9c0 --- /dev/null +++ b/queue-4.13/usb-storage-fix-bogus-hardware-error-messages-for-ata-pass-thru-devices.patch @@ -0,0 +1,88 @@ +From a4fd4a724d6c30ad671046d83be2e9be2f11d275 Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Thu, 21 Sep 2017 16:02:05 -0400 +Subject: usb-storage: fix bogus hardware error messages for ATA pass-thru devices + +From: Alan Stern + +commit a4fd4a724d6c30ad671046d83be2e9be2f11d275 upstream. + +Ever since commit a621bac3044e ("scsi_lib: correctly retry failed zero +length REQ_TYPE_FS commands"), people have been getting bogus error +messages for USB disk drives using ATA pass-thru. For example: + +[ 1344.880193] sd 6:0:0:0: [sdb] Attached SCSI disk +[ 1345.069152] sd 6:0:0:0: [sdb] tag#0 FAILED Result: hostbyte=DID_ERROR driverbyte=DRIVER_SENSE +[ 1345.069159] sd 6:0:0:0: [sdb] tag#0 Sense Key : Hardware Error [current] [descriptor] +[ 1345.069162] sd 6:0:0:0: [sdb] tag#0 Add. Sense: No additional sense information +[ 1345.069168] sd 6:0:0:0: [sdb] tag#0 CDB: ATA command pass through(16) 85 06 20 00 00 00 00 00 00 00 00 00 00 00 e5 00 +[ 1345.172252] sd 6:0:0:0: [sdb] tag#0 FAILED Result: hostbyte=DID_ERROR driverbyte=DRIVER_SENSE +[ 1345.172258] sd 6:0:0:0: [sdb] tag#0 Sense Key : Hardware Error [current] [descriptor] +[ 1345.172261] sd 6:0:0:0: [sdb] tag#0 Add. Sense: No additional sense information +[ 1345.172266] sd 6:0:0:0: [sdb] tag#0 CDB: ATA command pass through(12)/Blank a1 06 20 da 00 00 4f c2 00 b0 00 00 + +These messages can be quite annoying, because programs like udisks2 +provoke them every 10 minutes or so. Other programs can also have +this effect, such as those in smartmontools. + +I don't fully understand how that commit induced the SCSI core to log +these error messages, but the underlying cause for them is code added +to usb-storage by commit f1a0743bc0e7 ("USB: storage: When a device +returns no sense data, call it a Hardware Error"). At the time it was +necessary to do this, in order to prevent an infinite retry loop with +some not-so-great mass storage devices. + +However, the ATA pass-thru protocol uses SCSI sense data to return +command status values, and some devices always report Check Condition +status for ATA pass-thru commands to ensure that the host retrieves +the sense data, even if the command succeeded. This violates the USB +mass-storage protocol (Check Condition status is supposed to mean the +command failed), but we can't help that. + +This patch attempts to mitigate the problem of these bogus error +reports by changing usb-storage. The HARDWARE ERROR sense key will be +inserted only for commands that aren't ATA pass-thru. + +Thanks to Ewan Milne for pointing out that this mechanism was present +in usb-storage. 8 years after writing it, I had completely forgotten +its existence. + +Signed-off-by: Alan Stern +Tested-by: Kris Lindgren +Ref: https://bugzilla.redhat.com/show_bug.cgi?id=1351305 +CC: Ewan D. Milne +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/storage/transport.c | 14 +++++++++++++- + 1 file changed, 13 insertions(+), 1 deletion(-) + +--- a/drivers/usb/storage/transport.c ++++ b/drivers/usb/storage/transport.c +@@ -834,13 +834,25 @@ Retry_Sense: + if (result == USB_STOR_TRANSPORT_GOOD) { + srb->result = SAM_STAT_GOOD; + srb->sense_buffer[0] = 0x0; ++ } ++ ++ /* ++ * ATA-passthru commands use sense data to report ++ * the command completion status, and often devices ++ * return Check Condition status when nothing is ++ * wrong. ++ */ ++ else if (srb->cmnd[0] == ATA_16 || ++ srb->cmnd[0] == ATA_12) { ++ /* leave the data alone */ ++ } + + /* + * If there was a problem, report an unspecified + * hardware error to prevent the higher layers from + * entering an infinite retry loop. + */ +- } else { ++ else { + srb->result = DID_ERROR << 16; + if ((sshdr.response_code & 0x72) == 0x72) + srb->sense_buffer[1] = HARDWARE_ERROR; diff --git a/queue-4.13/usb-storage-unusual_devs-entry-to-fix-write-access-regression-for-seagate-external-drives.patch b/queue-4.13/usb-storage-unusual_devs-entry-to-fix-write-access-regression-for-seagate-external-drives.patch new file mode 100644 index 00000000000..b50df8fcf40 --- /dev/null +++ b/queue-4.13/usb-storage-unusual_devs-entry-to-fix-write-access-regression-for-seagate-external-drives.patch @@ -0,0 +1,37 @@ +From 113f6eb6d50cfa5e2a1cdcf1678b12661fa272ab Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Thu, 21 Sep 2017 15:59:30 -0400 +Subject: usb-storage: unusual_devs entry to fix write-access regression for Seagate external drives + +From: Alan Stern + +commit 113f6eb6d50cfa5e2a1cdcf1678b12661fa272ab upstream. + +Kris Lindgren reports that without the NO_WP_DETECT flag, his Seagate +external disk drive fails all write accesses. This regresssion dates +back approximately to the start of the 4.x kernel releases. + +Signed-off-by: Alan Stern +Reported-by: Kris Lindgren +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/storage/unusual_devs.h | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/drivers/usb/storage/unusual_devs.h ++++ b/drivers/usb/storage/unusual_devs.h +@@ -1459,6 +1459,13 @@ UNUSUAL_DEV( 0x0bc2, 0x3010, 0x0000, 0x0 + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_SANE_SENSE ), + ++/* Reported by Kris Lindgren */ ++UNUSUAL_DEV( 0x0bc2, 0x3332, 0x0000, 0x9999, ++ "Seagate", ++ "External", ++ USB_SC_DEVICE, USB_PR_DEVICE, NULL, ++ US_FL_NO_WP_DETECT ), ++ + UNUSUAL_DEV( 0x0d49, 0x7310, 0x0000, 0x9999, + "Maxtor", + "USB to SATA",