Skip to content

Commit

Permalink
Merge tag 'usb-5.12-rc3' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/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
  ...
  • Loading branch information
torvalds committed Mar 13, 2021
2 parents 4206234 + d26c00e commit 5c7bdbf
Show file tree
Hide file tree
Showing 19 changed files with 226 additions and 107 deletions.
5 changes: 5 additions & 0 deletions drivers/usb/class/cdc-acm.c
Original file line number Diff line number Diff line change
Expand Up @@ -1935,6 +1935,11 @@ static const struct usb_device_id acm_ids[] = {
.driver_info = SEND_ZERO_PACKET,
},

/* Exclude Goodix Fingerprint Reader */
{ USB_DEVICE(0x27c6, 0x5395),
.driver_info = IGNORE_DEVICE,
},

/* control interfaces without any protocol set */
{ USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM,
USB_CDC_PROTO_NONE) },
Expand Down
16 changes: 12 additions & 4 deletions drivers/usb/class/usblp.c
Original file line number Diff line number Diff line change
Expand Up @@ -494,16 +494,24 @@ static int usblp_release(struct inode *inode, struct file *file)
/* No kernel lock - fine */
static __poll_t usblp_poll(struct file *file, struct poll_table_struct *wait)
{
__poll_t ret;
struct usblp *usblp = file->private_data;
__poll_t ret = 0;
unsigned long flags;

struct usblp *usblp = file->private_data;
/* Should we check file->f_mode & FMODE_WRITE before poll_wait()? */
poll_wait(file, &usblp->rwait, wait);
poll_wait(file, &usblp->wwait, wait);

mutex_lock(&usblp->mut);
if (!usblp->present)
ret |= EPOLLHUP;
mutex_unlock(&usblp->mut);

spin_lock_irqsave(&usblp->lock, flags);
ret = ((usblp->bidir && usblp->rcomplete) ? EPOLLIN | EPOLLRDNORM : 0) |
((usblp->no_paper || usblp->wcomplete) ? EPOLLOUT | EPOLLWRNORM : 0);
if (usblp->bidir && usblp->rcomplete)
ret |= EPOLLIN | EPOLLRDNORM;
if (usblp->no_paper || usblp->wcomplete)
ret |= EPOLLOUT | EPOLLWRNORM;
spin_unlock_irqrestore(&usblp->lock, flags);
return ret;
}
Expand Down
18 changes: 13 additions & 5 deletions drivers/usb/dwc3/dwc3-qcom.c
Original file line number Diff line number Diff line change
Expand Up @@ -358,8 +358,10 @@ static int dwc3_qcom_suspend(struct dwc3_qcom *qcom)
if (ret)
dev_warn(qcom->dev, "failed to disable interconnect: %d\n", ret);

if (device_may_wakeup(qcom->dev))
dwc3_qcom_enable_interrupts(qcom);

qcom->is_suspended = true;
dwc3_qcom_enable_interrupts(qcom);

return 0;
}
Expand All @@ -372,7 +374,8 @@ static int dwc3_qcom_resume(struct dwc3_qcom *qcom)
if (!qcom->is_suspended)
return 0;

dwc3_qcom_disable_interrupts(qcom);
if (device_may_wakeup(qcom->dev))
dwc3_qcom_disable_interrupts(qcom);

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

qcom->dwc3 = of_find_device_by_node(dwc3_np);
if (!qcom->dwc3) {
ret = -ENODEV;
dev_err(dev, "failed to get dwc3 platform device\n");
return -ENODEV;
}

return 0;
node_put:
of_node_put(dwc3_np);

return ret;
}

static struct platform_device *
Expand Down Expand Up @@ -938,6 +944,8 @@ static const struct dwc3_acpi_pdata sdm845_acpi_urs_pdata = {
static const struct acpi_device_id dwc3_qcom_acpi_match[] = {
{ "QCOM2430", (unsigned long)&sdm845_acpi_pdata },
{ "QCOM0304", (unsigned long)&sdm845_acpi_urs_pdata },
{ "QCOM0497", (unsigned long)&sdm845_acpi_urs_pdata },
{ "QCOM04A6", (unsigned long)&sdm845_acpi_pdata },
{ },
};
MODULE_DEVICE_TABLE(acpi, dwc3_qcom_acpi_match);
Expand Down
1 change: 1 addition & 0 deletions drivers/usb/gadget/function/f_uac1.c
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,7 @@ static void f_audio_disable(struct usb_function *f)
uac1->as_out_alt = 0;
uac1->as_in_alt = 0;

u_audio_stop_playback(&uac1->g_audio);
u_audio_stop_capture(&uac1->g_audio);
}

