]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.14-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 3 Sep 2019 18:42:46 +0000 (20:42 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 3 Sep 2019 18:42:46 +0000 (20:42 +0200)
added patches:
usb-cdc-wdm-fix-race-between-write-and-disconnect-due-to-flag-abuse.patch
usb-chipidea-udc-don-t-do-hardware-access-if-gadget-has-stopped.patch
usb-host-ohci-fix-a-race-condition-between-shutdown-and-irq.patch
usb-host-xhci-rcar-fix-typo-in-compatible-string-matching.patch
usb-storage-add-new-jms567-revision-to-unusual_devs.patch
usb-storage-ums-realtek-update-module-parameter-description-for-auto_delink_en.patch
usb-storage-ums-realtek-whitelist-auto-delink-support.patch

queue-4.14/series
queue-4.14/usb-cdc-wdm-fix-race-between-write-and-disconnect-due-to-flag-abuse.patch [new file with mode: 0644]
queue-4.14/usb-chipidea-udc-don-t-do-hardware-access-if-gadget-has-stopped.patch [new file with mode: 0644]
queue-4.14/usb-host-ohci-fix-a-race-condition-between-shutdown-and-irq.patch [new file with mode: 0644]
queue-4.14/usb-host-xhci-rcar-fix-typo-in-compatible-string-matching.patch [new file with mode: 0644]
queue-4.14/usb-storage-add-new-jms567-revision-to-unusual_devs.patch [new file with mode: 0644]
queue-4.14/usb-storage-ums-realtek-update-module-parameter-description-for-auto_delink_en.patch [new file with mode: 0644]
queue-4.14/usb-storage-ums-realtek-whitelist-auto-delink-support.patch [new file with mode: 0644]

index eaf1bd9dcb458ee5dbd67ba69e4d16ff22c8b5ff..4a13a2bbe1525dea2a0031d816e7ff9ef1c6508f 100644 (file)
@@ -28,3 +28,10 @@ x86-apic-include-the-ldr-when-clearing-out-apic-registers.patch
 ftrace-fix-null-pointer-dereference-in-t_probe_next.patch
 ftrace-check-for-successful-allocation-of-hash.patch
 ftrace-check-for-empty-hash-and-comment-the-race-with-registering-probes.patch
+usb-storage-add-new-jms567-revision-to-unusual_devs.patch
+usb-cdc-wdm-fix-race-between-write-and-disconnect-due-to-flag-abuse.patch
+usb-chipidea-udc-don-t-do-hardware-access-if-gadget-has-stopped.patch
+usb-host-ohci-fix-a-race-condition-between-shutdown-and-irq.patch
+usb-host-xhci-rcar-fix-typo-in-compatible-string-matching.patch
+usb-storage-ums-realtek-update-module-parameter-description-for-auto_delink_en.patch
+usb-storage-ums-realtek-whitelist-auto-delink-support.patch
diff --git a/queue-4.14/usb-cdc-wdm-fix-race-between-write-and-disconnect-due-to-flag-abuse.patch b/queue-4.14/usb-cdc-wdm-fix-race-between-write-and-disconnect-due-to-flag-abuse.patch
new file mode 100644 (file)
index 0000000..0ae0472
--- /dev/null
@@ -0,0 +1,64 @@
+From 1426bd2c9f7e3126e2678e7469dca9fd9fc6dd3e Mon Sep 17 00:00:00 2001
+From: Oliver Neukum <oneukum@suse.com>
+Date: Tue, 27 Aug 2019 12:34:36 +0200
+Subject: USB: cdc-wdm: fix race between write and disconnect due to flag abuse
+
+From: Oliver Neukum <oneukum@suse.com>
+
+commit 1426bd2c9f7e3126e2678e7469dca9fd9fc6dd3e upstream.
+
+In case of a disconnect an ongoing flush() has to be made fail.
+Nevertheless we cannot be sure that any pending URB has already
+finished, so although they will never succeed, they still must
+not be touched.
+The clean solution for this is to check for WDM_IN_USE
+and WDM_DISCONNECTED in flush(). There is no point in ever
+clearing WDM_IN_USE, as no further writes make sense.
+
+The issue is as old as the driver.
+
+Fixes: afba937e540c9 ("USB: CDC WDM driver")
+Reported-by: syzbot+d232cca6ec42c2edb3fc@syzkaller.appspotmail.com
+Signed-off-by: Oliver Neukum <oneukum@suse.com>
+Cc: stable <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20190827103436.21143-1-oneukum@suse.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/class/cdc-wdm.c |   16 ++++++++++++----
+ 1 file changed, 12 insertions(+), 4 deletions(-)
+
+--- a/drivers/usb/class/cdc-wdm.c
++++ b/drivers/usb/class/cdc-wdm.c
+@@ -584,10 +584,20 @@ static int wdm_flush(struct file *file,
+ {
+       struct wdm_device *desc = file->private_data;
+-      wait_event(desc->wait, !test_bit(WDM_IN_USE, &desc->flags));
++      wait_event(desc->wait,
++                      /*
++                       * needs both flags. We cannot do with one
++                       * because resetting it would cause a race
++                       * with write() yet we need to signal
++                       * a disconnect
++                       */
++                      !test_bit(WDM_IN_USE, &desc->flags) ||
++                      test_bit(WDM_DISCONNECTING, &desc->flags));
+       /* cannot dereference desc->intf if WDM_DISCONNECTING */
+-      if (desc->werr < 0 && !test_bit(WDM_DISCONNECTING, &desc->flags))
++      if (test_bit(WDM_DISCONNECTING, &desc->flags))
++              return -ENODEV;
++      if (desc->werr < 0)
+               dev_err(&desc->intf->dev, "Error in flush path: %d\n",
+                       desc->werr);
+@@ -955,8 +965,6 @@ static void wdm_disconnect(struct usb_in
+       spin_lock_irqsave(&desc->iuspin, flags);
+       set_bit(WDM_DISCONNECTING, &desc->flags);
+       set_bit(WDM_READ, &desc->flags);
+-      /* to terminate pending flushes */
+-      clear_bit(WDM_IN_USE, &desc->flags);
+       spin_unlock_irqrestore(&desc->iuspin, flags);
+       wake_up_all(&desc->wait);
+       mutex_lock(&desc->rlock);
diff --git a/queue-4.14/usb-chipidea-udc-don-t-do-hardware-access-if-gadget-has-stopped.patch b/queue-4.14/usb-chipidea-udc-don-t-do-hardware-access-if-gadget-has-stopped.patch
new file mode 100644 (file)
index 0000000..2d2b739
--- /dev/null
@@ -0,0 +1,118 @@
+From cbe85c88ce80fb92956a0793518d415864dcead8 Mon Sep 17 00:00:00 2001
+From: Peter Chen <peter.chen@nxp.com>
+Date: Tue, 20 Aug 2019 02:07:58 +0000
+Subject: usb: chipidea: udc: don't do hardware access if gadget has stopped
+
+From: Peter Chen <peter.chen@nxp.com>
+
+commit cbe85c88ce80fb92956a0793518d415864dcead8 upstream.
+
+After _gadget_stop_activity is executed, we can consider the hardware
+operation for gadget has finished, and the udc can be stopped and enter
+low power mode. So, any later hardware operations (from usb_ep_ops APIs
+or usb_gadget_ops APIs) should be considered invalid, any deinitializatons
+has been covered at _gadget_stop_activity.
+
+I meet this problem when I plug out usb cable from PC using mass_storage
+gadget, my callstack like: vbus interrupt->.vbus_session->
+composite_disconnect ->pm_runtime_put_sync(&_gadget->dev),
+the composite_disconnect will call fsg_disable, but fsg_disable calls
+usb_ep_disable using async way, there are register accesses for
+usb_ep_disable. So sometimes, I get system hang due to visit register
+without clock, sometimes not.
+
+The Linux Kernel USB maintainer Alan Stern suggests this kinds of solution.
+See: http://marc.info/?l=linux-usb&m=138541769810983&w=2.
+
+Cc: <stable@vger.kernel.org> #v4.9+
+Signed-off-by: Peter Chen <peter.chen@nxp.com>
+Link: https://lore.kernel.org/r/20190820020503.27080-2-peter.chen@nxp.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/chipidea/udc.c |   32 ++++++++++++++++++++++++--------
+ 1 file changed, 24 insertions(+), 8 deletions(-)
+
+--- a/drivers/usb/chipidea/udc.c
++++ b/drivers/usb/chipidea/udc.c
+@@ -711,12 +711,6 @@ static int _gadget_stop_activity(struct
+       struct ci_hdrc    *ci = container_of(gadget, struct ci_hdrc, gadget);
+       unsigned long flags;
+-      spin_lock_irqsave(&ci->lock, flags);
+-      ci->gadget.speed = USB_SPEED_UNKNOWN;
+-      ci->remote_wakeup = 0;
+-      ci->suspended = 0;
+-      spin_unlock_irqrestore(&ci->lock, flags);
+-
+       /* flush all endpoints */
+       gadget_for_each_ep(ep, gadget) {
+               usb_ep_fifo_flush(ep);
+@@ -734,6 +728,12 @@ static int _gadget_stop_activity(struct
+               ci->status = NULL;
+       }
++      spin_lock_irqsave(&ci->lock, flags);
++      ci->gadget.speed = USB_SPEED_UNKNOWN;
++      ci->remote_wakeup = 0;
++      ci->suspended = 0;
++      spin_unlock_irqrestore(&ci->lock, flags);
++
+       return 0;
+ }
+@@ -1305,6 +1305,10 @@ static int ep_disable(struct usb_ep *ep)
+               return -EBUSY;
+       spin_lock_irqsave(hwep->lock, flags);
++      if (hwep->ci->gadget.speed == USB_SPEED_UNKNOWN) {
++              spin_unlock_irqrestore(hwep->lock, flags);
++              return 0;
++      }
+       /* only internal SW should disable ctrl endpts */
+@@ -1394,6 +1398,10 @@ static int ep_queue(struct usb_ep *ep, s
+               return -EINVAL;
+       spin_lock_irqsave(hwep->lock, flags);
++      if (hwep->ci->gadget.speed == USB_SPEED_UNKNOWN) {
++              spin_unlock_irqrestore(hwep->lock, flags);
++              return 0;
++      }
+       retval = _ep_queue(ep, req, gfp_flags);
+       spin_unlock_irqrestore(hwep->lock, flags);
+       return retval;
+@@ -1417,8 +1425,8 @@ static int ep_dequeue(struct usb_ep *ep,
+               return -EINVAL;
+       spin_lock_irqsave(hwep->lock, flags);
+-
+-      hw_ep_flush(hwep->ci, hwep->num, hwep->dir);
++      if (hwep->ci->gadget.speed != USB_SPEED_UNKNOWN)
++              hw_ep_flush(hwep->ci, hwep->num, hwep->dir);
+       list_for_each_entry_safe(node, tmpnode, &hwreq->tds, td) {
+               dma_pool_free(hwep->td_pool, node->ptr, node->dma);
+@@ -1489,6 +1497,10 @@ static void ep_fifo_flush(struct usb_ep
+       }
+       spin_lock_irqsave(hwep->lock, flags);
++      if (hwep->ci->gadget.speed == USB_SPEED_UNKNOWN) {
++              spin_unlock_irqrestore(hwep->lock, flags);
++              return;
++      }
+       hw_ep_flush(hwep->ci, hwep->num, hwep->dir);
+@@ -1557,6 +1569,10 @@ static int ci_udc_wakeup(struct usb_gadg
+       int ret = 0;
+       spin_lock_irqsave(&ci->lock, flags);
++      if (ci->gadget.speed == USB_SPEED_UNKNOWN) {
++              spin_unlock_irqrestore(&ci->lock, flags);
++              return 0;
++      }
+       if (!ci->remote_wakeup) {
+               ret = -EOPNOTSUPP;
+               goto out;
diff --git a/queue-4.14/usb-host-ohci-fix-a-race-condition-between-shutdown-and-irq.patch b/queue-4.14/usb-host-ohci-fix-a-race-condition-between-shutdown-and-irq.patch
new file mode 100644 (file)
index 0000000..c5e0174
--- /dev/null
@@ -0,0 +1,134 @@
+From a349b95d7ca0cea71be4a7dac29830703de7eb62 Mon Sep 17 00:00:00 2001
+From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Date: Tue, 27 Aug 2019 12:51:50 +0900
+Subject: usb: host: ohci: fix a race condition between shutdown and irq
+
+From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+
+commit a349b95d7ca0cea71be4a7dac29830703de7eb62 upstream.
+
+This patch fixes an issue that the following error is
+possible to happen when ohci hardware causes an interruption
+and the system is shutting down at the same time.
+
+[   34.851754] usb 2-1: USB disconnect, device number 2
+[   35.166658] irq 156: nobody cared (try booting with the "irqpoll" option)
+[   35.173445] CPU: 0 PID: 22 Comm: kworker/0:1 Not tainted 5.3.0-rc5 #85
+[   35.179964] Hardware name: Renesas Salvator-X 2nd version board based on r8a77965 (DT)
+[   35.187886] Workqueue: usb_hub_wq hub_event
+[   35.192063] Call trace:
+[   35.194509]  dump_backtrace+0x0/0x150
+[   35.198165]  show_stack+0x14/0x20
+[   35.201475]  dump_stack+0xa0/0xc4
+[   35.204785]  __report_bad_irq+0x34/0xe8
+[   35.208614]  note_interrupt+0x2cc/0x318
+[   35.212446]  handle_irq_event_percpu+0x5c/0x88
+[   35.216883]  handle_irq_event+0x48/0x78
+[   35.220712]  handle_fasteoi_irq+0xb4/0x188
+[   35.224802]  generic_handle_irq+0x24/0x38
+[   35.228804]  __handle_domain_irq+0x5c/0xb0
+[   35.232893]  gic_handle_irq+0x58/0xa8
+[   35.236548]  el1_irq+0xb8/0x180
+[   35.239681]  __do_softirq+0x94/0x23c
+[   35.243253]  irq_exit+0xd0/0xd8
+[   35.246387]  __handle_domain_irq+0x60/0xb0
+[   35.250475]  gic_handle_irq+0x58/0xa8
+[   35.254130]  el1_irq+0xb8/0x180
+[   35.257268]  kernfs_find_ns+0x5c/0x120
+[   35.261010]  kernfs_find_and_get_ns+0x3c/0x60
+[   35.265361]  sysfs_unmerge_group+0x20/0x68
+[   35.269454]  dpm_sysfs_remove+0x2c/0x68
+[   35.273284]  device_del+0x80/0x370
+[   35.276683]  hid_destroy_device+0x28/0x60
+[   35.280686]  usbhid_disconnect+0x4c/0x80
+[   35.284602]  usb_unbind_interface+0x6c/0x268
+[   35.288867]  device_release_driver_internal+0xe4/0x1b0
+[   35.293998]  device_release_driver+0x14/0x20
+[   35.298261]  bus_remove_device+0x110/0x128
+[   35.302350]  device_del+0x148/0x370
+[   35.305832]  usb_disable_device+0x8c/0x1d0
+[   35.309921]  usb_disconnect+0xc8/0x2d0
+[   35.313663]  hub_event+0x6e0/0x1128
+[   35.317146]  process_one_work+0x1e0/0x320
+[   35.321148]  worker_thread+0x40/0x450
+[   35.324805]  kthread+0x124/0x128
+[   35.328027]  ret_from_fork+0x10/0x18
+[   35.331594] handlers:
+[   35.333862] [<0000000079300c1d>] usb_hcd_irq
+[   35.338126] [<0000000079300c1d>] usb_hcd_irq
+[   35.342389] Disabling IRQ #156
+
+ohci_shutdown() disables all the interrupt and rh_state is set to
+OHCI_RH_HALTED. In other hand, ohci_irq() is possible to enable
+OHCI_INTR_SF and OHCI_INTR_MIE on ohci_irq(). Note that OHCI_INTR_SF
+is possible to be set by start_ed_unlink() which is called:
+ ohci_irq()
+  -> process_done_list()
+   -> takeback_td()
+    -> start_ed_unlink()
+
+So, ohci_irq() has the following condition, the issue happens by
+&ohci->regs->intrenable = OHCI_INTR_MIE | OHCI_INTR_SF and
+ohci->rh_state = OHCI_RH_HALTED:
+
+       /* interrupt for some other device? */
+       if (ints == 0 || unlikely(ohci->rh_state == OHCI_RH_HALTED))
+               return IRQ_NOTMINE;
+
+To fix the issue, ohci_shutdown() holds the spin lock while disabling
+the interruption and changing the rh_state flag to prevent reenable
+the OHCI_INTR_MIE unexpectedly. Note that io_watchdog_func() also
+calls the ohci_shutdown() and it already held the spin lock, so that
+the patch makes a new function as _ohci_shutdown().
+
+This patch is inspired by a Renesas R-Car Gen3 BSP patch
+from Tho Vu.
+
+Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Cc: stable <stable@vger.kernel.org>
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+Link: https://lore.kernel.org/r/1566877910-6020-1-git-send-email-yoshihiro.shimoda.uh@renesas.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/ohci-hcd.c |   15 ++++++++++++---
+ 1 file changed, 12 insertions(+), 3 deletions(-)
+
+--- a/drivers/usb/host/ohci-hcd.c
++++ b/drivers/usb/host/ohci-hcd.c
+@@ -417,8 +417,7 @@ static void ohci_usb_reset (struct ohci_
+  * other cases where the next software may expect clean state from the
+  * "firmware".  this is bus-neutral, unlike shutdown() methods.
+  */
+-static void
+-ohci_shutdown (struct usb_hcd *hcd)
++static void _ohci_shutdown(struct usb_hcd *hcd)
+ {
+       struct ohci_hcd *ohci;
+@@ -434,6 +433,16 @@ ohci_shutdown (struct usb_hcd *hcd)
+       ohci->rh_state = OHCI_RH_HALTED;
+ }
++static void ohci_shutdown(struct usb_hcd *hcd)
++{
++      struct ohci_hcd *ohci = hcd_to_ohci(hcd);
++      unsigned long flags;
++
++      spin_lock_irqsave(&ohci->lock, flags);
++      _ohci_shutdown(hcd);
++      spin_unlock_irqrestore(&ohci->lock, flags);
++}
++
+ /*-------------------------------------------------------------------------*
+  * HC functions
+  *-------------------------------------------------------------------------*/
+@@ -752,7 +761,7 @@ static void io_watchdog_func(unsigned lo
+  died:
+                       usb_hc_died(ohci_to_hcd(ohci));
+                       ohci_dump(ohci);
+-                      ohci_shutdown(ohci_to_hcd(ohci));
++                      _ohci_shutdown(ohci_to_hcd(ohci));
+                       goto done;
+               } else {
+                       /* No write back because the done queue was empty */
diff --git a/queue-4.14/usb-host-xhci-rcar-fix-typo-in-compatible-string-matching.patch b/queue-4.14/usb-host-xhci-rcar-fix-typo-in-compatible-string-matching.patch
new file mode 100644 (file)
index 0000000..20f7366
--- /dev/null
@@ -0,0 +1,35 @@
+From 636bd02a7ba9025ff851d0cfb92768c8fa865859 Mon Sep 17 00:00:00 2001
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+Date: Tue, 27 Aug 2019 14:51:12 +0200
+Subject: usb: host: xhci: rcar: Fix typo in compatible string matching
+
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+
+commit 636bd02a7ba9025ff851d0cfb92768c8fa865859 upstream.
+
+It's spelled "renesas", not "renensas".
+
+Due to this typo, RZ/G1M and RZ/G1N were not covered by the check.
+
+Fixes: 2dc240a3308b ("usb: host: xhci: rcar: retire use of xhci_plat_type_is()")
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Cc: stable <stable@vger.kernel.org>
+Reviewed-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Link: https://lore.kernel.org/r/20190827125112.12192-1-geert+renesas@glider.be
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci-rcar.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/host/xhci-rcar.c
++++ b/drivers/usb/host/xhci-rcar.c
+@@ -113,7 +113,7 @@ static int xhci_rcar_is_gen2(struct devi
+       return of_device_is_compatible(node, "renesas,xhci-r8a7790") ||
+               of_device_is_compatible(node, "renesas,xhci-r8a7791") ||
+               of_device_is_compatible(node, "renesas,xhci-r8a7793") ||
+-              of_device_is_compatible(node, "renensas,rcar-gen2-xhci");
++              of_device_is_compatible(node, "renesas,rcar-gen2-xhci");
+ }
+ static int xhci_rcar_is_gen3(struct device *dev)
diff --git a/queue-4.14/usb-storage-add-new-jms567-revision-to-unusual_devs.patch b/queue-4.14/usb-storage-add-new-jms567-revision-to-unusual_devs.patch
new file mode 100644 (file)
index 0000000..181ebc8
--- /dev/null
@@ -0,0 +1,32 @@
+From 08d676d1685c2a29e4d0e1b0242324e564d4589e Mon Sep 17 00:00:00 2001
+From: Henk van der Laan <opensource@henkvdlaan.com>
+Date: Fri, 16 Aug 2019 22:08:47 +0200
+Subject: usb-storage: Add new JMS567 revision to unusual_devs
+
+From: Henk van der Laan <opensource@henkvdlaan.com>
+
+commit 08d676d1685c2a29e4d0e1b0242324e564d4589e upstream.
+
+Revision 0x0117 suffers from an identical issue to earlier revisions,
+therefore it should be added to the quirks list.
+
+Signed-off-by: Henk van der Laan <opensource@henkvdlaan.com>
+Cc: stable <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20190816200847.21366-1-opensource@henkvdlaan.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/storage/unusual_devs.h |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/storage/unusual_devs.h
++++ b/drivers/usb/storage/unusual_devs.h
+@@ -2119,7 +2119,7 @@ UNUSUAL_DEV(  0x14cd, 0x6600, 0x0201, 0x
+               US_FL_IGNORE_RESIDUE ),
+ /* Reported by Michael Büsch <m@bues.ch> */
+-UNUSUAL_DEV(  0x152d, 0x0567, 0x0114, 0x0116,
++UNUSUAL_DEV(  0x152d, 0x0567, 0x0114, 0x0117,
+               "JMicron",
+               "USB to ATA/ATAPI Bridge",
+               USB_SC_DEVICE, USB_PR_DEVICE, NULL,
diff --git a/queue-4.14/usb-storage-ums-realtek-update-module-parameter-description-for-auto_delink_en.patch b/queue-4.14/usb-storage-ums-realtek-update-module-parameter-description-for-auto_delink_en.patch
new file mode 100644 (file)
index 0000000..320fc52
--- /dev/null
@@ -0,0 +1,35 @@
+From f6445b6b2f2bb1745080af4a0926049e8bca2617 Mon Sep 17 00:00:00 2001
+From: Kai-Heng Feng <kai.heng.feng@canonical.com>
+Date: Wed, 28 Aug 2019 01:34:49 +0800
+Subject: USB: storage: ums-realtek: Update module parameter description for auto_delink_en
+
+From: Kai-Heng Feng <kai.heng.feng@canonical.com>
+
+commit f6445b6b2f2bb1745080af4a0926049e8bca2617 upstream.
+
+The option named "auto_delink_en" is a bit misleading, as setting it to
+false doesn't really disable auto-delink but let auto-delink be firmware
+controlled.
+
+Update the description to reflect the real usage of this parameter.
+
+Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
+Cc: stable <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20190827173450.13572-1-kai.heng.feng@canonical.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/storage/realtek_cr.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/storage/realtek_cr.c
++++ b/drivers/usb/storage/realtek_cr.c
+@@ -50,7 +50,7 @@ MODULE_LICENSE("GPL");
+ static int auto_delink_en = 1;
+ module_param(auto_delink_en, int, S_IRUGO | S_IWUSR);
+-MODULE_PARM_DESC(auto_delink_en, "enable auto delink");
++MODULE_PARM_DESC(auto_delink_en, "auto delink mode (0=firmware, 1=software [default])");
+ #ifdef CONFIG_REALTEK_AUTOPM
+ static int ss_en = 1;
diff --git a/queue-4.14/usb-storage-ums-realtek-whitelist-auto-delink-support.patch b/queue-4.14/usb-storage-ums-realtek-whitelist-auto-delink-support.patch
new file mode 100644 (file)
index 0000000..c333951
--- /dev/null
@@ -0,0 +1,52 @@
+From 1902a01e2bcc3abd7c9a18dc05e78c7ab4a53c54 Mon Sep 17 00:00:00 2001
+From: Kai-Heng Feng <kai.heng.feng@canonical.com>
+Date: Wed, 28 Aug 2019 01:34:50 +0800
+Subject: USB: storage: ums-realtek: Whitelist auto-delink support
+
+From: Kai-Heng Feng <kai.heng.feng@canonical.com>
+
+commit 1902a01e2bcc3abd7c9a18dc05e78c7ab4a53c54 upstream.
+
+Auto-delink requires writing special registers to ums-realtek devices.
+Unconditionally enable auto-delink may break newer devices.
+
+So only enable auto-delink by default for the original three IDs,
+0x0138, 0x0158 and 0x0159.
+
+Realtek is working on a patch to properly support auto-delink for other
+IDs.
+
+BugLink: https://bugs.launchpad.net/bugs/1838886
+Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+Cc: stable <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20190827173450.13572-2-kai.heng.feng@canonical.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/storage/realtek_cr.c |   13 ++++++++-----
+ 1 file changed, 8 insertions(+), 5 deletions(-)
+
+--- a/drivers/usb/storage/realtek_cr.c
++++ b/drivers/usb/storage/realtek_cr.c
+@@ -1009,12 +1009,15 @@ static int init_realtek_cr(struct us_dat
+                       goto INIT_FAIL;
+       }
+-      if (CHECK_FW_VER(chip, 0x5888) || CHECK_FW_VER(chip, 0x5889) ||
+-          CHECK_FW_VER(chip, 0x5901))
+-              SET_AUTO_DELINK(chip);
+-      if (STATUS_LEN(chip) == 16) {
+-              if (SUPPORT_AUTO_DELINK(chip))
++      if (CHECK_PID(chip, 0x0138) || CHECK_PID(chip, 0x0158) ||
++          CHECK_PID(chip, 0x0159)) {
++              if (CHECK_FW_VER(chip, 0x5888) || CHECK_FW_VER(chip, 0x5889) ||
++                              CHECK_FW_VER(chip, 0x5901))
+                       SET_AUTO_DELINK(chip);
++              if (STATUS_LEN(chip) == 16) {
++                      if (SUPPORT_AUTO_DELINK(chip))
++                              SET_AUTO_DELINK(chip);
++              }
+       }
+ #ifdef CONFIG_REALTEK_AUTOPM
+       if (ss_en)