Skip to content

Commit 5c7bdbf

Browse files
committed
Merge tag 'usb-5.12-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
Pull USB fixes from Greg KH: "Here are a small number of USB fixes for 5.12-rc3 to resolve a bunch of reported issues: - usbip fixups for issues found by syzbot - xhci driver fixes and quirk additions - gadget driver fixes - dwc3 QCOM driver fix - usb-serial new ids and fixes - usblp fix for a long-time issue - cdc-acm quirk addition - other tiny fixes for reported problems All of these have been in linux-next for a while with no reported issues" * tag 'usb-5.12-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (25 commits) xhci: Fix repeated xhci wake after suspend due to uncleared internal wake state usb: xhci: Fix ASMedia ASM1042A and ASM3242 DMA addressing xhci: Improve detection of device initiated wake signal. usb: xhci: do not perform Soft Retry for some xHCI hosts usbip: fix vudc usbip_sockfd_store races leading to gpf usbip: fix vhci_hcd attach_store() races leading to gpf usbip: fix stub_dev usbip_sockfd_store() races leading to gpf usbip: fix vudc to check for stream socket usbip: fix vhci_hcd to check for stream socket usbip: fix stub_dev to check for stream socket usb: dwc3: qcom: Add missing DWC3 OF node refcount decrement USB: usblp: fix a hang in poll() if disconnected USB: gadget: udc: s3c2410_udc: fix return value check in s3c2410_udc_probe() usb: renesas_usbhs: Clear PIPECFG for re-enabling pipe with other EPNUM usb: dwc3: qcom: Honor wakeup enabled/disabled state usb: gadget: f_uac1: stop playback on function disable usb: gadget: f_uac2: always increase endpoint max_packet_size by one audio slot USB: gadget: u_ether: Fix a configfs return code usb: dwc3: qcom: add ACPI device id for sc8180x Goodix Fingerprint device is not a modem ...
2 parents 4206234 + d26c00e commit 5c7bdbf

File tree

19 files changed

+226
-107
lines changed

19 files changed

+226
-107
lines changed

drivers/usb/class/cdc-acm.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1935,6 +1935,11 @@ static const struct usb_device_id acm_ids[] = {
19351935
.driver_info = SEND_ZERO_PACKET,
19361936
},
19371937

1938+
/* Exclude Goodix Fingerprint Reader */
1939+
{ USB_DEVICE(0x27c6, 0x5395),
1940+
.driver_info = IGNORE_DEVICE,
1941+
},
1942+
19381943
/* control interfaces without any protocol set */
19391944
{ USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM,
19401945
USB_CDC_PROTO_NONE) },

drivers/usb/class/usblp.c

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -494,16 +494,24 @@ static int usblp_release(struct inode *inode, struct file *file)
494494
/* No kernel lock - fine */
495495
static __poll_t usblp_poll(struct file *file, struct poll_table_struct *wait)
496496
{
497-
__poll_t ret;
497+
struct usblp *usblp = file->private_data;
498+
__poll_t ret = 0;
498499
unsigned long flags;
499500

500-
struct usblp *usblp = file->private_data;
501501
/* Should we check file->f_mode & FMODE_WRITE before poll_wait()? */
502502
poll_wait(file, &usblp->rwait, wait);
503503
poll_wait(file, &usblp->wwait, wait);
504+
505+
mutex_lock(&usblp->mut);
506+
if (!usblp->present)
507+
ret |= EPOLLHUP;
508+
mutex_unlock(&usblp->mut);
509+
504510
spin_lock_irqsave(&usblp->lock, flags);
505-
ret = ((usblp->bidir && usblp->rcomplete) ? EPOLLIN | EPOLLRDNORM : 0) |
506-
((usblp->no_paper || usblp->wcomplete) ? EPOLLOUT | EPOLLWRNORM : 0);
511+
if (usblp->bidir && usblp->rcomplete)
512+
ret |= EPOLLIN | EPOLLRDNORM;
513+
if (usblp->no_paper || usblp->wcomplete)
514+
ret |= EPOLLOUT | EPOLLWRNORM;
507515
spin_unlock_irqrestore(&usblp->lock, flags);
508516
return ret;
509517
}