Expand Down
2 changes: 1 addition & 1 deletion drivers/usb/gadget/function/f_uac2.c
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,7 @@ static int set_ep_max_packet_size(const struct f_uac2_opts *uac2_opts,
}

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

Expand Down
5 changes: 2 additions & 3 deletions drivers/usb/gadget/function/u_ether_configfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -182,12 +182,11 @@ out: \
size_t len) \
{ \
struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \
int ret; \
int ret = -EINVAL; \
u8 val; \
\
mutex_lock(&opts->lock); \
ret = sscanf(page, "%02hhx", &val); \
if (ret > 0) { \
if (sscanf(page, "%02hhx", &val) > 0) { \
opts->_n_ = val; \
ret = len; \
} \
Expand Down
4 changes: 2 additions & 2 deletions drivers/usb/gadget/udc/s3c2410_udc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1773,8 +1773,8 @@ static int s3c2410_udc_probe(struct platform_device *pdev)
udc_info = dev_get_platdata(&pdev->dev);

base_addr = devm_platform_ioremap_resource(pdev, 0);
if (!base_addr) {
retval = -ENOMEM;
if (IS_ERR(base_addr)) {
retval = PTR_ERR(base_addr);
goto err_mem;
}

Expand Down
13 changes: 11 additions & 2 deletions drivers/usb/host/xhci-pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
#define PCI_DEVICE_ID_ASMEDIA_1042A_XHCI 0x1142
#define PCI_DEVICE_ID_ASMEDIA_1142_XHCI 0x1242
#define PCI_DEVICE_ID_ASMEDIA_2142_XHCI 0x2142
#define PCI_DEVICE_ID_ASMEDIA_3242_XHCI 0x3242

static const char hcd_name[] = "xhci_hcd";

Expand Down Expand Up @@ -276,11 +277,14 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
pdev->device == PCI_DEVICE_ID_ASMEDIA_1042_XHCI)
xhci->quirks |= XHCI_BROKEN_STREAMS;
if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA &&
pdev->device == PCI_DEVICE_ID_ASMEDIA_1042A_XHCI)
pdev->device == PCI_DEVICE_ID_ASMEDIA_1042A_XHCI) {
xhci->quirks |= XHCI_TRUST_TX_LENGTH;
xhci->quirks |= XHCI_NO_64BIT_SUPPORT;
}
if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA &&
(pdev->device == PCI_DEVICE_ID_ASMEDIA_1142_XHCI ||
pdev->device == PCI_DEVICE_ID_ASMEDIA_2142_XHCI))
pdev->device == PCI_DEVICE_ID_ASMEDIA_2142_XHCI ||
pdev->device == PCI_DEVICE_ID_ASMEDIA_3242_XHCI))
xhci->quirks |= XHCI_NO_64BIT_SUPPORT;

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

if (pdev->vendor == PCI_VENDOR_ID_AMD &&
(pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_2 ||
pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_4))
xhci->quirks |= XHCI_NO_SOFT_RETRY;

if (xhci->quirks & XHCI_RESET_ON_RESUME)
xhci_dbg_trace(xhci, trace_xhci_dbg_quirks,
"QUIRK: Resetting on resume");
Expand Down
3 changes: 2 additions & 1 deletion drivers/usb/host/xhci-ring.c
Original file line number Diff line number Diff line change
Expand Up @@ -2484,7 +2484,8 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td,
remaining = 0;
break;
case COMP_USB_TRANSACTION_ERROR:
if ((ep_ring->err_count++ > MAX_SOFT_RETRY) ||
if (xhci->quirks & XHCI_NO_SOFT_RETRY ||
(ep_ring->err_count++ > MAX_SOFT_RETRY) ||
le32_to_cpu(slot_ctx->tt_info) & TT_SLOT)
break;

Expand Down
78 changes: 43 additions & 35 deletions drivers/usb/host/xhci.c
Original file line number Diff line number Diff line change
Expand Up @@ -883,44 +883,42 @@ static void xhci_clear_command_ring(struct xhci_hcd *xhci)
xhci_set_cmd_ring_deq(xhci);
}

static void xhci_disable_port_wake_on_bits(struct xhci_hcd *xhci)
/*
* Disable port wake bits if do_wakeup is not set.
*
* Also clear a possible internal port wake state left hanging for ports that
* detected termination but never successfully enumerated (trained to 0U).
* Internal wake causes immediate xHCI wake after suspend. PORT_CSC write done
* at enumeration clears this wake, force one here as well for unconnected ports
*/

