Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'usb-5.12-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb

Pull USB fixes from Greg KH:
"Here are a few small USB driver fixes for 5.12-rc6 to resolve reported
problems.

They include:

- a number of cdc-acm fixes for reported problems. It seems more
people are using this driver lately...

- dwc3 driver fixes for reported problems, and fixes for the fixes :)

- dwc2 driver fixes for reported issues.

- musb driver fix.

- new USB quirk additions.

All of these have been in linux-next for a while with no reported
issues"

* tag 'usb-5.12-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (23 commits)
usb: dwc2: Prevent core suspend when port connection flag is 0
usb: dwc2: Fix HPRT0.PrtSusp bit setting for HiKey 960 board.
usb: musb: Fix suspend with devices connected for a64
usb: xhci-mtk: fix broken streams issue on 0.96 xHCI
usb: dwc3: gadget: Clear DEP flags after stop transfers in ep disable
usbip: vhci_hcd fix shift out-of-bounds in vhci_hub_control()
USB: quirks: ignore remote wake-up on Fibocom L850-GL LTE modem
USB: cdc-acm: do not log successful probe on later errors
USB: cdc-acm: always claim data interface
USB: cdc-acm: use negation for NULL checks
USB: cdc-acm: clean up probe error labels
USB: cdc-acm: drop redundant driver-data reset
USB: cdc-acm: drop redundant driver-data assignment
USB: cdc-acm: fix use-after-free after probe failure
USB: cdc-acm: fix double free on probe failure
USB: cdc-acm: downgrade message to debug
USB: cdc-acm: untangle a circular dependency between callback and softint
cdc-acm: fix BREAK rx code path adding necessary calls
usb: gadget: udc: amd5536udc_pci fix null-ptr-dereference
usb: dwc3: pci: Enable dis_uX_susphy_quirk for Intel Merrifield
...