drivers/usb/dwc3/dwc3-qcom.c

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -358,8 +358,10 @@ static int dwc3_qcom_suspend(struct dwc3_qcom *qcom)
358358
if (ret)
359359
dev_warn(qcom->dev, "failed to disable interconnect: %d\n", ret);
360360

361+
if (device_may_wakeup(qcom->dev))
362+
dwc3_qcom_enable_interrupts(qcom);
363+
361364
qcom->is_suspended = true;
362-
dwc3_qcom_enable_interrupts(qcom);
363365

364366
return 0;
365367
}
@@ -372,7 +374,8 @@ static int dwc3_qcom_resume(struct dwc3_qcom *qcom)
372374
if (!qcom->is_suspended)
373375
return 0;
374376

375-
dwc3_qcom_disable_interrupts(qcom);
377+
if (device_may_wakeup(qcom->dev))
378+
dwc3_qcom_disable_interrupts(qcom);
376379

377380
for (i = 0; i < qcom->num_clocks; i++) {
378381
ret = clk_prepare_enable(qcom->clks[i]);
@@ -650,16 +653,19 @@ static int dwc3_qcom_of_register_core(struct platform_device *pdev)
650653
ret = of_platform_populate(np, NULL, NULL, dev);
651654
if (ret) {
652655
dev_err(dev, "failed to register dwc3 core - %d\n", ret);
653-
return ret;
656+
goto node_put;
654657
}
655658

656659
qcom->dwc3 = of_find_device_by_node(dwc3_np);
657660
if (!qcom->dwc3) {
661+
ret = -ENODEV;
658662
dev_err(dev, "failed to get dwc3 platform device\n");
659-
return -ENODEV;
660663
}
661664

662-
return 0;
665+
node_put:
666+
of_node_put(dwc3_np);
667+
668+
return ret;
663669
}
664670

665671
static struct platform_device *
@@ -938,6 +944,8 @@ static const struct dwc3_acpi_pdata sdm845_acpi_urs_pdata = {
938944
static const struct acpi_device_id dwc3_qcom_acpi_match[] = {
939945
{ "QCOM2430", (unsigned long)&sdm845_acpi_pdata },
940946
{ "QCOM0304", (unsigned long)&sdm845_acpi_urs_pdata },
947+
{ "QCOM0497", (unsigned long)&sdm845_acpi_urs_pdata },
948+
{ "QCOM04A6", (unsigned long)&sdm845_acpi_pdata },
941949
{ },
942950
};
943951
MODULE_DEVICE_TABLE(acpi, dwc3_qcom_acpi_match);

drivers/usb/gadget/function/f_uac1.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -499,6 +499,7 @@ static void f_audio_disable(struct usb_function *f)
499499
uac1->as_out_alt = 0;
500500
uac1->as_in_alt = 0;
501501

502+
u_audio_stop_playback(&uac1->g_audio);
502503
u_audio_stop_capture(&uac1->g_audio);
503504
}
504505

drivers/usb/gadget/function/f_uac2.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -478,7 +478,7 @@ static int set_ep_max_packet_size(const struct f_uac2_opts *uac2_opts,
478478
}
479479

480480
max_size_bw = num_channels(chmask) * ssize *
481-
DIV_ROUND_UP(srate, factor / (1 << (ep_desc->bInterval - 1)));
481+
((srate / (factor / (1 << (ep_desc->bInterval - 1)))) + 1);
482482
ep_desc->wMaxPacketSize = cpu_to_le16(min_t(u16, max_size_bw,
483483
max_size_ep));
484484

