Skip to content

Commit b5beaa4

Browse files
committed
Merge tag 'usb-6.10-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
Pull USB / Thunderbolt fixes from Greg KH: "Here are some small USB and Thunderbolt driver fixes for 6.10-rc4. Included in here are: - thunderbolt debugfs bugfix - USB typec bugfixes - kcov usb bugfix - xhci bugfixes - usb-storage bugfix - dt-bindings bugfix - cdc-wdm log message spam bugfix All of these, except for the last cdc-wdm log level change, have been in linux-next for a while with no reported problems. The cdc-wdm bugfix has been tested by syzbot and proved to fix the reported cpu lockup issues when the log is constantly spammed by a broken device" * tag 'usb-6.10-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: USB: class: cdc-wdm: Fix CPU lockup caused by excessive log messages xhci: Handle TD clearing for multiple streams case xhci: Apply broken streams quirk to Etron EJ188 xHCI host xhci: Apply reset resume quirk to Etron EJ188 xHCI host xhci: Set correct transferred length for cancelled bulk transfers usb-storage: alauda: Check whether the media is initialized usb: typec: ucsi: Ack also failed Get Error commands kcov, usb: disable interrupts in kcov_remote_start_usb_softirq dt-bindings: usb: realtek,rts5411: Add missing "additionalProperties" on child nodes usb: typec: tcpm: Ignore received Hard Reset in TOGGLING state usb: typec: tcpm: fix use-after-free case in tcpm_register_source_caps USB: xen-hcd: Traverse host/ when CONFIG_USB_XEN_HCD is selected usb: typec: ucsi: glink: increase max ports for x1e80100 Revert "usb: chipidea: move ci_ulpi_init after the phy initialization" thunderbolt: debugfs: Fix margin debugfs node creation condition
2 parents 6efc63a + 22f0081 commit b5beaa4

File tree

15 files changed

+131
-42
lines changed

15 files changed

+131
-42
lines changed

Documentation/devicetree/bindings/usb/realtek,rts5411.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ patternProperties:
6565
description: The hard wired USB devices
6666
type: object
6767
$ref: /schemas/usb/usb-device.yaml
68+
additionalProperties: true
6869

6970
required:
7071
- peer-hub

drivers/thunderbolt/debugfs.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -943,8 +943,9 @@ static void margining_port_init(struct tb_port *port)
943943
debugfs_create_file("run", 0600, dir, port, &margining_run_fops);
944944
debugfs_create_file("results", 0600, dir, port, &margining_results_fops);
945945
debugfs_create_file("test", 0600, dir, port, &margining_test_fops);
946-
if (independent_voltage_margins(usb4) ||
947-
(supports_time(usb4) && independent_time_margins(usb4)))
946+
if (independent_voltage_margins(usb4) == USB4_MARGIN_CAP_0_VOLTAGE_HL ||
947+
(supports_time(usb4) &&
948+
independent_time_margins(usb4) == USB4_MARGIN_CAP_1_TIME_LR))
948949
debugfs_create_file("margin", 0600, dir, port, &margining_margin_fops);
949950
}
950951

drivers/usb/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ obj-$(CONFIG_USB_R8A66597_HCD) += host/
3535
obj-$(CONFIG_USB_FSL_USB2) += host/
3636
obj-$(CONFIG_USB_FOTG210_HCD) += host/
3737
obj-$(CONFIG_USB_MAX3421_HCD) += host/
38+
obj-$(CONFIG_USB_XEN_HCD) += host/
3839

3940
obj-$(CONFIG_USB_C67X00_HCD) += c67x00/
4041

drivers/usb/chipidea/core.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1084,6 +1084,10 @@ static int ci_hdrc_probe(struct platform_device *pdev)
10841084
return -ENODEV;
10851085
}
10861086

1087+
ret = ci_ulpi_init(ci);
1088+
if (ret)
1089+
return ret;
1090+
10871091
if (ci->platdata->phy) {
10881092
ci->phy = ci->platdata->phy;
10891093
} else if (ci->platdata->usb_phy) {
@@ -1138,10 +1142,6 @@ static int ci_hdrc_probe(struct platform_device *pdev)
11381142
goto ulpi_exit;
11391143
}
11401144

1141-
ret = ci_ulpi_init(ci);
1142-
if (ret)
1143-
return ret;
1144-
11451145
ci->hw_bank.phys = res->start;
11461146

11471147
ci->irq = platform_get_irq(pdev, 0);

drivers/usb/chipidea/ulpi.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,11 @@ int ci_ulpi_init(struct ci_hdrc *ci)
6868
if (ci->platdata->phy_mode != USBPHY_INTERFACE_MODE_ULPI)
6969
return 0;
7070

71+
/*
72+
* Set PORTSC correctly so we can read/write ULPI registers for
73+
* identification purposes
74+
*/
75+
hw_phymode_configure(ci);
7176

7277
ci->ulpi_ops.read = ci_ulpi_read;
7378
ci->ulpi_ops.write = ci_ulpi_write;