+112 -67
+70 -50
drivers/usb/class/cdc-acm.c
··· 147 147 #define acm_send_break(acm, ms) \ 148 148 acm_ctrl_msg(acm, USB_CDC_REQ_SEND_BREAK, ms, NULL, 0) 149 149 150 - static void acm_kill_urbs(struct acm *acm) 150 + static void acm_poison_urbs(struct acm *acm) 151 151 { 152 152 int i; 153 153 154 - usb_kill_urb(acm->ctrlurb); 154 + usb_poison_urb(acm->ctrlurb); 155 155 for (i = 0; i < ACM_NW; i++) 156 - usb_kill_urb(acm->wb[i].urb); 156 + usb_poison_urb(acm->wb[i].urb); 157 157 for (i = 0; i < acm->rx_buflimit; i++) 158 - usb_kill_urb(acm->read_urbs[i]); 158 + usb_poison_urb(acm->read_urbs[i]); 159 159 } 160 + 161 + static void acm_unpoison_urbs(struct acm *acm) 162 + { 163 + int i; 164 + 165 + for (i = 0; i < acm->rx_buflimit; i++) 166 + usb_unpoison_urb(acm->read_urbs[i]); 167 + for (i = 0; i < ACM_NW; i++) 168 + usb_unpoison_urb(acm->wb[i].urb); 169 + usb_unpoison_urb(acm->ctrlurb); 170 + } 171 + 160 172 161 173 /* 162 174 * Write buffer management. ··· 238 226 239 227 rc = usb_submit_urb(wb->urb, GFP_ATOMIC); 240 228 if (rc < 0) { 241 - dev_err(&acm->data->dev, 242 - "%s - usb_submit_urb(write bulk) failed: %d\n", 243 - __func__, rc); 229 + if (rc != -EPERM) 230 + dev_err(&acm->data->dev, 231 + "%s - usb_submit_urb(write bulk) failed: %d\n", 232 + __func__, rc); 244 233 acm_write_done(acm, wb); 245 234 } 246 235 return rc; ··· 326 313 acm->iocount.dsr++; 327 314 if (difference & ACM_CTRL_DCD) 328 315 acm->iocount.dcd++; 329 - if (newctrl & ACM_CTRL_BRK) 316 + if (newctrl & ACM_CTRL_BRK) { 330 317 acm->iocount.brk++; 318 + tty_insert_flip_char(&acm->port, 0, TTY_BREAK); 319 + } 331 320 if (newctrl & ACM_CTRL_RI) 332 321 acm->iocount.rng++; 333 322 if (newctrl & ACM_CTRL_FRAMING) ··· 495 480 dev_vdbg(&acm->data->dev, "got urb %d, len %d, status %d\n", 496 481 rb->index, urb->actual_length, status); 497 482 498 - if (!acm->dev) { 499 - dev_dbg(&acm->data->dev, "%s - disconnected\n", __func__); 500 - return; 501 - } 502 - 503 483 switch (status) { 504 484 case 0: 505 485 usb_mark_last_busy(acm->dev); ··· 659 649 660 650 res = acm_set_control(acm, val); 661 651 if (res && (acm->ctrl_caps & USB_CDC_CAP_LINE)) 662 - dev_err(&acm->control->dev, "failed to set dtr/rts\n"); 652 + /* This is broken in too many devices to spam the logs */ 653 + dev_dbg(&acm->control->dev, "failed to set dtr/rts\n"); 663 654 } 664 655 665 656 static int acm_port_activate(struct tty_port *port, struct tty_struct *tty) ··· 742 731 * Need to grab write_lock to prevent race with resume, but no need to 743 732 * hold it due to the tty-port initialised flag. 744 733 */ 734 + acm_poison_urbs(acm); 745 735 spin_lock_irq(&acm->write_lock); 746 736 spin_unlock_irq(&acm->write_lock); 747 737 ··· 759 747 usb_autopm_put_interface_async(acm->control); 760 748 } 761 749 762 - acm_kill_urbs(acm); 750 + acm_unpoison_urbs(acm); 751 + 763 752 } 764 753 765 754 static void acm_tty_cleanup(struct tty_struct *tty) ··· 1309 1296 if (!combined_interfaces && intf != control_interface) 1310 1297 return -ENODEV; 1311 1298 1312 - if (!combined_interfaces && usb_interface_claimed(data_interface)) { 1313 - /* valid in this context */ 1314 - dev_dbg(&intf->dev, "The data interface isn't available\n"); 1315 - return -EBUSY; 1316 - } 1317 - 1318 - 1319 1299 if (data_interface->cur_altsetting->desc.bNumEndpoints < 2 || 1320 1300 control_interface->cur_altsetting->desc.bNumEndpoints == 0) 1321 1301 return -EINVAL; ··· 1329 1323 dev_dbg(&intf->dev, "interfaces are valid\n"); 1330 1324 1331 1325 acm = kzalloc(sizeof(struct acm), GFP_KERNEL); 1332 - if (acm == NULL) 1333 - goto alloc_fail; 1326 + if (!acm) 1327 + return -ENOMEM; 1334 1328 1335 1329 tty_port_init(&acm->port); 1336 1330 acm->port.ops = &acm_port_ops; ··· 1347 1341 1348 1342 minor = acm_alloc_minor(acm); 1349 1343 if (minor < 0) 1350 - goto alloc_fail1; 1344 + goto err_put_port; 1351 1345 1352 1346 acm->minor = minor; 1353 1347 acm->dev = usb_dev; ··· 1378 1372 1379 1373 buf = usb_alloc_coherent(usb_dev, ctrlsize, GFP_KERNEL, &acm->ctrl_dma); 1380 1374 if (!buf) 1381 - goto alloc_fail1; 1375 + goto err_put_port; 1382 1376 acm->ctrl_buffer = buf; 1383 1377 1384 1378 if (acm_write_buffers_alloc(acm) < 0) 1385 - goto alloc_fail2; 1379 + goto err_free_ctrl_buffer; 1386 1380 1387 1381 acm->ctrlurb = usb_alloc_urb(0, GFP_KERNEL); 1388 1382 if (!acm->ctrlurb) 1389 - goto alloc_fail3; 1383 + goto err_free_write_buffers; 1390 1384 1391 1385 for (i = 0; i < num_rx_buf; i++) { 1392 1386 struct acm_rb *rb = &(acm->read_buffers[i]); ··· 1395 1389 rb->base = usb_alloc_coherent(acm->dev, readsize, GFP_KERNEL, 1396 1390 &rb->dma); 1397 1391 if (!rb->base) 1398 - goto alloc_fail4; 1392 + goto err_free_read_urbs; 1399 1393 rb->index = i; 1400 1394 rb->instance = acm; 1401 1395 1402 1396 urb = usb_alloc_urb(0, GFP_KERNEL); 1403 1397 if (!urb) 1404 - goto alloc_fail4; 1398 + goto err_free_read_urbs; 1405 1399 1406 1400 urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; 1407 1401 urb->transfer_dma = rb->dma; ··· 1422 1416 struct acm_wb *snd = &(acm->wb[i]); 1423 1417 1424 1418 snd->urb = usb_alloc_urb(0, GFP_KERNEL); 1425 - if (snd->urb == NULL) 1426 - goto alloc_fail5; 1419 + if (!snd->urb) 1420 + goto err_free_write_urbs; 1427 1421 1428 1422 if (usb_endpoint_xfer_int(epwrite)) 1429 1423 usb_fill_int_urb(snd->urb, usb_dev, acm->out, ··· 1441 1435 1442 1436 i = device_create_file(&intf->dev, &dev_attr_bmCapabilities); 1443 1437 if (i < 0) 1444 - goto alloc_fail5; 1438 + goto err_free_write_urbs; 1445 1439 1446 1440 if (h.usb_cdc_country_functional_desc) { /* export the country data */ 1447 1441 struct usb_cdc_country_functional_desc * cfd = ··· 1486 1480 acm->nb_index = 0; 1487 1481 acm->nb_size = 0; 1488 1482 1489 - dev_info(&intf->dev, "ttyACM%d: USB ACM device\n", minor); 1490 - 1491 1483 acm->line.dwDTERate = cpu_to_le32(9600); 1492 1484 acm->line.bDataBits = 8; 1493 1485 acm_set_line(acm, &acm->line); 1494 1486 1495 - usb_driver_claim_interface(&acm_driver, data_interface, acm); 1496 - usb_set_intfdata(data_interface, acm); 1487 + if (!acm->combined_interfaces) { 1488 + rv = usb_driver_claim_interface(&acm_driver, data_interface, acm); 1489 + if (rv) 1490 + goto err_remove_files; 1491 + } 1497 1492 1498 1493 tty_dev = tty_port_register_device(&acm->port, acm_tty_driver, minor, 1499 1494 &control_interface->dev); 1500 1495 if (IS_ERR(tty_dev)) { 1501 1496 rv = PTR_ERR(tty_dev); 1502 - goto alloc_fail6; 1497 + goto err_release_data_interface; 1503 1498 } 1504 1499 1505 1500 if (quirks & CLEAR_HALT_CONDITIONS) { ··· 1508 1501 usb_clear_halt(usb_dev, acm->out); 1509 1502 } 1510 1503 1504 + dev_info(&intf->dev, "ttyACM%d: USB ACM device\n", minor); 1505 + 1511 1506 return 0; 1512 - alloc_fail6: 1507 + 1508 + err_release_data_interface: 1509 + if (!acm->combined_interfaces) { 1510 + /* Clear driver data so that disconnect() returns early. */ 1511 + usb_set_intfdata(data_interface, NULL); 1512 + usb_driver_release_interface(&acm_driver, data_interface); 1513 + } 1514 + err_remove_files: 1513 1515 if (acm->country_codes) { 1514 1516 device_remove_file(&acm->control->dev, 1515 1517 &dev_attr_wCountryCodes); 1516 1518 device_remove_file(&acm->control->dev, 1517 1519 &dev_attr_iCountryCodeRelDate); 1518 - kfree(acm->country_codes); 1519 1520 } 1520 1521 device_remove_file(&acm->control->dev, &dev_attr_bmCapabilities); 1521 - alloc_fail5: 1522 - usb_set_intfdata(intf, NULL); 1522 + err_free_write_urbs: 1523 1523 for (i = 0; i < ACM_NW; i++) 1524 1524 usb_free_urb(acm->wb[i].urb); 1525 - alloc_fail4: 1525 + err_free_read_urbs: 1526 1526 for (i = 0; i < num_rx_buf; i++) 1527 1527 usb_free_urb(acm->read_urbs[i]); 1528 1528 acm_read_buffers_free(acm); 1529 1529 usb_free_urb(acm->ctrlurb); 1530 - alloc_fail3: 1530 + err_free_write_buffers: 1531 1531 acm_write_buffers_free(acm); 1532 - alloc_fail2: 1532 + err_free_ctrl_buffer: 1533 1533 usb_free_coherent(usb_dev, ctrlsize, acm->ctrl_buffer, acm->ctrl_dma); 1534 - alloc_fail1: 1534 + err_put_port: 1535 1535 tty_port_put(&acm->port); 1536 - alloc_fail: 1536 + 1537 1537 return rv; 1538 1538 } 1539 1539 ··· 1554 1540 if (!acm) 1555 1541 return; 1556 1542 1557 - mutex_lock(&acm->mutex); 1558 1543 acm->disconnected = true; 1544 + /* 1545 + * there is a circular dependency. acm_softint() can resubmit 1546 + * the URBs in error handling so we need to block any 1547 + * submission right away 1548 + */ 1549 + acm_poison_urbs(acm); 1550 + mutex_lock(&acm->mutex); 1559 1551 if (acm->country_codes) { 1560 1552 device_remove_file(&acm->control->dev, 1561 1553 &dev_attr_wCountryCodes); ··· 1580 1560 tty_kref_put(tty); 1581 1561 } 1582 1562 1583 - acm_kill_urbs(acm); 1584 1563 cancel_delayed_work_sync(&acm->dwork); 1585 1564 1586 1565 tty_unregister_device(acm_tty_driver, acm->minor); ··· 1621 1602 if (cnt) 1622 1603 return 0; 1623 1604 1624 - acm_kill_urbs(acm); 1605 + acm_poison_urbs(acm); 1625 1606 cancel_delayed_work_sync(&acm->dwork); 1626 1607 acm->urbs_in_error_delay = 0; 1627 1608 ··· 1634 1615 struct urb *urb; 1635 1616 int rv = 0; 1636 1617 1618 + acm_unpoison_urbs(acm); 1637 1619 spin_lock_irq(&acm->write_lock); 1638 1620 1639 1621 if (--acm->susp_count)
+4
drivers/usb/core/quirks.c
··· 498 498 /* DJI CineSSD */ 499 499 { USB_DEVICE(0x2ca3, 0x0031), .driver_info = USB_QUIRK_NO_LPM }, 500 500 501 + /* Fibocom L850-GL LTE Modem */ 502 + { USB_DEVICE(0x2cb7, 0x0007), .driver_info = 503 + USB_QUIRK_IGNORE_REMOTE_WAKEUP }, 504 + 501 505 /* INTEL VALUE SSD */ 502 506 { USB_DEVICE(0x8086, 0xf1a5), .driver_info = USB_QUIRK_RESET_RESUME }, 503 507
+3 -2
drivers/usb/dwc2/hcd.c
··· 4322 4322 if (hsotg->op_state == OTG_STATE_B_PERIPHERAL) 4323 4323 goto unlock; 4324 4324 4325 - if (hsotg->params.power_down > DWC2_POWER_DOWN_PARAM_PARTIAL) 4325 + if (hsotg->params.power_down != DWC2_POWER_DOWN_PARAM_PARTIAL || 4326 + hsotg->flags.b.port_connect_status == 0) 4326 4327 goto skip_power_saving; 4327 4328 4328 4329 /* ··· 5399 5398 dwc2_writel(hsotg, hprt0, HPRT0); 5400 5399 5401 5400 /* Wait for the HPRT0.PrtSusp register field to be set */ 5402 - if (dwc2_hsotg_wait_bit_set(hsotg, HPRT0, HPRT0_SUSP, 3000)) 5401 + if (dwc2_hsotg_wait_bit_set(hsotg, HPRT0, HPRT0_SUSP, 5000)) 5403 5402 dev_warn(hsotg->dev, "Suspend wasn't generated\n"); 5404 5403 5405 5404 /*
+2
drivers/usb/dwc3/dwc3-pci.c
··· 120 120 static const struct property_entry dwc3_pci_mrfld_properties[] = { 121 121 PROPERTY_ENTRY_STRING("dr_mode", "otg"), 122 122 PROPERTY_ENTRY_STRING("linux,extcon-name", "mrfld_bcove_pwrsrc"), 123 + PROPERTY_ENTRY_BOOL("snps,dis_u3_susphy_quirk"), 124 + PROPERTY_ENTRY_BOOL("snps,dis_u2_susphy_quirk"), 123 125 PROPERTY_ENTRY_BOOL("linux,sysdev_is_parent"), 124 126 {} 125 127 };
+3
drivers/usb/dwc3/dwc3-qcom.c
··· 244 244 struct device *dev = qcom->dev; 245 245 int ret; 246 246 247 + if (has_acpi_companion(dev)) 248 + return 0; 249 + 247 250 qcom->icc_path_ddr = of_icc_get(dev, "usb-ddr"); 248 251 if (IS_ERR(qcom->icc_path_ddr)) { 249 252 dev_err(dev, "failed to get usb-ddr path: %ld\n",
+6 -5
drivers/usb/dwc3/gadget.c
··· 791 791 reg &= ~DWC3_DALEPENA_EP(dep->number); 792 792 dwc3_writel(dwc->regs, DWC3_DALEPENA, reg); 793 793 794 - dep->stream_capable = false; 795 - dep->type = 0; 796 - dep->flags = 0; 797 - 798 794 /* Clear out the ep descriptors for non-ep0 */ 799 795 if (dep->number > 1) { 800 796 dep->endpoint.comp_desc = NULL; ··· 798 802 } 799 803 800 804 dwc3_remove_requests(dwc, dep); 805 + 806 + dep->stream_capable = false; 807 + dep->type = 0; 808 + dep->flags = 0; 801 809 802 810 return 0; 803 811 } ··· 2083 2083 u32 reg; 2084 2084 2085 2085 speed = dwc->gadget_max_speed; 2086 - if (speed > dwc->maximum_speed) 2086 + if (speed == USB_SPEED_UNKNOWN || speed > dwc->maximum_speed) 2087 2087 speed = dwc->maximum_speed; 2088 2088 2089 2089 if (speed == USB_SPEED_SUPER_PLUS && ··· 2523 2523 unsigned long flags; 2524 2524 2525 2525 spin_lock_irqsave(&dwc->lock, flags); 2526 + dwc->gadget_max_speed = USB_SPEED_SUPER_PLUS; 2526 2527 dwc->gadget_ssp_rate = rate; 2527 2528 spin_unlock_irqrestore(&dwc->lock, flags); 2528 2529 }
+5 -5
drivers/usb/gadget/udc/amd5536udc_pci.c
··· 153 153 pci_set_master(pdev); 154 154 pci_try_set_mwi(pdev); 155 155 156 + dev->phys_addr = resource; 157 + dev->irq = pdev->irq; 158 + dev->pdev = pdev; 159 + dev->dev = &pdev->dev; 160 + 156 161 /* init dma pools */ 157 162 if (use_dma) { 158 163 retval = init_dma_pools(dev); 159 164 if (retval != 0) 160 165 goto err_dma; 161 166 } 162 - 163 - dev->phys_addr = resource; 164 - dev->irq = pdev->irq; 165 - dev->pdev = pdev; 166 - dev->dev = &pdev->dev; 167 167 168 168 /* general probing */ 169 169 if (udc_probe(dev)) {
+9 -1
drivers/usb/host/xhci-mtk.c
··· 397 397 xhci->quirks |= XHCI_SPURIOUS_SUCCESS; 398 398 if (mtk->lpm_support) 399 399 xhci->quirks |= XHCI_LPM_SUPPORT; 400 + 401 + /* 402 + * MTK xHCI 0.96: PSA is 1 by default even if doesn't support stream, 403 + * and it's 3 when support it. 404 + */ 405 + if (xhci->hci_version < 0x100 && HCC_MAX_PSA(xhci->hcc_params) == 4) 406 + xhci->quirks |= XHCI_BROKEN_STREAMS; 400 407 } 401 408 402 409 /* called during probe() after chip reset completes */ ··· 555 548 if (ret) 556 549 goto put_usb3_hcd; 557 550 558 - if (HCC_MAX_PSA(xhci->hcc_params) >= 4) 551 + if (HCC_MAX_PSA(xhci->hcc_params) >= 4 && 552 + !(xhci->quirks & XHCI_BROKEN_STREAMS)) 559 553 xhci->shared_hcd->can_do_streams = 1; 560 554 561 555 ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED);
+8 -4
drivers/usb/musb/musb_core.c
··· 2004 2004 MUSB_DEVCTL_HR; 2005 2005 switch (devctl & ~s) { 2006 2006 case MUSB_QUIRK_B_DISCONNECT_99: 2007 - musb_dbg(musb, "Poll devctl in case of suspend after disconnect\n"); 2008 - schedule_delayed_work(&musb->irq_work, 2009 - msecs_to_jiffies(1000)); 2010 - break; 2007 + if (musb->quirk_retries && !musb->flush_irq_work) { 2008 + musb_dbg(musb, "Poll devctl in case of suspend after disconnect\n"); 2009 + schedule_delayed_work(&musb->irq_work, 2010 + msecs_to_jiffies(1000)); 2011 + musb->quirk_retries--; 2012 + break; 2013 + } 2014 + fallthrough; 2011 2015 case MUSB_QUIRK_B_INVALID_VBUS_91: 2012 2016 if (musb->quirk_retries && !musb->flush_irq_work) { 2013 2017 musb_dbg(musb,
+2
drivers/usb/usbip/vhci_hcd.c
··· 594 594 pr_err("invalid port number %d\n", wIndex); 595 595 goto error; 596 596 } 597 + if (wValue >= 32) 598 + goto error; 597 599 if (hcd->speed == HCD_USB3) { 598 600 if ((vhci_hcd->port_status[rhport] & 599 601 USB_SS_PORT_STAT_POWER) != 0) {