drivers/usb/gadget/function/u_ether_configfs.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -182,12 +182,11 @@ out: \
182182
size_t len) \
183183
{ \
184184
struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \
185-
int ret; \
185+
int ret = -EINVAL; \
186186
u8 val; \
187187
\
188188
mutex_lock(&opts->lock); \
189-
ret = sscanf(page, "%02hhx", &val); \
190-
if (ret > 0) { \
189+
if (sscanf(page, "%02hhx", &val) > 0) { \
191190
opts->_n_ = val; \
192191
ret = len; \
193192
} \

drivers/usb/gadget/udc/s3c2410_udc.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1773,8 +1773,8 @@ static int s3c2410_udc_probe(struct platform_device *pdev)
17731773
udc_info = dev_get_platdata(&pdev->dev);
17741774

17751775
base_addr = devm_platform_ioremap_resource(pdev, 0);
1776-
if (!base_addr) {
1777-
retval = -ENOMEM;
1776+
if (IS_ERR(base_addr)) {
1777+
retval = PTR_ERR(base_addr);
17781778
goto err_mem;
17791779
}
17801780

drivers/usb/host/xhci-pci.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
#define PCI_DEVICE_ID_ASMEDIA_1042A_XHCI 0x1142
6767
#define PCI_DEVICE_ID_ASMEDIA_1142_XHCI 0x1242
6868
#define PCI_DEVICE_ID_ASMEDIA_2142_XHCI 0x2142
69+
#define PCI_DEVICE_ID_ASMEDIA_3242_XHCI 0x3242
6970

7071
static const char hcd_name[] = "xhci_hcd";
7172

@@ -276,11 +277,14 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
276277
pdev->device == PCI_DEVICE_ID_ASMEDIA_1042_XHCI)
277278
xhci->quirks |= XHCI_BROKEN_STREAMS;
278279
if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA &&
279-
pdev->device == PCI_DEVICE_ID_ASMEDIA_1042A_XHCI)
280+
pdev->device == PCI_DEVICE_ID_ASMEDIA_1042A_XHCI) {
280281
xhci->quirks |= XHCI_TRUST_TX_LENGTH;
282+
xhci->quirks |= XHCI_NO_64BIT_SUPPORT;
283+
}
281284
if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA &&
282285
(pdev->device == PCI_DEVICE_ID_ASMEDIA_1142_XHCI ||
283-
pdev->device == PCI_DEVICE_ID_ASMEDIA_2142_XHCI))
286+
pdev->device == PCI_DEVICE_ID_ASMEDIA_2142_XHCI ||
287+
pdev->device == PCI_DEVICE_ID_ASMEDIA_3242_XHCI))
284288
xhci->quirks |= XHCI_NO_64BIT_SUPPORT;
285289

286290
if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA &&
@@ -295,6 +299,11 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
295299
pdev->device == 0x9026)
296300
xhci->quirks |= XHCI_RESET_PLL_ON_DISCONNECT;
297301

302+
if (pdev->vendor == PCI_VENDOR_ID_AMD &&
303+
(pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_2 ||
304+
pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_4))
305+
xhci->quirks |= XHCI_NO_SOFT_RETRY;
306+
298307
if (xhci->quirks & XHCI_RESET_ON_RESUME)
299308
xhci_dbg_trace(xhci, trace_xhci_dbg_quirks,
300309
"QUIRK: Resetting on resume");

drivers/usb/host/xhci-ring.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2484,7 +2484,8 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td,
24842484
remaining = 0;
24852485
break;
24862486
case COMP_USB_TRANSACTION_ERROR:
2487-
if ((ep_ring->err_count++ > MAX_SOFT_RETRY) ||
2487+
if (xhci->quirks & XHCI_NO_SOFT_RETRY ||
2488+
(ep_ring->err_count++ > MAX_SOFT_RETRY) ||
24882489
le32_to_cpu(slot_ctx->tt_info) & TT_SLOT)
24892490
break;
24902491

drivers/usb/host/xhci.c

Lines changed: 43 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -883,44 +883,42 @@ static void xhci_clear_command_ring(struct xhci_hcd *xhci)
883883
xhci_set_cmd_ring_deq(xhci);
884884
}
885885