drivers/usb/class/cdc-wdm.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -266,14 +266,14 @@ static void wdm_int_callback(struct urb *urb)
266266
dev_err(&desc->intf->dev, "Stall on int endpoint\n");
267267
goto sw; /* halt is cleared in work */
268268
default:
269-
dev_err(&desc->intf->dev,
269+
dev_err_ratelimited(&desc->intf->dev,
270270
"nonzero urb status received: %d\n", status);
271271
break;
272272
}
273273
}
274274

275275
if (urb->actual_length < sizeof(struct usb_cdc_notification)) {
276-
dev_err(&desc->intf->dev, "wdm_int_callback - %d bytes\n",
276+
dev_err_ratelimited(&desc->intf->dev, "wdm_int_callback - %d bytes\n",
277277
urb->actual_length);
278278
goto exit;
279279
}

drivers/usb/core/hcd.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1623,6 +1623,7 @@ static void __usb_hcd_giveback_urb(struct urb *urb)
16231623
struct usb_hcd *hcd = bus_to_hcd(urb->dev->bus);
16241624
struct usb_anchor *anchor = urb->anchor;
16251625
int status = urb->unlinked;
1626+
unsigned long flags;
16261627

16271628
urb->hcpriv = NULL;
16281629
if (unlikely((urb->transfer_flags & URB_SHORT_NOT_OK) &&
@@ -1640,13 +1641,14 @@ static void __usb_hcd_giveback_urb(struct urb *urb)
16401641
/* pass ownership to the completion handler */
16411642
urb->status = status;
16421643
/*
1643-
* This function can be called in task context inside another remote
1644-
* coverage collection section, but kcov doesn't support that kind of
1645-
* recursion yet. Only collect coverage in softirq context for now.
1644+
* Only collect coverage in the softirq context and disable interrupts
1645+
* to avoid scenarios with nested remote coverage collection sections
1646+
* that KCOV does not support.
1647+
* See the comment next to kcov_remote_start_usb_softirq() for details.
16461648
*/
1647-
kcov_remote_start_usb_softirq((u64)urb->dev->bus->busnum);
1649+
flags = kcov_remote_start_usb_softirq((u64)urb->dev->bus->busnum);
16481650
urb->complete(urb);
1649-
kcov_remote_stop_softirq();
1651+
kcov_remote_stop_softirq(flags);
16501652

16511653
usb_anchor_resume_wakeups(anchor);
16521654
atomic_dec(&urb->use_count);

drivers/usb/host/xhci-pci.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636

3737
#define PCI_VENDOR_ID_ETRON 0x1b6f
3838
#define PCI_DEVICE_ID_EJ168 0x7023
39+
#define PCI_DEVICE_ID_EJ188 0x7052
3940

4041
#define PCI_DEVICE_ID_INTEL_LYNXPOINT_XHCI 0x8c31
4142
#define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI 0x9c31
@@ -395,6 +396,12 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
395396
xhci->quirks |= XHCI_RESET_ON_RESUME;
396397
xhci->quirks |= XHCI_BROKEN_STREAMS;
397398
}
399+
if (pdev->vendor == PCI_VENDOR_ID_ETRON &&
400+
pdev->device == PCI_DEVICE_ID_EJ188) {
401+
xhci->quirks |= XHCI_RESET_ON_RESUME;
402+
xhci->quirks |= XHCI_BROKEN_STREAMS;
403+
}
404+
398405
if (pdev->vendor == PCI_VENDOR_ID_RENESAS &&
399406
pdev->device == 0x0014) {
400407
xhci->quirks |= XHCI_ZERO_64B_REGS;

drivers/usb/host/xhci-ring.c

Lines changed: 45 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1031,13 +1031,27 @@ static int xhci_invalidate_cancelled_tds(struct xhci_virt_ep *ep)
10311031
break;
10321032
case TD_DIRTY: /* TD is cached, clear it */
10331033
case TD_HALTED:
1034+
case TD_CLEARING_CACHE_DEFERRED:
1035+
if (cached_td) {
1036+
if (cached_td->urb->stream_id != td->urb->stream_id) {
1037+
/* Multiple streams case, defer move dq */
1038+
xhci_dbg(xhci,
1039+
"Move dq deferred: stream %u URB %p\n",
1040+
td->urb->stream_id, td->urb);
1041+
td->cancel_status = TD_CLEARING_CACHE_DEFERRED;
1042+
break;
1043+
}
1044+
1045+
/* Should never happen, but clear the TD if it does */
1046+
xhci_warn(xhci,
1047+
"Found multiple active URBs %p and %p in stream %u?\n",
1048+
td->urb, cached_td->urb,
1049+
td->urb->stream_id);
1050+
td_to_noop(xhci, ring, cached_td, false);
1051+
cached_td->cancel_status = TD_CLEARED;
1052+
}
1053+
10341054
td->cancel_status = TD_CLEARING_CACHE;
1035-
if (cached_td)
1036-
/* FIXME stream case, several stopped rings */
1037-
xhci_dbg(xhci,
1038-
"Move dq past stream %u URB %p instead of stream %u URB %p\n",
1039-
td->urb->stream_id, td->urb,
1040-
cached_td->urb->stream_id, cached_td->urb);
10411055
cached_td = td;
10421056
break;
10431057
}
@@ -1057,10 +1071,16 @@ static int xhci_invalidate_cancelled_tds(struct xhci_virt_ep *ep)
10571071
if (err) {
10581072
/* Failed to move past cached td, just set cached TDs to no-op */
10591073
list_for_each_entry_safe(td, tmp_td, &ep->cancelled_td_list, cancelled_td_list) {
1060-
if (td->cancel_status != TD_CLEARING_CACHE)
1074+
/*
1075+
* Deferred TDs need to have the deq pointer set after the above command
1076+
* completes, so if that failed we just give up on all of them (and
1077+
* complain loudly since this could cause issues due to caching).
1078+
*/
1079+
if (td->cancel_status != TD_CLEARING_CACHE &&
1080+
td->cancel_status != TD_CLEARING_CACHE_DEFERRED)
10611081
continue;
1062-
xhci_dbg(xhci, "Failed to clear cancelled cached URB %p, mark clear anyway\n",
1063-
td->urb);
1082+
xhci_warn(xhci, "Failed to clear cancelled cached URB %p, mark clear anyway\n",
1083+
td->urb);
10641084
td_to_noop(xhci, ring, td, false);
10651085
td->cancel_status = TD_CLEARED;
10661086
}
@@ -1346,6 +1366,7 @@ static void xhci_handle_cmd_set_deq(struct xhci_hcd *xhci, int slot_id,
13461366
struct xhci_ep_ctx *ep_ctx;
13471367
struct xhci_slot_ctx *slot_ctx;
13481368
struct xhci_td *td, *tmp_td;
1369+
bool deferred = false;
13491370

13501371
ep_index = TRB_TO_EP_INDEX(le32_to_cpu(trb->generic.field[3]));
13511372
stream_id = TRB_TO_STREAM_ID(le32_to_cpu(trb->generic.field[2]));
@@ -1432,6 +1453,8 @@ static void xhci_handle_cmd_set_deq(struct xhci_hcd *xhci, int slot_id,
14321453
xhci_dbg(ep->xhci, "%s: Giveback cancelled URB %p TD\n",
14331454
__func__, td->urb);
14341455
xhci_td_cleanup(ep->xhci, td, ep_ring, td->status);
1456+
} else if (td->cancel_status == TD_CLEARING_CACHE_DEFERRED) {
1457+
deferred = true;
14351458
} else {
14361459
xhci_dbg(ep->xhci, "%s: Keep cancelled URB %p TD as cancel_status is %d\n",
14371460
__func__, td->urb, td->cancel_status);
@@ -1441,8 +1464,17 @@ static void xhci_handle_cmd_set_deq(struct xhci_hcd *xhci, int slot_id,
14411464
ep->ep_state &= ~SET_DEQ_PENDING;
14421465
ep->queued_deq_seg = NULL;
14431466
ep->queued_deq_ptr = NULL;
1444-
/* Restart any rings with pending URBs */
1445-
ring_doorbell_for_active_rings(xhci, slot_id, ep_index);
1467+
1468+
if (deferred) {
1469+
/* We have more streams to clear */
1470+
xhci_dbg(ep->xhci, "%s: Pending TDs to clear, continuing with invalidation\n",
1471+
__func__);
1472+
xhci_invalidate_cancelled_tds(ep);
1473+
} else {
1474+
/* Restart any rings with pending URBs */
1475+
xhci_dbg(ep->xhci, "%s: All TDs cleared, ring doorbell\n", __func__);
1476+
ring_doorbell_for_active_rings(xhci, slot_id, ep_index);
1477+
}
14461478
}
14471479

14481480
static void xhci_handle_cmd_reset_ep(struct xhci_hcd *xhci, int slot_id,
@@ -2524,9 +2556,8 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_virt_ep *ep,
25242556
goto finish_td;
25252557
case COMP_STOPPED_LENGTH_INVALID:
25262558
/* stopped on ep trb with invalid length, exclude it */
2527-
ep_trb_len = 0;
2528-
remaining = 0;
2529-
break;
2559+
td->urb->actual_length = sum_trb_lengths(xhci, ep_ring, ep_trb);
2560+
goto finish_td;
25302561
case COMP_USB_TRANSACTION_ERROR:
25312562
if (xhci->quirks & XHCI_NO_SOFT_RETRY ||
25322563
(ep->err_count++ > MAX_SOFT_RETRY) ||

drivers/usb/host/xhci.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1276,6 +1276,7 @@ enum xhci_cancelled_td_status {
12761276
TD_DIRTY = 0,
12771277
TD_HALTED,
12781278
TD_CLEARING_CACHE,
1279+
TD_CLEARING_CACHE_DEFERRED,
12791280
TD_CLEARED,
12801281
};
12811282

0 commit comments

Comments
 (0)