static void xhci_disable_hub_port_wake(struct xhci_hcd *xhci,
struct xhci_hub *rhub,
bool do_wakeup)
{
struct xhci_port **ports;
int port_index;
unsigned long flags;
u32 t1, t2, portsc;
int i;

spin_lock_irqsave(&xhci->lock, flags);

/* disable usb3 ports Wake bits */
port_index = xhci->usb3_rhub.num_ports;
ports = xhci->usb3_rhub.ports;
while (port_index--) {
t1 = readl(ports[port_index]->addr);
portsc = t1;
t1 = xhci_port_state_to_neutral(t1);
t2 = t1 & ~PORT_WAKE_BITS;
if (t1 != t2) {
writel(t2, ports[port_index]->addr);
xhci_dbg(xhci, "disable wake bits port %d-%d, portsc: 0x%x, write: 0x%x\n",
xhci->usb3_rhub.hcd->self.busnum,
port_index + 1, portsc, t2);
}
}
for (i = 0; i < rhub->num_ports; i++) {
portsc = readl(rhub->ports[i]->addr);
t1 = xhci_port_state_to_neutral(portsc);
t2 = t1;

/* clear wake bits if do_wake is not set */
if (!do_wakeup)
t2 &= ~PORT_WAKE_BITS;

/* Don't touch csc bit if connected or connect change is set */
if (!(portsc & (PORT_CSC | PORT_CONNECT)))
t2 |= PORT_CSC;

/* disable usb2 ports Wake bits */
port_index = xhci->usb2_rhub.num_ports;
ports = xhci->usb2_rhub.ports;
while (port_index--) {
t1 = readl(ports[port_index]->addr);
portsc = t1;
t1 = xhci_port_state_to_neutral(t1);
t2 = t1 & ~PORT_WAKE_BITS;
if (t1 != t2) {
writel(t2, ports[port_index]->addr);
xhci_dbg(xhci, "disable wake bits port %d-%d, portsc: 0x%x, write: 0x%x\n",
xhci->usb2_rhub.hcd->self.busnum,
port_index + 1, portsc, t2);
writel(t2, rhub->ports[i]->addr);
xhci_dbg(xhci, "config port %d-%d wake bits, portsc: 0x%x, write: 0x%x\n",
rhub->hcd->self.busnum, i + 1, portsc, t2);
}
}
spin_unlock_irqrestore(&xhci->lock, flags);
Expand Down Expand Up @@ -983,8 +981,8 @@ int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup)
return -EINVAL;

/* Clear root port wake on bits if wakeup not allowed. */
if (!do_wakeup)
xhci_disable_port_wake_on_bits(xhci);
xhci_disable_hub_port_wake(xhci, &xhci->usb3_rhub, do_wakeup);
xhci_disable_hub_port_wake(xhci, &xhci->usb2_rhub, do_wakeup);

if (!HCD_HW_ACCESSIBLE(hcd))
return 0;
Expand Down Expand Up @@ -1088,6 +1086,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
struct usb_hcd *secondary_hcd;
int retval = 0;
bool comp_timer_running = false;
bool pending_portevent = false;

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

done:
if (retval == 0) {
/* Resume root hubs only when have pending events. */
if (xhci_pending_portevent(xhci)) {
/*
* Resume roothubs only if there are pending events.
* USB 3 devices resend U3 LFPS wake after a 100ms delay if
* the first wake signalling failed, give it that chance.
*/
pending_portevent = xhci_pending_portevent(xhci);
if (!pending_portevent) {
msleep(120);
pending_portevent = xhci_pending_portevent(xhci);
}

if (pending_portevent) {
usb_hcd_resume_root_hub(xhci->shared_hcd);
usb_hcd_resume_root_hub(hcd);
}
}

/*
* If system is subject to the Quirk, Compliance Mode Timer needs to
* be re-initialized Always after a system resume. Ports are subject
Expand Down
1 change: 1 addition & 0 deletions drivers/usb/host/xhci.h
Original file line number Diff line number Diff line change
Expand Up @@ -1891,6 +1891,7 @@ struct xhci_hcd {
#define XHCI_SKIP_PHY_INIT BIT_ULL(37)
#define XHCI_DISABLE_SPARSE BIT_ULL(38)
#define XHCI_SG_TRB_CACHE_SIZE_QUIRK BIT_ULL(39)
#define XHCI_NO_SOFT_RETRY BIT_ULL(40)

unsigned int num_active_eps;
unsigned int limit_active_eps;
Expand Down
2 changes: 2 additions & 0 deletions drivers/usb/renesas_usbhs/pipe.c
Original file line number Diff line number Diff line change
Expand Up @@ -746,6 +746,8 @@ struct usbhs_pipe *usbhs_pipe_malloc(struct usbhs_priv *priv,

void usbhs_pipe_free(struct usbhs_pipe *pipe)
{
usbhsp_pipe_select(pipe);
usbhsp_pipe_cfg_set(pipe, 0xFFFF, 0);
usbhsp_put_pipe(pipe);
}

Expand Down
1 change: 1 addition & 0 deletions drivers/usb/serial/ch341.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ static const struct usb_device_id id_table[] = {
{ USB_DEVICE(0x1a86, 0x7522) },
{ USB_DEVICE(0x1a86, 0x7523) },
{ USB_DEVICE(0x4348, 0x5523) },
{ USB_DEVICE(0x9986, 0x7523) },
{ },
};
MODULE_DEVICE_TABLE(usb, id_table);
Expand Down
3 changes: 3 additions & 0 deletions drivers/usb/serial/cp210x.c
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ static const struct usb_device_id id_table[] = {
{ USB_DEVICE(0x10C4, 0x8857) }, /* CEL EM357 ZigBee USB Stick */
{ USB_DEVICE(0x10C4, 0x88A4) }, /* MMB Networks ZigBee USB Device */
{ USB_DEVICE(0x10C4, 0x88A5) }, /* Planet Innovation Ingeni ZigBee USB Device */
{ USB_DEVICE(0x10C4, 0x88D8) }, /* Acuity Brands nLight Air Adapter */
{ USB_DEVICE(0x10C4, 0x88FB) }, /* CESINEL MEDCAL STII Network Analyzer */
{ USB_DEVICE(0x10C4, 0x8938) }, /* CESINEL MEDCAL S II Network Analyzer */
{ USB_DEVICE(0x10C4, 0x8946) }, /* Ketra N1 Wireless Interface */
Expand Down Expand Up @@ -201,6 +202,8 @@ static const struct usb_device_id id_table[] = {
{ USB_DEVICE(0x1901, 0x0194) }, /* GE Healthcare Remote Alarm Box */
{ USB_DEVICE(0x1901, 0x0195) }, /* GE B850/B650/B450 CP2104 DP UART interface */
{ USB_DEVICE(0x1901, 0x0196) }, /* GE B850 CP2105 DP UART interface */
{ USB_DEVICE(0x1901, 0x0197) }, /* GE CS1000 Display serial interface */
{ USB_DEVICE(0x1901, 0x0198) }, /* GE CS1000 M.2 Key E serial interface */
{ USB_DEVICE(0x199B, 0xBA30) }, /* LORD WSDA-200-USB */
{ USB_DEVICE(0x19CF, 0x3000) }, /* Parrot NMEA GPS Flight Recorder */
{ USB_DEVICE(0x1ADB, 0x0001) }, /* Schweitzer Engineering C662 Cable */
Expand Down
26 changes: 16 additions & 10 deletions drivers/usb/serial/io_edgeport.c
Original file line number Diff line number Diff line change
Expand Up @@ -3003,26 +3003,32 @@ static int edge_startup(struct usb_serial *serial)
response = -ENODEV;
}

usb_free_urb(edge_serial->interrupt_read_urb);
kfree(edge_serial->interrupt_in_buffer);

usb_free_urb(edge_serial->read_urb);
kfree(edge_serial->bulk_in_buffer);

kfree(edge_serial);

return response;
goto error;
}

/* start interrupt read for this edgeport this interrupt will
* continue as long as the edgeport is connected */
response = usb_submit_urb(edge_serial->interrupt_read_urb,
GFP_KERNEL);
if (response)
if (response) {
dev_err(ddev, "%s - Error %d submitting control urb\n",
__func__, response);

goto error;
}
}
return response;

error:
usb_free_urb(edge_serial->interrupt_read_urb);
kfree(edge_serial->interrupt_in_buffer);

usb_free_urb(edge_serial->read_urb);
kfree(edge_serial->bulk_in_buffer);

kfree(edge_serial);

return response;
}


Expand Down
Loading

0 comments on commit 5c7bdbf

Please sign in to comment.