886-
static void xhci_disable_port_wake_on_bits(struct xhci_hcd *xhci)
886+
/*
887+
* Disable port wake bits if do_wakeup is not set.
888+
*
889+
* Also clear a possible internal port wake state left hanging for ports that
890+
* detected termination but never successfully enumerated (trained to 0U).
891+
* Internal wake causes immediate xHCI wake after suspend. PORT_CSC write done
892+
* at enumeration clears this wake, force one here as well for unconnected ports
893+
*/
894+
895+
static void xhci_disable_hub_port_wake(struct xhci_hcd *xhci,
896+
struct xhci_hub *rhub,
897+
bool do_wakeup)
887898
{
888-
struct xhci_port **ports;
889-
int port_index;
890899
unsigned long flags;
891900
u32 t1, t2, portsc;
901+
int i;
892902

893903
spin_lock_irqsave(&xhci->lock, flags);
894904

895-
/* disable usb3 ports Wake bits */
896-
port_index = xhci->usb3_rhub.num_ports;
897-
ports = xhci->usb3_rhub.ports;
898-
while (port_index--) {
899-
t1 = readl(ports[port_index]->addr);
900-
portsc = t1;
901-
t1 = xhci_port_state_to_neutral(t1);
902-
t2 = t1 & ~PORT_WAKE_BITS;
903-
if (t1 != t2) {
904-
writel(t2, ports[port_index]->addr);
905-
xhci_dbg(xhci, "disable wake bits port %d-%d, portsc: 0x%x, write: 0x%x\n",
906-
xhci->usb3_rhub.hcd->self.busnum,
907-
port_index + 1, portsc, t2);
908-
}
909-
}
905+
for (i = 0; i < rhub->num_ports; i++) {
906+
portsc = readl(rhub->ports[i]->addr);
907+
t1 = xhci_port_state_to_neutral(portsc);
908+
t2 = t1;
909+
910+
/* clear wake bits if do_wake is not set */
911+
if (!do_wakeup)
912+
t2 &= ~PORT_WAKE_BITS;
913+
914+
/* Don't touch csc bit if connected or connect change is set */
915+
if (!(portsc & (PORT_CSC | PORT_CONNECT)))
916+
t2 |= PORT_CSC;
910917

911-
/* disable usb2 ports Wake bits */
912-
port_index = xhci->usb2_rhub.num_ports;
913-
ports = xhci->usb2_rhub.ports;
914-
while (port_index--) {
915-
t1 = readl(ports[port_index]->addr);
916-
portsc = t1;
917-
t1 = xhci_port_state_to_neutral(t1);
918-
t2 = t1 & ~PORT_WAKE_BITS;
919918
if (t1 != t2) {
920-
writel(t2, ports[port_index]->addr);
921-
xhci_dbg(xhci, "disable wake bits port %d-%d, portsc: 0x%x, write: 0x%x\n",
922-
xhci->usb2_rhub.hcd->self.busnum,
923-
port_index + 1, portsc, t2);
919+
writel(t2, rhub->ports[i]->addr);
920+
xhci_dbg(xhci, "config port %d-%d wake bits, portsc: 0x%x, write: 0x%x\n",
921+
rhub->hcd->self.busnum, i + 1, portsc, t2);
924922
}
925923
}
926924
spin_unlock_irqrestore(&xhci->lock, flags);
@@ -983,8 +981,8 @@ int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup)
983981
return -EINVAL;
984982

985983
/* Clear root port wake on bits if wakeup not allowed. */
986-
if (!do_wakeup)
987-
xhci_disable_port_wake_on_bits(xhci);
984+
xhci_disable_hub_port_wake(xhci, &xhci->usb3_rhub, do_wakeup);
985+
xhci_disable_hub_port_wake(xhci, &xhci->usb2_rhub, do_wakeup);
988986

989987
if (!HCD_HW_ACCESSIBLE(hcd))
990988
return 0;
@@ -1088,6 +1086,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
10881086
struct usb_hcd *secondary_hcd;
10891087
int retval = 0;
10901088
bool comp_timer_running = false;
1089+
bool pending_portevent = false;
10911090

10921091
if (!hcd->state)
10931092
return 0;
@@ -1226,13 +1225,22 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
12261225

12271226
done:
12281227
if (retval == 0) {
1229-
/* Resume root hubs only when have pending events. */
1230-
if (xhci_pending_portevent(xhci)) {
1228+
/*
1229+
* Resume roothubs only if there are pending events.
1230+
* USB 3 devices resend U3 LFPS wake after a 100ms delay if
1231+
* the first wake signalling failed, give it that chance.
1232+
*/
1233+
pending_portevent = xhci_pending_portevent(xhci);
1234+
if (!pending_portevent) {
1235+
msleep(120);
1236+
pending_portevent = xhci_pending_portevent(xhci);
1237+
}
1238+
1239+
if (pending_portevent) {
12311240
usb_hcd_resume_root_hub(xhci->shared_hcd);
12321241
usb_hcd_resume_root_hub(hcd);
12331242
}
12341243
}
1235-
12361244
/*
12371245
* If system is subject to the Quirk, Compliance Mode Timer needs to
12381246
* be re-initialized Always after a system resume. Ports are subject

0 commit comments

Comments
 (0)