From 5e4010e36a58978e42b2ee13739ff9b50209c830 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Thu, 11 Mar 2021 14:03:18 +0800 Subject: [PATCH 01/23] usb: dwc3: qcom: skip interconnect init for ACPI probe The ACPI probe starts failing since commit bea46b981515 ("usb: dwc3: qcom: Add interconnect support in dwc3 driver"), because there is no interconnect support for ACPI, and of_icc_get() call in dwc3_qcom_interconnect_init() will just return -EINVAL. Fix the problem by skipping interconnect init for ACPI probe, and then the NULL icc_path_ddr will simply just scheild all ICC calls. Fixes: bea46b981515 ("usb: dwc3: qcom: Add interconnect support in dwc3 driver") Signed-off-by: Shawn Guo Cc: stable Link: https://lore.kernel.org/r/20210311060318.25418-1-shawn.guo@linaro.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/dwc3/dwc3-qcom.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/dwc3/dwc3-qcom.c b/drivers/usb/dwc3/dwc3-qcom.c index fcaf04483ad0..3de291ab951a 100644 --- a/drivers/usb/dwc3/dwc3-qcom.c +++ b/drivers/usb/dwc3/dwc3-qcom.c @@ -244,6 +244,9 @@ static int dwc3_qcom_interconnect_init(struct dwc3_qcom *qcom) struct device *dev = qcom->dev; int ret; + if (has_acpi_companion(dev)) + return 0; + qcom->icc_path_ddr = of_icc_get(dev, "usb-ddr"); if (IS_ERR(qcom->icc_path_ddr)) { dev_err(dev, "failed to get usb-ddr path: %ld\n", From cdb651b6021ee091abc24e9fbd9774d318ab96a6 Mon Sep 17 00:00:00 2001 From: Thinh Nguyen Date: Mon, 8 Mar 2021 18:16:44 -0800 Subject: [PATCH 02/23] usb: dwc3: gadget: Set gadget_max_speed when set ssp_rate Set the dwc->gadget_max_speed to SuperSpeed Plus if the user sets the ssp_rate. The udc_set_ssp_rate() is intended for setting the gadget's speed to SuperSpeed Plus at the specified rate. Fixes: 072cab8a0fe2 ("usb: dwc3: gadget: Implement setting of SSP rate") Cc: Signed-off-by: Thinh Nguyen Link: https://lore.kernel.org/r/0b2732e2f380d9912ee87f39dc82c2139223bad9.1615254129.git.Thinh.Nguyen@synopsys.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/dwc3/gadget.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 4a337f348651..006476a4737b 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -2523,6 +2523,7 @@ static void dwc3_gadget_set_ssp_rate(struct usb_gadget *g, unsigned long flags; spin_lock_irqsave(&dwc->lock, flags); + dwc->gadget_max_speed = USB_SPEED_SUPER_PLUS; dwc->gadget_ssp_rate = rate; spin_unlock_irqrestore(&dwc->lock, flags); } From 93f1d43c5767d70a1af89f54ef16a7d3e99af048 Mon Sep 17 00:00:00 2001 From: Thinh Nguyen Date: Mon, 8 Mar 2021 18:16:50 -0800 Subject: [PATCH 03/23] usb: dwc3: gadget: Use max speed if unspecified If the gadget driver doesn't specify a max_speed, then use the controller's maximum supported speed as default. For DWC_usb32 IP, the gadget's speed maybe limited to gen2x1 rate only if the driver's max_speed is unknown. This scenario should not occur with the current implementation since the default gadget driver's max_speed should always be specified. However, to make the driver more robust and help with readability, let's cover all the scenarios in __dwc3_gadget_set_speed(). Fixes: 450b9e9fabd8 ("usb: dwc3: gadget: Set speed only up to the max supported") Cc: Signed-off-by: Thinh Nguyen Link: https://lore.kernel.org/r/55ac7001af73bfe9bc750c6446ef4ac8cf6f9313.1615254129.git.Thinh.Nguyen@synopsys.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/dwc3/gadget.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 006476a4737b..4c15c3fce303 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -2083,7 +2083,7 @@ static void __dwc3_gadget_set_speed(struct dwc3 *dwc) u32 reg; speed = dwc->gadget_max_speed; - if (speed > dwc->maximum_speed) + if (speed == USB_SPEED_UNKNOWN || speed > dwc->maximum_speed) speed = dwc->maximum_speed; if (speed == USB_SPEED_SUPER_PLUS && From b522f830d35189e0283fa4d5b4b3ef8d7a78cfcb Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 22 Mar 2021 14:52:44 +0200 Subject: [PATCH 04/23] usb: dwc3: pci: Enable dis_uX_susphy_quirk for Intel Merrifield It seems that on Intel Merrifield platform the USB PHY shouldn't be suspended. Otherwise it can't be enabled by simply change the cable in the connector. Enable corresponding quirk for the platform in question. Fixes: e5f4ca3fce90 ("usb: dwc3: ulpi: Fix USB2.0 HS/FS/LS PHY suspend regression") Suggested-by: Serge Semin Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20210322125244.79407-1-andriy.shevchenko@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/dwc3/dwc3-pci.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c index 3d3918a8d5fb..4c5c6972124a 100644 --- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c @@ -120,6 +120,8 @@ static const struct property_entry dwc3_pci_intel_properties[] = { static const struct property_entry dwc3_pci_mrfld_properties[] = { PROPERTY_ENTRY_STRING("dr_mode", "otg"), PROPERTY_ENTRY_STRING("linux,extcon-name", "mrfld_bcove_pwrsrc"), + PROPERTY_ENTRY_BOOL("snps,dis_u3_susphy_quirk"), + PROPERTY_ENTRY_BOOL("snps,dis_u2_susphy_quirk"), PROPERTY_ENTRY_BOOL("linux,sysdev_is_parent"), {} }; From 72035f4954f0bca2d8c47cf31b3629c42116f5b7 Mon Sep 17 00:00:00 2001 From: Tong Zhang Date: Wed, 17 Mar 2021 19:04:00 -0400 Subject: [PATCH 05/23] usb: gadget: udc: amd5536udc_pci fix null-ptr-dereference init_dma_pools() calls dma_pool_create(...dev->dev) to create dma pool. however, dev->dev is actually set after calling init_dma_pools(), which effectively makes dma_pool_create(..NULL) and cause crash. To fix this issue, init dma only after dev->dev is set. [ 1.317993] RIP: 0010:dma_pool_create+0x83/0x290 [ 1.323257] Call Trace: [ 1.323390] ? pci_write_config_word+0x27/0x30 [ 1.323626] init_dma_pools+0x41/0x1a0 [snps_udc_core] [ 1.323899] udc_pci_probe+0x202/0x2b1 [amd5536udc_pci] Fixes: 7c51247a1f62 (usb: gadget: udc: Provide correct arguments for 'dma_pool_create') Cc: stable Signed-off-by: Tong Zhang Link: https://lore.kernel.org/r/20210317230400.357756-1-ztong0001@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/udc/amd5536udc_pci.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/usb/gadget/udc/amd5536udc_pci.c b/drivers/usb/gadget/udc/amd5536udc_pci.c index 8d387e0e4d91..c80f9bd51b75 100644 --- a/drivers/usb/gadget/udc/amd5536udc_pci.c +++ b/drivers/usb/gadget/udc/amd5536udc_pci.c @@ -153,6 +153,11 @@ static int udc_pci_probe( pci_set_master(pdev); pci_try_set_mwi(pdev); + dev->phys_addr = resource; + dev->irq = pdev->irq; + dev->pdev = pdev; + dev->dev = &pdev->dev; + /* init dma pools */ if (use_dma) { retval = init_dma_pools(dev); @@ -160,11 +165,6 @@ static int udc_pci_probe( goto err_dma; } - dev->phys_addr = resource; - dev->irq = pdev->irq; - dev->pdev = pdev; - dev->dev = &pdev->dev; - /* general probing */ if (udc_probe(dev)) { retval = -ENODEV; From 08dff274edda54310d6f1cf27b62fddf0f8d146e Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Thu, 11 Mar 2021 14:37:14 +0100 Subject: [PATCH 06/23] cdc-acm: fix BREAK rx code path adding necessary calls Counting break events is nice but we should actually report them to the tty layer. Fixes: 5a6a62bdb9257 ("cdc-acm: add TIOCMIWAIT") Signed-off-by: Oliver Neukum Link: https://lore.kernel.org/r/20210311133714.31881-1-oneukum@suse.com Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-acm.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 39ddb5585ded..b013671261a2 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -313,8 +313,10 @@ static void acm_process_notification(struct acm *acm, unsigned char *buf) acm->iocount.dsr++; if (difference & ACM_CTRL_DCD) acm->iocount.dcd++; - if (newctrl & ACM_CTRL_BRK) + if (newctrl & ACM_CTRL_BRK) { acm->iocount.brk++; + tty_insert_flip_char(&acm->port, 0, TTY_BREAK); + } if (newctrl & ACM_CTRL_RI) acm->iocount.rng++; if (newctrl & ACM_CTRL_FRAMING) From 6069e3e927c8fb3a1947b07d1a561644ea960248 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Thu, 11 Mar 2021 14:01:25 +0100 Subject: [PATCH 07/23] USB: cdc-acm: untangle a circular dependency between callback and softint We have a cycle of callbacks scheduling works which submit URBs with thos callbacks. This needs to be blocked, stopped and unblocked to untangle the circle. The issue leads to faults like: [ 55.068392] Unable to handle kernel paging request at virtual address 6b6b6c03 [ 55.075624] pgd = be866494 [ 55.078335] [6b6b6c03] *pgd=00000000 [ 55.081924] Internal error: Oops: 5 [#1] PREEMPT SMP ARM [ 55.087238] Modules linked in: ppp_async crc_ccitt ppp_generic slhc xt_TCPMSS xt_tcpmss xt_hl nf_log_ipv6 nf_log_ipv4 nf_log_common xt_policy xt_limit xt_conntrack xt_tcpudp xt_pkttype ip6table_mangle iptable_nat nf_nat nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 iptable_mangle ip6table_filter ip6_tables iptable_filter ip_tables des_generic md5 sch_fq_codel cdc_mbim cdc_wdm cdc_ncm usbnet mii cdc_acm usb_storage ip_tunnel xfrm_user xfrm6_tunnel tunnel6 xfrm4_tunnel tunnel4 esp6 esp4 ah6 ah4 xfrm_algo xt_LOG xt_LED xt_comment x_tables ipv6 [ 55.134954] CPU: 0 PID: 82 Comm: kworker/0:2 Tainted: G T 5.8.17 #1 [ 55.142526] Hardware name: Freescale i.MX7 Dual (Device Tree) [ 55.148304] Workqueue: events acm_softint [cdc_acm] [ 55.153196] PC is at kobject_get+0x10/0xa4 [ 55.157302] LR is at usb_get_dev+0x14/0x1c [ 55.161402] pc : [<8047c06c>] lr : [<80560448>] psr: 20000193 [ 55.167671] sp : bca39ea8 ip : 00007374 fp : bf6cbd80 [ 55.172899] r10: 00000000 r9 : bdd92284 r8 : bdd92008 [ 55.178128] r7 : 6b6b6b6b r6 : fffffffe r5 : 60000113 r4 : 6b6b6be3 [ 55.184658] r3 : 6b6b6b6b r2 : 00000111 r1 : 00000000 r0 : 6b6b6be3 [ 55.191191] Flags: nzCv IRQs off FIQs on Mode SVC_32 ISA ARM Segment none [ 55.198417] Control: 10c5387d Table: bcf0c06a DAC: 00000051 [ 55.204168] Process kworker/0:2 (pid: 82, stack limit = 0x9bdd2a89) [ 55.210439] Stack: (0xbca39ea8 to 0xbca3a000) [ 55.214805] 9ea0: bf6cbd80 80769a50 6b6b6b6b 80560448 bdeb0500 8056bfe8 [ 55.222991] 9ec0: 00000002 b76da000 00000000 bdeb0500 bdd92448 bca38000 bdeb0510 8056d69c [ 55.231177] 9ee0: bca38000 00000000 80c050fc 00000000 bca39f44 09d42015 00000000 00000001 [ 55.239363] 9f00: bdd92448 bdd92438 bdd92000 7f1158c4 bdd92448 bca2ee00 bf6cbd80 bf6cef00 [ 55.247549] 9f20: 00000000 00000000 00000000 801412d8 bf6cbd98 80c03d00 bca2ee00 bf6cbd80 [ 55.255735] 9f40: bca2ee14 bf6cbd98 80c03d00 00000008 bca38000 80141568 00000000 80c446ae [ 55.263921] 9f60: 00000000 bc9ed880 bc9f0700 bca38000 bc117eb4 80141524 bca2ee00 bc9ed8a4 [ 55.272107] 9f80: 00000000 80147cc8 00000000 bc9f0700 80147b84 00000000 00000000 00000000 [ 55.280292] 9fa0: 00000000 00000000 00000000 80100148 00000000 00000000 00000000 00000000 [ 55.288477] 9fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 [ 55.296662] 9fe0: 00000000 00000000 00000000 00000000 00000013 00000000 00000000 00000000 [ 55.304860] [<8047c06c>] (kobject_get) from [<80560448>] (usb_get_dev+0x14/0x1c) [ 55.312271] [<80560448>] (usb_get_dev) from [<8056bfe8>] (usb_hcd_unlink_urb+0x50/0xd8) [ 55.320286] [<8056bfe8>] (usb_hcd_unlink_urb) from [<8056d69c>] (usb_kill_urb.part.0+0x44/0xd0) [ 55.329004] [<8056d69c>] (usb_kill_urb.part.0) from [<7f1158c4>] (acm_softint+0x4c/0x10c [cdc_acm]) [ 55.338082] [<7f1158c4>] (acm_softint [cdc_acm]) from [<801412d8>] (process_one_work+0x19c/0x3e8) [ 55.346969] [<801412d8>] (process_one_work) from [<80141568>] (worker_thread+0x44/0x4dc) [ 55.355072] [<80141568>] (worker_thread) from [<80147cc8>] (kthread+0x144/0x180) [ 55.362481] [<80147cc8>] (kthread) from [<80100148>] (ret_from_fork+0x14/0x2c) [ 55.369706] Exception stack(0xbca39fb0 to 0xbca39ff8) Tested-by: Bruno Thomsen Signed-off-by: Oliver Neukum Cc: stable Link: https://lore.kernel.org/r/20210311130126.15972-1-oneukum@suse.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-acm.c | 48 ++++++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 16 deletions(-) diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index b013671261a2..d684cf94b1c0 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -147,17 +147,29 @@ static inline int acm_set_control(struct acm *acm, int control) #define acm_send_break(acm, ms) \ acm_ctrl_msg(acm, USB_CDC_REQ_SEND_BREAK, ms, NULL, 0) -static void acm_kill_urbs(struct acm *acm) +static void acm_poison_urbs(struct acm *acm) { int i; - usb_kill_urb(acm->ctrlurb); + usb_poison_urb(acm->ctrlurb); for (i = 0; i < ACM_NW; i++) - usb_kill_urb(acm->wb[i].urb); + usb_poison_urb(acm->wb[i].urb); for (i = 0; i < acm->rx_buflimit; i++) - usb_kill_urb(acm->read_urbs[i]); + usb_poison_urb(acm->read_urbs[i]); } +static void acm_unpoison_urbs(struct acm *acm) +{ + int i; + + for (i = 0; i < acm->rx_buflimit; i++) + usb_unpoison_urb(acm->read_urbs[i]); + for (i = 0; i < ACM_NW; i++) + usb_unpoison_urb(acm->wb[i].urb); + usb_unpoison_urb(acm->ctrlurb); +} + + /* * Write buffer management. * All of these assume proper locks taken by the caller. @@ -226,9 +238,10 @@ static int acm_start_wb(struct acm *acm, struct acm_wb *wb) rc = usb_submit_urb(wb->urb, GFP_ATOMIC); if (rc < 0) { - dev_err(&acm->data->dev, - "%s - usb_submit_urb(write bulk) failed: %d\n", - __func__, rc); + if (rc != -EPERM) + dev_err(&acm->data->dev, + "%s - usb_submit_urb(write bulk) failed: %d\n", + __func__, rc); acm_write_done(acm, wb); } return rc; @@ -482,11 +495,6 @@ static void acm_read_bulk_callback(struct urb *urb) dev_vdbg(&acm->data->dev, "got urb %d, len %d, status %d\n", rb->index, urb->actual_length, status); - if (!acm->dev) { - dev_dbg(&acm->data->dev, "%s - disconnected\n", __func__); - return; - } - switch (status) { case 0: usb_mark_last_busy(acm->dev); @@ -733,6 +741,7 @@ static void acm_port_shutdown(struct tty_port *port) * Need to grab write_lock to prevent race with resume, but no need to * hold it due to the tty-port initialised flag. */ + acm_poison_urbs(acm); spin_lock_irq(&acm->write_lock); spin_unlock_irq(&acm->write_lock); @@ -749,7 +758,8 @@ static void acm_port_shutdown(struct tty_port *port) usb_autopm_put_interface_async(acm->control); } - acm_kill_urbs(acm); + acm_unpoison_urbs(acm); + } static void acm_tty_cleanup(struct tty_struct *tty) @@ -1542,8 +1552,14 @@ static void acm_disconnect(struct usb_interface *intf) if (!acm) return; - mutex_lock(&acm->mutex); acm->disconnected = true; + /* + * there is a circular dependency. acm_softint() can resubmit + * the URBs in error handling so we need to block any + * submission right away + */ + acm_poison_urbs(acm); + mutex_lock(&acm->mutex); if (acm->country_codes) { device_remove_file(&acm->control->dev, &dev_attr_wCountryCodes); @@ -1562,7 +1578,6 @@ static void acm_disconnect(struct usb_interface *intf) tty_kref_put(tty); } - acm_kill_urbs(acm); cancel_delayed_work_sync(&acm->dwork); tty_unregister_device(acm_tty_driver, acm->minor); @@ -1604,7 +1619,7 @@ static int acm_suspend(struct usb_interface *intf, pm_message_t message) if (cnt) return 0; - acm_kill_urbs(acm); + acm_poison_urbs(acm); cancel_delayed_work_sync(&acm->dwork); acm->urbs_in_error_delay = 0; @@ -1617,6 +1632,7 @@ static int acm_resume(struct usb_interface *intf) struct urb *urb; int rv = 0; + acm_unpoison_urbs(acm); spin_lock_irq(&acm->write_lock); if (--acm->susp_count) From e4c77070ad45fc940af1d7fb1e637c349e848951 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Thu, 11 Mar 2021 14:01:26 +0100 Subject: [PATCH 08/23] USB: cdc-acm: downgrade message to debug This failure is so common that logging an error here amounts to spamming log files. Reviewed-by: Bruno Thomsen Signed-off-by: Oliver Neukum Cc: stable Link: https://lore.kernel.org/r/20210311130126.15972-2-oneukum@suse.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-acm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index d684cf94b1c0..fd2fce072985 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -659,7 +659,8 @@ static void acm_port_dtr_rts(struct tty_port *port, int raise) res = acm_set_control(acm, val); if (res && (acm->ctrl_caps & USB_CDC_CAP_LINE)) - dev_err(&acm->control->dev, "failed to set dtr/rts\n"); + /* This is broken in too many devices to spam the logs */ + dev_dbg(&acm->control->dev, "failed to set dtr/rts\n"); } static int acm_port_activate(struct tty_port *port, struct tty_struct *tty) From 7180495cb3d0e2a2860d282a468b4146c21da78f Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 22 Mar 2021 16:53:11 +0100 Subject: [PATCH 09/23] USB: cdc-acm: fix double free on probe failure If tty-device registration fails the driver copy of any Country Selection functional descriptor would end up being freed twice; first explicitly in the error path and then again in the tty-port destructor. Drop the first erroneous free that was left when fixing a tty-port resource leak. Fixes: cae2bc768d17 ("usb: cdc-acm: Decrement tty port's refcount if probe() fail") Cc: stable@vger.kernel.org # 4.19 Cc: Jaejoong Kim Acked-by: Oliver Neukum Signed-off-by: Johan Hovold Link: https://lore.kernel.org/r/20210322155318.9837-2-johan@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-acm.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index fd2fce072985..d5fbb943c4c1 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -1521,7 +1521,6 @@ static int acm_probe(struct usb_interface *intf, &dev_attr_wCountryCodes); device_remove_file(&acm->control->dev, &dev_attr_iCountryCodeRelDate); - kfree(acm->country_codes); } device_remove_file(&acm->control->dev, &dev_attr_bmCapabilities); alloc_fail5: From 4e49bf376c0451ad2eae2592e093659cde12be9a Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 22 Mar 2021 16:53:12 +0100 Subject: [PATCH 10/23] USB: cdc-acm: fix use-after-free after probe failure If tty-device registration fails the driver would fail to release the data interface. When the device is later disconnected, the disconnect callback would still be called for the data interface and would go about releasing already freed resources. Fixes: c93d81955005 ("usb: cdc-acm: fix error handling in acm_probe()") Cc: stable@vger.kernel.org # 3.9 Cc: Alexey Khoroshilov Acked-by: Oliver Neukum Signed-off-by: Johan Hovold Link: https://lore.kernel.org/r/20210322155318.9837-3-johan@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-acm.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index d5fbb943c4c1..6decf8f2b9ae 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -1516,6 +1516,11 @@ static int acm_probe(struct usb_interface *intf, return 0; alloc_fail6: + if (!acm->combined_interfaces) { + /* Clear driver data so that disconnect() returns early. */ + usb_set_intfdata(data_interface, NULL); + usb_driver_release_interface(&acm_driver, data_interface); + } if (acm->country_codes) { device_remove_file(&acm->control->dev, &dev_attr_wCountryCodes); From 8111a8cbd5dde0b6ea8c388ff4840d4e465b5edd Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 22 Mar 2021 16:53:13 +0100 Subject: [PATCH 11/23] USB: cdc-acm: drop redundant driver-data assignment The interface driver data has already been set by usb_driver_claim_interface() so drop the redundant subsequent assignment. Acked-by: Oliver Neukum Signed-off-by: Johan Hovold Link: https://lore.kernel.org/r/20210322155318.9837-4-johan@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-acm.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 6decf8f2b9ae..d73570d31ed8 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -1500,7 +1500,6 @@ static int acm_probe(struct usb_interface *intf, acm_set_line(acm, &acm->line); usb_driver_claim_interface(&acm_driver, data_interface, acm); - usb_set_intfdata(data_interface, acm); tty_dev = tty_port_register_device(&acm->port, acm_tty_driver, minor, &control_interface->dev); From dda6faaa2bdadc56b9ad034602307a51d11e26a7 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 22 Mar 2021 16:53:14 +0100 Subject: [PATCH 12/23] USB: cdc-acm: drop redundant driver-data reset There's no need to clear the interface driver data on failed probe (and driver core will clear it anyway). Acked-by: Oliver Neukum Signed-off-by: Johan Hovold Link: https://lore.kernel.org/r/20210322155318.9837-5-johan@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-acm.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index d73570d31ed8..104e10b4ebfa 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -1528,7 +1528,6 @@ static int acm_probe(struct usb_interface *intf, } device_remove_file(&acm->control->dev, &dev_attr_bmCapabilities); alloc_fail5: - usb_set_intfdata(intf, NULL); for (i = 0; i < ACM_NW; i++) usb_free_urb(acm->wb[i].urb); alloc_fail4: From 4cde059acd11e79b205525e5fd66175d8576ec88 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 22 Mar 2021 16:53:15 +0100 Subject: [PATCH 13/23] USB: cdc-acm: clean up probe error labels Name the probe error labels after what they do rather than using sequence numbers which is harder to review and maintain (e.g. may require renaming unrelated labels when a label is added or removed). Acked-by: Oliver Neukum Signed-off-by: Johan Hovold Link: https://lore.kernel.org/r/20210322155318.9837-6-johan@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-acm.c | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 104e10b4ebfa..4844f50e54de 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -1337,7 +1337,7 @@ static int acm_probe(struct usb_interface *intf, acm = kzalloc(sizeof(struct acm), GFP_KERNEL); if (acm == NULL) - goto alloc_fail; + return -ENOMEM; tty_port_init(&acm->port); acm->port.ops = &acm_port_ops; @@ -1354,7 +1354,7 @@ static int acm_probe(struct usb_interface *intf, minor = acm_alloc_minor(acm); if (minor < 0) - goto alloc_fail1; + goto err_put_port; acm->minor = minor; acm->dev = usb_dev; @@ -1385,15 +1385,15 @@ static int acm_probe(struct usb_interface *intf, buf = usb_alloc_coherent(usb_dev, ctrlsize, GFP_KERNEL, &acm->ctrl_dma); if (!buf) - goto alloc_fail1; + goto err_put_port; acm->ctrl_buffer = buf; if (acm_write_buffers_alloc(acm) < 0) - goto alloc_fail2; + goto err_free_ctrl_buffer; acm->ctrlurb = usb_alloc_urb(0, GFP_KERNEL); if (!acm->ctrlurb) - goto alloc_fail3; + goto err_free_write_buffers; for (i = 0; i < num_rx_buf; i++) { struct acm_rb *rb = &(acm->read_buffers[i]); @@ -1402,13 +1402,13 @@ static int acm_probe(struct usb_interface *intf, rb->base = usb_alloc_coherent(acm->dev, readsize, GFP_KERNEL, &rb->dma); if (!rb->base) - goto alloc_fail4; + goto err_free_read_urbs; rb->index = i; rb->instance = acm; urb = usb_alloc_urb(0, GFP_KERNEL); if (!urb) - goto alloc_fail4; + goto err_free_read_urbs; urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; urb->transfer_dma = rb->dma; @@ -1430,7 +1430,7 @@ static int acm_probe(struct usb_interface *intf, snd->urb = usb_alloc_urb(0, GFP_KERNEL); if (snd->urb == NULL) - goto alloc_fail5; + goto err_free_write_urbs; if (usb_endpoint_xfer_int(epwrite)) usb_fill_int_urb(snd->urb, usb_dev, acm->out, @@ -1448,7 +1448,7 @@ static int acm_probe(struct usb_interface *intf, i = device_create_file(&intf->dev, &dev_attr_bmCapabilities); if (i < 0) - goto alloc_fail5; + goto err_free_write_urbs; if (h.usb_cdc_country_functional_desc) { /* export the country data */ struct usb_cdc_country_functional_desc * cfd = @@ -1505,7 +1505,7 @@ static int acm_probe(struct usb_interface *intf, &control_interface->dev); if (IS_ERR(tty_dev)) { rv = PTR_ERR(tty_dev); - goto alloc_fail6; + goto err_release_data_interface; } if (quirks & CLEAR_HALT_CONDITIONS) { @@ -1514,7 +1514,8 @@ static int acm_probe(struct usb_interface *intf, } return 0; -alloc_fail6: + +err_release_data_interface: if (!acm->combined_interfaces) { /* Clear driver data so that disconnect() returns early. */ usb_set_intfdata(data_interface, NULL); @@ -1527,21 +1528,21 @@ static int acm_probe(struct usb_interface *intf, &dev_attr_iCountryCodeRelDate); } device_remove_file(&acm->control->dev, &dev_attr_bmCapabilities); -alloc_fail5: +err_free_write_urbs: for (i = 0; i < ACM_NW; i++) usb_free_urb(acm->wb[i].urb); -alloc_fail4: +err_free_read_urbs: for (i = 0; i < num_rx_buf; i++) usb_free_urb(acm->read_urbs[i]); acm_read_buffers_free(acm); usb_free_urb(acm->ctrlurb); -alloc_fail3: +err_free_write_buffers: acm_write_buffers_free(acm); -alloc_fail2: +err_free_ctrl_buffer: usb_free_coherent(usb_dev, ctrlsize, acm->ctrl_buffer, acm->ctrl_dma); -alloc_fail1: +err_put_port: tty_port_put(&acm->port); -alloc_fail: + return rv; } From f8255ee192e92fdb885a9ff6bc90d74f5bfb7cd6 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 22 Mar 2021 16:53:16 +0100 Subject: [PATCH 14/23] USB: cdc-acm: use negation for NULL checks Use negation consistently throughout the driver for NULL checks. Acked-by: Oliver Neukum Signed-off-by: Johan Hovold Link: https://lore.kernel.org/r/20210322155318.9837-7-johan@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-acm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 4844f50e54de..1f0fcabef5d2 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -1336,7 +1336,7 @@ static int acm_probe(struct usb_interface *intf, dev_dbg(&intf->dev, "interfaces are valid\n"); acm = kzalloc(sizeof(struct acm), GFP_KERNEL); - if (acm == NULL) + if (!acm) return -ENOMEM; tty_port_init(&acm->port); @@ -1429,7 +1429,7 @@ static int acm_probe(struct usb_interface *intf, struct acm_wb *snd = &(acm->wb[i]); snd->urb = usb_alloc_urb(0, GFP_KERNEL); - if (snd->urb == NULL) + if (!snd->urb) goto err_free_write_urbs; if (usb_endpoint_xfer_int(epwrite)) From 0b2b23ca20ac9329d91bdba713028cf279423383 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 22 Mar 2021 16:53:17 +0100 Subject: [PATCH 15/23] USB: cdc-acm: always claim data interface Make sure to always claim the data interface and bail out if binding fails. Note that the driver had a check to verify that the data interface was not already bound to a driver but would not detect other failures (e.g. if the interface was not authorised). Signed-off-by: Johan Hovold Link: https://lore.kernel.org/r/20210322155318.9837-8-johan@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-acm.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 1f0fcabef5d2..5ce525d22425 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -1309,13 +1309,6 @@ static int acm_probe(struct usb_interface *intf, if (!combined_interfaces && intf != control_interface) return -ENODEV; - if (!combined_interfaces && usb_interface_claimed(data_interface)) { - /* valid in this context */ - dev_dbg(&intf->dev, "The data interface isn't available\n"); - return -EBUSY; - } - - if (data_interface->cur_altsetting->desc.bNumEndpoints < 2 || control_interface->cur_altsetting->desc.bNumEndpoints == 0) return -EINVAL; @@ -1499,7 +1492,11 @@ static int acm_probe(struct usb_interface *intf, acm->line.bDataBits = 8; acm_set_line(acm, &acm->line); - usb_driver_claim_interface(&acm_driver, data_interface, acm); + if (!acm->combined_interfaces) { + rv = usb_driver_claim_interface(&acm_driver, data_interface, acm); + if (rv) + goto err_remove_files; + } tty_dev = tty_port_register_device(&acm->port, acm_tty_driver, minor, &control_interface->dev); @@ -1521,6 +1518,7 @@ static int acm_probe(struct usb_interface *intf, usb_set_intfdata(data_interface, NULL); usb_driver_release_interface(&acm_driver, data_interface); } +err_remove_files: if (acm->country_codes) { device_remove_file(&acm->control->dev, &dev_attr_wCountryCodes); From 79579411826647fd573dbe301c4d933bc90e4be7 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 22 Mar 2021 16:53:18 +0100 Subject: [PATCH 16/23] USB: cdc-acm: do not log successful probe on later errors Do not log the successful-probe message until the tty device has been registered. Signed-off-by: Johan Hovold Link: https://lore.kernel.org/r/20210322155318.9837-9-johan@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-acm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 5ce525d22425..3fda1ec961d7 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -1486,8 +1486,6 @@ static int acm_probe(struct usb_interface *intf, acm->nb_index = 0; acm->nb_size = 0; - dev_info(&intf->dev, "ttyACM%d: USB ACM device\n", minor); - acm->line.dwDTERate = cpu_to_le32(9600); acm->line.bDataBits = 8; acm_set_line(acm, &acm->line); @@ -1510,6 +1508,8 @@ static int acm_probe(struct usb_interface *intf, usb_clear_halt(usb_dev, acm->out); } + dev_info(&intf->dev, "ttyACM%d: USB ACM device\n", minor); + return 0; err_release_data_interface: From 0bd860493f81eb2a46173f6f5e44cc38331c8dbd Mon Sep 17 00:00:00 2001 From: Vincent Palatin Date: Fri, 19 Mar 2021 13:48:02 +0100 Subject: [PATCH 17/23] USB: quirks: ignore remote wake-up on Fibocom L850-GL LTE modem This LTE modem (M.2 card) has a bug in its power management: there is some kind of race condition for U3 wake-up between the host and the device. The modem firmware sometimes crashes/locks when both events happen at the same time and the modem fully drops off the USB bus (and sometimes re-enumerates, sometimes just gets stuck until the next reboot). Tested with the modem wired to the XHCI controller on an AMD 3015Ce platform. Without the patch, the modem dropped of the USB bus 5 times in 3 days. With the quirk, it stayed connected for a week while the 'runtime_suspended_time' counter incremented as excepted. Signed-off-by: Vincent Palatin Link: https://lore.kernel.org/r/20210319124802.2315195-1-vpalatin@chromium.org Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/quirks.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index 6ade3daf7858..76ac5d6555ae 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c @@ -498,6 +498,10 @@ static const struct usb_device_id usb_quirk_list[] = { /* DJI CineSSD */ { USB_DEVICE(0x2ca3, 0x0031), .driver_info = USB_QUIRK_NO_LPM }, + /* Fibocom L850-GL LTE Modem */ + { USB_DEVICE(0x2cb7, 0x0007), .driver_info = + USB_QUIRK_IGNORE_REMOTE_WAKEUP }, + /* INTEL VALUE SSD */ { USB_DEVICE(0x8086, 0xf1a5), .driver_info = USB_QUIRK_RESET_RESUME }, From 1cc5ed25bdade86de2650a82b2730108a76de20c Mon Sep 17 00:00:00 2001 From: Shuah Khan Date: Wed, 24 Mar 2021 17:06:54 -0600 Subject: [PATCH 18/23] usbip: vhci_hcd fix shift out-of-bounds in vhci_hub_control() Fix shift out-of-bounds in vhci_hub_control() SetPortFeature handling. UBSAN: shift-out-of-bounds in drivers/usb/usbip/vhci_hcd.c:605:42 shift exponent 768 is too large for 32-bit type 'int' Reported-by: syzbot+3dea30b047f41084de66@syzkaller.appspotmail.com Cc: stable@vger.kernel.org Signed-off-by: Shuah Khan Link: https://lore.kernel.org/r/20210324230654.34798-1-skhan@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/usbip/vhci_hcd.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/usbip/vhci_hcd.c b/drivers/usb/usbip/vhci_hcd.c index 3209b5ddd30c..a20a8380ca0c 100644 --- a/drivers/usb/usbip/vhci_hcd.c +++ b/drivers/usb/usbip/vhci_hcd.c @@ -594,6 +594,8 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, pr_err("invalid port number %d\n", wIndex); goto error; } + if (wValue >= 32) + goto error; if (hcd->speed == HCD_USB3) { if ((vhci_hcd->port_status[rhport] & USB_SS_PORT_STAT_POWER) != 0) { From 5aef629704ad4d983ecf5c8a25840f16e45b6d59 Mon Sep 17 00:00:00 2001 From: Wesley Cheng Date: Wed, 24 Mar 2021 11:31:04 -0700 Subject: [PATCH 19/23] usb: dwc3: gadget: Clear DEP flags after stop transfers in ep disable Ensure that dep->flags are cleared until after stop active transfers is completed. Otherwise, the ENDXFER command will not be executed during ep disable. Fixes: f09ddcfcb8c5 ("usb: dwc3: gadget: Prevent EP queuing while stopping transfers") Cc: stable Reported-and-tested-by: Andy Shevchenko Tested-by: Marek Szyprowski Signed-off-by: Wesley Cheng Link: https://lore.kernel.org/r/1616610664-16495-1-git-send-email-wcheng@codeaurora.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/dwc3/gadget.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 4c15c3fce303..c7ef218e7a8c 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -791,10 +791,6 @@ static int __dwc3_gadget_ep_disable(struct dwc3_ep *dep) reg &= ~DWC3_DALEPENA_EP(dep->number); dwc3_writel(dwc->regs, DWC3_DALEPENA, reg); - dep->stream_capable = false; - dep->type = 0; - dep->flags = 0; - /* Clear out the ep descriptors for non-ep0 */ if (dep->number > 1) { dep->endpoint.comp_desc = NULL; @@ -803,6 +799,10 @@ static int __dwc3_gadget_ep_disable(struct dwc3_ep *dep) dwc3_remove_requests(dwc, dep); + dep->stream_capable = false; + dep->type = 0; + dep->flags = 0; + return 0; } From 6f978a30c9bb12dab1302d0f06951ee290f5e600 Mon Sep 17 00:00:00 2001 From: Chunfeng Yun Date: Tue, 23 Mar 2021 15:02:46 +0800 Subject: [PATCH 20/23] usb: xhci-mtk: fix broken streams issue on 0.96 xHCI The MediaTek 0.96 xHCI controller on some platforms does not support bulk stream even HCCPARAMS says supporting, due to MaxPSASize is set a default value 1 by mistake, here use XHCI_BROKEN_STREAMS quirk to fix it. Fixes: 94a631d91ad3 ("usb: xhci-mtk: check hcc_params after adding primary hcd") Cc: stable Signed-off-by: Chunfeng Yun Link: https://lore.kernel.org/r/1616482975-17841-4-git-send-email-chunfeng.yun@mediatek.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-mtk.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c index fe010cc61f19..2f27dc0d9c6b 100644 --- a/drivers/usb/host/xhci-mtk.c +++ b/drivers/usb/host/xhci-mtk.c @@ -397,6 +397,13 @@ static void xhci_mtk_quirks(struct device *dev, struct xhci_hcd *xhci) xhci->quirks |= XHCI_SPURIOUS_SUCCESS; if (mtk->lpm_support) xhci->quirks |= XHCI_LPM_SUPPORT; + + /* + * MTK xHCI 0.96: PSA is 1 by default even if doesn't support stream, + * and it's 3 when support it. + */ + if (xhci->hci_version < 0x100 && HCC_MAX_PSA(xhci->hcc_params) == 4) + xhci->quirks |= XHCI_BROKEN_STREAMS; } /* called during probe() after chip reset completes */ @@ -548,7 +555,8 @@ static int xhci_mtk_probe(struct platform_device *pdev) if (ret) goto put_usb3_hcd; - if (HCC_MAX_PSA(xhci->hcc_params) >= 4) + if (HCC_MAX_PSA(xhci->hcc_params) >= 4 && + !(xhci->quirks & XHCI_BROKEN_STREAMS)) xhci->shared_hcd->can_do_streams = 1; ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED); From 92af4fc6ec331228aca322ca37c8aea7b150a151 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Wed, 24 Mar 2021 09:11:41 +0200 Subject: [PATCH 21/23] usb: musb: Fix suspend with devices connected for a64 Pinephone running on Allwinner A64 fails to suspend with USB devices connected as reported by Bhushan Shah . Reverting commit 5fbf7a253470 ("usb: musb: fix idling for suspend after disconnect interrupt") fixes the issue. Let's add suspend checks also for suspend after disconnect interrupt quirk handling like we already do elsewhere. Fixes: 5fbf7a253470 ("usb: musb: fix idling for suspend after disconnect interrupt") Reported-by: Bhushan Shah Tested-by: Bhushan Shah Signed-off-by: Tony Lindgren Link: https://lore.kernel.org/r/20210324071142.42264-1-tony@atomide.com Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/musb_core.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 1cd87729ba60..fc0457db62e1 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -2004,10 +2004,14 @@ static void musb_pm_runtime_check_session(struct musb *musb) MUSB_DEVCTL_HR; switch (devctl & ~s) { case MUSB_QUIRK_B_DISCONNECT_99: - musb_dbg(musb, "Poll devctl in case of suspend after disconnect\n"); - schedule_delayed_work(&musb->irq_work, - msecs_to_jiffies(1000)); - break; + if (musb->quirk_retries && !musb->flush_irq_work) { + musb_dbg(musb, "Poll devctl in case of suspend after disconnect\n"); + schedule_delayed_work(&musb->irq_work, + msecs_to_jiffies(1000)); + musb->quirk_retries--; + break; + } + fallthrough; case MUSB_QUIRK_B_INVALID_VBUS_91: if (musb->quirk_retries && !musb->flush_irq_work) { musb_dbg(musb, From 5e3bbae8ee3d677a0aa2919dc62b5c60ea01ba61 Mon Sep 17 00:00:00 2001 From: Artur Petrosyan Date: Fri, 26 Mar 2021 14:24:46 +0400 Subject: [PATCH 22/23] usb: dwc2: Fix HPRT0.PrtSusp bit setting for HiKey 960 board. Increased the waiting timeout for HPRT0.PrtSusp register field to be set, because on HiKey 960 board HPRT0.PrtSusp wasn't generated with the existing timeout. Cc: # 4.18 Fixes: 22bb5cfdf13a ("usb: dwc2: Fix host exit from hibernation flow.") Signed-off-by: Artur Petrosyan Acked-by: Minas Harutyunyan Link: https://lore.kernel.org/r/20210326102447.8F7FEA005D@mailhost.synopsys.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/dwc2/hcd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index fc3269f5faf1..40e5655921bf 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -5398,7 +5398,7 @@ int dwc2_host_enter_hibernation(struct dwc2_hsotg *hsotg) dwc2_writel(hsotg, hprt0, HPRT0); /* Wait for the HPRT0.PrtSusp register field to be set */ - if (dwc2_hsotg_wait_bit_set(hsotg, HPRT0, HPRT0_SUSP, 3000)) + if (dwc2_hsotg_wait_bit_set(hsotg, HPRT0, HPRT0_SUSP, 5000)) dev_warn(hsotg->dev, "Suspend wasn't generated\n"); /* From 93f672804bf2d7a49ef3fd96827ea6290ca1841e Mon Sep 17 00:00:00 2001 From: Artur Petrosyan Date: Fri, 26 Mar 2021 14:25:09 +0400 Subject: [PATCH 23/23] usb: dwc2: Prevent core suspend when port connection flag is 0 In host mode port connection status flag is "0" when loading the driver. After loading the driver system asserts suspend which is handled by "_dwc2_hcd_suspend()" function. Before the system suspend the port connection status is "0". As result need to check the "port_connect_status" if it is "0", then skipping entering to suspend. Cc: # 5.2 Fixes: 6f6d70597c15 ("usb: dwc2: bus suspend/resume for hosts with DWC2_POWER_DOWN_PARAM_NONE") Signed-off-by: Artur Petrosyan Link: https://lore.kernel.org/r/20210326102510.BDEDEA005D@mailhost.synopsys.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/dwc2/hcd.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index 40e5655921bf..1a9789ec5847 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -4322,7 +4322,8 @@ static int _dwc2_hcd_suspend(struct usb_hcd *hcd) if (hsotg->op_state == OTG_STATE_B_PERIPHERAL) goto unlock; - if (hsotg->params.power_down > DWC2_POWER_DOWN_PARAM_PARTIAL) + if (hsotg->params.power_down != DWC2_POWER_DOWN_PARAM_PARTIAL || + hsotg->flags.b.port_connect_status == 0) goto skip_power_saving; /*